import streamlit as st import pandas as pd import plotly.express as px import plotly.graph_objects as go from datetime import datetime if 'submitted' not in st.session_state: st.session_state.submitted = False st.set_page_config(page_title="Blowby Pressure & Fuel Impact Dashboard", layout="wide") st.markdown(""" """, unsafe_allow_html=True) def show_thank_you_message(): st.markdown("""
Terimakasih sudah simulasi
""", unsafe_allow_html=True) if st.session_state.submitted: show_thank_you_message() else: with st.sidebar: st.markdown("

⚙️ Dashboard Controls

", unsafe_allow_html=True) st.markdown("**Developed by: Bukit Technology (RnD)**") st.markdown(f"**Last Updated:** {datetime.now().strftime('%Y-%m-%d')}") st.markdown("---") st.markdown("Use this calculator to analyze blowby pressure and fuel impact for strategic decisions.") col_logo, col_title = st.columns([1, 4]) with col_logo: try: st.image("buma ina.png", width=150) except FileNotFoundError: st.warning("⚠️ File logo 'buma_ina.PNG' tidak ditemukan. Silakan pastikan file ada di direktori yang sama dengan script.") with col_title: st.title("Calculator CHA for Fuel Rate Impact") # st.markdown("**Analisis Blowby Pressure & Fuel Impact untuk Pengambilan Keputusan Strategis**") try: detail = pd.read_csv('1_DEV_SUMMARY_detail_data_HD785_7_ENGINE_last3month.csv') except FileNotFoundError: st.error("❌ File '1_DEV_SUMMARY_detail_data_HD785_7_ENGINE_last3month.csv' tidak ditemukan.") st.stop() st.subheader("🔍 Pilih Unit untuk Analisis") unit_list = sorted(detail['equipment_no'].dropna().unique()) selected_unit = st.selectbox("Pilih unit number yang akan disimulasikan:", unit_list, help="Pilih nomor peralatan untuk analisis") unit_df = detail[detail['equipment_no'] == selected_unit].sort_values("comp_life") if unit_df.empty: st.warning("⚠️ Data tidak tersedia untuk unit ini.") st.stop() current_life_df = ( detail[detail['solving_algorithm'].notna()] .sort_values(['equipment_no', 'comp_life']) .groupby('equipment_no') .tail(1) ) if selected_unit not in current_life_df['equipment_no'].values: st.error("❌ Data current component life tidak tersedia untuk unit ini.") st.stop() current_life = current_life_df.loc[current_life_df['equipment_no'] == selected_unit, 'comp_life'].iloc[0] col1, col2 = st.columns([2, 1]) with col1: st.subheader("📊 Grafik Blowby Pressure terhadap Umur Komponen") max_life = unit_df['comp_life'].max() fig = px.line(unit_df, x='comp_life', y='blowby_press_max_act', title=f"Unit: {selected_unit}", labels={'comp_life': 'Component Life (Hours)', 'blowby_press_max_act': 'Pressure (mmH2O)'}, line_shape='linear', render_mode='svg') fig.add_vline(x=current_life, line_dash="dash", line_color="#7f8c8d", annotation_text="Current Life", annotation_position="top left") fig.update_traces(line_color='#1abc9c', line_width=3, marker=dict(size=8)) fig.update_layout( plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)', font=dict(family="Poppins", size=12, color="#ecf0f1"), title_font=dict(size=18, color="#f1c40f"), showlegend=True, xaxis=dict(showgrid=True, gridcolor='rgba(255,255,255,0.2)'), yaxis=dict(showgrid=True, gridcolor='rgba(255,255,255,0.2)') ) st.plotly_chart(fig, use_container_width=True) with col2: st.subheader("⏳ Current Component Life") st.markdown(f"""

Current Life

{current_life:,.0f} jam

""", unsafe_allow_html=True) st.subheader("⚙️ Simulasi Perpanjangan Umur Komponen") input_method = st.radio("Pilih metode input:", ["Slider", "Input Numerik"], horizontal=True) max_deviation = int(max_life - current_life) if input_method == "Slider": extended_life = st.slider( "Simulasikan Perpanjangan Umur Komponen Hingga (jam):", min_value=int(current_life + 100), max_value=int(max_life), value=int(min(current_life + 1000, max_life)), step=100, help="Geser untuk memilih umur komponen yang diinginkan" ) deviation = extended_life - current_life else: deviation = st.number_input( "Masukkan Perpanjangan Umur Komponen Sebesar (jam):", min_value=100, max_value=max_deviation, value=min(1000, max_deviation), step=100, help="Masukkan jumlah jam perpanjangan dari current life" ) extended_life = current_life + deviation st.markdown(f"**Umur Komponen Diperpanjang Hingga:** {extended_life:,.0f} jam (Perpanjangan: {deviation:,.0f} jam)", unsafe_allow_html=True) sim_df = unit_df[(unit_df['comp_life'] > current_life) & (unit_df['comp_life'] <= extended_life)] def hitung_avg_blowby(df, batas): tmp = df[['comp_life', 'blowby_press_max_act']].dropna().sort_values('comp_life') tmp = tmp[tmp['comp_life'] <= batas] if tmp.empty: return 0 tail = tmp.tail(10) if len(tail) < 10: st.warning(f"Hanya {len(tail)} titik data (<= {batas} jam).") return tail['blowby_press_max_act'].mean() def hitung_avg_blowbyawal(df, batas): tmp = df[['comp_life', 'blowby_press_max_act']].dropna().sort_values('comp_life') tmp = tmp[tmp['comp_life'] <= batas] if tmp.empty: return 0 tail = tmp.tail(30) if len(tail) < 30: st.warning(f"Hanya {len(tail)} titik data (<= {batas} jam).") return tail['blowby_press_max_act'].mean() def fuel_awal_data(df, batas): tmp = df[['comp_life', 'fuel_rate_act']].dropna().sort_values('comp_life') tmp = tmp[tmp['comp_life'] <= batas] if tmp.empty: return 0 tail = tmp.tail(5) if len(tail) < 5: st.warning(f"Hanya {len(tail)} titik data (<= {batas} jam).") return tail['fuel_rate_act'].mean() def fuel_awal_setelah_replacement(df, batas): tmp = df[['comp_life', 'fuel_rate_act']].dropna().sort_values('comp_life') tmp = tmp[tmp['comp_life'] <= batas] if tmp.empty: return 0 head = tmp.head(5) if len(head) < 5: st.warning(f"Hanya {len(head)} titik data (<= {batas} jam).") return head['fuel_rate_act'].mean() st.subheader("⛽ Prediksi Fuel Rate") avg_blowby_awal = fuel_awal_data(unit_df, current_life) avg_blowby_akhir = hitung_avg_blowby(unit_df, extended_life) fuel_setelah_replacement =fuel_awal_setelah_replacement(unit_df, extended_life) delta_life = extended_life - current_life fuel_rate_awal = (avg_blowby_awal * 0.004) + 71.86 # L/h fuel_rate_akhir = (avg_blowby_akhir * 0.004) + 71.86 # L/h hours_ext = extended_life - current_life fuel_usage = fuel_rate_akhir * hours_ext # total L over extension col3, col4, col5 = st.columns(3) with col3: st.markdown(f"""

Fuel Rate Terakhir

{fuel_rate_awal:.2f} L/h

""", unsafe_allow_html=True) with col4: st.markdown(f"""

Fuel Akumulasi

{(fuel_rate_akhir * delta_life):,.2f} L

""", unsafe_allow_html=True) with col5: st.markdown(f"""

Total Extend

{delta_life:,.2f} Hm

""", unsafe_allow_html=True) if not sim_df.empty and sim_df['trendline_blow'].notna().any(): last_f = sim_df['trendline_blow'].dropna().iloc[-1] fr_f = last_f * 0.004 + 71.86 rpm_f = last_f * 0.034 + 1303.75 col6, col7 = st.columns(2) with col6: st.markdown(f"""

Fuel Rate Forecast

{fr_f:.2f} L/h

""", unsafe_allow_html=True) with col7: st.markdown(f"""

Engine Speed Forecast

{rpm_f:.2f} RPM

""", unsafe_allow_html=True) st.subheader("💰 Analisis Keuntungan dan Kerugian") harga_engine = 110_000 # USD harga_fuel = 1 # USD/L cost_per_h = harga_engine / current_life saving = ((cost_per_h * delta_life) + (fuel_setelah_replacement* delta_life)) fuel_cost = fuel_usage * harga_fuel net_savings = fuel_cost - saving col8, col9, col10 = st.columns(3) with col8: st.markdown(f"""

Cost Replacement

USD {saving:,.2f}

""", unsafe_allow_html=True) with col9: st.markdown(f"""

Cost Fuel (Extend)

USD {fuel_cost:,.2f}

""", unsafe_allow_html=True) with col10: st.markdown(f"""

Net Savings

USD {net_savings:,.2f}

""", unsafe_allow_html=True) st.subheader("Perbandingan Penghematan vs Biaya Fuel") fig2 = go.Figure() fig2.add_trace(go.Bar( x=[saving, fuel_cost], y=["Replacement Cost", "Fuel Cost if Extend"], orientation='h', marker=dict(color=['#2ecc71', '#e74c3c']), text=[f"USD {saving:,.2f}", f"USD {fuel_cost:,.2f}"], textposition='auto' )) fig2.update_layout( title="Perbandingan Biaya", title_font=dict(size=18, color="#f1c40f"), plot_bgcolor='rgba(0,0,0,0)', paper_bgcolor='rgba(0,0,0,0)', font=dict(family="Poppins", size=12, color="#ecf0f1"), showlegend=False, xaxis=dict(showgrid=True, gridcolor='rgba(255,255,255,0.2)'), yaxis=dict(showgrid=False) ) st.plotly_chart(fig2, use_container_width=True) st.subheader("🔄 Opsi Tindakan") choice = st.radio("Pilih tindakan:", ["replacement/service", "extend component"], horizontal=True) if choice == "replacement/service": st.success("✅ Anda memilih untuk replacement component.") else: st.error("❌ Anda memilih untuk extend component.") if st.button("Submit"): st.session_state.submitted = True st.rerun() # Mengganti st.experimental_rerun() dengan st.rerun() st.markdown("---") st.markdown("

© 2025 Your Company. All Rights Reserved.

", unsafe_allow_html=True)