import gradio as gr import pandas as pd import numpy as np # ================= LOAD DATA — AMBIL TEKANAN, SUHU & WAKTU TERAKHIR ================= last_pressure = 85.0 last_temperature = 54.0 last_time = "–" try: df = pd.read_excel("df_final.xlsx", sheet_name="Sheet1") df.columns = df.columns.str.replace("Â", "", regex=False) for col in df.select_dtypes(include='object').columns: df[col] = df[col].astype(str).str.replace("Â", "", regex=False) df['Time'] = pd.to_datetime(df['Time'], errors='coerce') df = df.dropna(subset=['Time']) if not df.empty: last_row = df.sort_values('Time', ascending=False).iloc[0] last_pressure = float(last_row['Pressure']) if pd.notna(last_row.get('Pressure')) else 85.0 last_temperature = float(last_row['Temperature']) if pd.notna(last_row.get('Temperature')) else 54.0 last_time = last_row['Time'].strftime("%Y-%m-%d %H:%M") except Exception as e: pass # tetap pakai default jika gagal # ================= BATAS AMAN (SESUAI STANDAR OPERASIONAL) ================= red_low = 70.0 amber_low = 75.0 amber_high = 95.0 red_high = 100.0 def get_safe_fill_range(last_p): lower = max(last_p - 10, amber_low + 0.5) upper = min(last_p + 10, amber_high - 0.5) return round(lower, 1), round(upper, 1) # ================= CUSTOM CSS — Tengah, Wide, Bersih ================= custom_css = """ body, .gradio-container { background: #000000 !important; color: #FFFFFF !important; font-family: 'Segoe UI', system-ui, sans-serif; } .gradio-container { max-width: 100% !important; padding: 20px !important; } #title-box { background: #003A8F; color: white; padding: 18px 32px; border-radius: 12px; margin: 20px auto 30px auto; text-align: center; width: fit-content; min-width: 500px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4); } #title-box h1 { margin: 0; font-size: 26px; font-weight: 700; } .center-section { display: flex; flex-direction: column; align-items: center; width: 100%; max-width: 700px; margin: 0 auto; gap: 24px; } .info-card { background: #121212; border: 1px solid #333; border-radius: 12px; padding: 20px; width: 100%; text-align: center; font-size: 18px; } .gr-button { background: #003A8F !important; color: white !important; font-weight: bold; font-size: 18px !important; padding: 12px 36px !important; border-radius: 8px !important; border: none !important; margin-top: 8px; } .gr-button:hover { background: #002D6B !important; transform: translateY(-1px); box-shadow: 0 4px 10px rgba(0, 58, 143, 0.4); } label { color: #CCCCCC !important; font-size: 18px !important; font-weight: 500; } .output-area { background: #121212; border: 1px solid #333; border-radius: 12px; padding: 26px; width: 100%; font-size: 18px; line-height: 1.6; margin-top: 10px; } .output-area h3 { color: #FFD100; margin: 18px 0 12px 0; font-size: 22px; font-weight: 600; } .output-area p { margin: 10px 0; } .output-area .safe { color: #00FF00; font-weight: bold; } .output-area .caution { color: #FFA500; font-weight: bold; } .output-area .danger { color: #FF0000; font-weight: bold; } .footer { margin-top: 24px; color: #888; font-size: 15px; text-align: center; width: 100%; } """ # ================= GRADIO — MODE WIDE, UI TENGAH ================= with gr.Blocks(title="Michelin Mining Tyre Analytics — Objective 6", css=custom_css, mode="wide") as demo: gr.HTML("""
Data Terakhir: {last_time}
Suhu: {last_temperature} °C | Tekanan: {last_pressure} psi
Ideal Tekanan pada {temp}°C: {ideal} psi
Status: {status}
Berdasarkan tekanan terakhir {last_pressure} psi ({last_time}):
Isi tekanan antara {lower_safe} – {upper_safe} psi
Maksimal penambahan: +{min(10.0, max_add):.1f} psi (agar tidak melebihi {amber_high} psi)
Maksimal pengurangan: −{min(10.0, max_sub):.1f} psi (agar tidak turun di bawah {amber_low} psi)
Jangan isi kurang dari {amber_low} psi (batas Amber bawah)
Jangan isi lebih dari {amber_high} psi (batas Amber atas)
Hindari tekanan di bawah {red_low} psi atau di atas {red_high} psi (zona Red)
Catatan: Rekomendasi mempertahankan margin aman minimal 0.5 psi dari zona Amber.
""" return rec_html btn_submit.click(simulate, inputs=[tyre_type], outputs=output) demo.launch()