jerin commited on
Commit
8e50b17
1 Parent(s): 0c3f62c

update dashbord with fault color

Browse files
Files changed (3) hide show
  1. dashboard.py +44 -19
  2. src/rtu/RTUAnomalizer1.py +12 -10
  3. src/rtu/RTUAnomalizer2.py +10 -8
dashboard.py CHANGED
@@ -11,6 +11,7 @@ import mqtt_client
11
  import time
12
  from src.rtu.RTUPipeline import RTUPipeline
13
  from src.rtu.RTUAnomalizer1 import RTUAnomalizer1
 
14
  import plotly.express as px
15
 
16
  rtu_data_pipeline = RTUPipeline(
@@ -38,15 +39,15 @@ rtu_anomalizers.append(
38
  )
39
 
40
  rtu_anomalizers.append(
41
- RTUAnomalizer1(
42
- prediction_model_path="src/rtu/models/lstm_2rtu_smooth_04.keras",
43
  clustering_model_paths=[
44
- "src/rtu/models/kmeans_rtu_1.pkl",
45
- "src/rtu/models/kmeans_rtu_2.pkl",
46
  ],
47
  pca_model_paths=[
48
- "src/rtu/models/pca_rtu_1.pkl",
49
- "src/rtu/models/pca_rtu_2.pkl",
50
  ],
51
  num_inputs=rtu_data_pipeline.num_inputs,
52
  num_outputs=rtu_data_pipeline.num_outputs,
@@ -159,12 +160,21 @@ for i in range(4):
159
 
160
 
161
  # Temperatures streaming and updates
162
- def update_status_boxes(df):
163
  for i in range(4):
164
  sa_temp = df[f"rtu_00{i+1}_sa_temp"].iloc[-1]
165
  ra_temp = df[f"rtu_00{i+1}_ra_temp"].iloc[-1]
166
  rtu_placeholders[i]["sa_temp"].markdown(f"**SA temp:** {sa_temp} °F")
167
  rtu_placeholders[i]["ra_temp"].markdown(f"**RA temp:** {ra_temp} °F")
 
 
 
 
 
 
 
 
 
168
 
169
 
170
  # Zones
@@ -344,7 +354,7 @@ with st.container():
344
  distances = []
345
 
346
 
347
- def create_residual_plot(resid_pca_list, rtu_id, lim=8):
348
  if rtu_id % 2 == 1:
349
  ax1 = 0
350
  ax2 = 1
@@ -354,6 +364,7 @@ def create_residual_plot(resid_pca_list, rtu_id, lim=8):
354
  fig = px.scatter(
355
  x=resid_pca_list[:, ax1],
356
  y=resid_pca_list[:, ax2],
 
357
  labels={"x": "Time", "y": "Residual"},
358
  width=500,
359
  height=500,
@@ -372,7 +383,7 @@ def create_residual_plot(resid_pca_list, rtu_id, lim=8):
372
  hoverlabel_font_color="black",
373
  hoverlabel_bordercolor="lightgray",
374
  )
375
- fig.update_traces(marker=dict(size=5, color="blue"))
376
 
377
  return fig
378
 
@@ -401,12 +412,20 @@ while True:
401
  )
402
 
403
  # Loop to update
404
- update_status_boxes(df)
405
 
406
  dist = None
407
  resid_pca_list_rtu = None
408
  resid_pca_list_rtu_2 = None
409
  resid_pca_list_vav_1 = None
 
 
 
 
 
 
 
 
410
 
411
  df_new1, df_trans1, df_new2, df_trans2 = rtu_data_pipeline.fit(
412
  pd.DataFrame(mqtt_client.data_list)
@@ -430,7 +449,10 @@ while True:
430
  resid_list,
431
  resid_pca_list_rtu,
432
  dist,
433
- over_threshold,
 
 
 
434
  ) = rtu_anomalizers[0].pipeline(
435
  df_new1, df_trans1, rtu_data_pipeline.scaler1
436
  )
@@ -440,7 +462,10 @@ while True:
440
  resid_list_2,
441
  resid_pca_list_rtu_2,
442
  dist_2,
443
- over_threshold_2,
 
 
 
444
  ) = rtu_anomalizers[1].pipeline(
445
  df_new1, df_trans1, rtu_data_pipeline.scaler1
446
  )
@@ -464,31 +489,31 @@ while True:
464
  resid_rtu1_placeholder, resid_rtu2_placeholder = st.columns(2)
465
  with resid_rtu1_placeholder:
466
  st.subheader("RTU 1 Residuals")
467
- fig = create_residual_plot(resid_pca_list_rtu, rtu_id=1)
468
  st.plotly_chart(fig)
469
 
470
  with resid_rtu2_placeholder:
471
  st.subheader("RTU 2 Residuals")
472
- fig = create_residual_plot(resid_pca_list_rtu, rtu_id=2)
473
  st.plotly_chart(fig)
474
 
475
  resid_rtu3_placeholder, resid_rtu4_placeholder = st.columns(2)
476
  with resid_rtu3_placeholder:
477
  st.subheader("RTU 3 Residuals")
478
- fig = create_residual_plot(resid_pca_list_rtu, rtu_id=3)
479
  st.plotly_chart(fig)
480
 
481
  with resid_rtu4_placeholder:
482
  st.subheader("RTU 4 Residuals")
483
- fig = create_residual_plot(resid_pca_list_rtu, rtu_id=4)
484
  st.plotly_chart(fig)
485
 
486
  if resid_pca_list_vav_1 is not None:
487
- print(resid_pca_list_vav_1)
488
  with resid_vav_placeholder.container():
489
  st.subheader("VAV 1 Residuals")
490
  fig = create_residual_plot(
491
- np.array(resid_pca_list_vav_1), rtu_id=1, lim=15
492
  )
493
  st.plotly_chart(fig)
494
 
@@ -507,5 +532,5 @@ while True:
507
  # ax.set_xlabel("Time")
508
  # ax.set_ylabel("Energy (kWh)")
509
  # st.pyplot(fig)
510
-
511
  mqtt_client.data_list.clear()
 
11
  import time
12
  from src.rtu.RTUPipeline import RTUPipeline
13
  from src.rtu.RTUAnomalizer1 import RTUAnomalizer1
14
+ from src.rtu.RTUAnomalizer2 import RTUAnomalizer2
15
  import plotly.express as px
16
 
17
  rtu_data_pipeline = RTUPipeline(
 
39
  )
40
 
41
  rtu_anomalizers.append(
42
+ RTUAnomalizer2(
43
+ prediction_model_path="src/rtu/models/lstm_2rtu_smooth_03.keras",
44
  clustering_model_paths=[
45
+ "src/rtu/models/kmeans_rtu_3.pkl",
46
+ "src/rtu/models/kmeans_rtu_4.pkl",
47
  ],
48
  pca_model_paths=[
49
+ "src/rtu/models/pca_rtu_3.pkl",
50
+ "src/rtu/models/pca_rtu_4.pkl",
51
  ],
52
  num_inputs=rtu_data_pipeline.num_inputs,
53
  num_outputs=rtu_data_pipeline.num_outputs,
 
160
 
161
 
162
  # Temperatures streaming and updates
163
+ def update_status_boxes(df,fault):
164
  for i in range(4):
165
  sa_temp = df[f"rtu_00{i+1}_sa_temp"].iloc[-1]
166
  ra_temp = df[f"rtu_00{i+1}_ra_temp"].iloc[-1]
167
  rtu_placeholders[i]["sa_temp"].markdown(f"**SA temp:** {sa_temp} °F")
168
  rtu_placeholders[i]["ra_temp"].markdown(f"**RA temp:** {ra_temp} °F")
169
+ if fault[i]== 1:
170
+ rtu_placeholders[i]["box"].markdown(
171
+ f"""
172
+ <div style='background-color:#ff4d4d;padding:3px;border-radius:5px;margin-bottom:10px'>
173
+ <h4 style='color:black;text-align:center;'>RTU{i+1}</h4>
174
+ </div>
175
+ """,
176
+ unsafe_allow_html=True,
177
+ )
178
 
179
 
180
  # Zones
 
354
  distances = []
355
 
356
 
357
+ def create_residual_plot(resid_pca_list, distance, rtu_id,lim=8):
358
  if rtu_id % 2 == 1:
359
  ax1 = 0
360
  ax2 = 1
 
364
  fig = px.scatter(
365
  x=resid_pca_list[:, ax1],
366
  y=resid_pca_list[:, ax2],
367
+ color=distance,
368
  labels={"x": "Time", "y": "Residual"},
369
  width=500,
370
  height=500,
 
383
  hoverlabel_font_color="black",
384
  hoverlabel_bordercolor="lightgray",
385
  )
386
+ # fig.update_traces(marker=dict(size=5, color="blue"))
387
 
388
  return fig
389
 
 
412
  )
413
 
414
  # Loop to update
415
+
416
 
417
  dist = None
418
  resid_pca_list_rtu = None
419
  resid_pca_list_rtu_2 = None
420
  resid_pca_list_vav_1 = None
421
+ rtu_1_distance = None
422
+ rtu_2_distance = None
423
+ fault_1 = None
424
+ fault_2 = None
425
+ rtu_3_distance = None
426
+ rtu_4_distance = None
427
+ fault_3 = None
428
+ fault_4 = None
429
 
430
  df_new1, df_trans1, df_new2, df_trans2 = rtu_data_pipeline.fit(
431
  pd.DataFrame(mqtt_client.data_list)
 
449
  resid_list,
450
  resid_pca_list_rtu,
451
  dist,
452
+ rtu_1_distance,
453
+ rtu_2_distance,
454
+ fault_1,
455
+ fault_2
456
  ) = rtu_anomalizers[0].pipeline(
457
  df_new1, df_trans1, rtu_data_pipeline.scaler1
458
  )
 
462
  resid_list_2,
463
  resid_pca_list_rtu_2,
464
  dist_2,
465
+ rtu_3_distance,
466
+ rtu_4_distance,
467
+ fault_3,
468
+ fault_4
469
  ) = rtu_anomalizers[1].pipeline(
470
  df_new1, df_trans1, rtu_data_pipeline.scaler1
471
  )
 
489
  resid_rtu1_placeholder, resid_rtu2_placeholder = st.columns(2)
490
  with resid_rtu1_placeholder:
491
  st.subheader("RTU 1 Residuals")
492
+ fig = create_residual_plot(resid_pca_list_rtu, rtu_1_distance, rtu_id=1)
493
  st.plotly_chart(fig)
494
 
495
  with resid_rtu2_placeholder:
496
  st.subheader("RTU 2 Residuals")
497
+ fig = create_residual_plot(resid_pca_list_rtu, rtu_2_distance, rtu_id=2)
498
  st.plotly_chart(fig)
499
 
500
  resid_rtu3_placeholder, resid_rtu4_placeholder = st.columns(2)
501
  with resid_rtu3_placeholder:
502
  st.subheader("RTU 3 Residuals")
503
+ fig = create_residual_plot(resid_pca_list_rtu, rtu_3_distance, rtu_id=3)
504
  st.plotly_chart(fig)
505
 
506
  with resid_rtu4_placeholder:
507
  st.subheader("RTU 4 Residuals")
508
+ fig = create_residual_plot(resid_pca_list_rtu, rtu_4_distance, rtu_id=4)
509
  st.plotly_chart(fig)
510
 
511
  if resid_pca_list_vav_1 is not None:
512
+ # print(resid_pca_list_vav_1)
513
  with resid_vav_placeholder.container():
514
  st.subheader("VAV 1 Residuals")
515
  fig = create_residual_plot(
516
+ np.array(resid_pca_list_vav_1),rtu_4_distance, rtu_id=1, lim=15
517
  )
518
  st.plotly_chart(fig)
519
 
 
532
  # ax.set_xlabel("Time")
533
  # ax.set_ylabel("Energy (kWh)")
534
  # st.pyplot(fig)
535
+ update_status_boxes(df,[fault_1,fault_2,fault_3,fault_4])
536
  mqtt_client.data_list.clear()
src/rtu/RTUAnomalizer1.py CHANGED
@@ -44,8 +44,8 @@ class RTUAnomalizer1:
44
  self.initialize_lists()
45
  )
