SHELLAPANDIANGANHUNGING commited on
Commit
160e66f
Β·
verified Β·
1 Parent(s): aef3f26

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -100
app.py CHANGED
@@ -1,10 +1,9 @@
1
  import gradio as gr
2
  import pandas as pd
3
- import numpy as np
4
 
5
- # ================= LOAD DATA β€” AMBIL TEKANAN & WAKTU TERAKHIR =================
6
  last_pressure = 85.0
7
- last_time = "–"
8
 
9
  try:
10
  df = pd.read_excel("df_final.xlsx", sheet_name="Sheet1")
@@ -16,23 +15,34 @@ try:
16
 
17
  if not df.empty:
18
  last_row = df.sort_values('Time').iloc[-1]
19
- last_pressure = float(last_row['Pressure']) if pd.notna(last_row.get('Pressure')) else 85.0
20
  last_time = last_row['Time'].strftime("%H:%M")
21
- except Exception as e:
22
- pass # tetap pakai default jika gagal
23
 
24
- # ================= BATAS AMAN (SESUAI STANDAR OPERASIONAL) =================
25
- red_low = 70.0
26
- amber_low = 75.0
27
- amber_high = 95.0
28
- red_high = 100.0
29
 
30
- def get_safe_fill_range(last_p):
31
- lower = max(last_p - 10, amber_low + 0.5)
32
- upper = min(last_p + 10, amber_high - 0.5)
33
- return round(lower, 1), round(upper, 1)
 
34
 
35
- # ================= CUSTOM CSS β€” BERSIH, PROFESIONAL, SATU HALAMAN =================
 
 
 
 
 
 
 
 
 
 
36
  custom_css = """
37
  body, .gradio-container {
38
  background: #000000 !important;
@@ -52,96 +62,80 @@ body, .gradio-container {
52
  #title-box {
53
  background: #003A8F;
54
  color: white;
55
- padding: 16px 32px;
56
- border-radius: 12px;
57
- margin-bottom: 32px;
58
  text-align: center;
59
  width: 100%;
60
- max-width: 800px;
61
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
62
  }
63
  #title-box h1 {
64
  margin: 0;
65
- font-size: 28px;
66
- font-weight: 700;
67
  }
68
  .form-section {
 
 
69
  display: flex;
70
  flex-direction: column;
71
- align-items: flex-start;
72
- width: 100%;
73
- max-width: 800px;
74
  gap: 24px;
75
  }
76
- .control-row {
77
- display: flex;
78
- gap: 24px;
79
  width: 100%;
80
- align-items: center;
 
81
  }
82
- .control-row > div {
83
  flex: 1;
84
- min-width: 200px;
85
- }
86
- .gradio-html, .output-area {
87
- width: 100%;
88
- max-width: 800px;
89
- background: #121212;
90
- border: 1px solid #333;
91
- border-radius: 12px;
92
- padding: 24px;
93
- margin-top: 16px;
94
- font-size: 18px;
95
- line-height: 1.6;
96
- }
97
- .output-area h3 {
98
- color: #FFD100;
99
- margin: 16px 0 12px 0;
100
- font-size: 22px;
101
- font-weight: 600;
102
- }
103
- .output-area p {
104
- margin: 10px 0;
105
- }
106
- .output-area .safe {
107
- color: #00FF00;
108
- font-weight: bold;
109
- }
110
- .output-area .caution {
111
- color: #FFA500;
112
- font-weight: bold;
113
- }
114
- .output-area .danger {
115
- color: #FF0000;
116
- font-weight: bold;
117
  }
118
  .gr-button {
119
  background: #003A8F !important;
120
  color: white !important;
121
- font-weight: bold;
122
- font-size: 18px !important;
123
- padding: 12px 32px !important;
124
  border-radius: 8px !important;
125
  border: none !important;
126
  width: auto !important;
127
- margin-top: 12px;
128
  }
129
  .gr-button:hover {
130
  background: #002D6B !important;
131
- transform: scale(1.03);
132
- box-shadow: 0 4px 12px rgba(0, 58, 143, 0.4);
133
  }
134
  label {
135
  color: #CCCCCC !important;
136
- font-size: 18px !important;
137
  font-weight: 500;
138
  }
139
- input, select {
140
- font-size: 18px !important;
 
 
 
 
 
 
 
141
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  """
143
 
