Spaces:
Sleeping
Sleeping
| import pickle | |
| import pandas as pd | |
| from datetime import datetime, timedelta | |
| class ModelManager: | |
| """Manages ML model loading and inference""" | |
| def __init__(self, model_path='model_ai_bta.pkl', laju_path='laju_penipisan.pkl'): | |
| self.model = None | |
| self.laju_penipisan = None | |
| self.load_models(model_path, laju_path) | |
| def load_models(self, model_path, laju_path): | |
| """Load ML model dan laju penipisan dari pickle files""" | |
| try: | |
| with open(model_path, 'rb') as f: | |
| self.model = pickle.load(f) | |
| print(f"✓ Model loaded successfully from {model_path}") | |
| except Exception as e: | |
| print(f"✗ Error loading model: {e}") | |
| raise | |
| try: | |
| with open(laju_path, 'rb') as f: | |
| self.laju_penipisan = pickle.load(f) | |
| print(f"✓ Laju penipisan loaded successfully: {self.laju_penipisan}") | |
| except Exception as e: | |
| print(f"✗ Error loading laju penipisan: {e}") | |
| raise | |
| def predict(self, cone_depan, bodi_tengah, cone_belakang): | |
| """Predict ketebalan BTA given temperature inputs | |
| Returns: ketebalan_prediksi (float) | |
| """ | |
| suhu_avg = (cone_depan + bodi_tengah + cone_belakang) / 3 | |
| diff_std = suhu_avg - 400 | |
| # Prepare input features untuk model | |
| input_features = pd.DataFrame([{ | |
| 'cone_depan_smooth': cone_depan, | |
| 'body_tengah_smooth': bodi_tengah, | |
| 'cone_belakang_smooth': cone_belakang, | |
| 'suhu_avg_smooth': suhu_avg, | |
| 'diff_std': diff_std | |
| }]) | |
| # Predict | |
| ketebalan_prediksi = self.model.predict(input_features)[0] | |
| return ketebalan_prediksi | |
| def predict_batch(self, df): | |
| """Predict ketebalan untuk batch data | |
| Args: | |
| df: DataFrame dengan columns [cone_depan, bodi_tengah, cone_belakang, suhu_avg] | |
| Returns: array of predictions | |
| """ | |
| # Ensure numeric columns | |
| for col in ['cone_depan', 'bodi_tengah', 'cone_belakang']: | |
| if col in df.columns: | |
| df[col] = pd.to_numeric(df[col], errors='coerce') | |
| if 'suhu_avg' not in df.columns: | |
| df['suhu_avg'] = (df['cone_depan'] + df['bodi_tengah'] + df['cone_belakang']) / 3 | |
| df['diff_std'] = df['suhu_avg'] - 400 | |
| input_features = pd.DataFrame({ | |
| 'cone_depan_smooth': df['cone_depan'], | |
| 'body_tengah_smooth': df['bodi_tengah'], | |
| 'cone_belakang_smooth': df['cone_belakang'], | |
| 'suhu_avg_smooth': df['suhu_avg'], | |
| 'diff_std': df['diff_std'] | |
| }) | |
| predictions = self.model.predict(input_features) | |
| return predictions | |
| def calculate_rul(self, ketebalan_prediksi, min_safe_thickness=115): | |
| """Calculate Remaining Useful Life (RUL) | |
| Args: | |
| ketebalan_prediksi: predicted thickness (mm) | |
| min_safe_thickness: minimum safe thickness (mm) | |
| Returns: dict with keys: sisa_tebal, sisa_hari, tgl_target, status | |
| """ | |
| sisa_tebal = ketebalan_prediksi - min_safe_thickness | |
| if sisa_tebal <= 0: | |
| status = "⚠️ CRITICAL (Perlu Perbaikan Segera)" | |
| sisa_hari = 0 | |
| tgl_target = datetime.now() | |
| sisa_hari_str = "0 Hari" | |
| tgl_target_str = "SEGERA AKSI" | |
| else: | |
| status = "✅ AMAN" | |
| sisa_hari = int(sisa_tebal / self.laju_penipisan) | |
| tgl_target = datetime.now() + timedelta(days=sisa_hari) | |
| sisa_hari_str = f"± {sisa_hari} Hari" | |
| tgl_target_str = tgl_target.strftime('%d %B %Y') | |
| return { | |
| 'sisa_tebal': sisa_tebal, | |
| 'sisa_hari': sisa_hari, | |
| 'tgl_target': tgl_target_str, | |
| 'status': status, | |
| 'sisa_hari_str': sisa_hari_str | |
| } | |