bhagwandas commited on
Commit
eb0d83d
Β·
verified Β·
1 Parent(s): 07d1a6c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -45
app.py CHANGED
@@ -18,7 +18,17 @@ st.set_page_config(
18
  EMBED_MODEL = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
19
  GEN_MODEL = pipeline('text2text-generation', model='google/flan-t5-base')
20
 
21
- # Custom Style
 
 
 
 
 
 
 
 
 
 
22
  st.markdown("""
23
  <style>
24
  html, body, [class*="css"] {
@@ -33,12 +43,6 @@ st.markdown("""
33
  margin-bottom: 1rem;
34
  box-shadow: 0 0 8px rgba(88,166,255,0.2);
35
  }
36
- .metric-box {
37
- background-color: #1f2937;
38
- padding: 0.75rem;
39
- border-radius: 8px;
40
- margin-top: 0.5rem;
41
- }
42
  </style>
43
  """, unsafe_allow_html=True)
44
 
@@ -51,20 +55,20 @@ st.markdown("""
51
  </div>
52
  """, unsafe_allow_html=True)
53
 
54
- # Upload CSV
55
  uploaded_file = st.sidebar.file_uploader("πŸ“‚ Upload sensor log (CSV)", type=["csv"])
56
 
57
  if uploaded_file:
58
  df = pd.read_csv(uploaded_file)
59
  numeric_cols = df.select_dtypes(include=np.number).columns.tolist()
60
 
61
- # Run Anomaly Detection
62
- iso = IsolationForest(contamination=0.02)
63
  labels = iso.fit_predict(df[numeric_cols])
64
  df['status'] = ['❌ Fault Detected' if x == -1 else 'βœ… Healthy' for x in labels]
65
  df['maintenance_flag'] = ['πŸ”§ Inspect Required' if x == -1 else '🟒 Stable' for x in labels]
66
 
67
- # NLP Embeddings for RAG
68
  if 'chunks' not in st.session_state or 'embeddings' not in st.session_state:
69
  chunks = [
70
  f"[Entry {i}] " + ", ".join([f"{col}: {row[col]:.2f}" for col in numeric_cols])
@@ -74,32 +78,38 @@ if uploaded_file:
74
  st.session_state.chunks = chunks
75
  st.session_state.embeddings = embeddings
76
 
77
- # Dashboard Layout
78
  col1, col2 = st.columns(2)
79
-
80
  with col1:
81
  st.markdown("### 🧠 Machine Health Summary")
82
  status_counts = df['status'].value_counts()
83
- fig1, ax1 = plt.subplots()
84
- ax1.bar(status_counts.index, status_counts.values, color=["red", "green"])
85
- ax1.set_title("Health Status Count")
86
- ax1.set_ylabel("Instances")
 
87
  ax1.set_facecolor("#0f1117")
88
  ax1.tick_params(colors='white')
89
  ax1.title.set_color('white')
 
90
  ax1.yaxis.label.set_color('white')
91
  for spine in ax1.spines.values():
92
  spine.set_edgecolor('white')
 
 
 
 
93
  st.pyplot(fig1)
94
 
95
  with col2:
96
  st.markdown("### πŸ§ͺ Parameters Monitored")
97
  st.markdown(f"""
98
  <div class="card">
99
- <div style='line-height: 1.8;'>{' β€’ '.join(numeric_cols)}</div>
100
  </div>
101
  """, unsafe_allow_html=True)
102
 
 
103
  st.markdown("### πŸ“‰ Sensor Trend (with Fault Overlay)")
104
  col3, col4 = st.columns(2)
105
  time_col = col3.selectbox("πŸ•’ Time Column", ["None"] + list(df.columns))
@@ -110,17 +120,18 @@ if uploaded_file:
110
 
111
  x_vals = df[time_col] if time_col != "None" else df.index
112
  y_vals = df[trend_param]
 
113
 
114
- fig2, ax2 = plt.subplots()
115
- ax2.plot(x_vals, y_vals, label=trend_param, color="skyblue")
116
  ax2.scatter(
117
  x_vals[df['status'] == '❌ Fault Detected'],
118
  y_vals[df['status'] == '❌ Fault Detected'],
119
  color='red', label='Fault Detected', zorder=5
120
  )
121
- ax2.set_title(f"{trend_param} Trend")
122
  ax2.set_xlabel("Time" if time_col != "None" else "Index")
123
- ax2.set_ylabel(trend_param)
124
  ax2.legend()
125
  ax2.set_facecolor("#0f1117")
126
  ax2.tick_params(colors='white')
@@ -131,25 +142,45 @@ if uploaded_file:
131
  spine.set_edgecolor('white')
132
  st.pyplot(fig2)
133
 
134
- # Export Fault Records
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  st.markdown("### πŸ“€ Export Anomalies")
136
- anomalies_df = df[df['status'] == '❌ Fault Detected']
137
- buffer = BytesIO()
138
- anomalies_df.to_csv(buffer, index=False)
139
- st.download_button(
140
- label="⬇️ Download Fault Log",
141
- data=buffer.getvalue(),
142
- file_name="fault_anomalies.csv",
143
- mime="text/csv"
144
- )
145
 
146
- # Fault Correlation
147
  st.markdown("### 🏷️ Fault Distribution by Machine/Component")
148
- metadata_cols = [col for col in df.columns if 'machine' in col.lower() or 'component' in col.lower()]
149
- for meta in metadata_cols:
150
- st.markdown(f"**{meta} – Fault Frequency**")
151
- meta_counts = df[df['status'] == '❌ Fault Detected'][meta].value_counts()
152
- st.bar_chart(meta_counts)
153
 
154
  # Role Assistant
155
  st.markdown("### πŸ’¬ Technical Assistant by Role")
@@ -169,20 +200,20 @@ if uploaded_file:
169
  }
170
 
171
  role = st.selectbox("πŸ‘€ Select your role", roles.keys())
172
- user_input = st.text_input("🧠 Ask a question")
173
 
174
- if user_input:
175
- query_vec = EMBED_MODEL.encode([user_input])[0]
176
- sims = np.dot(st.session_state.embeddings, query_vec)
177
- top_idxs = np.argsort(sims)[-5:][::-1]
178
- context = "\n".join([st.session_state.chunks[i] for i in top_idxs])
179
 
180
  prompt = (
181
  f"ROLE: {role}\n"
182
  f"RESPONSIBILITIES: {roles[role]['description']}\n"
183
  f"COMMUNICATION STYLE: {roles[role]['style']}\n\n"
184
  f"DATA CONTEXT:\n{context}\n\n"
185
- f"QUESTION:\n{user_input}\n\n"
186
  f"ANSWER:\n"
187
  )
188
  result = GEN_MODEL(prompt, max_length=400)[0]['generated_text']
 
18
  EMBED_MODEL = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
19
  GEN_MODEL = pipeline('text2text-generation', model='google/flan-t5-base')
20
 
21
+ # Optional: Units per parameter
22
+ unit_map = {
23
+ "temperature": "Β°C",
24
+ "vibration": "mm/s",
25
+ "pressure": "bar",
26
+ "current": "A",
27
+ "voltage": "V",
28
+ "speed": "RPM"
29
+ }
30
+
31
+ # Style
32
  st.markdown("""
33
  <style>
34
  html, body, [class*="css"] {
 
43
  margin-bottom: 1rem;
44
  box-shadow: 0 0 8px rgba(88,166,255,0.2);
45
  }
 
 
 
 
 
 
46
  </style>
47
  """, unsafe_allow_html=True)
48
 
 
55
  </div>
56
  """, unsafe_allow_html=True)