144
- # ================= GRADIO LAYOUT β€” FULL KIRI, TANPA SIMBOL =================
145
  with gr.Blocks(title="Michelin Mining Tyre Analytics β€” Objective 6", css=custom_css) as demo:
146
  gr.HTML("""
147
  <div id="title-box">
@@ -150,63 +144,71 @@ with gr.Blocks(title="Michelin Mining Tyre Analytics β€” Objective 6", css=custo
150
  """)
151
 
152
  with gr.Column(elem_classes="form-section"):
153
- with gr.Row(elem_classes="control-row"):
 
154
  temperature = gr.Slider(
155
  label="Suhu Saat Ini (Β°C)",
156
  minimum=40,
157
  maximum=70,
158
  value=54,
159
  step=0.5,
160
- interactive=True
 
161
  )
162
  tyre_type = gr.Radio(
163
  choices=["10 (Depan)", "11 (Belakang)"],
164
  label="Jenis Ban",
165
  value="10 (Depan)",
166
- interactive=True
 
167
  )
168
 
169
- last_info = gr.Markdown(
170
- f"Tekanan Terakhir: {last_pressure} psi | Jam: {last_time}"
171
- )
172
 
 
173
  btn_submit = gr.Button("Submit", elem_classes="gr-button")
 
 
174
  output = gr.HTML(elem_classes="output-area")
175
 
176
- # ================= LOGIKA SIMULASI β€” BERSIH & BERBASIS DATA NYATA =================
177
  def simulate(tyre_str, temp):
178
- # Interpolasi sederhana: baseline 54Β°C β†’ 85 psi, slope 0.42 psi/Β°C
179
- ideal = 85.0 + 0.42 * (temp - 54.0)
180
- ideal = round(ideal, 1)
181
-
182
- lower_safe, upper_safe = get_safe_fill_range(last_pressure)
183
 
184
- # Status penilaian
185
- if ideal < red_low:
186
  status = '<span class="danger">Risiko Red β€” Tekanan terlalu rendah</span>'
187
- elif ideal < amber_low:
188
  status = '<span class="caution">Risiko Amber β€” Tekanan mendekati batas bawah</span>'
189
- elif ideal > red_high:
190
  status = '<span class="danger">Risiko Red β€” Tekanan terlalu tinggi</span>'
191
- elif ideal > amber_high:
192
  status = '<span class="caution">Risiko Amber β€” Tekanan mendekati batas atas</span>'
193
  else:
194
  status = '<span class="safe">Dalam zona aman</span>'
195
 
196
- rec_html = f"""
 
 
 
197
  <h3>Hasil Simulasi</h3>
198
- <p>Ideal Tekanan pada {temp}Β°C: {ideal} psi</p>
199
  <p>Status: {status}</p>
200
- <hr>
201
  <h3>Rekomendasi Isi Ulang</h3>
202
  <p>Berdasarkan tekanan terakhir ({last_pressure} psi pukul {last_time}):</p>
203
- <p class="safe">Isi tekanan antara {lower_safe} – {upper_safe} psi</p>
204
- <p class="caution">Jangan isi kurang dari {amber_low} psi (batas Amber bawah)</p>
205
- <p class="caution">Jangan isi lebih dari {amber_high} psi (batas Amber atas)</p>
206
- <p class="danger">Hindari tekanan di bawah {red_low} psi atau di atas {red_high} psi (zona Red)</p>
207
- <p style="margin-top:16px;"><em>Catatan: Rekomendasi ini mempertahankan margin aman minimal 0.5 psi dari zona Amber.</em></p>
 
 
208
  """
209
- return rec_html
210
 
211
  btn_submit.click(simulate, inputs=[tyre_type, temperature], outputs=output)
212
 
 
1
  import gradio as gr
2
  import pandas as pd
 
3
 
4
+ # ================= DEFAULT & DATA =================
5
  last_pressure = 85.0
6
+ last_time = "10:38"
7
 
8
  try:
9
  df = pd.read_excel("df_final.xlsx", sheet_name="Sheet1")
 
