| |
| import requests |
|
|
| |
| import streamlit as st |
|
|
| |
| import pandas as pd |
|
|
| |
| |
| |
| st.set_page_config( |
| page_title="Predictive Maintenenace App", |
| layout="wide" |
| ) |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| st.markdown(""" |
| <style> |
| .block-container { |
| padding-top: 0.75rem; |
| padding-bottom: 0.75rem; |
| } |
| </style> |
| """, unsafe_allow_html=True) |
|
|
|
|
| |
| |
| |
| st.title("๐๏ธ Predict Maintenance") |
| st.markdown(""" |
| The Predict Maintenance app help to predict if an engine needs maintenance based on operating sensor parameters. |
| *Suggested ranges are based on known information - input is not restricted to the specified range* |
| """) |
|
|
|
|
| |
| |
| |
| def formatted_number_input(title, hint, minval, maxval, defvalue, steps, valformat="%.4f"): |
|
|
| st.markdown('<div style="margin-bottom:4px;">', unsafe_allow_html=True) |
| |
| user_input = st.number_input( |
| label=f"{title} ({hint})", |
| |
| |
| value=defvalue, |
| |
| format=valformat, |
| |
| ) |
| |
| return user_input |
|
|
|
|
| st.markdown(""" |
| <style> |
| /* Reduce top padding */ |
| .block-container { |
| padding-top: 1rem; |
| padding-bottom: 1rem; |
| } |
| /* Shared card styling */ |
| .card { |
| border-radius: 16px; |
| padding: 22px; |
| margin-bottom: 20px; |
| transition: 0.3s ease-in-out; |
| } |
| /* INPUT CARD */ |
| .input-card { |
| background: linear-gradient(145deg, #0f172a, #111827); |
| border: 1px solid #334155; |
| box-shadow: 0 0 0 1px rgba(59,130,246,0.15); |
| } |
| /* OUTPUT CARD */ |
| .output-card { |
| background: linear-gradient(145deg, #111827, #0b1220); |
| border: 1px solid #16a34a; |
| box-shadow: 0 0 12px rgba(34,197,94,0.25); |
| } |
| /* Card title */ |
| .card-title { |
| font-size: 1.2rem; |
| font-weight: 600; |
| margin-bottom: 16px; |
| letter-spacing: 0.5px; |
| } |
| /* Button styling */ |
| div.stButton > button { |
| width: 100%; |
| border-radius: 10px; |
| height: 3em; |
| font-weight: 600; |
| background: linear-gradient(90deg, #2563eb, #1d4ed8); |
| color: white; |
| border: none; |
| } |
| div.stButton > button:hover { |
| background: linear-gradient(90deg, #1d4ed8, #1e40af); |
| } |
| </style> |
| """, unsafe_allow_html=True) |
|
|
| |
| |
| |
| |
|
|
| |
| |
| col_inputs, col_output = st.columns([3, 1.5]) |
|
|
| |
| with col_inputs: |
|
|
| |
| with st.form("engine_form"): |
|
|
| |
| st.subheader("๐ง Engine Parameters") |
|
|
| |
| col_left, col_right = st.columns(2) |
| |
| |
| with col_left: |
| |
| rpm = formatted_number_input( |
| "Engine RPM", |
| "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 in 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 in kPa", |
| "0.01 to 25.0", |
| minval=0.01, |
| maxval=25.0, |
| defvalue=6.500000, |
| steps=0.01, |
| valformat="%.6f" |
| ) |
| |
| |
| with col_right: |
| coolant_pressure = formatted_number_input( |
| "Coolant Pressure in 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 in ยฐ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 in ยฐC", |
| "50.0 to 200.0", |
| minval=50.0, |
| maxval=200.0, |
| defvalue=75.000000, |
| steps=0.1, |
| valformat="%.6f" |
| ) |
|
|
| submitted = st.form_submit_button("๐ Check Maintenance") |
|
|
| |
| with col_output: |
|
|
|
|
| |
| |
| |
| with st.expander("๐ง Prediction Result", expanded=True): |
|
|
| |
| |
| output_placeholder = st.empty() |
| probability_placeholder = st.empty() |
| details_placeholder = st.empty() |
|
|
| |
| |
| input_summary_header = st.empty() |
| input_summary_details = st.empty() |
|
|
| |
| if submitted: |
| |
| |
| 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: |
| |
| result = response.json () |
| |
| resp_status = result.get ("status") |
| |
| if resp_status == "success": |
| |
| |
| prediction_from_backend = result.get ("prediction") |
| probability = result.get ("probability") |
|
|
| |
| formatted_prob = f"{probability * 100:.2f}%" |
| |
| |
| if prediction_from_backend == 1: |
| output_placeholder.error("โ ๏ธ Engine needs maintenance") |
| else: |
| output_placeholder.success("โ
Engine operating normally") |
|
|
| |
| probability_placeholder.metric("Failure Probability", formatted_prob) |
|
|
| |
| details_placeholder.markdown(f""" |
| *Model :* XGBoost |
| *Inference :* Real-time |
| |
| *Note* : Probability of 50% and above is considered as Maintenance Needed. |
| """) |
| |
| |
| input_summary_header.subheader("๐ฆ Input Data Summary") |
| input_summary_details.dataframe (input_df) |
| |
| else: |
| |
| error_str = result.get ("message") |
| |
| output_placeholder.error(f"โ ๏ธ {error_str}") |
| |
| elif response.status_code == 400 or response.status_code == 500: |
| |
| |
| result = response.json () |
| |
| |
| error_str = result.get ("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("---") |
|
|
| st.subheader ("Batch Prediction for Engine Maintenance") |
| st.markdown(""" |
| *Select csv file with engine sensor parameters to find prediction for all readings* |
| """) |
|
|
| file = st.file_uploader ("Upload CSV file", type=["csv"]) |
|
|
| if file is not None and st.button("๐ Check Maintenance"): |
|
|
| 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": |
| |
| |
| predictions_from_backend = result.get ("predictions") |
|
|
| |
| probabilities = result.get ("probabilities") |
|
|
| |
| input_df = pd.read_csv(file) |
|
|
| |
| if len(predictions_from_backend) == len(input_df): |
| |
| |
| input_df["Prediction"] = predictions_from_backend |
| input_df["Probability"] = probabilities |
| |
| st.success("Batch prediction completed successfully") |
|
|
| st.markdown(""" |
| *Prediction : 1 deontes Maintenance is needed* |
| """) |
|
|
| st.markdown(""" |
| *Probability : This column indicates failure probability. Value ranges from 0 to 1. Value of 0.5 (50%) and above is considered as Maintenance Needed* |
| """) |
|
|
| st.markdown(""" |
| """) |
| |
| |
| 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: |
| |
| |
| 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}") |
|
|