57
 
58
+ # File Upload
59
  uploaded_file = st.sidebar.file_uploader("πŸ“‚ Upload sensor log (CSV)", type=["csv"])
60
 
61
  if uploaded_file:
62
  df = pd.read_csv(uploaded_file)
63
  numeric_cols = df.select_dtypes(include=np.number).columns.tolist()
64
 
65
+ # Anomaly Detection
66
+ iso = IsolationForest(contamination=0.02, random_state=42)
67
  labels = iso.fit_predict(df[numeric_cols])
68
  df['status'] = ['❌ Fault Detected' if x == -1 else 'βœ… Healthy' for x in labels]
69
  df['maintenance_flag'] = ['πŸ”§ Inspect Required' if x == -1 else '🟒 Stable' for x in labels]
70
 
71
+ # NLP Embeddings
72
  if 'chunks' not in st.session_state or 'embeddings' not in st.session_state:
73
  chunks = [
74
  f"[Entry {i}] " + ", ".join([f"{col}: {row[col]:.2f}" for col in numeric_cols])
 
78
  st.session_state.chunks = chunks
79
  st.session_state.embeddings = embeddings
80
 
81
+ # Health Summary
82
  col1, col2 = st.columns(2)
 
83
  with col1:
84
  st.markdown("### 🧠 Machine Health Summary")
85
  status_counts = df['status'].value_counts()
86
+ fig1, ax1 = plt.subplots(figsize=(5, 4))
87
+ bars = ax1.bar(status_counts.index, status_counts.values, color=["red", "green"])
88
+ ax1.set_title("Detected Machine Health Conditions", fontsize=14)
89
+ ax1.set_ylabel("Record Count")
90
+ ax1.set_xlabel("Status")
91
  ax1.set_facecolor("#0f1117")
92
  ax1.tick_params(colors='white')
93
  ax1.title.set_color('white')
94
+ ax1.xaxis.label.set_color('white')
95
  ax1.yaxis.label.set_color('white')
96
  for spine in ax1.spines.values():
97
  spine.set_edgecolor('white')
98
+ for bar in bars:
99
+ height = bar.get_height()
100
+ ax1.annotate(f'{height:,}', xy=(bar.get_x() + bar.get_width()/2, height),
101
+ xytext=(0, 6), textcoords="offset points", ha='center', color='white')
102
  st.pyplot(fig1)
103
 
104
  with col2:
105
  st.markdown("### πŸ§ͺ Parameters Monitored")
106
  st.markdown(f"""
107
  <div class="card">
108
+ {' β€’ '.join(numeric_cols)}
109
  </div>
110
  """, unsafe_allow_html=True)
111
 
112
+ # Trend Plot
113
  st.markdown("### πŸ“‰ Sensor Trend (with Fault Overlay)")
114
  col3, col4 = st.columns(2)
115
  time_col = col3.selectbox("πŸ•’ Time Column", ["None"] + list(df.columns))
 
120
 
121
  x_vals = df[time_col] if time_col != "None" else df.index
122
  y_vals = df[trend_param]
123
+ y_label = f"{trend_param} ({unit_map.get(trend_param.lower(), '')})"
124
 
125
+ fig2, ax2 = plt.subplots(figsize=(8, 4.5))
126
+ ax2.plot(x_vals, y_vals, label=trend_param, color="skyblue", linewidth=1.5)
127
  ax2.scatter(
128
  x_vals[df['status'] == '❌ Fault Detected'],
129
  y_vals[df['status'] == '❌ Fault Detected'],
130
  color='red', label='Fault Detected', zorder=5
131
  )
132
+ ax2.set_title(f"{trend_param} Sensor Trend")
133
  ax2.set_xlabel("Time" if time_col != "None" else "Index")
134
+ ax2.set_ylabel(y_label)
135
  ax2.legend()
136
  ax2.set_facecolor("#0f1117")
137
  ax2.tick_params(colors='white')
 
142
  spine.set_edgecolor('white')
143
  st.pyplot(fig2)
144
 
145
+ img_buffer = BytesIO()
146
+ fig2.savefig(img_buffer, format='png', bbox_inches="tight")
147
+ st.download_button("πŸ“· Download Trend Chart (PNG)", img_buffer.getvalue(), file_name="sensor_trend.png")
148
+
149
+ # Fault Rate Over Time
150
+ if time_col != "None":
151
+ st.markdown("### πŸ“ˆ Fault Rate Over Time")
152
+ df[time_col] = pd.to_datetime(df[time_col], errors='coerce')
153
+ df['fault_flag'] = df['status'].apply(lambda x: 1 if x == '❌ Fault Detected' else 0)
154
+ freq = 'H' if (df[time_col].max() - df[time_col].min()).days <= 3 else 'D'
155
+ grouped = df.set_index(time_col)['fault_flag'].resample(freq).mean() * 100
156
+
157
+ fig3, ax3 = plt.subplots(figsize=(8, 4))
158
+ ax3.plot(grouped.index, grouped, color='orange', linewidth=2)
159
+ ax3.set_title("Fault Rate Over Time")
160
+ ax3.set_ylabel("Fault Rate (%)")
161
+ ax3.set_xlabel("Time")
162
+ ax3.set_facecolor("#0f1117")
163
+ ax3.tick_params(colors='white')
164
+ ax3.title.set_color('white')
165
+ ax3.yaxis.label.set_color('white')
166
+ ax3.xaxis.label.set_color('white')
167
+ for spine in ax3.spines.values():
168
+ spine.set_edgecolor('white')
169
+ st.pyplot(fig3)
170
+
171
+ # Export Faults
172
  st.markdown("### πŸ“€ Export Anomalies")
173
+ fault_df = df[df['status'] == '❌ Fault Detected']
174
+ buf = BytesIO()
175
+ fault_df.to_csv(buf, index=False)
176
+ st.download_button("⬇️ Download Fault Log", data=buf.getvalue(), file_name="faults.csv", mime="text/csv")
 
 
 
 
 
177
 
178
+ # Metadata correlation
179
  st.markdown("### 🏷️ Fault Distribution by Machine/Component")
180
+ meta_cols = [c for c in df.columns if 'machine' in c.lower() or 'component' in c.lower()]
181
+ for col in meta_cols:
182
+ st.markdown(f"**{col} – Fault Frequency**")
183
+ st.bar_chart(df[df['status'] == '❌ Fault Detected'][col].value_counts())
 
184
 
185
  # Role Assistant
186
  st.markdown("### πŸ’¬ Technical Assistant by Role")
 
200
  }
201
 
202
  role = st.selectbox("πŸ‘€ Select your role", roles.keys())
203
+ question = st.text_input("🧠 Ask a question")
204
 
205
+ if question:
206
+ qvec = EMBED_MODEL.encode([question])[0]
207
+ sims = np.dot(st.session_state.embeddings, qvec)
208
+ idxs = np.argsort(sims)[-5:][::-1]
209
+ context = "\n".join([st.session_state.chunks[i] for i in idxs])
210
 
211
  prompt = (
212
  f"ROLE: {role}\n"
213
  f"RESPONSIBILITIES: {roles[role]['description']}\n"
214
  f"COMMUNICATION STYLE: {roles[role]['style']}\n\n"
215
  f"DATA CONTEXT:\n{context}\n\n"
216
+ f"QUESTION:\n{question}\n\n"
217
  f"ANSWER:\n"
218
  )
219
  result = GEN_MODEL(prompt, max_length=400)[0]['generated_text']