46
 
47
- self.fault_1 = None
48
- self.fault_2 = None
49
 
50
  def initialize_lists(self, size=30):
51
  """
@@ -59,7 +59,7 @@ class RTUAnomalizer1:
59
  """
60
  initial_values = [[0] * self.num_outputs] * size
61
  initial_values1 = [[0] * 4] * size
62
- initial_values2 = [[0] * 2] * size*2
63
  return (
64
  initial_values.copy(),
65
  initial_values.copy(),
@@ -197,8 +197,8 @@ class RTUAnomalizer1:
197
  axis=1,
198
  )
199
  )
200
- self.distance_list.pop(0)
201
- self.distance_list.append(dist)
202
  resid_pcas = np.array(resid_pcas).flatten().tolist()
203
  self.resid_pca_list.pop(0)
204
  self.resid_pca_list.append(resid_pcas)
@@ -206,12 +206,14 @@ class RTUAnomalizer1:
206
  return np.array(dist)
207
  def fault_windowing(self):
208
  rtu_1_dist = np.array(self.distance_list).T[0]>1 #rtu_1_threshold
209
- if sum(rtu_1_dist)>80*60: # 80% of the 60 min window
 
210
  self.fault_1 = 1
211
  else:
212
  self.fault_1 = 0
213
- rtu_2_dist = np.array(self.distance_list).T[1]>2.5 #rtu_2_threshold
214
- if sum(rtu_2_dist)>80*60: # 80% of the 60 min window
 
