iStillWaters commited on
Commit
ca669da
·
verified ·
1 Parent(s): 527087e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +175 -94
app.py CHANGED
@@ -63,29 +63,79 @@ def load_css():
63
  footer {visibility: hidden;}
64
  header {visibility: hidden;}
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  /* Title Section */
67
  .main-title {
68
  font-family: 'Orbitron', sans-serif;
69
- font-size: 3.5rem;
70
  font-weight: 900;
71
  text-align: center;
72
  background: linear-gradient(135deg, #00d4ff 0%, #0090ff 50%, #0051ff 100%);
73
  -webkit-background-clip: text;
74
  -webkit-text-fill-color: transparent;
75
  background-clip: text;
76
- margin-bottom: 0.5rem;
77
  text-transform: uppercase;
78
- letter-spacing: 3px;
79
  text-shadow: 0 0 30px rgba(0, 212, 255, 0.3);
80
  }
81
 
82
  .subtitle {
83
  font-family: 'Rajdhani', sans-serif;
84
- font-size: 1.2rem;
85
  text-align: center;
86
  color: #8b95a5;
87
- margin-bottom: 3rem;
88
- letter-spacing: 2px;
89
  }
90
 
91
  /* Dashboard Container */
@@ -94,15 +144,15 @@ def load_css():
94
  width: 100%;
95
  max-width: 1400px;
96
  margin: 0 auto;
97
- padding: 2rem;
98
  }
99
 
100
  /* Central Engine Icon Container */
