import streamlit as st # web development import numpy as np # np mean, np random import pandas as pd # read csv, df manipulation import time # to simulate a real time data, time loop import plotly.express as px # interactive charts import paho.mqtt.client as mqtt import json import warnings from tensorflow.keras.models import load_model import joblib import plotly.graph_objects as go warnings.filterwarnings('ignore') model = load_model("lstm_4rtu_smooth_02.keras") scaler = joblib.load('scaler_1.pkl') # kmeans = joblib.load('kmeans_model.pkl') kmeans1 = joblib.load('kmeans_model1.pkl') kmeans2 = joblib.load('kmeans_model2.pkl') kmeans3 = joblib.load('kmeans_model3.pkl') kmeans4 = joblib.load('kmeans_model4.pkl') pca = joblib.load('pca_model.pkl') st.set_page_config( page_title = 'Real-Time Data Buliding 59', page_icon = '✅', layout = 'wide' ) st.title("Buliding 59 Dashboard") placeholder = st.empty() broker_address = "localhost" broker_port = 1883 topic = "sensor_data" df = pd.DataFrame(columns=['hp_hws_temp', 'rtu_003_sa_temp', 'rtu_003_oadmpr_pct', 'rtu_003_ra_temp', 'rtu_003_oa_temp', 'rtu_003_ma_temp', 'rtu_003_sf_vfd_spd_fbk_tn', 'rtu_003_rf_vfd_spd_fbk_tn', 'rtu_004_sa_temp', 'rtu_004_oadmpr_pct', 'rtu_004_ra_temp', 'rtu_004_oa_temp', 'rtu_004_ma_temp', 'rtu_004_sf_vfd_spd_fbk_tn', 'rtu_004_rf_vfd_spd_fbk_tn', 'rtu_001_sa_temp', 'rtu_001_oadmpr_pct', 'rtu_001_ra_temp', 'rtu_001_oa_temp', 'rtu_001_ma_temp', 'rtu_001_sf_vfd_spd_fbk_tn', 'rtu_001_rf_vfd_spd_fbk_tn', 'rtu_002_sa_temp', 'rtu_002_oadmpr_pct', 'rtu_002_ra_temp', 'rtu_002_oa_temp', 'rtu_002_ma_temp', 'rtu_002_sf_vfd_spd_fbk_tn', 'rtu_002_rf_vfd_spd_fbk_tn', 'rtu_004_sat_sp_tn', 'rtu_003_sat_sp_tn', 'rtu_001_sat_sp_tn', 'rtu_002_sat_sp_tn', 'air_temp_set_1', 'air_temp_set_2', 'dew_point_temperature_set_1d', 'relative_humidity_set_1', 'solar_radiation_set_1']) 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] 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] 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] 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] 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] 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] def on_message(client, userdata, message): global df payload = json.loads(message.payload.decode()) hp_hws_temp = payload['hp_hws_temp'] rtu_003_sa_temp = payload['rtu_003_sa_temp'] rtu_003_oadmpr_pct = payload['rtu_003_oadmpr_pct'] rtu_003_ra_temp = payload['rtu_003_ra_temp'] rtu_003_oa_temp = payload['rtu_003_oa_temp'] rtu_003_ma_temp = payload['rtu_003_ma_temp'] rtu_003_sf_vfd_spd_fbk_tn = payload['rtu_003_sf_vfd_spd_fbk_tn'] rtu_003_rf_vfd_spd_fbk_tn =payload['rtu_003_rf_vfd_spd_fbk_tn'] rtu_004_sa_temp = payload['rtu_004_sa_temp'] rtu_004_oadmpr_pct = payload['rtu_004_oadmpr_pct'] rtu_004_ra_temp = payload['rtu_004_ra_temp'] rtu_004_oa_temp = payload['rtu_004_oa_temp'] rtu_004_ma_temp = payload['rtu_004_ma_temp'] rtu_004_sf_vfd_spd_fbk_tn = payload['rtu_004_sf_vfd_spd_fbk_tn'] rtu_004_rf_vfd_spd_fbk_tn = payload['rtu_004_rf_vfd_spd_fbk_tn'] rtu_001_sa_temp = payload['rtu_001_sa_temp'] rtu_001_oadmpr_pct = payload['rtu_001_oadmpr_pct'] rtu_001_ra_temp = payload['rtu_001_ra_temp'] rtu_001_oa_temp = payload['rtu_001_oa_temp'] rtu_001_ma_temp = payload['rtu_001_ma_temp'] rtu_001_sf_vfd_spd_fbk_tn = payload['rtu_001_sf_vfd_spd_fbk_tn'] rtu_001_rf_vfd_spd_fbk_tn =payload['rtu_001_rf_vfd_spd_fbk_tn'] rtu_002_sa_temp = payload['rtu_002_sa_temp'] rtu_002_oadmpr_pct = payload['rtu_002_oadmpr_pct'] rtu_002_ra_temp = payload['rtu_002_ra_temp'] rtu_002_oa_temp = payload['rtu_002_oa_temp'] rtu_002_ma_temp = payload['rtu_002_ma_temp'] rtu_002_sf_vfd_spd_fbk_tn = payload['rtu_002_sf_vfd_spd_fbk_tn'] rtu_002_rf_vfd_spd_fbk_tn = payload['rtu_002_rf_vfd_spd_fbk_tn'] rtu_004_sat_sp_tn = payload['rtu_004_sat_sp_tn'] rtu_003_sat_sp_tn = payload['rtu_003_sat_sp_tn'] rtu_001_sat_sp_tn = payload['rtu_001_sat_sp_tn'] rtu_002_sat_sp_tn = payload['rtu_002_sat_sp_tn'] air_temp_set_1 = payload['air_temp_set_1'] air_temp_set_2 = payload['air_temp_set_2'] dew_point_temperature_set_1d = payload['dew_point_temperature_set_1d'] relative_humidity_set_1 = payload['relative_humidity_set_1'] solar_radiation_set_1 = payload['solar_radiation_set_1'] len_df = len(df) df.loc[len_df] = {'hp_hws_temp':hp_hws_temp, 'rtu_003_sa_temp':rtu_003_sa_temp, 'rtu_003_oadmpr_pct': rtu_003_oadmpr_pct, 'rtu_003_ra_temp':rtu_003_ra_temp, 'rtu_003_oa_temp': rtu_003_oa_temp, 'rtu_003_ma_temp': rtu_003_ma_temp, 'rtu_003_sf_vfd_spd_fbk_tn': rtu_003_sf_vfd_spd_fbk_tn, 'rtu_003_rf_vfd_spd_fbk_tn':rtu_003_rf_vfd_spd_fbk_tn, 'rtu_004_sa_temp':rtu_004_sa_temp, 'rtu_004_oadmpr_pct':rtu_004_oadmpr_pct, 'rtu_004_ra_temp':rtu_004_ra_temp, 'rtu_004_oa_temp':rtu_004_oa_temp, 'rtu_004_ma_temp':rtu_004_ma_temp, 'rtu_004_sf_vfd_spd_fbk_tn':rtu_004_sf_vfd_spd_fbk_tn, 'rtu_004_rf_vfd_spd_fbk_tn':rtu_004_rf_vfd_spd_fbk_tn, 'rtu_001_sa_temp':rtu_001_sa_temp, 'rtu_001_oadmpr_pct': rtu_001_oadmpr_pct, 'rtu_001_ra_temp':rtu_001_ra_temp, 'rtu_001_oa_temp': rtu_001_oa_temp, 'rtu_001_ma_temp': rtu_001_ma_temp, 'rtu_001_sf_vfd_spd_fbk_tn': rtu_001_sf_vfd_spd_fbk_tn, 'rtu_001_rf_vfd_spd_fbk_tn':rtu_001_rf_vfd_spd_fbk_tn, 'rtu_002_sa_temp':rtu_002_sa_temp, 'rtu_002_oadmpr_pct':rtu_002_oadmpr_pct, 'rtu_002_ra_temp':rtu_002_ra_temp, 'rtu_002_oa_temp':rtu_002_oa_temp, 'rtu_002_ma_temp':rtu_002_ma_temp, 'rtu_002_sf_vfd_spd_fbk_tn':rtu_002_sf_vfd_spd_fbk_tn, 'rtu_002_rf_vfd_spd_fbk_tn':rtu_002_rf_vfd_spd_fbk_tn, 'rtu_004_sat_sp_tn':rtu_004_sat_sp_tn, 'rtu_003_sat_sp_tn' :rtu_003_sat_sp_tn, 'rtu_001_sat_sp_tn':rtu_001_sat_sp_tn, 'rtu_002_sat_sp_tn':rtu_002_sat_sp_tn, 'air_temp_set_1':air_temp_set_1, 'air_temp_set_2':air_temp_set_2, 'dew_point_temperature_set_1d':dew_point_temperature_set_1d, 'relative_humidity_set_1':relative_humidity_set_1, 'solar_radiation_set_1':solar_radiation_set_1} if len_df>30: df_window = df[len_df-31:len_df] df_window = df_window.astype('float32') df_trans = scaler.transform(df_window) df_new = df_trans[:30,:].reshape((1,30,34))# pred = model.predict(df_new) pred_copy = pred.copy() actual = df_trans[30,:29]# resid = actual - pred #--------- pred.resize((pred.shape[0], pred.shape[1] + len(df_trans[30,29:])))# pred[:, -len(df_trans[30,29:]):] = df_trans[30,29:]# pred = scaler.inverse_transform(np.array(pred)) actual = scaler.inverse_transform(np.array([df_trans[30,:]])) #--------- actual_list.pop(0) pred_list.pop(0) resid_list.pop(0) # distance.pop(0) # pca_x.pop(0) # pca_y.pop(0) actual_list.append(actual[0,1]) pred_list.append(pred[0,1]) resid_list.append(resid[0,1]) # distance.append(np.linalg.norm(pred_copy-kmeans.cluster_centers_[0], ord=2, axis = 1)) # dist_color = [1 if num >= 5 else 0 for num in distance] dist = [] dist.append(np.linalg.norm(resid[:,1:8]-kmeans1.cluster_centers_[0], ord=2, axis = 1)) dist.append(np.linalg.norm(resid[:,8:15]-kmeans2.cluster_centers_[0], ord=2, axis = 1)) dist.append(np.linalg.norm(resid[:,15:22]-kmeans3.cluster_centers_[0], ord=2, axis = 1)) dist.append(np.linalg.norm(resid[:,22:29]-kmeans4.cluster_centers_[0], ord=2, axis = 1)) dist = np.array(dist) # dist_color = [1 if num >= 2 else 0 for num in dist] # pca_cord = pca.transform(resid) # pca_x.append(pca_cord[0,0]) # pca_y.append(pca_cord[0,1]) # clust_center = pca.transform(kmeans.cluster_centers_) # theta = np.linspace(0, 2*np.pi, 100) # radius = 2 # x_circle = clust_center[0, 0] + radius * np.cos(theta) # y_circle = clust_center[0, 1] + radius * np.sin(theta) ind = np.linspace(1, 30, 30) with placeholder.container(): col1, fig_col1, fig_col2 = st.columns(3) with col1: st.header("RTU Status") for i in range(4): rtu = ['RTU 1', 'RTU 2', 'RTU 3', 'RTU 4'] tol = [2,2,2,0.1]#[4.5,4,5,5] status_icon = "🔧" if dist[i,0] > tol[i] else "🔄" status = "Damper or Fan issue" if dist[i,0] > tol[i] else "Normal" 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}" st.markdown(status_markdown, unsafe_allow_html=True) with fig_col1: # st.markdown("### Fault") st.header("Fault") fig1 = go.Figure() # fig1.add_trace(go.Scatter(x=ind, y=resid_list, mode='lines', name='Actual',line=dict(color='blue'))) # fig1 = px.scatter(x=pca_x, y=pca_y,color=dist_color,color_discrete_map={'1': 'red', '0': 'green'}) # fig1.add_trace(go.Scatter(x=x_circle, y=y_circle, mode='lines',line=dict(color='green'))) colors = ['red' if value > 0.1 else 'blue' for value in dist[:, 0]] fig1 = fig1.add_trace(go.Bar(x=['RTU 1', 'RTU 2', 'RTU 3', 'RTU 4'],y=dist[:, 0],marker_color=colors,width=0.4)) fig1.update_layout(width=500,height=400 ) st.write(fig1) with fig_col2: st.header("Mixed Air temperature") fig2 = go.Figure() fig2.add_trace(go.Scatter(x=ind, y=actual_list, mode='lines', name='Actual',line=dict(color='blue'))) fig2.add_trace(go.Scatter(x=ind, y=pred_list, mode='lines', name='Predicted',line=dict(color='red', dash='dot'))) fig2.update_layout(yaxis_range=[50, 80],width=500,height=400 ) st.write(fig2) st.markdown("### Detailed Data View") st.dataframe(df[len_df-5:len_df]) # time.sleep(1) client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION1) client.on_message = on_message client.connect(broker_address, broker_port) client.subscribe(topic) client.loop_forever()