Spaces:
Sleeping
Sleeping
akshayballal
commited on
Commit
•
3759ba9
1
Parent(s):
2bc71f8
chore: Remove unused pickle files and refactor VAV module
Browse files- dashboard.py +185 -67
- physLSTM/kmeans_vav_2.pkl +0 -3
- physLSTM/lstm_vav_02.keras +0 -0
- physLSTM/lstm_vav_rtu1.ipynb +0 -0
- physLSTM/lstm_vav_rtu2.ipynb +0 -0
- physLSTM/lstm_vav_rtu3.ipynb +0 -0
- physLSTM/lstm_vav_rtu4.ipynb +0 -0
- pipeline.ipynb +0 -132
- src/energy_prediction/EnergyPredictionPipeline.py +5 -5
- src/energy_prediction/models/lstm_energy_north_01.keras +0 -0
- src/energy_prediction/models/lstm_energy_south_01.keras +0 -0
- src/vav/VAVPipeline.py +28 -2
- src/vav/models/kmeans_vav_2.pkl +1 -1
- src/vav/models/kmeans_vav_3.pkl +2 -2
- src/vav/models/kmeans_vav_4.pkl +2 -2
- src/vav/models/lstm_vav_02.keras +0 -0
- src/vav/models/lstm_vav_03.keras +0 -0
- src/vav/models/lstm_vav_04.keras +0 -0
- src/vav/models/pca_vav_2.pkl +1 -1
- physLSTM/pca_vav_2.pkl → src/vav/models/pca_vav_3.pkl +2 -2
- physLSTM/scaler_vav_1.pkl → src/vav/models/pca_vav_4.pkl +2 -2
- src/vav/models/scaler_vav_2.pkl +2 -2
- src/vav/models/scaler_vav_3.pkl +2 -2
- src/vav/models/scaler_vav_4.pkl +2 -2
- streamlit.py +0 -260
dashboard.py
CHANGED
@@ -56,12 +56,12 @@ rtu_anomalizers.append(
|
|
56 |
|
57 |
vav_pipelines = []
|
58 |
vav_anomalizers = []
|
59 |
-
for i in range(1,
|
60 |
vav_pipelines.append(
|
61 |
VAVPipeline(rtu_id=i, scaler_path=f"src/vav/models/scaler_vav_{i}.pkl")
|
62 |
)
|
63 |
|
64 |
-
for i in range(1,
|
65 |
vav_anomalizers.append(
|
66 |
VAVAnomalizer(
|
67 |
rtu_id=i,
|
@@ -75,26 +75,26 @@ for i in range(1, 2):
|
|
75 |
|
76 |
|
77 |
all_data = pd.read_csv("data/bootstrap_data.csv")
|
78 |
-
df_faults = pd.DataFrame(columns
|
79 |
-
current_stat = [False,False,False,False]
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
|
99 |
|
100 |
# Set the layout of the page to 'wide'
|
@@ -161,13 +161,13 @@ for i in range(4):
|
|
161 |
|
162 |
|
163 |
# Temperatures streaming and updates
|
164 |
-
def update_status_boxes(df,fault):
|
165 |
for i in range(4):
|
166 |
sa_temp = df[f"rtu_00{i+1}_sa_temp"].iloc[-1]
|
167 |
ra_temp = df[f"rtu_00{i+1}_ra_temp"].iloc[-1]
|
168 |
rtu_placeholders[i]["sa_temp"].markdown(f"**SA temp:** {sa_temp} °F")
|
169 |
rtu_placeholders[i]["ra_temp"].markdown(f"**RA temp:** {ra_temp} °F")
|
170 |
-
if fault[i]== 1:
|
171 |
rtu_placeholders[i]["box"].markdown(
|
172 |
f"""
|
173 |
<div style='background-color:#ff4d4d;padding:3px;border-radius:5px;margin-bottom:10px'>
|
@@ -176,8 +176,6 @@ def update_status_boxes(df,fault):
|
|
176 |
""",
|
177 |
unsafe_allow_html=True,
|
178 |
)
|
179 |
-
|
180 |
-
|
181 |
|
182 |
|
183 |
# Zones
|
@@ -304,19 +302,24 @@ with row1_col3:
|
|
304 |
</div>""",
|
305 |
unsafe_allow_html=True,
|
306 |
)
|
307 |
-
|
308 |
fault_placeholder["dataframe"].dataframe(df_faults)
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
|
|
|
|
|
|
|
|
313 |
current_stat[i] = True
|
314 |
-
|
315 |
-
if fault[i]== 0 and current_stat[i] == True:
|
316 |
-
df_faults.loc[len(df_faults)] = [df_time,f
|
317 |
current_stat[i] = False
|
318 |
fault_placeholder["dataframe"].dataframe(df_faults)
|
319 |
|
|
|
320 |
# Details
|
321 |
with st.container():
|
322 |
st.markdown(
|
@@ -361,7 +364,7 @@ with st.container():
|
|
361 |
distances = []
|
362 |
|
363 |
|
364 |
-
def create_residual_plot(resid_pca_list, distance, rtu_id,lim=8):
|
365 |
if rtu_id % 2 == 1:
|
366 |
ax1 = 0
|
367 |
ax2 = 1
|
@@ -401,7 +404,6 @@ resid_placeholder = st.empty()
|
|
401 |
resid_vav_placeholder = st.empty()
|
402 |
|
403 |
|
404 |
-
|
405 |
while True:
|
406 |
|
407 |
if mqtt_client.data_list:
|
@@ -422,12 +424,12 @@ while True:
|
|
422 |
)
|
423 |
|
424 |
# Loop to update
|
425 |
-
|
426 |
|
427 |
dist = None
|
428 |
resid_pca_list_rtu = None
|
429 |
resid_pca_list_rtu_2 = None
|
430 |
resid_pca_list_vav_1 = None
|
|
|
431 |
rtu_1_distance = None
|
432 |
rtu_2_distance = None
|
433 |
fault_1 = None
|
@@ -436,7 +438,6 @@ while True:
|
|
436 |
rtu_4_distance = None
|
437 |
fault_3 = None
|
438 |
fault_4 = None
|
439 |
-
|
440 |
|
441 |
df_new1, df_trans1, df_new2, df_trans2 = rtu_data_pipeline.fit(
|
442 |
pd.DataFrame(mqtt_client.data_list)
|
@@ -448,6 +449,27 @@ while True:
|
|
448 |
vav_anomalizers[0].num_inputs = vav_pipelines[0].num_inputs
|
449 |
vav_anomalizers[0].num_outputs = vav_pipelines[0].num_outputs
|
450 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
451 |
if (
|
452 |
not df_new1 is None
|
453 |
and not df_trans1 is None
|
@@ -463,7 +485,7 @@ while True:
|
|
463 |
rtu_1_distance,
|
464 |
rtu_2_distance,
|
465 |
fault_1,
|
466 |
-
fault_2
|
467 |
) = rtu_anomalizers[0].pipeline(
|
468 |
df_new1, df_trans1, rtu_data_pipeline.scaler1
|
469 |
)
|
@@ -476,7 +498,7 @@ while True:
|
|
476 |
rtu_3_distance,
|
477 |
rtu_4_distance,
|
478 |
fault_3,
|
479 |
-
fault_4
|
480 |
) = rtu_anomalizers[1].pipeline(
|
481 |
df_new1, df_trans1, rtu_data_pipeline.scaler1
|
482 |
)
|
@@ -491,58 +513,154 @@ while True:
|
|
491 |
vav_1_df_new, vav_1_df_trans, vav_pipelines[0].scaler
|
492 |
)
|
493 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
494 |
if resid_pca_list_rtu is not None:
|
495 |
resid_pca_list_rtu = np.array(resid_pca_list_rtu)
|
496 |
resid_pca_list_rtu_2 = np.array(resid_pca_list_rtu_2)
|
497 |
|
498 |
-
if resid_pca_list_rtu is not None:
|
499 |
with resid_placeholder.container():
|
500 |
resid_rtu1_placeholder, resid_rtu2_placeholder = st.columns(2)
|
501 |
with resid_rtu1_placeholder:
|
502 |
st.subheader("RTU 1 Residuals")
|
503 |
-
fig = create_residual_plot(
|
|
|
|
|
504 |
st.plotly_chart(fig)
|
505 |
|
506 |
with resid_rtu2_placeholder:
|
507 |
st.subheader("RTU 2 Residuals")
|
508 |
-
fig = create_residual_plot(
|
|
|
|
|
509 |
st.plotly_chart(fig)
|
510 |
|
511 |
resid_rtu3_placeholder, resid_rtu4_placeholder = st.columns(2)
|
512 |
with resid_rtu3_placeholder:
|
513 |
st.subheader("RTU 3 Residuals")
|
514 |
-
fig = create_residual_plot(
|
|
|
|
|
515 |
st.plotly_chart(fig)
|
516 |
|
517 |
with resid_rtu4_placeholder:
|
518 |
st.subheader("RTU 4 Residuals")
|
519 |
-
fig = create_residual_plot(
|
|
|
|
|
520 |
st.plotly_chart(fig)
|
521 |
|
522 |
-
if resid_pca_list_vav_1 is not None:
|
523 |
-
|
524 |
with resid_vav_placeholder.container():
|
525 |
-
st.
|
526 |
-
|
527 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
528 |
)
|
|
|
529 |
st.plotly_chart(fig)
|
530 |
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
548 |
mqtt_client.data_list.clear()
|
|
|
56 |
|
57 |
vav_pipelines = []
|
58 |
vav_anomalizers = []
|
59 |
+
for i in range(1, 5):
|
60 |
vav_pipelines.append(
|
61 |
VAVPipeline(rtu_id=i, scaler_path=f"src/vav/models/scaler_vav_{i}.pkl")
|
62 |
)
|
63 |
|
64 |
+
for i in range(1, 5):
|
65 |
vav_anomalizers.append(
|
66 |
VAVAnomalizer(
|
67 |
rtu_id=i,
|
|
|
75 |
|
76 |
|
77 |
all_data = pd.read_csv("data/bootstrap_data.csv")
|
78 |
+
df_faults = pd.DataFrame(columns=["_______Time_______", "__________Issue__________"])
|
79 |
+
current_stat = [False, False, False, False]
|
80 |
+
energy_pipeline_north = EnergyPredictionPipeline(
|
81 |
+
scaler_path="src/energy_prediction/models/scalerNorth.pkl",
|
82 |
+
wing="north",
|
83 |
+
bootstrap_data=all_data,
|
84 |
+
)
|
85 |
+
energy_pipeline_south = EnergyPredictionPipeline(
|
86 |
+
scaler_path="src/energy_prediction/models/scalerSouth.pkl",
|
87 |
+
wing="south",
|
88 |
+
bootstrap_data=all_data,
|
89 |
+
)
|
90 |
+
|
91 |
+
energy_prediction_model_north = EnergyPredictionModel(
|
92 |
+
model_path=r"src/energy_prediction/models/lstm_energy_north_01.keras"
|
93 |
+
)
|
94 |
+
|
95 |
+
energy_prediction_model_south = EnergyPredictionModel(
|
96 |
+
model_path=r"src/energy_prediction/models/lstm_energy_south_01.keras"
|
97 |
+
)
|
98 |
|
99 |
|
100 |
# Set the layout of the page to 'wide'
|
|
|
161 |
|
162 |
|
163 |
# Temperatures streaming and updates
|
164 |
+
def update_status_boxes(df, fault):
|
165 |
for i in range(4):
|
166 |
sa_temp = df[f"rtu_00{i+1}_sa_temp"].iloc[-1]
|
167 |
ra_temp = df[f"rtu_00{i+1}_ra_temp"].iloc[-1]
|
168 |
rtu_placeholders[i]["sa_temp"].markdown(f"**SA temp:** {sa_temp} °F")
|
169 |
rtu_placeholders[i]["ra_temp"].markdown(f"**RA temp:** {ra_temp} °F")
|
170 |
+
if fault[i] == 1:
|
171 |
rtu_placeholders[i]["box"].markdown(
|
172 |
f"""
|
173 |
<div style='background-color:#ff4d4d;padding:3px;border-radius:5px;margin-bottom:10px'>
|
|
|
176 |
""",
|
177 |
unsafe_allow_html=True,
|
178 |
)
|
|
|
|
|
179 |
|
180 |
|
181 |
# Zones
|
|
|
302 |
</div>""",
|
303 |
unsafe_allow_html=True,
|
304 |
)
|
305 |
+
|
306 |
fault_placeholder["dataframe"].dataframe(df_faults)
|
307 |
+
|
308 |
+
|
309 |
+
def fault_table_update(fault, df_faults, current_stat, df_time):
|
310 |
+
if fault[i] == 1 and current_stat[i] == False:
|
311 |
+
df_faults.loc[len(df_faults)] = [
|
312 |
+
df_time,
|
313 |
+
f"RTU_0{i+1}_fan/damper_fault - Start",
|
314 |
+
]
|
315 |
current_stat[i] = True
|
316 |
+
|
317 |
+
if fault[i] == 0 and current_stat[i] == True:
|
318 |
+
df_faults.loc[len(df_faults)] = [df_time, f"RTU_0{i+1}_fan/damper_fault - End"]
|
319 |
current_stat[i] = False
|
320 |
fault_placeholder["dataframe"].dataframe(df_faults)
|
321 |
|
322 |
+
|
323 |
# Details
|
324 |
with st.container():
|
325 |
st.markdown(
|
|
|
364 |
distances = []
|
365 |
|
366 |
|
367 |
+
def create_residual_plot(resid_pca_list, distance, rtu_id, lim=8):
|
368 |
if rtu_id % 2 == 1:
|
369 |
ax1 = 0
|
370 |
ax2 = 1
|
|
|
404 |
resid_vav_placeholder = st.empty()
|
405 |
|
406 |
|
|
|
407 |
while True:
|
408 |
|
409 |
if mqtt_client.data_list:
|
|
|
424 |
)
|
425 |
|
426 |
# Loop to update
|
|
|
427 |
|
428 |
dist = None
|
429 |
resid_pca_list_rtu = None
|
430 |
resid_pca_list_rtu_2 = None
|
431 |
resid_pca_list_vav_1 = None
|
432 |
+
resid_pca_list_vav_2 = None
|
433 |
rtu_1_distance = None
|
434 |
rtu_2_distance = None
|
435 |
fault_1 = None
|
|
|
438 |
rtu_4_distance = None
|
439 |
fault_3 = None
|
440 |
fault_4 = None
|
|
|
441 |
|
442 |
df_new1, df_trans1, df_new2, df_trans2 = rtu_data_pipeline.fit(
|
443 |
pd.DataFrame(mqtt_client.data_list)
|
|
|
449 |
vav_anomalizers[0].num_inputs = vav_pipelines[0].num_inputs
|
450 |
vav_anomalizers[0].num_outputs = vav_pipelines[0].num_outputs
|
451 |
|
452 |
+
vav_2_df_new, vav_2_df_trans = vav_pipelines[1].fit(
|
453 |
+
pd.DataFrame(mqtt_client.data_list)
|
454 |
+
)
|
455 |
+
vav_anomalizers[1].num_inputs = vav_pipelines[1].num_inputs
|
456 |
+
vav_anomalizers[1].num_outputs = vav_pipelines[1].num_outputs
|
457 |
+
|
458 |
+
vav_3_df_new, vav_3_df_trans = vav_pipelines[2].fit(
|
459 |
+
pd.DataFrame(mqtt_client.data_list)
|
460 |
+
)
|
461 |
+
vav_anomalizers[2].num_inputs = vav_pipelines[2].num_inputs
|
462 |
+
vav_anomalizers[2].num_outputs = vav_pipelines[2].num_outputs
|
463 |
+
|
464 |
+
vav_4_df_new, vav_4_df_trans = vav_pipelines[3].fit(
|
465 |
+
pd.DataFrame(mqtt_client.data_list)
|
466 |
+
)
|
467 |
+
vav_anomalizers[3].num_inputs = vav_pipelines[3].num_inputs
|
468 |
+
vav_anomalizers[3].num_outputs = vav_pipelines[3].num_outputs
|
469 |
+
|
470 |
+
energy_df_north = energy_pipeline_north.fit(all_data)
|
471 |
+
energy_df_south = energy_pipeline_south.fit(all_data)
|
472 |
+
|
473 |
if (
|
474 |
not df_new1 is None
|
475 |
and not df_trans1 is None
|
|
|
485 |
rtu_1_distance,
|
486 |
rtu_2_distance,
|
487 |
fault_1,
|
488 |
+
fault_2,
|
489 |
) = rtu_anomalizers[0].pipeline(
|
490 |
df_new1, df_trans1, rtu_data_pipeline.scaler1
|
491 |
)
|
|
|
498 |
rtu_3_distance,
|
499 |
rtu_4_distance,
|
500 |
fault_3,
|
501 |
+
fault_4,
|
502 |
) = rtu_anomalizers[1].pipeline(
|
503 |
df_new1, df_trans1, rtu_data_pipeline.scaler1
|
504 |
)
|
|
|
513 |
vav_1_df_new, vav_1_df_trans, vav_pipelines[0].scaler
|
514 |
)
|
515 |
|
516 |
+
if not vav_2_df_new is None:
|
517 |
+
(
|
518 |
+
actual_list_vav_2,
|
519 |
+
pred_list_vav_2,
|
520 |
+
resid_list_vav_2,
|
521 |
+
resid_pca_list_vav_2,
|
522 |
+
dist_vav_2,
|
523 |
+
) = vav_anomalizers[1].pipeline(
|
524 |
+
vav_2_df_new, vav_2_df_trans, vav_pipelines[1].scaler
|
525 |
+
)
|
526 |
+
|
527 |
+
if not vav_3_df_new is None:
|
528 |
+
(
|
529 |
+
actual_list_vav_3,
|
530 |
+
pred_list_vav_3,
|
531 |
+
resid_list_vav_3,
|
532 |
+
resid_pca_list_vav_3,
|
533 |
+
dist_vav_3,
|
534 |
+
) = vav_anomalizers[2].pipeline(
|
535 |
+
vav_3_df_new, vav_3_df_trans, vav_pipelines[2].scaler
|
536 |
+
)
|
537 |
+
|
538 |
+
if not vav_4_df_new is None:
|
539 |
+
(
|
540 |
+
actual_list_vav_4,
|
541 |
+
pred_list_vav_4,
|
542 |
+
resid_list_vav_4,
|
543 |
+
resid_pca_list_vav_4,
|
544 |
+
dist_vav_4,
|
545 |
+
) = vav_anomalizers[3].pipeline(
|
546 |
+
vav_4_df_new, vav_4_df_trans, vav_pipelines[3].scaler
|
547 |
+
)
|
548 |
+
|
549 |
if resid_pca_list_rtu is not None:
|
550 |
resid_pca_list_rtu = np.array(resid_pca_list_rtu)
|
551 |
resid_pca_list_rtu_2 = np.array(resid_pca_list_rtu_2)
|
552 |
|
553 |
+
if resid_pca_list_rtu is not None: # Plot RTU residuals
|
554 |
with resid_placeholder.container():
|
555 |
resid_rtu1_placeholder, resid_rtu2_placeholder = st.columns(2)
|
556 |
with resid_rtu1_placeholder:
|
557 |
st.subheader("RTU 1 Residuals")
|
558 |
+
fig = create_residual_plot(
|
559 |
+
resid_pca_list_rtu, rtu_1_distance, rtu_id=1
|
560 |
+
)
|
561 |
st.plotly_chart(fig)
|
562 |
|
563 |
with resid_rtu2_placeholder:
|
564 |
st.subheader("RTU 2 Residuals")
|
565 |
+
fig = create_residual_plot(
|
566 |
+
resid_pca_list_rtu, rtu_2_distance, rtu_id=2
|
567 |
+
)
|
568 |
st.plotly_chart(fig)
|
569 |
|
570 |
resid_rtu3_placeholder, resid_rtu4_placeholder = st.columns(2)
|
571 |
with resid_rtu3_placeholder:
|
572 |
st.subheader("RTU 3 Residuals")
|
573 |
+
fig = create_residual_plot(
|
574 |
+
resid_pca_list_rtu, rtu_3_distance, rtu_id=3
|
575 |
+
)
|
576 |
st.plotly_chart(fig)
|
577 |
|
578 |
with resid_rtu4_placeholder:
|
579 |
st.subheader("RTU 4 Residuals")
|
580 |
+
fig = create_residual_plot(
|
581 |
+
resid_pca_list_rtu, rtu_4_distance, rtu_id=4
|
582 |
+
)
|
583 |
st.plotly_chart(fig)
|
584 |
|
585 |
+
if resid_pca_list_vav_1 is not None: # Plot VAV residuals
|
586 |
+
|
587 |
with resid_vav_placeholder.container():
|
588 |
+
resid_rtu_1_vav_placeholder, resid_rtu_2_vav_placeholder = st.columns(2)
|
589 |
+
|
590 |
+
with resid_rtu_1_vav_placeholder:
|
591 |
+
st.subheader("VAV 1 Residuals")
|
592 |
+
fig = create_residual_plot(
|
593 |
+
np.array(resid_pca_list_vav_1), rtu_4_distance, rtu_id=1, lim=15
|
594 |
+
)
|
595 |
+
st.plotly_chart(fig)
|
596 |
+
|
597 |
+
with resid_rtu_2_vav_placeholder:
|
598 |
+
st.subheader("VAV 2 Residuals")
|
599 |
+
fig = create_residual_plot(
|
600 |
+
np.array(resid_pca_list_vav_2), rtu_4_distance, rtu_id=1, lim=15
|
601 |
+
)
|
602 |
+
st.plotly_chart(fig)
|
603 |
+
|
604 |
+
resid_rtu_3_vav_placeholder, resid_rtu_4_vav_placeholder = st.columns(2)
|
605 |
+
with resid_rtu_3_vav_placeholder:
|
606 |
+
st.subheader("VAV 3 Residuals")
|
607 |
+
fig = create_residual_plot(
|
608 |
+
np.array(resid_pca_list_vav_3), rtu_4_distance, rtu_id=1, lim=15
|
609 |
+
)
|
610 |
+
st.plotly_chart(fig)
|
611 |
+
|
612 |
+
with resid_rtu_4_vav_placeholder:
|
613 |
+
st.subheader("VAV 4 Residuals")
|
614 |
+
fig = create_residual_plot(
|
615 |
+
np.array(resid_pca_list_vav_4), rtu_4_distance, rtu_id=1, lim=15
|
616 |
+
)
|
617 |
+
st.plotly_chart(fig)
|
618 |
+
|
619 |
+
current_time = pd.to_datetime(df_time)
|
620 |
+
|
621 |
+
if energy_df_north is not None:
|
622 |
+
|
623 |
+
energy_prediction_north = energy_prediction_model_north.pipeline(
|
624 |
+
energy_df_north, energy_pipeline_north.scaler
|
625 |
+
).flatten()
|
626 |
+
|
627 |
+
x_time = pd.date_range(
|
628 |
+
current_time, periods=len(energy_prediction_north), freq="1h"
|
629 |
+
)
|
630 |
+
|
631 |
+
with north_wing_energy_container:
|
632 |
+
|
633 |
+
fig = px.line(
|
634 |
+
x=x_time,
|
635 |
+
y=energy_prediction_north,
|
636 |
+
labels={"x": "Time", "y": "Energy (kWh)"},
|
637 |
+
height=200,
|
638 |
)
|
639 |
+
|
640 |
st.plotly_chart(fig)
|
641 |
|
642 |
+
if energy_df_south is not None:
|
643 |
+
energy_prediction_south = energy_prediction_model_south.pipeline(
|
644 |
+
energy_df_south, energy_pipeline_south.scaler
|
645 |
+
).flatten()
|
646 |
+
|
647 |
+
x_time = pd.date_range(
|
648 |
+
current_time, periods=len(energy_prediction_south), freq="1h"
|
649 |
+
)
|
650 |
+
|
651 |
+
with south_wing_energy_container:
|
652 |
+
|
653 |
+
fig = px.line(
|
654 |
+
x=x_time,
|
655 |
+
y=energy_prediction_south,
|
656 |
+
labels={"x": "Time", "y": "Energy (kWh)"},
|
657 |
+
height=200,
|
658 |
+
)
|
659 |
+
|
660 |
+
st.plotly_chart(fig)
|
661 |
+
|
662 |
+
update_status_boxes(df, [fault_1, fault_2, fault_3, fault_4])
|
663 |
+
fault_table_update(
|
664 |
+
[fault_1, fault_2, fault_3, fault_4], df_faults, current_stat, df_time
|
665 |
+
)
|
666 |
mqtt_client.data_list.clear()
|
physLSTM/kmeans_vav_2.pkl
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:eac01ceecdae11713ee21462a8bd3dc7ea32e740c3daa42795b266a05e7c424a
|
3 |
-
size 1567961
|
|
|
|
|
|
|
|
physLSTM/lstm_vav_02.keras
DELETED
Binary file (660 kB)
|
|
physLSTM/lstm_vav_rtu1.ipynb
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
physLSTM/lstm_vav_rtu2.ipynb
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
physLSTM/lstm_vav_rtu3.ipynb
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
physLSTM/lstm_vav_rtu4.ipynb
ADDED
The diff for this file is too large to render.
See raw diff
|
|
pipeline.ipynb
DELETED
@@ -1,132 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"cells": [
|
3 |
-
{
|
4 |
-
"cell_type": "code",
|
5 |
-
"execution_count": null,
|
6 |
-
"metadata": {},
|
7 |
-
"outputs": [],
|
8 |
-
"source": [
|
9 |
-
"import numpy as np\n",
|
10 |
-
"\n",
|
11 |
-
"def initialize_lists(size=30):\n",
|
12 |
-
" initial_values = [0] * size\n",
|
13 |
-
" return initial_values.copy(), initial_values.copy(), initial_values.copy()\n",
|
14 |
-
"\n",
|
15 |
-
"def get_window(df, len_df):\n",
|
16 |
-
" if len_df > 30:\n",
|
17 |
-
" return df[len_df-31:len_df].astype('float32')\n",
|
18 |
-
" else:\n",
|
19 |
-
" return None\n",
|
20 |
-
"\n",
|
21 |
-
"def transform_window(df_window, scaler):\n",
|
22 |
-
" return scaler.transform(df_window)\n",
|
23 |
-
"\n",
|
24 |
-
"def prepare_input(df_trans):\n",
|
25 |
-
" return df_trans[:30,:].reshape((1,30,30))\n",
|
26 |
-
"\n",
|
27 |
-
"def predict(model, df_new):\n",
|
28 |
-
" return model.predict(df_new)\n",
|
29 |
-
"\n",
|
30 |
-
"def calculate_residuals(df_trans, pred):\n",
|
31 |
-
" actual = df_trans[30,:25]\n",
|
32 |
-
" resid = actual - pred\n",
|
33 |
-
" return actual, resid\n",
|
34 |
-
"\n",
|
35 |
-
"def resize_prediction(pred, df_trans):\n",
|
36 |
-
" pred.resize((pred.shape[0], pred.shape[1] + len(df_trans[30,25:])))\n",
|
37 |
-
" pred[:, -len(df_trans[30,25:]):] = df_trans[30,25:]\n",
|
38 |
-
" return pred\n",
|
39 |
-
"\n",
|
40 |
-
"def inverse_transform(scaler, pred, df_trans):\n",
|
41 |
-
" pred = scaler.inverse_transform(np.array(pred))\n",
|
42 |
-
" actual = scaler.inverse_transform(np.array([df_trans[30,:]]))\n",
|
43 |
-
" return actual, pred\n",
|
44 |
-
"\n",
|
45 |
-
"def update_lists(actual_list, pred_list, resid_list, actual, pred, resid):\n",
|
46 |
-
" actual_list.pop(0)\n",
|
47 |
-
" pred_list.pop(0)\n",
|
48 |
-
" resid_list.pop(0)\n",
|
49 |
-
" actual_list.append(actual[0,1])\n",
|
50 |
-
" pred_list.append(pred[0,1])\n",
|
51 |
-
" resid_list.append(resid[0,1])\n",
|
52 |
-
" return actual_list, pred_list, resid_list\n",
|
53 |
-
"\n",
|
54 |
-
"def calculate_distances(resid, kmeans1, kmeans2, kmeans3, kmeans4):\n",
|
55 |
-
" dist = []\n",
|
56 |
-
" dist.append(np.linalg.norm(resid[:,1:8]-kmeans1.cluster_centers_[0], ord=2, axis=1))\n",
|
57 |
-
" dist.append(np.linalg.norm(resid[:,8:15]-kmeans2.cluster_centers_[0], ord=2, axis=1))\n",
|
58 |
-
" dist.append(np.linalg.norm(resid[:,15:22]-kmeans3.cluster_centers_[0], ord=2, axis=1))\n",
|
59 |
-
" dist.append(np.linalg.norm(resid[:,22:29]-kmeans4.cluster_centers_[0], ord=2, axis=1))\n",
|
60 |
-
" return np.array(dist)\n",
|
61 |
-
"\n",
|
62 |
-
"def pipeline(df, scaler, model, kmeans1, kmeans2, kmeans3, kmeans4):\n",
|
63 |
-
" actual_list, pred_list, resid_list = initialize_lists()\n",
|
64 |
-
" len_df = np.len(df)\n",
|
65 |
-
" df_window = get_window(df, len_df)\n",
|
66 |
-
" if df_window is not None:\n",
|
67 |
-
" df_trans = transform_window(df_window, scaler)\n",
|
68 |
-
" df_new = prepare_input(df_trans)\n",
|
69 |
-
" pred = predict(model, df_new)\n",
|
70 |
-
" actual, resid = calculate_residuals(df_trans, pred)\n",
|
71 |
-
" pred = resize_prediction(pred, df_trans)\n",
|
72 |
-
" actual, pred = inverse_transform(scaler, pred, df_trans)\n",
|
73 |
-
" actual_list, pred_list, resid_list = update_lists(actual_list, pred_list, resid_list, actual, pred, resid)\n",
|
74 |
-
" dist = calculate_distances(resid, kmeans1, kmeans2, kmeans3, kmeans4)\n",
|
75 |
-
" return actual_list, pred_list, resid_list, dist\n",
|
76 |
-
" else:\n",
|
77 |
-
" return actual_list, pred_list, resid_list, None\n"
|
78 |
-
]
|
79 |
-
},
|
80 |
-
{
|
81 |
-
"cell_type": "code",
|
82 |
-
"execution_count": 1,
|
83 |
-
"metadata": {},
|
84 |
-
"outputs": [
|
85 |
-
{
|
86 |
-
"data": {
|
87 |
-
"text/plain": [
|
88 |
-
"['a', 'b', 'c', 'd']"
|
89 |
-
]
|
90 |
-
},
|
91 |
-
"execution_count": 1,
|
92 |
-
"metadata": {},
|
93 |
-
"output_type": "execute_result"
|
94 |
-
}
|
95 |
-
],
|
96 |
-
"source": [
|
97 |
-
"inp = ['a', 'b']\n",
|
98 |
-
"out = ['c','d']\n",
|
99 |
-
"\n",
|
100 |
-
"inp+out"
|
101 |
-
]
|
102 |
-
},
|
103 |
-
{
|
104 |
-
"cell_type": "code",
|
105 |
-
"execution_count": null,
|
106 |
-
"metadata": {},
|
107 |
-
"outputs": [],
|
108 |
-
"source": []
|
109 |
-
}
|
110 |
-
],
|
111 |
-
"metadata": {
|
112 |
-
"kernelspec": {
|
113 |
-
"display_name": "smartbuilding",
|
114 |
-
"language": "python",
|
115 |
-
"name": "python3"
|
116 |
-
},
|
117 |
-
"language_info": {
|
118 |
-
"codemirror_mode": {
|
119 |
-
"name": "ipython",
|
120 |
-
"version": 3
|
121 |
-
},
|
122 |
-
"file_extension": ".py",
|
123 |
-
"mimetype": "text/x-python",
|
124 |
-
"name": "python",
|
125 |
-
"nbconvert_exporter": "python",
|
126 |
-
"pygments_lexer": "ipython3",
|
127 |
-
"version": "3.11.8"
|
128 |
-
}
|
129 |
-
},
|
130 |
-
"nbformat": 4,
|
131 |
-
"nbformat_minor": 2
|
132 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/energy_prediction/EnergyPredictionPipeline.py
CHANGED
@@ -50,12 +50,12 @@ class EnergyPredictionPipeline:
|
|
50 |
|
51 |
return df
|
52 |
|
53 |
-
def prepare_input(self, df1):
|
54 |
|
55 |
df = df1.copy()
|
56 |
df["date"] = pd.to_datetime(df["date"])
|
57 |
df.set_index("date", inplace=True)
|
58 |
-
df = df.resample("
|
59 |
df = self.date_encoder(df)
|
60 |
df.reset_index(inplace=True, drop=True)
|
61 |
df = df.astype("float32")
|
@@ -69,7 +69,7 @@ class EnergyPredictionPipeline:
|
|
69 |
|
70 |
return self.df
|
71 |
|
72 |
-
def get_window(self, df):
|
73 |
|
74 |
time = df["date"].iloc[-1]
|
75 |
time = datetime.strptime(time, "%Y-%m-%d %H:%M:%S")
|
@@ -79,8 +79,8 @@ class EnergyPredictionPipeline:
|
|
79 |
else:
|
80 |
return None
|
81 |
|
82 |
-
def fit(self,
|
83 |
-
df_new = self.extract_data_from_message(
|
84 |
df_window = self.get_window(df_new)
|
85 |
if df_window is not None:
|
86 |
df = self.prepare_input(df_window)
|
|
|
50 |
|
51 |
return df
|
52 |
|
53 |
+
def prepare_input(self, df1: pd.DataFrame):
|
54 |
|
55 |
df = df1.copy()
|
56 |
df["date"] = pd.to_datetime(df["date"])
|
57 |
df.set_index("date", inplace=True)
|
58 |
+
df = df.resample("60min").mean()
|
59 |
df = self.date_encoder(df)
|
60 |
df.reset_index(inplace=True, drop=True)
|
61 |
df = df.astype("float32")
|
|
|
69 |
|
70 |
return self.df
|
71 |
|
72 |
+
def get_window(self, df: pd.DataFrame):
|
73 |
|
74 |
time = df["date"].iloc[-1]
|
75 |
time = datetime.strptime(time, "%Y-%m-%d %H:%M:%S")
|
|
|
79 |
else:
|
80 |
return None
|
81 |
|
82 |
+
def fit(self, df: pd.DataFrame):
|
83 |
+
df_new = self.extract_data_from_message(df)
|
84 |
df_window = self.get_window(df_new)
|
85 |
if df_window is not None:
|
86 |
df = self.prepare_input(df_window)
|
src/energy_prediction/models/lstm_energy_north_01.keras
CHANGED
Binary files a/src/energy_prediction/models/lstm_energy_north_01.keras and b/src/energy_prediction/models/lstm_energy_north_01.keras differ
|
|
src/energy_prediction/models/lstm_energy_south_01.keras
CHANGED
Binary files a/src/energy_prediction/models/lstm_energy_south_01.keras and b/src/energy_prediction/models/lstm_energy_south_01.keras differ
|
|
src/vav/VAVPipeline.py
CHANGED
@@ -39,8 +39,34 @@ class VAVPipeline:
|
|
39 |
if rtu_id == 1:
|
40 |
self.zones = [69, 68, 67, 66, 65, 64, 42, 41, 40, 39, 38, 37, 36]
|
41 |
if rtu_id == 2:
|
42 |
-
self.zones = [
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
self.output_col_names = []
|
45 |
self.input_col_names = [
|
46 |
f"rtu_00{rtu_id}_fltrd_sa_flow_tn",
|
|
|
39 |
if rtu_id == 1:
|
40 |
self.zones = [69, 68, 67, 66, 65, 64, 42, 41, 40, 39, 38, 37, 36]
|
41 |
if rtu_id == 2:
|
42 |
+
self.zones = [
|
43 |
+
72,
|
44 |
+
71,
|
45 |
+
63,
|
46 |
+
62,
|
47 |
+
60,
|
48 |
+
59,
|
49 |
+
58,
|
50 |
+
57,
|
51 |
+
50,
|
52 |
+
49,
|
53 |
+
44,
|
54 |
+
43,
|
55 |
+
35,
|
56 |
+
34,
|
57 |
+
33,
|
58 |
+
32,
|
59 |
+
31,
|
60 |
+
30,
|
61 |
+
29,
|
62 |
+
28,
|
63 |
+
]
|
64 |
+
|
65 |
+
if rtu_id == 3:
|
66 |
+
self.zones = [61, 56, 55, 48, 45, 26, 25, 18]
|
67 |
+
|
68 |
+
if rtu_id == 4:
|
69 |
+
self.zones = [16, 17, 21, 23, 24, 46, 47, 51, 52, 53, 54]
|
70 |
self.output_col_names = []
|
71 |
self.input_col_names = [
|
72 |
f"rtu_00{rtu_id}_fltrd_sa_flow_tn",
|
src/vav/models/kmeans_vav_2.pkl
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
size 1567961
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:ee2cdc974b315bbd708a0ca2faa084feedd284794e4a53412013dc29cd62f903
|
3 |
size 1567961
|
src/vav/models/kmeans_vav_3.pkl
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:ffd45990b3c8a63580195cc71b1c33b39fff6003e855430fe0ddde4b42225c9a
|
3 |
+
size 1567961
|
src/vav/models/kmeans_vav_4.pkl
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:51cc457df6f45e89c345e8ba79461dbe6ce4f4d975c0b42d18d400582d1be3fc
|
3 |
+
size 1567961
|
src/vav/models/lstm_vav_02.keras
CHANGED
Binary files a/src/vav/models/lstm_vav_02.keras and b/src/vav/models/lstm_vav_02.keras differ
|
|
src/vav/models/lstm_vav_03.keras
CHANGED
Binary files a/src/vav/models/lstm_vav_03.keras and b/src/vav/models/lstm_vav_03.keras differ
|
|
src/vav/models/lstm_vav_04.keras
CHANGED
Binary files a/src/vav/models/lstm_vav_04.keras and b/src/vav/models/lstm_vav_04.keras differ
|
|
src/vav/models/pca_vav_2.pkl
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
size 1371
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:e33e866c070ca03333683658d69a00ded03ac7bda2704f8b95d59f82c1478441
|
3 |
size 1371
|
physLSTM/pca_vav_2.pkl → src/vav/models/pca_vav_3.pkl
RENAMED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:5c1e89a6b52ba885943048e6c32b2c70263b6ca3709618b623f0cafa65955bad
|
3 |
+
size 1195
|
physLSTM/scaler_vav_1.pkl → src/vav/models/pca_vav_4.pkl
RENAMED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:f6926a53d803f3d2621cbe29f06dbc1f75c7a4ee74738b7ef31550bfd4874657
|
3 |
+
size 1275
|
src/vav/models/scaler_vav_2.pkl
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:562a4d725a8a1c502745ec6f801487fea985b1d4e984030537ad60757c25d348
|
3 |
+
size 1973
|
src/vav/models/scaler_vav_3.pkl
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:558ca56b2cb9fd886ab81d19517430abdc573db9607a375f5d86de69130187b7
|
3 |
+
size 1493
|
src/vav/models/scaler_vav_4.pkl
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:23f2e858e596e90833da43752d7111a8ea85c01a0c32ace1af86cf3a0d4c4997
|
3 |
+
size 1781
|
streamlit.py
DELETED
@@ -1,260 +0,0 @@
|
|
1 |
-
import streamlit as st # web development
|
2 |
-
import numpy as np # np mean, np random
|
3 |
-
import pandas as pd # read csv, df manipulation
|
4 |
-
import time # to simulate a real time data, time loop
|
5 |
-
import plotly.express as px # interactive charts
|
6 |
-
import paho.mqtt.client as mqtt
|
7 |
-
import json
|
8 |
-
import warnings
|
9 |
-
from tensorflow.keras.models import load_model
|
10 |
-
import joblib
|
11 |
-
import plotly.graph_objects as go
|
12 |
-
warnings.filterwarnings('ignore')
|
13 |
-
|
14 |
-
|
15 |
-
model = load_model(r"src\rtu\models\lstm_4rtu_smooth_02.keras")
|
16 |
-
scaler = joblib.load(r'src\rtu\models\scaler_1.pkl')
|
17 |
-
# kmeans = joblib.load('kmeans_model.pkl')
|
18 |
-
kmeans1 = joblib.load(r'src\rtu\models\kmeans_model1.pkl')
|
19 |
-
kmeans2 = joblib.load(r'src\rtu\models\kmeans_model2.pkl')
|
20 |
-
kmeans3 = joblib.load(r'src\rtu\models\kmeans_model3.pkl')
|
21 |
-
kmeans4 = joblib.load(r'src\rtu\models\kmeans_model4.pkl')
|
22 |
-
# pca = joblib.load('pca_model.pkl')
|
23 |
-
|
24 |
-
st.set_page_config(
|
25 |
-
page_title = 'Real-Time Data Buliding 59',
|
26 |
-
page_icon = '✅',
|
27 |
-
layout = 'wide'
|
28 |
-
)
|
29 |
-
|
30 |
-
st.title("Buliding 59 Dashboard")
|
31 |
-
placeholder = st.empty()
|
32 |
-
|
33 |
-
broker_address = "localhost"
|
34 |
-
broker_port = 1883
|
35 |
-
topic = "sensor_data"
|
36 |
-
|
37 |
-
df = pd.DataFrame(columns=['hp_hws_temp',
|
38 |
-
'rtu_003_sa_temp',
|
39 |
-
'rtu_003_oadmpr_pct',
|
40 |
-
'rtu_003_ra_temp',
|
41 |
-
'rtu_003_oa_temp',
|
42 |
-
'rtu_003_ma_temp',
|
43 |
-
'rtu_003_sf_vfd_spd_fbk_tn',
|
44 |
-
'rtu_003_rf_vfd_spd_fbk_tn',
|
45 |
-
'rtu_004_sa_temp',
|
46 |
-
'rtu_004_oadmpr_pct',
|
47 |
-
'rtu_004_ra_temp',
|
48 |
-
'rtu_004_oa_temp',
|
49 |
-
'rtu_004_ma_temp',
|
50 |
-
'rtu_004_sf_vfd_spd_fbk_tn',
|
51 |
-
'rtu_004_rf_vfd_spd_fbk_tn',
|
52 |
-
'rtu_001_sa_temp',
|
53 |
-
'rtu_001_oadmpr_pct',
|
54 |
-
'rtu_001_ra_temp',
|
55 |
-
'rtu_001_oa_temp',
|
56 |
-
'rtu_001_ma_temp',
|
57 |
-
'rtu_001_sf_vfd_spd_fbk_tn',
|
58 |
-
'rtu_001_rf_vfd_spd_fbk_tn',
|
59 |
-
'rtu_002_sa_temp',
|
60 |
-
'rtu_002_oadmpr_pct',
|
61 |
-
'rtu_002_ra_temp',
|
62 |
-
'rtu_002_oa_temp',
|
63 |
-
'rtu_002_ma_temp',
|
64 |
-
'rtu_002_sf_vfd_spd_fbk_tn',
|
65 |
-
'rtu_002_rf_vfd_spd_fbk_tn',
|
66 |
-
# 'rtu_004_sat_sp_tn',
|
67 |
-
# 'rtu_003_sat_sp_tn',
|
68 |
-
# 'rtu_001_sat_sp_tn',
|
69 |
-
# 'rtu_002_sat_sp_tn',
|
70 |
-
'air_temp_set_1',
|
71 |
-
'air_temp_set_2',
|
72 |
-
'dew_point_temperature_set_1d',
|
73 |
-
'relative_humidity_set_1',
|
74 |
-
'solar_radiation_set_1'])
|
75 |
-
actual_list = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
76 |
-
pred_list = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
77 |
-
resid_list = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
78 |
-
distance = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
79 |
-
pca_x = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
80 |
-
pca_y = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
81 |
-
|
82 |
-
def on_message(client, userdata, message):
|
83 |
-
global df
|
84 |
-
payload = json.loads(message.payload.decode())
|
85 |
-
|
86 |
-
hp_hws_temp = payload['hp_hws_temp']
|
87 |
-
rtu_003_sa_temp = payload['rtu_003_sa_temp']
|
88 |
-
rtu_003_oadmpr_pct = payload['rtu_003_oadmpr_pct']
|
89 |
-
rtu_003_ra_temp = payload['rtu_003_ra_temp']
|
90 |
-
rtu_003_oa_temp = payload['rtu_003_oa_temp']
|
91 |
-
rtu_003_ma_temp = payload['rtu_003_ma_temp']
|
92 |
-
rtu_003_sf_vfd_spd_fbk_tn = payload['rtu_003_sf_vfd_spd_fbk_tn']
|
93 |
-
rtu_003_rf_vfd_spd_fbk_tn =payload['rtu_003_rf_vfd_spd_fbk_tn']
|
94 |
-
rtu_004_sa_temp = payload['rtu_004_sa_temp']
|
95 |
-
rtu_004_oadmpr_pct = payload['rtu_004_oadmpr_pct']
|
96 |
-
rtu_004_ra_temp = payload['rtu_004_ra_temp']
|
97 |
-
rtu_004_oa_temp = payload['rtu_004_oa_temp']
|
98 |
-
rtu_004_ma_temp = payload['rtu_004_ma_temp']
|
99 |
-
rtu_004_sf_vfd_spd_fbk_tn = payload['rtu_004_sf_vfd_spd_fbk_tn']
|
100 |
-
rtu_004_rf_vfd_spd_fbk_tn = payload['rtu_004_rf_vfd_spd_fbk_tn']
|
101 |
-
rtu_001_sa_temp = payload['rtu_001_sa_temp']
|
102 |
-
rtu_001_oadmpr_pct = payload['rtu_001_oadmpr_pct']
|
103 |
-
rtu_001_ra_temp = payload['rtu_001_ra_temp']
|
104 |
-
rtu_001_oa_temp = payload['rtu_001_oa_temp']
|
105 |
-
rtu_001_ma_temp = payload['rtu_001_ma_temp']
|
106 |
-
rtu_001_sf_vfd_spd_fbk_tn = payload['rtu_001_sf_vfd_spd_fbk_tn']
|
107 |
-
rtu_001_rf_vfd_spd_fbk_tn =payload['rtu_001_rf_vfd_spd_fbk_tn']
|
108 |
-
rtu_002_sa_temp = payload['rtu_002_sa_temp']
|
109 |
-
rtu_002_oadmpr_pct = payload['rtu_002_oadmpr_pct']
|
110 |
-
rtu_002_ra_temp = payload['rtu_002_ra_temp']
|
111 |
-
rtu_002_oa_temp = payload['rtu_002_oa_temp']
|
112 |
-
rtu_002_ma_temp = payload['rtu_002_ma_temp']
|
113 |
-
rtu_002_sf_vfd_spd_fbk_tn = payload['rtu_002_sf_vfd_spd_fbk_tn']
|
114 |
-
rtu_002_rf_vfd_spd_fbk_tn = payload['rtu_002_rf_vfd_spd_fbk_tn']
|
115 |
-
# rtu_004_sat_sp_tn = payload['rtu_004_sat_sp_tn']
|
116 |
-
# rtu_003_sat_sp_tn = payload['rtu_003_sat_sp_tn']
|
117 |
-
# rtu_001_sat_sp_tn = payload['rtu_001_sat_sp_tn']
|
118 |
-
# rtu_002_sat_sp_tn = payload['rtu_002_sat_sp_tn']
|
119 |
-
air_temp_set_1 = payload['air_temp_set_1']
|
120 |
-
air_temp_set_2 = payload['air_temp_set_2']
|
121 |
-
dew_point_temperature_set_1d = payload['dew_point_temperature_set_1d']
|
122 |
-
relative_humidity_set_1 = payload['relative_humidity_set_1']
|
123 |
-
solar_radiation_set_1 = payload['solar_radiation_set_1']
|
124 |
-
|
125 |
-
len_df = len(df)
|
126 |
-
df.loc[len_df] = {'hp_hws_temp':hp_hws_temp,
|
127 |
-
'rtu_003_sa_temp':rtu_003_sa_temp,
|
128 |
-
'rtu_003_oadmpr_pct': rtu_003_oadmpr_pct,
|
129 |
-
'rtu_003_ra_temp':rtu_003_ra_temp,
|
130 |
-
'rtu_003_oa_temp': rtu_003_oa_temp,
|
131 |
-
'rtu_003_ma_temp': rtu_003_ma_temp,
|
132 |
-
'rtu_003_sf_vfd_spd_fbk_tn': rtu_003_sf_vfd_spd_fbk_tn,
|
133 |
-
'rtu_003_rf_vfd_spd_fbk_tn':rtu_003_rf_vfd_spd_fbk_tn,
|
134 |
-
'rtu_004_sa_temp':rtu_004_sa_temp,
|
135 |
-
'rtu_004_oadmpr_pct':rtu_004_oadmpr_pct,
|
136 |
-
'rtu_004_ra_temp':rtu_004_ra_temp,
|
137 |
-
'rtu_004_oa_temp':rtu_004_oa_temp,
|
138 |
-
'rtu_004_ma_temp':rtu_004_ma_temp,
|
139 |
-
'rtu_004_sf_vfd_spd_fbk_tn':rtu_004_sf_vfd_spd_fbk_tn,
|
140 |
-
'rtu_004_rf_vfd_spd_fbk_tn':rtu_004_rf_vfd_spd_fbk_tn,
|
141 |
-
'rtu_001_sa_temp':rtu_001_sa_temp,
|
142 |
-
'rtu_001_oadmpr_pct': rtu_001_oadmpr_pct,
|
143 |
-
'rtu_001_ra_temp':rtu_001_ra_temp,
|
144 |
-
'rtu_001_oa_temp': rtu_001_oa_temp,
|
145 |
-
'rtu_001_ma_temp': rtu_001_ma_temp,
|
146 |
-
'rtu_001_sf_vfd_spd_fbk_tn': rtu_001_sf_vfd_spd_fbk_tn,
|
147 |
-
'rtu_001_rf_vfd_spd_fbk_tn':rtu_001_rf_vfd_spd_fbk_tn,
|
148 |
-
'rtu_002_sa_temp':rtu_002_sa_temp,
|
149 |
-
'rtu_002_oadmpr_pct':rtu_002_oadmpr_pct,
|
150 |
-
'rtu_002_ra_temp':rtu_002_ra_temp,
|
151 |
-
'rtu_002_oa_temp':rtu_002_oa_temp,
|
152 |
-
'rtu_002_ma_temp':rtu_002_ma_temp,
|
153 |
-
'rtu_002_sf_vfd_spd_fbk_tn':rtu_002_sf_vfd_spd_fbk_tn,
|
154 |
-
'rtu_002_rf_vfd_spd_fbk_tn':rtu_002_rf_vfd_spd_fbk_tn,
|
155 |
-
# 'rtu_004_sat_sp_tn':rtu_004_sat_sp_tn,
|
156 |
-
# 'rtu_003_sat_sp_tn' :rtu_003_sat_sp_tn,
|
157 |
-
# 'rtu_001_sat_sp_tn':rtu_001_sat_sp_tn,
|
158 |
-
# 'rtu_002_sat_sp_tn':rtu_002_sat_sp_tn,
|
159 |
-
'air_temp_set_1':air_temp_set_1,
|
160 |
-
'air_temp_set_2':air_temp_set_2,
|
161 |
-
'dew_point_temperature_set_1d':dew_point_temperature_set_1d,
|
162 |
-
'relative_humidity_set_1':relative_humidity_set_1,
|
163 |
-
'solar_radiation_set_1':solar_radiation_set_1}
|
164 |
-
|
165 |
-
if len_df>30:
|
166 |
-
df_window = df[len_df-31:len_df]
|
167 |
-
df_window = df_window.astype('float32')
|
168 |
-
df_trans = scaler.transform(df_window)
|
169 |
-
df_new = df_trans[:30,:].reshape((1,30,34))#
|
170 |
-
pred = model.predict(df_new)
|
171 |
-
pred_copy = pred.copy()
|
172 |
-
actual = df_trans[30,:29]#
|
173 |
-
resid = actual - pred
|
174 |
-
#---------
|
175 |
-
pred.resize((pred.shape[0], pred.shape[1] + len(df_trans[30,29:])))#
|
176 |
-
pred[:, -len(df_trans[30,29:]):] = df_trans[30,29:]#
|
177 |
-
pred = scaler.inverse_transform(np.array(pred))
|
178 |
-
actual = scaler.inverse_transform(np.array([df_trans[30,:]]))
|
179 |
-
#---------
|
180 |
-
actual_list.pop(0)
|
181 |
-
pred_list.pop(0)
|
182 |
-
resid_list.pop(0)
|
183 |
-
# distance.pop(0)
|
184 |
-
# pca_x.pop(0)
|
185 |
-
# pca_y.pop(0)
|
186 |
-
actual_list.append(actual[0,1])
|
187 |
-
pred_list.append(pred[0,1])
|
188 |
-
resid_list.append(resid[0,1])
|
189 |
-
# distance.append(np.linalg.norm(pred_copy-kmeans.cluster_centers_[0], ord=2, axis = 1))
|
190 |
-
# dist_color = [1 if num >= 5 else 0 for num in distance]
|
191 |
-
dist = []
|
192 |
-
dist.append(np.linalg.norm(resid[:,1:8]-kmeans1.cluster_centers_[0], ord=2, axis = 1))
|
193 |
-
dist.append(np.linalg.norm(resid[:,8:15]-kmeans2.cluster_centers_[0], ord=2, axis = 1))
|
194 |
-
dist.append(np.linalg.norm(resid[:,15:22]-kmeans3.cluster_centers_[0], ord=2, axis = 1))
|
195 |
-
dist.append(np.linalg.norm(resid[:,22:29]-kmeans4.cluster_centers_[0], ord=2, axis = 1))
|
196 |
-
dist = np.array(dist)
|
197 |
-
# dist_color = [1 if num >= 2 else 0 for num in dist]
|
198 |
-
|
199 |
-
# pca_cord = pca.transform(resid)
|
200 |
-
# pca_x.append(pca_cord[0,0])
|
201 |
-
# pca_y.append(pca_cord[0,1])
|
202 |
-
# clust_center = pca.transform(kmeans.cluster_centers_)
|
203 |
-
# theta = np.linspace(0, 2*np.pi, 100)
|
204 |
-
# radius = 2
|
205 |
-
# x_circle = clust_center[0, 0] + radius * np.cos(theta)
|
206 |
-
# y_circle = clust_center[0, 1] + radius * np.sin(theta)
|
207 |
-
|
208 |
-
ind = np.linspace(1, 30, 30)
|
209 |
-
|
210 |
-
with placeholder.container():
|
211 |
-
col1, fig_col1, fig_col2 = st.columns(3)
|
212 |
-
with col1:
|
213 |
-
st.header("RTU Status")
|
214 |
-
for i in range(4):
|
215 |
-
rtu = ['RTU 1', 'RTU 2', 'RTU 3', 'RTU 4']
|
216 |
-
tol = [2,2,2,0.1]#[4.5,4,5,5]
|
217 |
-
status_icon = "🔧" if dist[i,0] > tol[i] else "🔄"
|
218 |
-
status = "Damper or Fan issue" if dist[i,0] > tol[i] else "Normal"
|
219 |
-
status_markdown = f"**{rtu[i]} {status_icon}**\n\nSA Temp: {int(actual[0,1])}°C\nRA Temp: {int(actual[0,3])}°C\n\nStatus: {status}"
|
220 |
-
st.markdown(status_markdown, unsafe_allow_html=True)
|
221 |
-
with fig_col1:
|
222 |
-
# st.markdown("### Fault")
|
223 |
-
st.header("Fault")
|
224 |
-
fig1 = go.Figure()
|
225 |
-
# fig1.add_trace(go.Scatter(x=ind, y=resid_list, mode='lines', name='Actual',line=dict(color='blue')))
|
226 |
-
# fig1 = px.scatter(x=pca_x, y=pca_y,color=dist_color,color_discrete_map={'1': 'red', '0': 'green'})
|
227 |
-
# fig1.add_trace(go.Scatter(x=x_circle, y=y_circle, mode='lines',line=dict(color='green')))
|
228 |
-
colors = ['red' if value > 0.1 else 'blue' for value in dist[:, 0]]
|
229 |
-
fig1 = fig1.add_trace(go.Bar(x=['RTU 1', 'RTU 2', 'RTU 3', 'RTU 4'],y=dist[:, 0],marker_color=colors,width=0.4))
|
230 |
-
fig1.update_layout(width=500,height=400 )
|
231 |
-
st.write(fig1)
|
232 |
-
with fig_col2:
|
233 |
-
st.header("Mixed Air temperature")
|
234 |
-
fig2 = go.Figure()
|
235 |
-
fig2.add_trace(go.Scatter(x=ind, y=actual_list, mode='lines', name='Actual',line=dict(color='blue')))
|
236 |
-
fig2.add_trace(go.Scatter(x=ind, y=pred_list, mode='lines', name='Predicted',line=dict(color='red', dash='dot')))
|
237 |
-
fig2.update_layout(yaxis_range=[50, 80],width=500,height=400 )
|
238 |
-
st.write(fig2)
|
239 |
-
|
240 |
-
st.markdown("### Detailed Data View")
|
241 |
-
st.dataframe(df[len_df-5:len_df])
|
242 |
-
# time.sleep(1)
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1)
|
247 |
-
client.on_message = on_message
|
248 |
-
client.connect(broker_address, broker_port)
|
249 |
-
client.subscribe(topic)
|
250 |
-
client.loop_forever()
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|