15
 
16
  if not df.empty:
17
  last_row = df.sort_values('Time').iloc[-1]
18
+ last_pressure = float(last_row.get('Pressure', 85.0)) if pd.notna(last_row.get('Pressure')) else 85.0
19
  last_time = last_row['Time'].strftime("%H:%M")
20
+ except:
21
+ pass # fallback ke default
22
 
23
+ # BATAS OPERASIONAL β€” tetap (bisa disesuaikan jika ada file konfig)
24
+ RED_LOW = 70.0
25
+ AMBER_LOW = 75.0
26
+ AMBER_HIGH = 95.0
27
+ RED_HIGH = 100.0
28
 
29
+ # ================= LOGIKA DINAMIS: MARGIN BERDASARKAN JARAK KE AMBER =================
30
+ def compute_fill_range(last_p):
31
+ # Jarak ke batas amber
32
+ max_decrease = last_p - AMBER_LOW # berapa boleh dikurangi tanpa kena amber_low
33
+ max_increase = AMBER_HIGH - last_p # berapa boleh ditambah tanpa kena amber_high
34
 
35
+ # Batas aman dengan buffer 0.5 psi
36
+ lower_bound = last_p - max_decrease + 0.5 # minimal: 0.5 di atas amber_low
37
+ upper_bound = last_p + max_increase - 0.5 # maksimal: 0.5 di bawah amber_high
38
+
39
+ # Pastikan tidak melewati red (safety double-check)
40
+ lower_bound = max(lower_bound, RED_LOW + 0.5)
41
+ upper_bound = min(upper_bound, RED_HIGH - 0.5)
42
+
43
+ return round(lower_bound, 1), round(upper_bound, 1)
44
+
45
+ # ================= CUSTOM CSS β€” BERSIH, RAPI, PROFESIONAL, FULL SCREEN =================
46
  custom_css = """
47
  body, .gradio-container {
48
  background: #000000 !important;
 
62
  #title-box {
63
  background: #003A8F;
64
  color: white;
65
+ padding: 16px 24px;
66
+ border-radius: 10px;
67
+ margin: 20px 0;
68
  text-align: center;
69
  width: 100%;
70
+ max-width: 760px;
71
+ box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
72
  }
73
  #title-box h1 {
74
  margin: 0;
75
+ font-size: 26px;
76
+ font-weight: 600;
77
  }
78
  .form-section {
79
+ width: 100%;
80
+ max-width: 760px;
81
  display: flex;
82
  flex-direction: column;
 
 
 
83
  gap: 24px;
84
  }
85
+ .row-block {
 
 
86
  width: 100%;
87
+ display: flex;
88
+ gap: 20px;
89
  }
90
+ .input-col {
91
  flex: 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  }
93
  .gr-button {
94
  background: #003A8F !important;
95
  color: white !important;
96
+ font-weight: 600;
97
+ font-size: 17px !important;
98
+ padding: 10px 28px !important;
99
  border-radius: 8px !important;
100
  border: none !important;
101
  width: auto !important;
102
+ margin-top: 8px;
103
  }
104
  .gr-button:hover {
105
  background: #002D6B !important;
106
+ box-shadow: 0 3px 8px rgba(0, 58, 143, 0.4);
 
107
  }
108
  label {
109
  color: #CCCCCC !important;
110
+ font-size: 17px !important;
111
  font-weight: 500;
112
  }
113
+ .gradio-html, .output-area {
114
+ width: 100%;
115
+ max-width: 760px;
116
+ background: #121212;
117
+ border: 1px solid #333;
118
+ border-radius: 10px;
119
+ padding: 22px;
120
+ font-size: 17px;
121
+ line-height: 1.5;
122
  }
123
+ .output-area h3 {
124
+ color: #FFD100;
125
+ margin: 18px 0 12px 0;
126
+ font-size: 20px;
127
+ font-weight: 600;
128
+ }
129
+ .output-area p {
130
+ margin: 8px 0;
131
+ font-size: 17px;
132
+ }
133
+ .output-area .safe { color: #00FF00; font-weight: bold; }
134
+ .output-area .caution { color: #FFA500; font-weight: bold; }
135
+ .output-area .danger { color: #FF0000; font-weight: bold; }
136
  """
