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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -103
app.py CHANGED
@@ -9,12 +9,16 @@ from io import BytesIO
9
 
10
  # App Config
11
  st.set_page_config(
12
- page_title="FactoryGPT 5.0 – Technical Role-Based Maintenance Assistant",
13
  page_icon="🧠",
14
  layout="wide"
15
  )
16
 
17
- # Styling
 
 
 
 
18
  st.markdown("""
19
  <style>
20
  html, body, [class*="css"] {
@@ -22,14 +26,18 @@ st.markdown("""
22
  background-color: #0f1117;
23
  color: #f0f0f0;
24
  }
25
- .stTextInput>div>div>input,
26
- .stSelectbox>div>div>div>div,
27
- .stFileUploader>div>div {
28
  background-color: #1a1c23;
29
- color: #fff;
 
 
 
30
  }
31
- .stDataFrame .blank {
32
- background-color: #0f1117 !important;
 
 
 
33
  }
34
  </style>
35
  """, unsafe_allow_html=True)
@@ -37,78 +45,82 @@ st.markdown("""
37
  # Header
38
  st.markdown("""
39
  <div style='text-align: center;'>
40
- <h1 style='color: #58a6ff;'>🏭 FactoryGPT 5.0 – Predictive Maintenance AI</h1>
41
- <p style='color: #bbb;'>Role-Based Technical Assistant β€’ Sensor Intelligence β€’ Industry 5.0</p>
42
  <hr style='border-top: 2px solid #888;'>
43
  </div>
44
  """, unsafe_allow_html=True)
45
 
46
- # Load NLP Models
47
- EMBED_MODEL = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
48
- GEN_MODEL = pipeline('text2text-generation', model='google/flan-t5-base')
49
-
50
- # File Upload
51
  uploaded_file = st.sidebar.file_uploader("πŸ“‚ Upload sensor log (CSV)", type=["csv"])
52
 
53
  if uploaded_file:
54
  df = pd.read_csv(uploaded_file)
55
  numeric_cols = df.select_dtypes(include=np.number).columns.tolist()
56
- st.success("βœ… Sensor log successfully loaded.")
57
-
58
- st.markdown("### πŸ“Š Sensor Data Snapshot")
59
- st.dataframe(df.head(), use_container_width=True)
60
 
61
- # Run Vector Chunking
62
- def convert_to_chunks(df):
63
- return [f"[Entry {i}] " + ", ".join([f"{col}: {row[col]:.2f}" for col in numeric_cols]) for i, row in df.iterrows()]
64
-
65
- if 'chunks' not in st.session_state or 'embeddings' not in st.session_state:
66
- chunks = convert_to_chunks(df)
67
- embeddings = EMBED_MODEL.encode(chunks)
68
- st.session_state.chunks = chunks
69
- st.session_state.embeddings = embeddings
70
-
71
- # Detect Anomalies
72
  iso = IsolationForest(contamination=0.02)
73
  labels = iso.fit_predict(df[numeric_cols])
74
  df['status'] = ['❌ Fault Detected' if x == -1 else 'βœ… Healthy' for x in labels]
75
  df['maintenance_flag'] = ['πŸ”§ Inspect Required' if x == -1 else '🟒 Stable' for x in labels]
76
 
77
- st.markdown("### πŸ”Ž Machine Health Assessment")
78
- st.dataframe(df[['status', 'maintenance_flag'] + numeric_cols].head(), use_container_width=True)
79
-
80
- # Health Overview Chart
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("Machine Health Status")
86
- ax1.set_ylabel("Occurrences")
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
- # Parameter Trend Chart
96
- st.markdown("### πŸ“‰ Sensor Parameter Trend")
97
- time_col = st.selectbox("πŸ•’ Select Time Column (optional)", ["None"] + list(df.columns))
98
- param = st.selectbox("πŸ“Œ Choose a Parameter to Visualize", numeric_cols)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
  if time_col != "None":
101
  df = df.sort_values(by=time_col)
102
 
103
- fig2, ax2 = plt.subplots()
104
  x_vals = df[time_col] if time_col != "None" else df.index
105
- ax2.plot(x_vals, df[param], label=param, color="skyblue")
106
- anomaly_x = x_vals[df['status'] == '❌ Fault Detected']
107
- anomaly_y = df[param][df['status'] == '❌ Fault Detected']
108
- ax2.scatter(anomaly_x, anomaly_y, color='red', label='Fault Detected', zorder=5)
109
- ax2.set_title(f"{param} Over Time")
 
 
 
 
 
110
  ax2.set_xlabel("Time" if time_col != "None" else "Index")
111
- ax2.set_ylabel(param)
112
  ax2.legend()
113
  ax2.set_facecolor("#0f1117")
114
  ax2.tick_params(colors='white')
@@ -119,62 +131,45 @@ if uploaded_file:
119
  spine.set_edgecolor('white')
120
  st.pyplot(fig2)
121
 
122
- # Parameter List
123
- st.markdown("### πŸ§ͺ Parameters Monitored")
124
- st.markdown(", ".join(numeric_cols))
125
-
126
- # Export Anomalies
127
- st.markdown("### πŸ“€ Export Flagged Anomalies")
128
  anomalies_df = df[df['status'] == '❌ Fault Detected']
129
  buffer = BytesIO()
130
  anomalies_df.to_csv(buffer, index=False)
131
  st.download_button(
132
- label="⬇️ Download Fault Records",
133
  data=buffer.getvalue(),
134
- file_name="fault_records.csv",
135
  mime="text/csv"
136
  )
137
 
