File size: 3,484 Bytes
af3ca30
62d5751
 
0b8845d
62d5751
 
 
 
 
 
 
 
 
 
 
 
 
0b8845d
 
 
 
 
 
62d5751
 
 
0b8845d
 
62d5751
 
 
 
0b8845d
 
62d5751
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
af3ca30
62d5751
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
import streamlit as st
import pandas as pd
import numpy as np
import os
import joblib

#  Configuration & Styling
st.set_page_config(page_title="SunStream Predictor", layout="wide")

st.markdown("""
    <style>
    .main { background-color: #f5f7f9; }
    .stMetric { background-color: #ffffff; padding: 15px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); }
    </style>
    """, unsafe_allow_html=True)



BASE_DIR = os.path.dirname(__file__)

model_path = os.path.join(BASE_DIR, "solar_model.pkl")
scaler_path = os.path.join(BASE_DIR, "solar_scaler.pkl")

# load models
@st.cache_resource
def load_assets():
    model = joblib.load(model_path)
    scaler = joblib.load(scaler_path)
    return model, scaler

try:
    model, scaler = load_assets()
except Exception as e:
    st.error(f"Error loading model: {e}")
    st.stop()

# Header
st.title("☀️ SunStream: Solar Output Predictor")
st.markdown("Professional-grade energy forecasting based on atmospheric conditions.")
st.divider()

#  Sidebar Inputs 
st.sidebar.header("Control Panel")
st.sidebar.info("Adjust weather parameters to see real-time predictions.")

hour = st.sidebar.slider("Hour of Day (24h)", 0, 23, 12)
cloud_cover = st.sidebar.slider("Cloud Cover (0-1)", 0.0, 1.0, 0.2, 0.01)
temp = st.sidebar.slider("Temperature (°C)", -10.0, 45.0, 25.0)
humidity = st.sidebar.slider("Relative Humidity (%)", 0.0, 100.0, 50.0)
visibility = st.sidebar.number_input("Visibility (km)", value=10.0)
wind_speed = st.sidebar.number_input("Wind Speed", value=5.0)
pressure = st.sidebar.number_input("Pressure", value=29.2)
altimeter = st.sidebar.number_input("Altimeter", value=30.0)
dew_point = st.sidebar.number_input("Dew Point", value=10.0)


#  Feature Engineering
def predict():
    # 1. Create engineered features
    h_sin = np.sin(2 * np.pi * hour / 23.0)
    h_cos = np.cos(2 * np.pi * hour / 23.0)
    heat_idx = temp * humidity

    # 2. Build feature array in the EXACT order
    features = np.array([[
        cloud_cover, visibility, temp, dew_point,
        humidity, wind_speed, pressure, altimeter,
        h_sin, h_cos, heat_idx
    ]])

    # 3. Scale and Predict
    features_scaled = scaler.transform(features)
    prediction = model.predict(features_scaled)[0]
    return max(0, round(prediction, 2))


result = predict()

#  Main Dashboard
col1, col2, col3 = st.columns([1, 1, 1])

with col1:
    st.metric(label="Estimated Output", value=f"{result} kWh")

with col2:
    efficiency = min(100, (result / 4500) * 100)
    st.metric(label="System Efficiency", value=f"{efficiency:.1f}%")

with col3:
    status = "Optimal" if cloud_cover < 0.3 and result > 1000 else "Sub-optimal"
    st.write(f"Current Status: \n## {status}")

#  Visualization
st.subheader("Hourly Forecast Simulation")
st.caption("How your current weather conditions would perform throughout the day.")


hours = np.arange(0, 24)
curve = []
for h in hours:
    h_sin, h_cos = np.sin(2 * np.pi * h / 23.0), np.cos(2 * np.pi * h / 23.0)
    feat = np.array([[cloud_cover, visibility, temp, dew_point, humidity, wind_speed, pressure, altimeter, h_sin, h_cos,
                      temp * humidity]])
    scaled_feat = scaler.transform(feat)
    curve.append(max(0, model.predict(scaled_feat)[0]))

chart_data = pd.DataFrame({"Hour": hours, "kWh": curve})
st.area_chart(chart_data.set_index("Hour"), color="#FF8C00")

st.success(" Innovation Tip: This model uses Cyclical Encoding to understand that 23:00 is close to 00:00!")