Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -679,7 +679,115 @@ with col8:
|
|
| 679 |
else:
|
| 680 |
st.warning("No data for Position 4 (18:00β06:00)")
|
| 681 |
|
| 682 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 683 |
#### OBJECTICVE 3
|
| 684 |
st.markdown('<h3 class="objective-title">OBJECTIVE 3: Correlation β How Does Heat Influence Pressure and Which Tyres Trigger Red Alarms?</h3>', unsafe_allow_html=True)
|
| 685 |
|
|
@@ -1128,6 +1236,7 @@ st.markdown(f"""
|
|
| 1128 |
</div>
|
| 1129 |
""", unsafe_allow_html=True)
|
| 1130 |
# ================= OBJECTIVE 5 =================
|
|
|
|
| 1131 |
st.markdown('<h3 class="objective-title">OBJECTIVE 5: Insights & Mitigation β How Can Red Pressure Alarms Be Reduced?</h3>', unsafe_allow_html=True)
|
| 1132 |
|
| 1133 |
# --- DATA PREP ---
|
|
@@ -1231,7 +1340,7 @@ insight_text = f"""
|
|
| 1231 |
try:
|
| 1232 |
import requests
|
| 1233 |
import json
|
| 1234 |
-
API_URL = "https://api-inference.huggingface.co/models/HuggingFaceH4/zephyr-7b-beta
|
| 1235 |
prompt = f"""
|
| 1236 |
Role: Fleet Operations Risk Analyst
|
| 1237 |
Insights:
|
|
|
|
| 679 |
else:
|
| 680 |
st.warning("No data for Position 4 (18:00β06:00)")
|
| 681 |
|
| 682 |
+
# =============== INSIGHT 2 (Ringkas) ===============
|
| 683 |
+
if alarm_data.empty:
|
| 684 |
+
insight_text = "β’ No data available for analysis."
|
| 685 |
+
else:
|
| 686 |
+
# Insight tetap sama
|
| 687 |
+
alarm_hours = alarm_data['hour']
|
| 688 |
+
|
| 689 |
+
def hour_to_band(h):
|
| 690 |
+
if 0 <= h < 6: return "00:00β06:00 (Night)"
|
| 691 |
+
if 6 <= h < 12: return "06:00β12:00 (Morning)"
|
| 692 |
+
if 12 <= h < 18: return "12:00β18:00 (Afternoon)"
|
| 693 |
+
return "18:00β00:00 (Evening)"
|
| 694 |
+
|
| 695 |
+
alarm_hours_df = pd.DataFrame({'hour': alarm_hours})
|
| 696 |
+
alarm_hours_df['band'] = alarm_hours_df['hour'].apply(hour_to_band)
|
| 697 |
+
band_counts = alarm_hours_df['band'].value_counts().sort_index()
|
| 698 |
+
|
| 699 |
+
top_bands = band_counts.nlargest(2)
|
| 700 |
+
dominant_band = top_bands.index[0] if len(top_bands) > 0 else "N/A"
|
| 701 |
+
second_dominant_band = top_bands.index[1] if len(top_bands) > 1 else "N/A"
|
| 702 |
+
|
| 703 |
+
dominant_pct = (top_bands.iloc[0] / band_counts.sum() * 100) if len(top_bands) > 0 else 0
|
| 704 |
+
second_pct = (top_bands.iloc[1] / band_counts.sum() * 100) if len(top_bands) > 1 else 0
|
| 705 |
+
|
| 706 |
+
# Hitung jumlah masing-masing jenis alarm
|
| 707 |
+
normal_alarms = alarm_data[alarm_data['Alarm Status'] == 'No Alarm'].shape[0]
|
| 708 |
+
red_alarms = alarm_data[alarm_data['Alarm Status'].str.contains('Red', na=False)].shape[0]
|
| 709 |
+
amber_alarms = alarm_data[alarm_data['Alarm Status'].str.contains('Amber', na=False)].shape[0]
|
| 710 |
+
|
| 711 |
+
# Insight Spesifik Per Position dan Shift
|
| 712 |
+
insight_lines = [
|
| 713 |
+
f"β’ Total alarms: Normal={normal_alarms}, Amber={amber_alarms}, Red={red_alarms}",
|
| 714 |
+
f"β’ Dominant period: {dominant_band} ({dominant_pct:.1f}%), Second: {second_dominant_band} ({second_pct:.1f}%)"
|
| 715 |
+
]
|
| 716 |
+
|
| 717 |
+
# Position 1 (Shift Pagi)
|
| 718 |
+
pos1_pagi = alarm_data[(alarm_data['Position'] == 1) & (alarm_data['hour'].between(6, 17, inclusive='both'))]
|
| 719 |
+
if not pos1_pagi.empty:
|
| 720 |
+
pos1_pagi_total = pos1_pagi.groupby('hour').size()
|
| 721 |
+
if not pos1_pagi_total.empty:
|
| 722 |
+
dominant_hour_p1_pagi = pos1_pagi_total.idxmax()
|
| 723 |
+
dominant_count_p1_pagi = pos1_pagi_total.max()
|
| 724 |
+
insight_lines.append(f"β’ Position 1 Shift 1 (06:00β18:00): Peak at {dominant_hour_p1_pagi:02d}:00 ({dominant_count_p1_pagi} alarms)")
|
| 725 |
+
# Position 1 (Shift Sore)
|
| 726 |
+
pos1_sore = alarm_data[(alarm_data['Position'] == 1) & (~alarm_data['hour'].between(6, 17, inclusive='both'))]
|
| 727 |
+
if not pos1_sore.empty:
|
| 728 |
+
pos1_sore_red = pos1_sore[pos1_sore['Alarm Status'].str.contains('Red', na=False)]
|
| 729 |
+
if not pos1_sore_red.empty:
|
| 730 |
+
red_percentage_p1_sore = (len(pos1_sore_red) / len(pos1_sore)) * 100
|
| 731 |
+
insight_lines.append(f"β’ Position 1 Shift 2 (18:00β06:00): {red_percentage_p1_sore:.1f}% are Red alarms")
|
| 732 |
+
|
| 733 |
+
# Position 2 (Shift Pagi)
|
| 734 |
+
pos2_pagi = alarm_data[(alarm_data['Position'] == 2) & (alarm_data['hour'].between(6, 17, inclusive='both'))]
|
| 735 |
+
if not pos2_pagi.empty:
|
| 736 |
+
pos2_pagi_total = pos2_pagi.groupby('hour').size()
|
| 737 |
+
if not pos2_pagi_total.empty:
|
| 738 |
+
dominant_hour_p2_pagi = pos2_pagi_total.idxmax()
|
| 739 |
+
dominant_count_p2_pagi = pos2_pagi_total.max()
|
| 740 |
+
insight_lines.append(f"β’ Position 2 Shift 1 (06:00β18:00): Peak at {dominant_hour_p2_pagi:02d}:00 ({dominant_count_p2_pagi} alarms)")
|
| 741 |
+
# Position 2 (Shift Sore)
|
| 742 |
+
pos2_sore = alarm_data[(alarm_data['Position'] == 2) & (~alarm_data['hour'].between(6, 17, inclusive='both'))]
|
| 743 |
+
if not pos2_sore.empty:
|
| 744 |
+
pos2_sore_red = pos2_sore[pos2_sore['Alarm Status'].str.contains('Red', na=False)]
|
| 745 |
+
if not pos2_sore_red.empty:
|
| 746 |
+
red_percentage_p2_sore = (len(pos2_sore_red) / len(pos2_sore)) * 100
|
| 747 |
+
insight_lines.append(f"β’ Position 2 Shift 2 (18:00β06:00): {red_percentage_p2_sore:.1f}% are Red alarms")
|
| 748 |
+
|
| 749 |
+
# Position 3 (Shift Pagi)
|
| 750 |
+
pos3_pagi = alarm_data[(alarm_data['Position'] == 3) & (alarm_data['hour'].between(6, 17, inclusive='both'))]
|
| 751 |
+
if not pos3_pagi.empty:
|
| 752 |
+
pos3_pagi_total = pos3_pagi.groupby('hour').size()
|
| 753 |
+
if not pos3_pagi_total.empty:
|
| 754 |
+
dominant_hour_p3_pagi = pos3_pagi_total.idxmax()
|
| 755 |
+
dominant_count_p3_pagi = pos3_pagi_total.max()
|
| 756 |
+
insight_lines.append(f"β’ Position 3 Shift 1 (06:00β18:00): Peak at {dominant_hour_p3_pagi:02d}:00 ({dominant_count_p3_pagi} alarms)")
|
| 757 |
+
# Position 3 (Shift Sore)
|
| 758 |
+
pos3_sore = alarm_data[(alarm_data['Position'] == 3) & (~alarm_data['hour'].between(6, 17, inclusive='both'))]
|
| 759 |
+
if not pos3_sore.empty:
|
| 760 |
+
pos3_sore_amber = pos3_sore[pos3_sore['Alarm Status'].str.contains('Amber', na=False)]
|
| 761 |
+
if not pos3_sore_amber.empty:
|
| 762 |
+
amber_percentage_p3_sore = (len(pos3_sore_amber) / len(pos3_sore)) * 100
|
| 763 |
+
insight_lines.append(f"β’ Position 3 Shift 2 (18:00β06:00): {amber_percentage_p3_sore:.1f}% are Amber alarms")
|
| 764 |
+
|
| 765 |
+
# Position 4 (Shift Pagi)
|
| 766 |
+
pos4_pagi = alarm_data[(alarm_data['Position'] == 4) & (alarm_data['hour'].between(6, 17, inclusive='both'))]
|
| 767 |
+
if not pos4_pagi.empty:
|
| 768 |
+
pos4_pagi_total = pos4_pagi.groupby('hour').size()
|
| 769 |
+
if not pos4_pagi_total.empty:
|
| 770 |
+
dominant_hour_p4_pagi = pos4_pagi_total.idxmax()
|
| 771 |
+
dominant_count_p4_pagi = pos4_pagi_total.max()
|
| 772 |
+
insight_lines.append(f"β’ Position 4 Shift 1 (06:00β18:00): Peak at {dominant_hour_p4_pagi:02d}:00 ({dominant_count_p4_pagi} alarms)")
|
| 773 |
+
# Position 4 (Shift Sore)
|
| 774 |
+
pos4_sore = alarm_data[(alarm_data['Position'] == 4) & (~alarm_data['hour'].between(6, 17, inclusive='both'))]
|
| 775 |
+
if not pos4_sore.empty:
|
| 776 |
+
pos4_sore_amber = pos4_sore[pos4_sore['Alarm Status'].str.contains('Amber', na=False)]
|
| 777 |
+
if not pos4_sore_amber.empty:
|
| 778 |
+
amber_percentage_p4_sore = (len(pos4_sore_amber) / len(pos4_sore)) * 100
|
| 779 |
+
insight_lines.append(f"β’ Position 4 Shift 2 (18:00β06:00): {amber_percentage_p4_sore:.1f}% are Amber alarms")
|
| 780 |
+
|
| 781 |
+
insight_text = "\n".join(insight_lines)
|
| 782 |
+
|
| 783 |
+
# =============== DISPLAY INSIGHT ===============
|
| 784 |
+
st.markdown(f"""
|
| 785 |
+
<div class="insight-box">
|
| 786 |
+
<div class="content">
|
| 787 |
+
{insight_text}
|
| 788 |
+
</div>
|
| 789 |
+
</div>
|
| 790 |
+
""", unsafe_allow_html=True)
|
| 791 |
#### OBJECTICVE 3
|
| 792 |
st.markdown('<h3 class="objective-title">OBJECTIVE 3: Correlation β How Does Heat Influence Pressure and Which Tyres Trigger Red Alarms?</h3>', unsafe_allow_html=True)
|
| 793 |
|
|
|
|
| 1236 |
</div>
|
| 1237 |
""", unsafe_allow_html=True)
|
| 1238 |
# ================= OBJECTIVE 5 =================
|
| 1239 |
+
# ================= OBJECTIVE 5 =================
|
| 1240 |
st.markdown('<h3 class="objective-title">OBJECTIVE 5: Insights & Mitigation β How Can Red Pressure Alarms Be Reduced?</h3>', unsafe_allow_html=True)
|
| 1241 |
|
| 1242 |
# --- DATA PREP ---
|
|
|
|
| 1340 |
try:
|
| 1341 |
import requests
|
| 1342 |
import json
|
| 1343 |
+
API_URL = "https://api-inference.huggingface.co/models/HuggingFaceH4/zephyr-7b-beta"
|
| 1344 |
prompt = f"""
|
| 1345 |
Role: Fleet Operations Risk Analyst
|
| 1346 |
Insights:
|