Spaces:
Running
Running
| # import requests for interacting with backend | |
| import requests | |
| # import streamlit library for IO | |
| import streamlit as st | |
| # import pandas | |
| import pandas as pd | |
| # --------------------------------------------------------- | |
| # PAGE CONFIG | |
| # --------------------------------------------------------- | |
| st.set_page_config( | |
| page_title="Predictive Maintenenace App", | |
| layout="wide" | |
| ) | |
| # --------------------------------------------------------- | |
| # TITLE | |
| # --------------------------------------------------------- | |
| #st.title("🏖️ Predict Engine Maintenance") | |
| #st.write("The Predict Maintenance app is a tool to predict if an Engine needs any maintenance based on provided operating sensor parameters.") | |
| #st.write("Fill in the details below and click **Predict** to see if the Engine needs maintenance to prevent from failure.") | |
| # ----------------------------- | |
| # Title & Description | |
| # ----------------------------- | |
| st.markdown(""" | |
| <style> | |
| .block-container { | |
| padding-top: 0.75rem; | |
| padding-bottom: 0.75rem; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # --------------------------------------------------------- | |
| # TITLE | |
| # --------------------------------------------------------- | |
| st.title("🏖️ Predict Maintenance") | |
| #st.write("The Predict Maintenance app is a tool to predict if an Engine needs any maintenance based on provided operating sensor parameters.") | |
| #st.write("Fill in the details below and click **Check for Maintenance** to see if the Engine needs maintenance to prevent from failure.") | |
| #st.write("Suggested Ranges are based on the Range of Values model trained on.") | |
| st.markdown(""" | |
| <style> | |
| .intro-text p { | |
| margin-bottom: 0.4rem; | |
| } | |
| </style> | |
| <div class="intro-text"> | |
| <p>The Predict Maintenance app is a tool to predict if an Engine needs any maintenance based on provided operating sensor parameters.</p> | |
| <p>Fill in the details below and click <b>Check for Maintenance</b> to see if the Engine needs maintenance.</p> | |
| <p><i>Suggested ranges are based on the range of values the model was trained on.</i></p> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| def formatted_number_input(title, hint, minval, maxval, defvalue, steps, valformat="%.4f"): | |
| st.markdown('<div style="margin-bottom:4px;">', unsafe_allow_html=True) | |
| #st.markdown(f"**{title}**") | |
| #st.caption(hint) | |
| #decimals=6 | |
| #raw = st.text_input( | |
| #label="", | |
| #value=f"{defvalue:.{decimals}f}", | |
| #label_visibility="collapsed" | |
| #) | |
| #user_input = float(raw) | |
| user_input = st.number_input( | |
| label=f"{title} (Suggested Range {hint})", | |
| #min_value=minval, | |
| #max_value=maxval, | |
| value=defvalue, | |
| #step=steps, | |
| format=valformat, | |
| #label_visibility="collapsed" | |
| ) | |
| return user_input | |
| st.markdown(""" | |
| <style> | |
| .card { | |
| background-color: #0f141a; | |
| border: 1px solid #2a2f36; | |
| border-radius: 12px; | |
| padding: 18px; | |
| margin-bottom: 20px; | |
| } | |
| .card-title { | |
| font-size: 1.1rem; | |
| font-weight: 600; | |
| margin-bottom: 12px; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # ==================================== | |
| # Section : Capture Engine Parameters | |
| # ==================================== | |
| #st.subheader ("Engine Parameters") | |
| # divide UI into two column layout by defining two columns | |
| # left column is used for input and right for output | |
| col_inputs, col_output = st.columns([3, 1.5]) | |
| # update contnent (input) in left input column | |
| with col_inputs: | |
| st.markdown('<div class="card">', unsafe_allow_html=True) | |
| st.markdown('<div class="card-title">🔧 Engine Parameters</div>', unsafe_allow_html=True) | |
| col_left, col_right = st.columns(2) | |
| # define inputs in left column | |
| with col_left: | |
| rpm = formatted_number_input( | |
| "Lubricating oil pressure (kPa)", | |
| "50 to 2500", | |
| minval=50.0, | |
| maxval=2500.0, | |
| defvalue=735.0, | |
| steps=10.0, | |
| valformat="%.2f" | |
| ) | |
| oil_pressure = formatted_number_input( | |
| "Lubricating oil pressure (kPa)", | |
| "0.001 to 10.0", | |
| minval=0.001, | |
| maxval=10.0, | |
| defvalue=3.300000, | |
| steps=0.001, | |
| valformat="%.6f" | |
| ) | |
| fuel_pressure = formatted_number_input( | |
| "Fuel Pressure (kPa)", | |
| "0.01 to 25.0", | |
| minval=0.01, | |
| maxval=25.0, | |
| defvalue=6.500000, | |
| steps=0.01, | |
| valformat="%.6f" | |
| ) | |
| # define inputs in left column | |
| with col_right: | |
| coolant_pressure = formatted_number_input( | |
| "Coolant Pressure (kPa)", | |
| "0.01 to 10.0", | |
| minval=0.01, | |
| maxval=10.0, | |
| defvalue=2.250000, | |
| steps=0.10, | |
| valformat="%.6f" | |
| ) | |
| lub_oil_temp = formatted_number_input( | |
| "Lubricating oil Temperature (°C)", | |
| "50.0 to 100.0", | |
| minval=50.0, | |
| maxval=100.0, | |
| defvalue=75.0, | |
| steps=0.1, | |
| valformat="%.6f" | |
| ) | |
| coolant_temp = formatted_number_input( | |
| "Coolant Temperature (°C)", | |
| "50.0 to 200.0", | |
| minval=50.0, | |
| maxval=200.0, | |
| defvalue=75.000000, | |
| steps=0.1, | |
| valformat="%.6f" | |
| ) | |
| st.markdown('</div>', unsafe_allow_html=True) | |
| #st.markdown('</div>', unsafe_allow_html=True) | |
| #st.markdown("---") | |
| #col_btn1, col_btn2, col_btn3 = st.columns([1,2,1]) | |
| with col_output: | |
| st.markdown('<div class="card">', unsafe_allow_html=True) | |
| st.markdown('<div class="card-title">🧠 Prediction Result</div>', unsafe_allow_html=True) | |
| output_placeholder = st.empty() | |
| details_placeholder = st.empty() | |
| # ========================== | |
| # Single Value Prediction | |
| # ========================== | |
| if st.button("Check fo Maintenance"): | |
| # extract the data collected into a structure | |
| input_data = { | |
| 'Engine_rpm' : float(rpm), | |
| 'Lub_oil_pressure' : float(oil_pressure), | |
| 'Fuel_pressure' : float(fuel_pressure), | |
| 'Coolant_pressure' : float(coolant_pressure), | |
| 'lub_oil_temp' : float(lub_oil_temp), | |
| 'Coolant_temp' : float(coolant_temp), | |
| } | |
| input_df = pd.DataFrame([input_data]) | |
| response = requests.post ( | |
| "https://harishsohani-AIMLProjectTestBackEnd.hf.space/v1/EngPredMaintenance", | |
| json=input_data | |
| ) | |
| if response.status_code == 200: | |
| ## get result as json | |
| result = response.json () | |
| resp_status = result.get ("status") | |
| if resp_status == "success": | |
| ## Get Sales Prediction Value | |
| prediction_from_backend = result.get ("prediction") # Extract only the value | |
| # generate output string | |
| if prediction_from_backend == 1: | |
| output_placeholder.error("⚠️ Engine likely needs maintenance") | |
| else: | |
| output_placeholder.success("✅ Engine operating normally") | |
| details_placeholder.markdown(""" | |
| **Model:** XGBoost | |
| **Threshold:** 0.5 | |
| **Inference:** Real-time | |
| """) | |
| else: | |
| error_str = result.get ("message") | |
| output_placeholder.error(f"⚠️ {error_str}") | |
| elif response.status_code == 400 or response.status_code == 500: # known errors | |
| ## get result as json | |
| result = response.json () | |
| # get error message | |
| error_str = result.get ("message") | |
| # show error message | |
| output_placeholder.error(f"⚠️ Error processing request- Status Code : {response.status_code}, error : {error_str}") | |
| else: | |
| output_placeholder.error(f"⚠️ Error processing request- Status Code : {response.status_code}") | |
| st.markdown('</div>', unsafe_allow_html=True) | |
| # ============================== | |
| # Batch Prediction | |
| # ============================== | |
| st.markdown("---") | |
| st.subheader ("Batch Prediction for Engine Maintenance") | |
| file = st.file_uploader ("Upload CSV file", type=["csv"]) | |
| if file is not None and st.button("Predict Batch"): | |
| inputfile = {"file": (file.name, file.getvalue(), "text/csv")} | |
| response = requests.post( | |
| "https://harishsohani-AIMLProjectTestBackEnd.hf.space/v1/EngPredMaintenanceForBatch", | |
| files=inputfile | |
| ) | |
| if response.status_code == 200: | |
| result = response.json () | |
| resp_status = result.get ("status") | |
| if resp_status == "success": | |
| ## Get Sales Prediction Value | |
| predictions_from_backend = result.get ("predictions") # Extract only the value | |
| # Convert list → DataFrame | |
| result_df = pd.DataFrame({ | |
| "Prediction": predictions_from_backend | |
| }) | |
| st.dataframe (result_df) | |
| input_df = pd.read_csv(file) | |
| # Ensure lengths match | |
| if len(predictions_from_backend) == len(input_df): | |
| # Add prediction column | |
| input_df["Prediction"] = predictions_from_backend | |
| st.success("Batch prediction completed successfully") | |
| # Show combined dataframe | |
| st.dataframe(input_df, use_container_width=True) | |
| else: | |
| st.error("Prediction count does not match input records") | |
| else: | |
| error_str = result.get ("message") | |
| st.error(error_str) | |
| elif response.status_code == 400 or response.status_code == 500: # known errors | |
| ## get result as json | |
| result = response.json () | |
| error_str = result.get ("message") | |
| st.error (f"Error processing request- Status Code : {response.status_code}, error : {error_str}") | |
| else: | |
| st.error (f"Error processing request- Status Code : {response.status_code}") | |