101
  .engine-container {
102
  position: relative;
103
- width: 320px;
104
- height: 320px;
105
- margin: 4rem auto;
106
  display: flex;
107
  align-items: center;
108
  justify-content: center;
@@ -114,7 +164,7 @@ def load_css():
114
  width: 100%;
115
  height: 100%;
116
  border-radius: 50%;
117
- border: 3px solid transparent;
118
  background: linear-gradient(45deg, transparent 30%, var(--ring-color, #00d4ff) 50%, transparent 70%);
119
  animation: rotate 4s linear infinite;
120
  opacity: 0.6;
@@ -128,16 +178,16 @@ def load_css():
128
  /* Engine Circle Background */
129
  .engine-circle {
130
  position: absolute;
131
- width: 280px;
132
- height: 280px;
133
  border-radius: 50%;
134
  background: radial-gradient(circle at 30% 30%,
135
  rgba(26, 31, 58, 0.9) 0%,
136
  rgba(10, 14, 39, 0.95) 100%);
137
- border: 4px solid var(--border-color, #1a4d7a);
138
  box-shadow:
139
- 0 0 40px var(--glow-color, rgba(0, 212, 255, 0.4)),
140
- inset 0 0 30px rgba(0, 0, 0, 0.5);
141
  display: flex;
142
  align-items: center;
143
  justify-content: center;
@@ -146,8 +196,8 @@ def load_css():
146
 
147
  /* Engine Icon */
148
  .engine-icon {
149
- font-size: 8rem;
150
- filter: drop-shadow(0 0 20px var(--glow-color, rgba(0, 212, 255, 0.6)));
151
  transition: all 0.5s ease;
152
  }
153
 
@@ -179,11 +229,11 @@ def load_css():
179
  /* Probability Display */
180
  .probability-display {
181
  position: absolute;
182
- bottom: -60px;
183
  left: 50%;
184
  transform: translateX(-50%);
185
  font-family: 'Orbitron', sans-serif;
186
- font-size: 1.8rem;
187
  font-weight: 700;
188
  color: var(--border-color, #00d4ff);
189
  text-shadow: 0 0 10px var(--glow-color, rgba(0, 212, 255, 0.5));
@@ -194,8 +244,8 @@ def load_css():
194
  .params-grid {
195
  display: grid;
196
  grid-template-columns: repeat(3, 1fr);
197
- gap: 2rem;
198
- margin-top: 4rem;
199
  max-width: 1200px;
200
  margin-left: auto;
201
  margin-right: auto;
@@ -207,8 +257,8 @@ def load_css():
207
  rgba(26, 31, 58, 0.6) 0%,
208
  rgba(10, 14, 39, 0.8) 100%);
209
  border: 2px solid rgba(0, 212, 255, 0.2);
210
- border-radius: 16px;
211
- padding: 1.5rem;
212
  backdrop-filter: blur(10px);
213
  transition: all 0.3s ease;
214
  position: relative;
@@ -242,18 +292,18 @@ def load_css():
242
 
243
  /* Parameter Icon */
244
  .param-icon {
245
- font-size: 2.5rem;
246
- margin-bottom: 0.5rem;
247
  display: inline-block;
248
  }
249
 
250
  /* Parameter Label */
251
  .param-label {
252
  font-family: 'Rajdhani', sans-serif;
253
- font-size: 1.1rem;
254
  font-weight: 600;
255
  color: #8b95a5;
256
- margin-bottom: 0.5rem;
257
  text-transform: uppercase;
258
  letter-spacing: 1px;
259
  }
@@ -261,10 +311,10 @@ def load_css():
261
  /* Parameter Value */
262
  .param-value {
263
  font-family: 'Orbitron', sans-serif;
264
- font-size: 2rem;
265
  font-weight: 700;
266
  color: var(--accent-color, #00d4ff);
267
- margin-bottom: 1rem;
268
  }
269
 
270
  /* Color Accents for Different Parameters */
@@ -278,10 +328,10 @@ def load_css():
278
  /* Analyze Button */
279
  .analyze-button {
280
  display: block;
281
- margin: 3rem auto;
282
- padding: 1.2rem 4rem;
283
  font-family: 'Orbitron', sans-serif;
284
- font-size: 1.3rem;
285
  font-weight: 700;
286
  color: #ffffff;
287
  background: linear-gradient(135deg, #0090ff 0%, #0051ff 100%);
@@ -303,14 +353,14 @@ def load_css():
303
  /* Status Badge */
304
  .status-badge {
305
  display: inline-block;
306
- padding: 0.8rem 2rem;
307
  font-family: 'Rajdhani', sans-serif;
308
- font-size: 1.3rem;
309
  font-weight: 700;
310
  border-radius: 30px;
311
  text-transform: uppercase;
312
  letter-spacing: 2px;
313
- margin-top: 1rem;
314
  }
315
 
316
  .badge-healthy {
@@ -341,35 +391,35 @@ def load_css():
341
  rgba(10, 14, 39, 0.6) 100%);
342
  border-left: 4px solid #00d4ff;
343
  border-radius: 8px;
344
- padding: 1.5rem;
345
- margin: 2rem 0;
346
  backdrop-filter: blur(10px);
347
  }
348
 
349
  .info-title {
350
  font-family: 'Rajdhani', sans-serif;
351
- font-size: 1.3rem;
352
  font-weight: 700;
353
  color: #00d4ff;
354
- margin-bottom: 1rem;
355
  text-transform: uppercase;
356
  letter-spacing: 1px;
357
  }
358
 
359
  .info-content {
360
  font-family: 'Rajdhani', sans-serif;
361
- font-size: 1.1rem;
362
  color: #b8c5d6;
363
- line-height: 1.6;
364
  }
365
 
366
  /* Recommendations List */
367
  .recommendation-item {
368
  font-family: 'Rajdhani', sans-serif;
369
- font-size: 1.1rem;
370
  color: #e0e6ed;
371
- padding: 0.8rem 1.2rem;
372
- margin: 0.5rem 0;
373
  background: rgba(0, 212, 255, 0.05);
374
  border-left: 3px solid #00d4ff;
375
  border-radius: 4px;
@@ -410,10 +460,10 @@ def load_css():
410
  /* Footer */
411
  .dashboard-footer {
412
  text-align: center;
413
- margin-top: 4rem;
414
- padding: 2rem;
415
  font-family: 'Rajdhani', sans-serif;
416
- font-size: 0.9rem;
417
  color: #6b7280;
418
  border-top: 1px solid rgba(107, 114, 128, 0.2);
419
  }
@@ -439,8 +489,8 @@ def create_circular_gauge(value, max_value, title, color, unit=""):
439
  fig = go.Figure(go.Indicator(
440
  mode = "gauge+number",
441
  value = value,
442
- number = {'suffix': f" {unit}", 'font': {'size': 24, 'color': color}},
443
- title = {'text': title, 'font': {'size': 14, 'color': '#8b95a5'}},
444
  gauge = {
445
  'axis': {'range': [0, max_value], 'tickwidth': 1, 'tickcolor': color},
446
  'bar': {'color': color, 'thickness': 0.7},
@@ -456,8 +506,8 @@ def create_circular_gauge(value, max_value, title, color, unit=""):
456
  ))
457
 
458
  fig.update_layout(
459
- height=200,
460
- margin=dict(l=10, r=10, t=40, b=10),
461
  paper_bgcolor='rgba(0,0,0,0)',
462
  plot_bgcolor='rgba(0,0,0,0)',
463
  font={'family': 'Rajdhani', 'color': '#e0e6ed'}
@@ -549,27 +599,56 @@ def main():
549
  st.markdown('<div class="param-card param-rpm">', unsafe_allow_html=True)
550
  st.markdown('<div class="param-icon">⚡</div>', unsafe_allow_html=True)
551
  st.markdown('<div class="param-label">Engine RPM</div>', unsafe_allow_html=True)
552
- rpm = st.slider("", 0, 2500, 750, 50, label_visibility="collapsed", key="rpm")
 
 
 
 
 
 
 
 
 
 
 
553
  st.markdown(f'<div class="param-value">{rpm}</div>', unsafe_allow_html=True)
554
- st.plotly_chart(create_circular_gauge(rpm, 2500, "RPM", "#00d4ff"), use_container_width=True)
555
  st.markdown('</div>', unsafe_allow_html=True)
556
 
557
  with col2:
558
  st.markdown('<div class="param-card param-fuel">', unsafe_allow_html=True)
559
  st.markdown('<div class="param-icon">⛽</div>', unsafe_allow_html=True)
560
  st.markdown('<div class="param-label">Fuel Pressure</div>', unsafe_allow_html=True)
561
- fuel_p = st.slider("", 0.0, 25.0, 6.2, 0.1, label_visibility="collapsed", key="fuel")
 
 
 
 
 
 
 
 
 
562
  st.markdown(f'<div class="param-value">{fuel_p:.1f} Bar</div>', unsafe_allow_html=True)
563
- st.plotly_chart(create_circular_gauge(fuel_p, 25, "Fuel", "#ff6b35", "Bar"), use_container_width=True)
564
  st.markdown('</div>', unsafe_allow_html=True)
565
 
566
  with col3:
567
  st.markdown('<div class="param-card param-oil-pressure">', unsafe_allow_html=True)
568
  st.markdown('<div class="param-icon">🛢️</div>', unsafe_allow_html=True)
569
  st.markdown('<div class="param-label">Oil Pressure</div>', unsafe_allow_html=True)
570
- lub_oil_p = st.slider("", 0.0, 10.0, 3.16, 0.1, label_visibility="collapsed", key="oil_p")
 
 
 
 
 
 
 
 
 
571
  st.markdown(f'<div class="param-value">{lub_oil_p:.2f} Bar</div>', unsafe_allow_html=True)
572
- st.plotly_chart(create_circular_gauge(lub_oil_p, 10, "Oil", "#ffaa00", "Bar"), use_container_width=True)
573
  st.markdown('</div>', unsafe_allow_html=True)
574
 
575
  # Second row
@@ -579,33 +658,59 @@ def main():
579
  st.markdown('<div class="param-card param-coolant-temp">', unsafe_allow_html=True)
580
  st.markdown('<div class="param-icon">🌡️</div>', unsafe_allow_html=True)
581
  st.markdown('<div class="param-label">Coolant Temp</div>', unsafe_allow_html=True)
582
- coolant_temp = st.slider("", 0.0, 200.0, 80.0, 1.0, label_visibility="collapsed", key="coolant_temp")
 
 
 
 
 
 
 
 
 
583
  st.markdown(f'<div class="param-value">{coolant_temp:.1f} °C</div>', unsafe_allow_html=True)
584
- st.plotly_chart(create_circular_gauge(coolant_temp, 200, "Temp", "#ff3366", "°C"), use_container_width=True)
585
  st.markdown('</div>', unsafe_allow_html=True)
586
 
587
  with col5:
588
  st.markdown('<div class="param-card param-coolant-pressure">', unsafe_allow_html=True)
589
  st.markdown('<div class="param-icon">💧</div>', unsafe_allow_html=True)
590
  st.markdown('<div class="param-label">Coolant Pressure</div>', unsafe_allow_html=True)
591
- coolant_p = st.slider("", 0.0, 10.0, 2.16, 0.1, label_visibility="collapsed", key="coolant_p")
 
 
 
 
 
 
 
 
 
592
  st.markdown(f'<div class="param-value">{coolant_p:.2f} Bar</div>', unsafe_allow_html=True)
593
- st.plotly_chart(create_circular_gauge(coolant_p, 10, "Coolant P", "#00ff88", "Bar"), use_container_width=True)
594
  st.markdown('</div>', unsafe_allow_html=True)
595
 
596
  with col6:
597
  st.markdown('<div class="param-card param-oil-temp">', unsafe_allow_html=True)
598
  st.markdown('<div class="param-icon">🔥</div>', unsafe_allow_html=True)
599
  st.markdown('<div class="param-label">Oil Temperature</div>', unsafe_allow_html=True)
600
- lub_oil_t = st.slider("", 0.0, 150.0, 80.0, 1.0, label_visibility="collapsed", key="oil_temp")
 
 
 
 
 
 
 
 
 
601
  st.markdown(f'<div class="param-value">{lub_oil_t:.1f} °C</div>', unsafe_allow_html=True)
602
- st.plotly_chart(create_circular_gauge(lub_oil_t, 150, "Oil Temp", "#a855f7", "°C"), use_container_width=True)
603
  st.markdown('</div>', unsafe_allow_html=True)
604
 
605
  st.markdown('</div>', unsafe_allow_html=True)
606
 
607
  # Central Engine Status Display
608
- st.markdown("---")
609
 
610
  # Analyze Button
611
  col_center = st.columns([1, 2, 1])
@@ -633,7 +738,7 @@ def main():
633
  st.session_state.current_status = status
634
 
635
  # Display Central Engine Status
636
- st.markdown("### 🔧 Engine Status")
637
 
638
  # Create centered layout for engine icon
639
  col_left, col_center, col_right = st.columns([1, 1, 1])
@@ -662,8 +767,7 @@ def main():
662
  """, unsafe_allow_html=True)
663
 
664
  # Recommendations
665
- st.markdown("---")
666
- st.markdown("### 📋 Recommendations")
667
 
668
  recommendations = get_recommendations(input_df, prob)
669
 
@@ -671,8 +775,7 @@ def main():
671
  st.markdown(f'<div class="recommendation-item">{rec}</div>', unsafe_allow_html=True)
672
 
673
  # Detailed Analysis
674
- st.markdown("---")
675
- st.markdown("### 📊 Detailed Analysis")
676
 
677
  col_detail1, col_detail2 = st.columns(2)
678
 
@@ -704,7 +807,7 @@ def main():
704
 
705
  else:
706
  # Default display before analysis
707
- st.markdown("### 🔧 Engine Status")
708
  col_left, col_center, col_right = st.columns([1, 1, 1])
709
 
710
  with col_center:
@@ -728,32 +831,10 @@ def main():
728
  </div>
729
  """, unsafe_allow_html=True)
730
 
731
- # Analysis History
732
- if st.session_state.predictions:
733
- st.markdown("---")
734
- st.markdown("### 📈 Analysis History")
735
-
736
- history_df = pd.DataFrame(st.session_state.predictions)
737
-
738
- # Display last 5 predictions
739
- st.markdown(f"**Total Analyses:** {len(history_df)} | **Showing last 5**")
740
-
741
- for idx, row in history_df.tail(5).iterrows():
742
- status, emoji, color, status_text = get_engine_status(row['probability'])
743
- st.markdown(f"""
744
- <div class="history-card">
745
- <strong>{emoji} {row['timestamp'].strftime('%H:%M:%S')}</strong> -
746
- Failure Risk: <span style="color: {color};">{row['probability']*100:.1f}%</span> -
747
- Status: {status_text}
748
- </div>
749
- """, unsafe_allow_html=True)
750
-
751
  # Footer
752
  st.markdown("""
753
  <div class="dashboard-footer">
754
- <p><strong>Engine Predictive Maintenance System</strong></p>
755
- <p>Powered by Machine Learning | Real-time Monitoring & Analysis</p>
756
- <p style="margin-top: 1rem; font-size: 0.8rem;">Capstone Project - 2024</p>
757
  </div>
758
  """, unsafe_allow_html=True)
759
 
 
63
  footer {visibility: hidden;}
64
  header {visibility: hidden;}
65
 
66
+ /* Hide slider labels */
67
+ .stSlider > label {
68
+ display: none !important;
69
+ }
70
+
71
+ /* Compact number inputs */
72
+ .stNumberInput > label {
73
+ display: none !important;
74
+ }
75
+
76
+ .stNumberInput > div {
77
+ margin-bottom: 0 !important;
78
+ }
79
+
80
+ .stNumberInput input {
81
+ font-size: 0.9rem !important;
82
+ padding: 0.3rem !important;
83
+ height: 2.2rem !important;
84
+ }
85
+
86
+ /* Reduce spacing in Streamlit elements */
87
+ .block-container {
88
+ padding-top: 1rem !important;
89
+ padding-bottom: 0rem !important;
90
+ }
91
+
92
+ /* Compact dividers */
93
+ hr {
94
+ margin: 0.5rem 0 !important;
95
+ }
96
+
97
+ /* Compact markdown headers */
98
+ h3 {
99
+ margin-top: 0.5rem !important;
100
+ margin-bottom: 0.5rem !important;
101
+ font-size: 1.3rem !important;
102
+ }
103
+
104
+ h4 {
105
+ margin-top: 0.5rem !important;
106
+ margin-bottom: 0.5rem !important;
107
+ font-size: 1.1rem !important;
108
+ font-family: 'Rajdhani', sans-serif !important;
109
+ }
110
+
111
+ /* Remove extra spacing from columns */
112
+ [data-testid="column"] {
113
+ padding: 0.3rem !important;
114
+ }
115
+
116
  /* Title Section */
117
  .main-title {
118
  font-family: 'Orbitron', sans-serif;
119
+ font-size: 2.2rem;
120
  font-weight: 900;
121
  text-align: center;
122
  background: linear-gradient(135deg, #00d4ff 0%, #0090ff 50%, #0051ff 100%);
123
  -webkit-background-clip: text;
124
  -webkit-text-fill-color: transparent;
125
  background-clip: text;
126
+ margin-bottom: 0.3rem;
127
  text-transform: uppercase;
128
+ letter-spacing: 2px;
129
  text-shadow: 0 0 30px rgba(0, 212, 255, 0.3);
130
  }
131
 
132
  .subtitle {
133
  font-family: 'Rajdhani', sans-serif;
134
+ font-size: 1rem;
135
  text-align: center;
136
  color: #8b95a5;
137
+ margin-bottom: 1rem;
138
+ letter-spacing: 1px;
139
  }
140
 
141
  /* Dashboard Container */
 
144
  width: 100%;
145
  max-width: 1400px;
146
  margin: 0 auto;
147
+ padding: 0.5rem;
148
  }
149
 
150
  /* Central Engine Icon Container */
151
  .engine-container {
152
  position: relative;
153
+ width: 180px;
154
+ height: 180px;
155
+ margin: 1rem auto;
156
  display: flex;
157
  align-items: center;
158
  justify-content: center;
 
164
  width: 100%;
165
  height: 100%;
166
  border-radius: 50%;
167
+ border: 2px solid transparent;
168
  background: linear-gradient(45deg, transparent 30%, var(--ring-color, #00d4ff) 50%, transparent 70%);
169
  animation: rotate 4s linear infinite;
170
  opacity: 0.6;
 
178
  /* Engine Circle Background */
179
  .engine-circle {
180
  position: absolute;
181
+ width: 160px;
182
+ height: 160px;
183
  border-radius: 50%;
184
  background: radial-gradient(circle at 30% 30%,
185
  rgba(26, 31, 58, 0.9) 0%,
186
  rgba(10, 14, 39, 0.95) 100%);
187
+ border: 3px solid var(--border-color, #1a4d7a);
188
  box-shadow:
189
+ 0 0 30px var(--glow-color, rgba(0, 212, 255, 0.4)),
190
+ inset 0 0 20px rgba(0, 0, 0, 0.5);
191
  display: flex;
192
  align-items: center;
193
  justify-content: center;
 
196
 
197
  /* Engine Icon */
198
  .engine-icon {
199
+ font-size: 5rem;
200
+ filter: drop-shadow(0 0 15px var(--glow-color, rgba(0, 212, 255, 0.6)));
201
  transition: all 0.5s ease;
202
  }
203
 
 
229
  /* Probability Display */
230
  .probability-display {
231
  position: absolute;
232
+ bottom: -35px;
233
  left: 50%;
234
  transform: translateX(-50%);
235
  font-family: 'Orbitron', sans-serif;
236
+ font-size: 1.2rem;
237
  font-weight: 700;
238
  color: var(--border-color, #00d4ff);
239
  text-shadow: 0 0 10px var(--glow-color, rgba(0, 212, 255, 0.5));
 
244
  .params-grid {
245
  display: grid;
246
  grid-template-columns: repeat(3, 1fr);
247
+ gap: 1rem;
248
+ margin-top: 1rem;
249
  max-width: 1200px;
250
  margin-left: auto;
251
  margin-right: auto;
 
257
  rgba(26, 31, 58, 0.6) 0%,
258
  rgba(10, 14, 39, 0.8) 100%);
259
  border: 2px solid rgba(0, 212, 255, 0.2);
260
+ border-radius: 12px;
261
+ padding: 0.8rem;
262
  backdrop-filter: blur(10px);
263
  transition: all 0.3s ease;
264
  position: relative;
 
292
 
293
  /* Parameter Icon */
294
  .param-icon {
295
+ font-size: 1.8rem;
296
+ margin-bottom: 0.3rem;
297
  display: inline-block;
298
  }
299
 
300
  /* Parameter Label */
301
  .param-label {
302
  font-family: 'Rajdhani', sans-serif;
303
+ font-size: 0.9rem;
304
  font-weight: 600;
305
  color: #8b95a5;
306
+ margin-bottom: 0.3rem;
307
  text-transform: uppercase;
308
  letter-spacing: 1px;
309
  }
 
311
  /* Parameter Value */
312
  .param-value {
313
  font-family: 'Orbitron', sans-serif;
314
+ font-size: 1.3rem;
315
  font-weight: 700;
316
  color: var(--accent-color, #00d4ff);
317
+ margin-bottom: 0.5rem;
318
  }
319
 
320
  /* Color Accents for Different Parameters */
 
328
  /* Analyze Button */
329
  .analyze-button {
330
  display: block;
331
+ margin: 1.5rem auto;
332
+ padding: 0.8rem 3rem;
333
  font-family: 'Orbitron', sans-serif;
334
+ font-size: 1.1rem;
335
  font-weight: 700;
336
  color: #ffffff;
337
  background: linear-gradient(135deg, #0090ff 0%, #0051ff 100%);
 
353
  /* Status Badge */
354
  .status-badge {
355
  display: inline-block;
356
+ padding: 0.5rem 1.5rem;
357
  font-family: 'Rajdhani', sans-serif;
358
+ font-size: 1.1rem;
359
  font-weight: 700;
360
  border-radius: 30px;
361
  text-transform: uppercase;
362
  letter-spacing: 2px;
363
+ margin-top: 0.5rem;
364
  }
365
 
366
  .badge-healthy {
 
391
  rgba(10, 14, 39, 0.6) 100%);
392
  border-left: 4px solid #00d4ff;
393
  border-radius: 8px;
394
+ padding: 0.8rem;
395
+ margin: 0.5rem 0;
396
  backdrop-filter: blur(10px);
397
  }
398
 
399
  .info-title {
400
  font-family: 'Rajdhani', sans-serif;
401
+ font-size: 1.1rem;
402
  font-weight: 700;
403
  color: #00d4ff;
404
+ margin-bottom: 0.5rem;
405
  text-transform: uppercase;
406
  letter-spacing: 1px;
407
  }
408
 
409
  .info-content {
410
  font-family: 'Rajdhani', sans-serif;
411
+ font-size: 0.95rem;
412
  color: #b8c5d6;
413
+ line-height: 1.5;
414
  }
415
 
416
  /* Recommendations List */
417
  .recommendation-item {
418
  font-family: 'Rajdhani', sans-serif;
419
+ font-size: 0.95rem;
420
  color: #e0e6ed;
421
+ padding: 0.5rem 1rem;
422
+ margin: 0.3rem 0;
423
  background: rgba(0, 212, 255, 0.05);
424
  border-left: 3px solid #00d4ff;
425
  border-radius: 4px;
 
460
  /* Footer */
461
  .dashboard-footer {
462
  text-align: center;
463
+ margin-top: 1rem;
464
+ padding: 0.5rem;
465
  font-family: 'Rajdhani', sans-serif;
466
+ font-size: 0.85rem;
467
  color: #6b7280;
468
  border-top: 1px solid rgba(107, 114, 128, 0.2);
469
  }
 
489
  fig = go.Figure(go.Indicator(
490
  mode = "gauge+number",
491
  value = value,
492
+ number = {'suffix': f" {unit}", 'font': {'size': 18, 'color': color}},
493
+ title = {'text': title, 'font': {'size': 12, 'color': '#8b95a5'}},
494
  gauge = {
495
  'axis': {'range': [0, max_value], 'tickwidth': 1, 'tickcolor': color},
496
  'bar': {'color': color, 'thickness': 0.7},
 
506
  ))
507
 
508
  fig.update_layout(
509
+ height=140,
510
+ margin=dict(l=10, r=10, t=30, b=5),
511
  paper_bgcolor='rgba(0,0,0,0)',
512
  plot_bgcolor='rgba(0,0,0,0)',
513
  font={'family': 'Rajdhani', 'color': '#e0e6ed'}
 
599
  st.markdown('<div class="param-card param-rpm">', unsafe_allow_html=True)
600
  st.markdown('<div class="param-icon">⚡</div>', unsafe_allow_html=True)
601
  st.markdown('<div class="param-label">Engine RPM</div>', unsafe_allow_html=True)
602
+
603
+ # Manual input and slider in columns
604
+ rpm_col1, rpm_col2 = st.columns([1, 2])
605
+ with rpm_col1:
606
+ rpm_input = st.number_input("", 0, 2500, 750, 50, label_visibility="collapsed", key="rpm_input")
607
+ with rpm_col2:
608
+ rpm = st.slider("", 0, 2500, rpm_input, 50, label_visibility="collapsed", key="rpm")
609
+
610
+ # Sync the values
611
+ if rpm != rpm_input:
612
+ rpm = rpm_input
613
+
614
  st.markdown(f'<div class="param-value">{rpm}</div>', unsafe_allow_html=True)
615
+ st.plotly_chart(create_circular_gauge(rpm, 2500, "RPM", "#00d4ff"), use_container_width=True, key="gauge_rpm")
616
  st.markdown('</div>', unsafe_allow_html=True)
617
 
618
  with col2:
619
  st.markdown('<div class="param-card param-fuel">', unsafe_allow_html=True)
620
  st.markdown('<div class="param-icon">⛽</div>', unsafe_allow_html=True)
621
  st.markdown('<div class="param-label">Fuel Pressure</div>', unsafe_allow_html=True)
622
+
623
+ fuel_col1, fuel_col2 = st.columns([1, 2])
624
+ with fuel_col1:
625
+ fuel_input = st.number_input("", 0.0, 25.0, 6.2, 0.1, label_visibility="collapsed", key="fuel_input")
626
+ with fuel_col2:
627
+ fuel_p = st.slider("", 0.0, 25.0, fuel_input, 0.1, label_visibility="collapsed", key="fuel")
628
+
629
+ if fuel_p != fuel_input:
630
+ fuel_p = fuel_input
631
+
632
  st.markdown(f'<div class="param-value">{fuel_p:.1f} Bar</div>', unsafe_allow_html=True)
633
+ st.plotly_chart(create_circular_gauge(fuel_p, 25, "Fuel", "#ff6b35", "Bar"), use_container_width=True, key="gauge_fuel")
634
  st.markdown('</div>', unsafe_allow_html=True)
635
 
636
  with col3:
637
  st.markdown('<div class="param-card param-oil-pressure">', unsafe_allow_html=True)
638
  st.markdown('<div class="param-icon">🛢️</div>', unsafe_allow_html=True)
639
  st.markdown('<div class="param-label">Oil Pressure</div>', unsafe_allow_html=True)
640
+
641
+ oil_p_col1, oil_p_col2 = st.columns([1, 2])
642
+ with oil_p_col1:
643
+ oil_p_input = st.number_input("", 0.0, 10.0, 3.16, 0.1, label_visibility="collapsed", key="oil_p_input")
644
+ with oil_p_col2:
645
+ lub_oil_p = st.slider("", 0.0, 10.0, oil_p_input, 0.1, label_visibility="collapsed", key="oil_p")
646
+
647
+ if lub_oil_p != oil_p_input:
648
+ lub_oil_p = oil_p_input
649
+
650
  st.markdown(f'<div class="param-value">{lub_oil_p:.2f} Bar</div>', unsafe_allow_html=True)
651
+ st.plotly_chart(create_circular_gauge(lub_oil_p, 10, "Oil", "#ffaa00", "Bar"), use_container_width=True, key="gauge_oil_p")
652
  st.markdown('</div>', unsafe_allow_html=True)
653
 
654
  # Second row
 
658
  st.markdown('<div class="param-card param-coolant-temp">', unsafe_allow_html=True)
659
  st.markdown('<div class="param-icon">🌡️</div>', unsafe_allow_html=True)
660
  st.markdown('<div class="param-label">Coolant Temp</div>', unsafe_allow_html=True)
661
+
662
+ coolant_t_col1, coolant_t_col2 = st.columns([1, 2])
663
+ with coolant_t_col1:
664
+ coolant_t_input = st.number_input("", 0.0, 200.0, 80.0, 1.0, label_visibility="collapsed", key="coolant_temp_input")
665
+ with coolant_t_col2:
666
+ coolant_temp = st.slider("", 0.0, 200.0, coolant_t_input, 1.0, label_visibility="collapsed", key="coolant_temp")
667
+
668
+ if coolant_temp != coolant_t_input:
669
+ coolant_temp = coolant_t_input
670
+
671
  st.markdown(f'<div class="param-value">{coolant_temp:.1f} °C</div>', unsafe_allow_html=True)
672
+ st.plotly_chart(create_circular_gauge(coolant_temp, 200, "Temp", "#ff3366", "°C"), use_container_width=True, key="gauge_coolant_t")
673
  st.markdown('</div>', unsafe_allow_html=True)
674
 
675
  with col5:
676
  st.markdown('<div class="param-card param-coolant-pressure">', unsafe_allow_html=True)
677
  st.markdown('<div class="param-icon">💧</div>', unsafe_allow_html=True)
678
  st.markdown('<div class="param-label">Coolant Pressure</div>', unsafe_allow_html=True)
679
+
680
+ coolant_p_col1, coolant_p_col2 = st.columns([1, 2])
681
+ with coolant_p_col1:
682
+ coolant_p_input = st.number_input("", 0.0, 10.0, 2.16, 0.1, label_visibility="collapsed", key="coolant_p_input")
683
+ with coolant_p_col2:
684
+ coolant_p = st.slider("", 0.0, 10.0, coolant_p_input, 0.1, label_visibility="collapsed", key="coolant_p")
685
+
686
+ if coolant_p != coolant_p_input:
687
+ coolant_p = coolant_p_input
688
+
689
  st.markdown(f'<div class="param-value">{coolant_p:.2f} Bar</div>', unsafe_allow_html=True)
690
+ st.plotly_chart(create_circular_gauge(coolant_p, 10, "Coolant P", "#00ff88", "Bar"), use_container_width=True, key="gauge_coolant_p")
691
  st.markdown('</div>', unsafe_allow_html=True)
692
 
693
  with col6:
694
  st.markdown('<div class="param-card param-oil-temp">', unsafe_allow_html=True)
695
  st.markdown('<div class="param-icon">🔥</div>', unsafe_allow_html=True)
696
  st.markdown('<div class="param-label">Oil Temperature</div>', unsafe_allow_html=True)
697
+
698
+ oil_t_col1, oil_t_col2 = st.columns([1, 2])
699
+ with oil_t_col1:
700
+ oil_t_input = st.number_input("", 0.0, 150.0, 80.0, 1.0, label_visibility="collapsed", key="oil_temp_input")
701
+ with oil_t_col2:
702
+ lub_oil_t = st.slider("", 0.0, 150.0, oil_t_input, 1.0, label_visibility="collapsed", key="oil_temp")
703
+
704
+ if lub_oil_t != oil_t_input:
705
+ lub_oil_t = oil_t_input
706
+
707
  st.markdown(f'<div class="param-value">{lub_oil_t:.1f} °C</div>', unsafe_allow_html=True)
708
+ st.plotly_chart(create_circular_gauge(lub_oil_t, 150, "Oil Temp", "#a855f7", "°C"), use_container_width=True, key="gauge_oil_t")
709
  st.markdown('</div>', unsafe_allow_html=True)
710
 
711
  st.markdown('</div>', unsafe_allow_html=True)
712
 
713
  # Central Engine Status Display
 
714
 
715
  # Analyze Button
716
  col_center = st.columns([1, 2, 1])
 
738
  st.session_state.current_status = status
739
 
740
  # Display Central Engine Status
741
+ st.markdown("#### 🔧 Engine Status")
742
 
743
  # Create centered layout for engine icon
744
  col_left, col_center, col_right = st.columns([1, 1, 1])
 
767
  """, unsafe_allow_html=True)
768
 
769
  # Recommendations
770
+ st.markdown("#### 📋 Recommendations")
 
771
 
772
  recommendations = get_recommendations(input_df, prob)
773
 
 
775
  st.markdown(f'<div class="recommendation-item">{rec}</div>', unsafe_allow_html=True)
776
 
777
  # Detailed Analysis
778
+ st.markdown("#### 📊 Analysis Details")
 
779
 
780
  col_detail1, col_detail2 = st.columns(2)
781
 
 
807
 
808
  else:
809
  # Default display before analysis
810
+ st.markdown("#### 🔧 Engine Status")
811
  col_left, col_center, col_right = st.columns([1, 1, 1])
812
 
813
  with col_center:
 
831
  </div>
832
  """, unsafe_allow_html=True)
833
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
834
  # Footer
835
  st.markdown("""
836
  <div class="dashboard-footer">
837
+ <p style="margin: 0.5rem 0; font-size: 0.8rem;">Engine Predictive Maintenance System | Powered by Machine Learning</p>
 
 
838
  </div>
839
  """, unsafe_allow_html=True)
840