harishsohani commited on
Commit
3d96e2d
·
verified ·
1 Parent(s): fa79b4d

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +311 -144
app.py CHANGED
@@ -7,53 +7,24 @@ import streamlit as st
7
  # import pandas
8
  import pandas as pd
9
 
10
- # define functiom which can provide formatted input with appropriate label and input text
11
- # this will help in p[roducing consistent representation
12
- def formatted_number_input(title, hint, **kwargs):
13
- st.markdown(f"**{title}**")
14
- st.caption(hint)
15
- return st.number_input("", **kwargs)
16
-
17
- def formatted_number_input2(title, hint, minval, maxval, defvalue, steps, valformat="%.6f"):
18
-
19
- st.markdown('<div style="margin-bottom:4px;">', unsafe_allow_html=True)
20
-
21
- col1, col2 = st.columns([3, 1], vertical_alignment="center")
22
-
23
- with col1:
24
- st.markdown(
25
- f"""
26
- <div style="line-height:1.0">
27
- <strong>{title}</strong><br>
28
- <span style="font-size:1.10em; color:gray;">(Range {hint})</span>
29
- </div>
30
- """,
31
- unsafe_allow_html=True
32
- )
33
-
34
- with col2:
35
- usre_input = st.number_input("",
36
- min_value=minval,
37
- max_value=maxval,
38
- value=defvalue,
39
- step=steps,
40
- format=valformat,
41
- label_visibility="collapsed"
42
- )
43
-
44
- st.markdown('</div>', unsafe_allow_html=True)
45
-
46
- return usre_input
47
-
48
  # ---------------------------------------------------------
49
  # PAGE CONFIG
50
  # ---------------------------------------------------------
51
  st.set_page_config(
52
- page_title="Predictive Maintenenace App" #,
53
- #layout="wide"
54
  )
55
 