215
  self.fault_2 = 1
216
  else:
217
  self.fault_2 = 0
@@ -235,7 +237,7 @@ class RTUAnomalizer1:
235
  actual, pred = self.inverse_transform(scaler, pred, df_trans)
236
  actual_list, pred_list, resid_list = self.update_lists(actual, pred, resid)
237
  dist = self.calculate_distances(resid)
238
-
239
  return (
240
  actual_list,
241
  pred_list,
@@ -243,7 +245,7 @@ class RTUAnomalizer1:
243
  self.resid_pca_list,
244
  dist,
245
  np.array(self.distance_list[30:]).T[0]>1, #rtu_1_threshold
246
- np.array(self.distance_list[30:]).T[1]>2.5, #rtu_2_threshold
247
  self.fault_1,
248
  self.fault_2
249
  )
 
44
  self.initialize_lists()
45
  )
46
 
47
+ self.fault_1 = 0
48
+ self.fault_2 = 0
49
 
50
  def initialize_lists(self, size=30):
51
  """
 
59
  """
60
  initial_values = [[0] * self.num_outputs] * size
61
  initial_values1 = [[0] * 4] * size
62
+ initial_values2 = [[0] * 2] * 60
63
  return (
64
  initial_values.copy(),
65
  initial_values.copy(),
 
197
  axis=1,
198
  )