137
 
138
+ # ================= INTERFACE β€” RAPI, KIRI, SATU HALAMAN =================
139
  with gr.Blocks(title="Michelin Mining Tyre Analytics β€” Objective 6", css=custom_css) as demo:
140
  gr.HTML("""
141
  <div id="title-box">
 
144
  """)
145
 
146
  with gr.Column(elem_classes="form-section"):
147
+ # Baris 1: Suhu & Jenis Ban (dalam satu baris)
148
+ with gr.Row(elem_classes="row-block"):
149
  temperature = gr.Slider(
150
  label="Suhu Saat Ini (Β°C)",
151
  minimum=40,
152
  maximum=70,
153
  value=54,
154
  step=0.5,
155
+ interactive=True,
156
+ elem_classes="input-col"
157
  )
158
  tyre_type = gr.Radio(
159
  choices=["10 (Depan)", "11 (Belakang)"],
160
  label="Jenis Ban",
161
  value="10 (Depan)",
162
+ interactive=True,
163
+ elem_classes="input-col"
164
  )
165
 
166
+ # Baris 2: Info tekanan terakhir (tengah, kecil)
167
+ gr.Markdown(f"<div style='font-size:16px;color:#AAAAAA;'>Tekanan terakhir: {last_pressure} psi | Jam: {last_time}</div>")
 
168
 
169
+ # Tombol Submit (kiri, compact)
170
  btn_submit = gr.Button("Submit", elem_classes="gr-button")
171
+
172
+ # Output
173
  output = gr.HTML(elem_classes="output-area")
174
 
175
+ # ================= LOGIKA SIMULASI β€” DINAMIS SESUAI BATAS AMBER =================
176
  def simulate(tyre_str, temp):
177
+ # Hitung tekanan ideal (sederhana, linear)
178
+ ideal_pressure = 85.0 + 0.42 * (temp - 54.0)
179
+ ideal_pressure = round(ideal_pressure, 1)
 
 
180
 
181
+ # Status vs zona
182
+ if ideal_pressure < RED_LOW:
183
  status = '<span class="danger">Risiko Red β€” Tekanan terlalu rendah</span>'
184
+ elif ideal_pressure < AMBER_LOW:
185
  status = '<span class="caution">Risiko Amber β€” Tekanan mendekati batas bawah</span>'
186
+ elif ideal_pressure > RED_HIGH:
187
  status = '<span class="danger">Risiko Red β€” Tekanan terlalu tinggi</span>'
188
+ elif ideal_pressure > AMBER_HIGH:
189
  status = '<span class="caution">Risiko Amber β€” Tekanan mendekati batas atas</span>'
190
  else:
191
  status = '<span class="safe">Dalam zona aman</span>'
192
 
193
+ # Hitung rekomendasi isi ulang DINAMIS
194
+ lower_fill, upper_fill = compute_fill_range(last_pressure)
195
+
196
+ rec = f"""
197
  <h3>Hasil Simulasi</h3>
198
+ <p>Ideal Tekanan pada {temp}Β°C: {ideal_pressure} psi</p>
199
  <p>Status: {status}</p>
200
+
201
  <h3>Rekomendasi Isi Ulang</h3>
202
  <p>Berdasarkan tekanan terakhir ({last_pressure} psi pukul {last_time}):</p>
203
+ <p class="safe">Isi tekanan antara {lower_fill} – {upper_fill} psi</p>
204
+ <p class="caution">Jangan isi kurang dari {AMBER_LOW} psi (batas Amber bawah)</p>
205
+ <p class="caution">Jangan isi lebih dari {AMBER_HIGH} psi (batas Amber atas)</p>
206
+ <p class="danger">Hindari tekanan di bawah {RED_LOW} psi atau di atas {RED_HIGH} psi (zona Red)</p>
207
+ <p style="margin-top:14px; font-size:15px; color:#999;">
208
+ Catatan: Rekomendasi mempertahankan jarak aman minimal 0.5 psi dari zona Amber.
209
+ </p>
210
  """
211
+ return rec
212
 
213
  btn_submit.click(simulate, inputs=[tyre_type, temperature], outputs=output)
214