56
 
 
 
 
 
 
 
 
 
 
57
  st.markdown("""
58
  <style>
59
  .block-container {
@@ -65,143 +36,339 @@ st.markdown("""
65
 
66
 
67
  # ---------------------------------------------------------
68
- # TITLE
69
  # ---------------------------------------------------------
70
  st.title("🏖️ Predict Maintenance")
71
- st.write("The Predict Maintenance app is a tool to predict if an Engine needs any maintenance based on provided operating sensor parameters.")
72
- st.write("Fill in the details below and click **Predict** to see if the Engine needs maintenance to prevent from failure.")
73
-
74
-
75
-
76
- # ====================================
77
- # Section : Capture Engine Parameters
78
- # ====================================
79
- st.subheader ("Engine Parameters")
80
-
81
- rpm = formatted_number_input2(
82
- "Lubricating oil pressure in kilopascals (kPa)",
83
- "50 to 2500",
84
- minval=50.0,
85
- maxval=2500.0,
86
- defvalue=735.0,
87
- steps=10.0,
88
- valformat="%.2f"
89
- )
90
-
91
-
92
- oil_pressure = formatted_number_input2(
93
- "Lubricating oil pressure in kilopascals (kPa)",
94
- "0.001 to 10.0",
95
- minval=0.001,
96
- maxval=10.0,
97
- defvalue=3.300000,
98
- steps=0.001,
99
- valformat="%.6f"
100
- )
101
-
102
-
103
- fuel_pressure = formatted_number_input2(
104
- "Fuel Pressure in kilopascals (kPa)",
105
- "0.01 to 25.0",
106
- minval=0.01,
107
- maxval=25.0,
108
- defvalue=6.500000,
109
- steps=0.01,
110
- valformat="%.6f"
111
- )
112
 
113
 
114
- coolant_pressure = formatted_number_input2(
115
- "Coolant Pressure in kilopascals (kPa)",
116
- "0.01 to 10.0",
117
- minval=0.01,
118
- maxval=10.0,
119
- defvalue=2.250000,
120
- steps=0.10,
121
- valformat="%.6f"
122
- )
123
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
- lub_oil_temp = formatted_number_input2(
126
- "Lubricating oil Temperature in degrees Celsius (°C)",
127
- "50.0 to 100.0",
128
- minval=50.0,
129
- maxval=100.0,
130
- defvalue=75.0,
131
- steps=0.1,
132
- valformat="%.6f"
133
- )
134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
- coolant_temp = formatted_number_input2(
137
- "Coolant Temperature in degrees Celsius (°C)",
138
- "50.0 to 200.0",
139
- minval=50.0,
140
- maxval=200.0,
141
- defvalue=75.000000,
142
- steps=0.1,
143
- valformat="%.6f"
144
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
 
 
 
 
146
 
147
- # ==========================
148
- # Single Value Prediction
149
- # ==========================
150
- if st.button("Check fo Maintenance"):
151
 
152
- # extract the data collected into a structure
153
- input_data = {
154
- 'Engine_rpm' : float(rpm),
155
- 'Lub_oil_pressure' : float(oil_pressure),
156
- 'Fuel_pressure' : float(fuel_pressure),
157
- 'Coolant_pressure' : float(coolant_pressure),
158
- 'lub_oil_temp' : float(lub_oil_temp),
159
- 'Coolant_temp' : float(coolant_temp),
160
- }
161
 
162
- input_df = pd.DataFrame([input_data])
163
 
164
- response = requests.post (
165
- "https://harishsohani-AIMLPredictiveMaintenanceBackEnd.hf.space/v1/EngPredMaintenance",
166
- json=input_data
167
- )
 
168
 
169
  if response.status_code == 200:
170
- ## get result as json
171
  result = response.json ()
172
 
173
  resp_status = result.get ("status")
174
-
175
  if resp_status == "success":
176
-
177
  ## Get Sales Prediction Value
178
- prediction_from_backend = result.get ("prediction") # Extract only the value
179
-
180
- # generate output string
181
- if prediction_from_backend == 1:
182
- resultstr = "Engine **likely** needs maintenance."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  else:
184
- resultstr = "Engine does not need any maintenance"
185
-
186
- st.success(resultstr)
187
 
 
188
  else:
189
 
190
  error_str = result.get ("message")
191
 
192
  st.error(error_str)
 
193
 
194
  elif response.status_code == 400 or response.status_code == 500: # known errors
195
-
196
  ## get result as json
197
  result = response.json ()
198
 
199
  error_str = result.get ("message")
200
  st.error (f"Error processing request- Status Code : {response.status_code}, error : {error_str}")
201
-
202
  else:
203
  st.error (f"Error processing request- Status Code : {response.status_code}")
204
-
205
- # Show the etails of data frame prepared from user input
206
- st.subheader("📦 Input Data Summary")
207
- st.dataframe (input_df)
 
7
  # import pandas
8
  import pandas as pd
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  # ---------------------------------------------------------
11
  # PAGE CONFIG
12
  # ---------------------------------------------------------
13
  st.set_page_config(
14
+ page_title="Predictive Maintenenace App",
15
+ layout="wide"
16
  )
17
 
18
 
19
+ # ---------------------------------------------------------
20
+ # TITLE
21
+ # ---------------------------------------------------------
22
+ #st.title("🏖️ Predict Engine Maintenance")
23
+ #st.write("The Predict Maintenance app is a tool to predict if an Engine needs any maintenance based on provided operating sensor parameters.")
24
+ #st.write("Fill in the details below and click **Predict** to see if the Engine needs maintenance to prevent from failure.")
25
+ # -----------------------------
26
+ # Title & Description
27
+ # -----------------------------
28
  st.markdown("""
29
  <style>
30
  .block-container {
 
36
 
37
 
38
  # ---------------------------------------------------------
39
+ # Set Page TITLE and additional information for consumer
40
  # ---------------------------------------------------------
41
  st.title("🏖️ Predict Maintenance")
42
+ st.markdown("""
43
+ The Predict Maintenance app help to predict if an engine needs maintenance based on operating sensor parameters.
44
+ *Suggested ranges are based on known information - input is not restricted to the specified range*
45
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
 
48
+ # generic function to provide input
49
+ # this is provided as an utiity to bring consistent user interface
50
+ # currently few parameters are used, rest or for later expansion
51
+ def formatted_number_input(title, hint, minval, maxval, defvalue, steps, valformat="%.4f"):
 
 
 
 
 
52
 
53
+ st.markdown('<div style="margin-bottom:4px;">', unsafe_allow_html=True)
54
+
55
+ user_input = st.number_input(
56
+ label=f"{title} ({hint})",
57
+ #min_value=minval,
58
+ #max_value=maxval,
59
+ value=defvalue,
60
+ #step=steps,
61
+ format=valformat,
62
+ #label_visibility="collapsed"
63
+ )
64
+
65
+ return user_input
66
 
 
 
 
 
 
 
 
 
 
67
 
68
+ st.markdown("""
69
+ <style>
70
+ /* Reduce top padding */
71
+ .block-container {
72
+ padding-top: 1rem;
73
+ padding-bottom: 1rem;
74
+ }
75
+ /* Shared card styling */
76
+ .card {
77
+ border-radius: 16px;
78
+ padding: 22px;
79
+ margin-bottom: 20px;
80
+ transition: 0.3s ease-in-out;
81
+ }
82
+ /* INPUT CARD */
83
+ .input-card {
84
+ background: linear-gradient(145deg, #0f172a, #111827);
85
+ border: 1px solid #334155;
86
+ box-shadow: 0 0 0 1px rgba(59,130,246,0.15);
87
+ }
88
+ /* OUTPUT CARD */
89
+ .output-card {
90
+ background: linear-gradient(145deg, #111827, #0b1220);
91
+ border: 1px solid #16a34a;
92
+ box-shadow: 0 0 12px rgba(34,197,94,0.25);
93
+ }
94
+ /* Card title */
95
+ .card-title {
96
+ font-size: 1.2rem;
97
+ font-weight: 600;
98
+ margin-bottom: 16px;
99
+ letter-spacing: 0.5px;
100
+ }
101
+ /* Button styling */
102
+ div.stButton > button {
103
+ width: 100%;
104
+ border-radius: 10px;
105
+ height: 3em;
106
+ font-weight: 600;
107
+ background: linear-gradient(90deg, #2563eb, #1d4ed8);
108
+ color: white;
109
+ border: none;
110
+ }
111
+ div.stButton > button:hover {
112
+ background: linear-gradient(90deg, #1d4ed8, #1e40af);
113
+ }
114
+ </style>
115
+ """, unsafe_allow_html=True)
116
 
117
+ # ====================================
118
+ # Section : Capture Engine Parameters
119
+ # ====================================
120
+ #st.subheader ("Engine Parameters")
121
+
122
+ # divide UI into two column layout by defining two columns
123
+ # left column is used for input and right for output
124
+ col_inputs, col_output = st.columns([3, 1.5])
125
+
126
+ # update contnent (input) in left input column
127
+ with col_inputs:
128
+
129
+ # using form for usre input, this proivides elegant interface
130
+ with st.form("engine_form"):
131
+
132
+ # set header string
133
+ st.subheader("🔧 Engine Parameters")
134
+
135
+ # create two columsn so we can spread the input into two columns
136
+ col_left, col_right = st.columns(2)
137
+
138
+ # define inputs in left column
139
+ with col_left:
140
+
141
+ rpm = formatted_number_input(
142
+ "Engine RPM",
143
+ "50 to 2500",
144
+ minval=50.0,
145
+ maxval=2500.0,
146
+ defvalue=735.0,
147
+ steps=10.0,
148
+ valformat="%.2f"
149
+ )
150
+
151
+
152
+ oil_pressure = formatted_number_input(
153
+ "Lubricating oil pressure in kPa",
154
+ "0.001 to 10.0",
155
+ minval=0.001,
156
+ maxval=10.0,
157
+ defvalue=3.300000,
158
+ steps=0.001,
159
+ valformat="%.6f"
160
+ )
161
+
162
+
163
+ fuel_pressure = formatted_number_input(
164
+ "Fuel Pressure in kPa",
165
+ "0.01 to 25.0",
166
+ minval=0.01,
167
+ maxval=25.0,
168
+ defvalue=6.500000,
169
+ steps=0.01,
170
+ valformat="%.6f"
171
+ )
172
+
173
+ # define inputs in left column
174
+ with col_right:
175
+ coolant_pressure = formatted_number_input(
176
+ "Coolant Pressure in kPa",
177
+ "0.01 to 10.0",
178
+ minval=0.01,
179
+ maxval=10.0,
180
+ defvalue=2.250000,
181
+ steps=0.10,
182
+ valformat="%.6f"
183
+ )
184
+
185
+
186
+ lub_oil_temp = formatted_number_input(
187
+ "Lubricating oil Temperature in °C",
188
+ "50.0 to 100.0",
189
+ minval=50.0,
190
+ maxval=100.0,
191
+ defvalue=75.0,
192
+ steps=0.1,
193
+ valformat="%.6f"
194
+ )
195
+
196
+
197
+ coolant_temp = formatted_number_input(
198
+ "Coolant Temperature in °C",
199
+ "50.0 to 200.0",
200
+ minval=50.0,
201
+ maxval=200.0,
202
+ defvalue=75.000000,
203
+ steps=0.1,
204
+ valformat="%.6f"
205
+ )
206
+
207
+ submitted = st.form_submit_button("🚀 Check Maintenance")
208
+
209
+
210
+ with col_output:
211
+
212
+ # define place holders for output display
213
+ output_placeholder = st.empty()
214
+ probability_placeholder = st.empty()
215
+ details_placeholder = st.empty()
216
+
217
+
218
+ # ==========================
219
+ # Single Value Prediction
220
+ # ==========================
221
+ with st.expander("🧠 Prediction Result", expanded=True):
222
+ # dispaly result only after submit is done
223
+ if submitted:
224
+
225
+ # extract the data collected into a structure
226
+ input_data = {
227
+ 'Engine_rpm' : float(rpm),
228
+ 'Lub_oil_pressure' : float(oil_pressure),
229
+ 'Fuel_pressure' : float(fuel_pressure),
230
+ 'Coolant_pressure' : float(coolant_pressure),
231
+ 'lub_oil_temp' : float(lub_oil_temp),
232
+ 'Coolant_temp' : float(coolant_temp),
233
+ }
234
+
235
+ input_df = pd.DataFrame([input_data])
236
+
237
+ response = requests.post (
238
+ "https://harishsohani-AIMLProjectTestBackEnd.hf.space/v1/EngPredMaintenance",
239
+ json=input_data
240
+ )
241
+
242
+ if response.status_code == 200:
243
+ ## get result as json
244
+ result = response.json ()
245
+
246
+ resp_status = result.get ("status")
247
+
248
+ if resp_status == "success":
249
+
250
+ ## Get Sales Prediction, probability Values
251
+ prediction_from_backend = result.get ("prediction") # Extract only the value
252
+ probability = result.get ("probability") # Extract only the value
253
+
254
+ # convert probability into % for representation
255
+ formatted_prob = f"{probability * 100:.2f}%"
256
+
257
+ # generate output string
258
+ if prediction_from_backend == 1:
259
+ output_placeholder.error("⚠️ Engine needs maintenance")
260
+ else:
261
+ output_placeholder.success("✅ Engine operating normally")
262
+
263
+ # dispaly probability of failur metric
264
+ probability_placeholder.metric("Failure Probability", formatted_prob)
265
+
266
+ # Display additional information
267
+ details_placeholder.markdown(f"""
268
+ *Model :* XGBoost
269
+ *Inference :* Real-time
270
+ *Note* : Probability of 50% and above is considered as Maintenance Needed.
271
+ """)
272
+
273
+ else:
274
+
275
+ error_str = result.get ("message")
276
+
277
+ output_placeholder.error(f"⚠️ {error_str}")
278
+
279
+ elif response.status_code == 400 or response.status_code == 500: # known errors
280
+
281
+ ## get result as json
282
+ result = response.json ()
283
+
284
+ # get error message
285
+ error_str = result.get ("message")
286
+
287
+ # show error message
288
+ output_placeholder.error(f"⚠️ Error processing request- Status Code : {response.status_code}, error : {error_str}")
289
+
290
+ else:
291
+ output_placeholder.error(f"⚠️ Error processing request- Status Code : {response.status_code}")
292
+
293
 
294
+ # ==============================
295
+ # Batch Prediction
296
+ # ==============================
297
+ st.markdown("---")
298
 
299
+ st.subheader ("Batch Prediction for Engine Maintenance")
300
+ st.markdown("""
301
+ *Select csv file with engine sensor parameters to find prediction for all readings*
302
+ """)
303
 
304
+ file = st.file_uploader ("Upload CSV file", type=["csv"])
 
 
 
 
 
 
 
 
305
 
306
+ if file is not None and st.button("🚀 Check Maintenance"):
307
 
308
+ inputfile = {"file": (file.name, file.getvalue(), "text/csv")}
309
+ response = requests.post(
310
+ "https://harishsohani-AIMLProjectTestBackEnd.hf.space/v1/EngPredMaintenanceForBatch",
311
+ files=inputfile
312
+ )
313
 
314
  if response.status_code == 200:
315
+
316
  result = response.json ()
317
 
318
  resp_status = result.get ("status")
319
+
320
  if resp_status == "success":
321
+
322
  ## Get Sales Prediction Value
323
+ predictions_from_backend = result.get ("predictions") # Extract only the value
324
+
325
+ ## get probabbilities from back end
326
+ probabilities = result.get ("probabilities") # Extract only the value
327
+
328
+ # read input data into data frame
329
+ input_df = pd.read_csv(file)
330
+
331
+ # Ensure lengths match
332
+ if len(predictions_from_backend) == len(input_df):
333
+
334
+ # Add prediction and probability column
335
+ input_df["Prediction"] = predictions_from_backend
336
+ input_df["Probability"] = probabilities
337
+
338
+ st.success("Batch prediction completed successfully")
339
+
340
+ st.markdown("""
341
+ *Prediction : 1 deontes Maintenance is needed*
342
+ """)
343
+
344
+ st.markdown("""
345
+ *Probability : This column indicates failure probability. Value ranges from 0 to 1. Value of 0.5 (50%) and above is considered as Maintenance Needed*
346
+ """)
347
+
348
+ st.markdown("""
349
+ """)
350
+
351
+ # Show combined dataframe
352
+ st.dataframe(input_df, use_container_width=True)
353
+
354
  else:
355
+ st.error("Prediction count does not match input records")
 
 
356
 
357
+
358
  else:
359
 
360
  error_str = result.get ("message")
361
 
362
  st.error(error_str)
363
+
364
 
365
  elif response.status_code == 400 or response.status_code == 500: # known errors
366
+
367
  ## get result as json
368
  result = response.json ()
369
 
370
  error_str = result.get ("message")
371
  st.error (f"Error processing request- Status Code : {response.status_code}, error : {error_str}")
372
+
373
  else:
374
  st.error (f"Error processing request- Status Code : {response.status_code}")