199
  )
200
+ self.distance_list.pop(0)
201
+ self.distance_list.append(np.concatenate(dist).tolist())
202
  resid_pcas = np.array(resid_pcas).flatten().tolist()
203
  self.resid_pca_list.pop(0)
204
  self.resid_pca_list.append(resid_pcas)
 
206
  return np.array(dist)
207
  def fault_windowing(self):
208
  rtu_1_dist = np.array(self.distance_list).T[0]>1 #rtu_1_threshold
209
+ rtu_1_dist = [int(x) for x in rtu_1_dist]
210
+ if sum(rtu_1_dist)>0.8*60: # 80% of the 60 min window
211
  self.fault_1 = 1
212
  else:
213
  self.fault_1 = 0
214
+ rtu_2_dist = np.array(self.distance_list).T[1]>0.5 #rtu_2_threshold
215
+ rtu_2_dist = [int(x) for x in rtu_2_dist]
216
+ if sum(rtu_2_dist)>0.05*60: # 80% of the 60 min window
217
  self.fault_2 = 1
218
  else:
219
  self.fault_2 = 0
 
237
  actual, pred = self.inverse_transform(scaler, pred, df_trans)
238
  actual_list, pred_list, resid_list = self.update_lists(actual, pred, resid)
239
  dist = self.calculate_distances(resid)