138
- # Fault Correlation if Metadata Exists
139
  st.markdown("### 🏷️ Fault Distribution by Machine/Component")
140
  metadata_cols = [col for col in df.columns if 'machine' in col.lower() or 'component' in col.lower()]
141
- for col in metadata_cols:
142
- st.markdown(f"**{col.capitalize()} – Fault Frequency**")
143
- fault_counts = df[df['status'] == '❌ Fault Detected'][col].value_counts()
144
- st.bar_chart(fault_counts)
145
 
146
- # Role-based Technical Assistant
147
  st.markdown("### πŸ’¬ Technical Assistant by Role")
148
  roles = {
149
  "Operator": {
150
- "description": "Focus on simple equipment behavior. Identify unusual patterns and suggest if operator actions are needed.",
151
- "style": (
152
- "Explain in clear and simple terms. Focus on sensor changes, safe operation, and when to escalate to maintenance. "
153
- "Avoid deep technical jargon."
154
- )
155
  },
156
  "Maintenance": {
157
- "description": "Examine possible fault conditions. Reference symptoms, parts affected, and recommend procedural maintenance actions.",
158
- "style": (
159
- "Give a technical breakdown of what components may be degrading. Recommend maintenance steps and cite related sensor evidence. "
160
- "Use concise, technician-friendly language."
161
- )
162
  },
163
  "Engineer": {
164
- "description": "Perform data-driven diagnostics. Detect systemic issues, control instability, or potential root causes.",
165
- "style": (
166
- "Provide a structured root cause analysis using engineering language. Mention potential failure modes (e.g., drift, thermal loss, PID lag), "
167
- "anomaly thresholds, and corrective engineering strategies."
168
- )
169
  }
170
  }
171
 
172
  role = st.selectbox("πŸ‘€ Select your role", roles.keys())
173
-
174
- if 'chat_history' not in st.session_state:
175
- st.session_state.chat_history = []
176
-
177
- user_input = st.text_input("🧠 Ask a question about equipment behavior")
178
 
179
  if user_input:
180
  query_vec = EMBED_MODEL.encode([user_input])[0]
@@ -182,22 +177,16 @@ if uploaded_file:
182
  top_idxs = np.argsort(sims)[-5:][::-1]
183
  context = "\n".join([st.session_state.chunks[i] for i in top_idxs])
184
 
185
- # Prompt Assembly
186
- system_instruction = (
187
  f"ROLE: {role}\n"
188
  f"RESPONSIBILITIES: {roles[role]['description']}\n"
189
  f"COMMUNICATION STYLE: {roles[role]['style']}\n\n"
190
  f"DATA CONTEXT:\n{context}\n\n"
191
  f"QUESTION:\n{user_input}\n\n"
192
- f"ANSWER AS {role.upper()}:\n"
193
  )
194
- response = GEN_MODEL(system_instruction, max_length=400)[0]['generated_text']
195
-
196
- st.session_state.chat_history.append((f"πŸ‘€ {role}", user_input))
197
- st.session_state.chat_history.append(("πŸ€– FactoryGPT", response))
198
-
199
- for speaker, msg in st.session_state.chat_history[-10:]:
200
- st.markdown(f"<div style='margin-bottom: 10px;'><b>{speaker}:</b><br>{msg}</div>", unsafe_allow_html=True)
201
 
202
  else:
203
- st.info("πŸ‘ˆ Upload a CSV sensor log to begin.")
 
9
 
10
  # App Config
11
  st.set_page_config(
12
+ page_title="FactoryGPT 5.0 – Maintenance Dashboard",
13
  page_icon="🧠",
14
  layout="wide"
15
  )
16
 
17
+ # Load NLP + Anomaly Models
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"] {
 
26
  background-color: #0f1117;
27
  color: #f0f0f0;
28
  }
29
+ .card {
 
 
30
  background-color: #1a1c23;
31
+ padding: 1rem;
32
+ border-radius: 10px;
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)
 
45
  # Header
46
  st.markdown("""
47
  <div style='text-align: center;'>
48
+ <h1 style='color: #58a6ff;'>🏭 FactoryGPT 5.0 – Technical Maintenance Dashboard</h1>
49
+ <p style='color: #bbb;'>Anomaly Monitoring β€’ Parameter Trends β€’ Role-Based Intelligence</p>
50
  <hr style='border-top: 2px solid #888;'>
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])
71
+ for i, row in df.iterrows()
72
+ ]
73
+ embeddings = EMBED_MODEL.encode(chunks)
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))
106
+ trend_param = col4.selectbox("πŸ“Œ Select Parameter", numeric_cols)
107
 
108
  if time_col != "None":
109
  df = df.sort_values(by=time_col)
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
  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")
156
  roles = {
157
  "Operator": {
158
+ "description": "Focus on equipment behavior. Spot abnormal patterns and guide simple actions.",
159
+ "style": "Explain simply. Emphasize safety and when to alert maintenance."
 
 
 
160
  },
161
  "Maintenance": {
162
+ "description": "Diagnose machine issues. Recommend parts to inspect or replace.",
163
+ "style": "Use technical language. Mention symptoms and sensor causes."
 
 
 
164
  },
165
  "Engineer": {
166
+ "description": "Analyze system behavior. Identify root causes or instability.",
167
+ "style": "Use RCA format. Discuss fault thresholds, control issues, and next steps."
 
 
 
168
  }
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]
 
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']
189
+ st.markdown(f"**πŸ€– Response:**\n\n{result}")
 
 
 
 
 
190
 
191
  else:
192
+ st.info("πŸ‘ˆ Upload a sensor CSV file to generate your technical dashboard.")