File size: 4,036 Bytes
8cdd0d8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
        }