240
+ self.fault_windowing()
241
  return (
242
  actual_list,
243
  pred_list,
 
245
  self.resid_pca_list,
246
  dist,
247
  np.array(self.distance_list[30:]).T[0]>1, #rtu_1_threshold
248
+ np.array(self.distance_list[30:]).T[1]>0.5, #rtu_2_threshold
249
  self.fault_1,
250
  self.fault_2
251
  )
src/rtu/RTUAnomalizer2.py CHANGED
@@ -3,7 +3,7 @@ from tensorflow.keras.models import load_model
3
  import joblib
4
 
5
 
6
- class RTUAnomalizer1:
7
  """
8
  Class for performing anomaly detection on RTU (Roof Top Unit) data.
9
  """
@@ -44,8 +44,8 @@ class RTUAnomalizer1:
44
  self.initialize_lists()
45
  )
46
 
47
- self.fault_1 = None
48
- self.fault_2 = None
49
 
50
  def initialize_lists(self, size=30):
51
  """
@@ -197,8 +197,8 @@ class RTUAnomalizer1:
197
  axis=1,
198
  )
199
  )
200
- self.distance_list.pop(0)
201
- self.distance_list.append(dist)
202
  resid_pcas = np.array(resid_pcas).flatten().tolist()
203
  self.resid_pca_list.pop(0)
204
  self.resid_pca_list.append(resid_pcas)
@@ -206,12 +206,14 @@ class RTUAnomalizer1:
206
  return np.array(dist)
207
  def fault_windowing(self):
208
  rtu_1_dist = np.array(self.distance_list).T[0]>1.5 #rtu_3_threshold
209
- if sum(rtu_1_dist)>80*60: # 80% of the 60 min window
 
210
  self.fault_1 = 1
211
  else:
212
  self.fault_1 = 0
213
  rtu_2_dist = np.array(self.distance_list).T[1]>1.5 #rtu_4_threshold
214
- if sum(rtu_2_dist)>80*60: # 80% of the 60 min window
 
215
  self.fault_2 = 1
216
  else:
217
  self.fault_2 = 0
@@ -235,7 +237,7 @@ class RTUAnomalizer1:
235
  actual, pred = self.inverse_transform(scaler, pred, df_trans)
236
  actual_list, pred_list, resid_list = self.update_lists(actual, pred, resid)
237
  dist = self.calculate_distances(resid)
238
-
239
  return (
240
  actual_list,
241
  pred_list,
 
3
  import joblib
4
 
5
 
6
+ class RTUAnomalizer2:
7
  """
8
  Class for performing anomaly detection on RTU (Roof Top Unit) data.
9
  """
 
44
  self.initialize_lists()
45
  )
46
 
47
+ self.fault_1 = 0
48
+ self.fault_2 = 0
49
 
50
  def initialize_lists(self, size=30):
51
  """
 
197
  axis=1,
198
  )
199
  )
200
+ self.distance_list.pop(0)
201
+ self.distance_list.append(np.concatenate(dist).tolist())
202
  resid_pcas = np.array(resid_pcas).flatten().tolist()
203
  self.resid_pca_list.pop(0)
204
  self.resid_pca_list.append(resid_pcas)
 
206
  return np.array(dist)
207
  def fault_windowing(self):
208
  rtu_1_dist = np.array(self.distance_list).T[0]>1.5 #rtu_3_threshold
209
+ rtu_1_dist = [int(x) for x in rtu_1_dist]
210
+ if sum(rtu_1_dist)>0.8*60: # 80% of the 60 min window
211
  self.fault_1 = 1
212
  else:
213
  self.fault_1 = 0
214
  rtu_2_dist = np.array(self.distance_list).T[1]>1.5 #rtu_4_threshold
215
+ rtu_2_dist = [int(x) for x in rtu_2_dist]
216
+ if sum(rtu_2_dist)>0.8*60: # 80% of the 60 min window
217
  self.fault_2 = 1
218
  else:
219
  self.fault_2 = 0
 
237
  actual, pred = self.inverse_transform(scaler, pred, df_trans)
238
  actual_list, pred_list, resid_list = self.update_lists(actual, pred, resid)
239
  dist = self.calculate_distances(resid)
240
+ self.fault_windowing()
241
  return (
242
  actual_list,
243
  pred_list,