File size: 8,461 Bytes
8879278
7c4cea5
 
e583e5b
7c4cea5
e583e5b
8879278
 
7c4cea5
 
 
 
 
d1cd9d0
 
8879278
d1cd9d0
 
 
 
8879278
 
7c4cea5
d1cd9d0
 
 
 
 
 
 
 
 
 
7c4cea5
d1cd9d0
 
e583e5b
d1cd9d0
 
 
7c4cea5
d1cd9d0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e583e5b
d1cd9d0
 
8879278
d1cd9d0
 
 
 
 
 
 
7c4cea5
8879278
d1cd9d0
 
 
 
 
 
 
 
8879278
d1cd9d0
8879278
d1cd9d0
8879278
d1cd9d0
 
 
8879278
7c4cea5
d1cd9d0
 
 
 
 
 
7c4cea5
d1cd9d0
 
 
7c4cea5
d1cd9d0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e583e5b
d1cd9d0
 
 
 
 
e583e5b
d1cd9d0
 
 
 
 
 
 
 
 
 
8879278
 
 
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import streamlit as st
from typing import Dict

# Constants
ONE_BR_UNITS = 23
TWO_BR_UNITS = 45
SOLAR_PANEL_RATING = 625  # W
BATTERY_CAPACITY = 200  # Ah
BATTERY_VOLTAGE = 12  # V
SYSTEM_LOSSES = 0.20
FEED_IN_TARIFF = 12

# Lighting specifications
LIGHTS_1BR = 5
LIGHTS_2BR = 8
LIGHT_POWER = 6  # Watts per light

def initialize_session_state():
    """Initialize session state variables"""
    defaults = {
        'solar_panels': 100,
        'batteries': 50,
        'panel_price': 13000,
        'battery_price': 39000,
        'grid_price': 28.44
    }
    for key, value in defaults.items():
        if key not in st.session_state:
            st.session_state[key] = value

def calculate_lighting_consumption(occupancy_1br: float, occupancy_2br: float) -> float:
    """Calculate daily lighting consumption"""
    return (
        (occupancy_1br * ONE_BR_UNITS * LIGHTS_1BR * LIGHT_POWER / 1000) +
        (occupancy_2br * TWO_BR_UNITS * LIGHTS_2BR * LIGHT_POWER / 1000)
    ) * 24  # Daily kWh

def calculate_appliance_consumption(occupancy_1br: float, occupancy_2br: float) -> float:
    """Calculate daily appliance consumption"""
    return (
        (occupancy_1br * ONE_BR_UNITS * (250 - (LIGHTS_1BR * LIGHT_POWER * 24 / 1000))) +
        (occupancy_2br * TWO_BR_UNITS * (400 - (LIGHTS_2BR * LIGHT_POWER * 24 / 1000)))
    )  # Daily kWh

def total_consumption(occupancy_1br: float, occupancy_2br: float, common_area: float) -> float:
    """Calculate total monthly consumption"""
    lighting = calculate_lighting_consumption(occupancy_1br, occupancy_2br)
    appliances = calculate_appliance_consumption(occupancy_1br, occupancy_2br)
    return (lighting + appliances + common_area) * 30  # Monthly kWh

def solar_production(panels: int) -> float:
    """Monthly solar production with losses"""
    return panels * SOLAR_PANEL_RATING * 5 * 0.8 * 30 / 1000  # 5 sun hours

def battery_storage(batteries: int) -> float:
    """Usable battery capacity"""
    return batteries * BATTERY_CAPACITY * BATTERY_VOLTAGE * 0.8 / 1000

def financial_analysis(consumption: float, production: float, storage: float) -> Dict:
    """Detailed financial calculations"""
    solar_used = min(production, consumption)
    grid_purchased = max(consumption - solar_used - storage, 0)
    
    return {
        'solar_contribution': solar_used / consumption * 100,
        'grid_dependency': grid_purchased / consumption * 100,
        'monthly_savings': (consumption * st.session_state.grid_price) - 
                          (grid_purchased * st.session_state.grid_price),
        'payback_period': (st.session_state.solar_panels * st.session_state.panel_price +
                          st.session_state.batteries * st.session_state.battery_price) /
                          ((consumption - grid_purchased) * st.session_state.grid_price * 12)
    }

def create_consumption_breakdown(occupancy_1br: float, occupancy_2br: float, common_area: float):
    """Create detailed consumption breakdown"""
    breakdown = {
        'Lighting': calculate_lighting_consumption(occupancy_1br, occupancy_2br) * 30,
        'Appliances': calculate_appliance_consumption(occupancy_1br, occupancy_2br) * 30,
        'Common Areas': common_area * 30
    }
    return pd.DataFrame.from_dict(breakdown, orient='index', columns=['kWh'])

# Streamlit Interface
def main():
    st.set_page_config("Solar Analysis Suite", "🌞", "wide")
    initialize_session_state()
    
    st.title("🌞 Advanced Solar Performance Analyzer")
    
    with st.sidebar:
        st.header("System Configuration")
        st.number_input("Solar Panels", 1, 1000, key='solar_panels')
        st.number_input("Batteries", 0, 500, key='batteries')
        st.number_input("Panel Price (Ksh)", 1000, 50000, key='panel_price')
        st.number_input("Battery Price (Ksh)", 5000, 100000, key='battery_price')
        st.number_input("Grid Price (Ksh/kWh)", 10.0, 50.0, key='grid_price')
    
    scenarios = {
        "Low Occupancy": {"1br": 0.0, "2br": 1.0, "common": 5.904},
        "Medium Occupancy": {"1br": 0.25, "2br": 1.0, "common": 5.904},
        "High Occupancy": {"1br": 0.5, "2br": 1.0, "common": 5.904}
    }
    
    analysis_data = []
    for name, params in scenarios.items():
        consumption = total_consumption(
            params["1br"], params["2br"], params["common"]
        )
        production = solar_production(st.session_state.solar_panels)
        storage = battery_storage(st.session_state.batteries)
        financials = financial_analysis(consumption, production, storage)
        
        analysis_data.append({
            "Scenario": name,
            "Consumption": consumption,
            "Production": production,
            **financials
        })
    
    df = pd.DataFrame(analysis_data)
    
    # Energy Flow Analysis
    st.header("Energy Flow Composition")
    fig, ax = plt.subplots(figsize=(10, 6))
    sns.barplot(df.melt(id_vars=['Scenario'], 
                value_vars=['solar_contribution', 'grid_dependency'],
                x='Scenario', y='value', hue='variable', ax=ax)
    ax.set_ylabel("Percentage (%)")
    ax.set_title("Energy Contribution Breakdown")
    st.pyplot(fig)
    
    with st.expander("🔍 Energy Flow Interpretation"):
        st.markdown("""

        **Understanding the Chart:**

        - **Solar Contribution**: Percentage of total energy needs met by solar production

        - **Grid Dependency**: Remaining energy required from grid

        - Ideal scenario shows high solar contribution with minimal grid dependency

        """)
    
    # Financial Analysis
    st.header("Financial Performance Metrics")
    
    # Metric 1: Monthly Savings
    fig1, ax1 = plt.subplots(figsize=(10, 4))
    sns.barplot(data=df, x='Scenario', y='monthly_savings', ax=ax1)
    ax1.set_title("Monthly Cost Savings")
    ax1.set_ylabel("Ksh")
    st.pyplot(fig1)
    
    with st.expander("💵 Savings Analysis"):
        st.markdown(f"""

        **Key Observations:**

        - Savings calculated as: `(Total Consumption × Grid Price) - (Grid Purchased × Grid Price)`

        - Current Grid Price: Ksh {st.session_state.grid_price}/kWh

        - Maximum potential savings limited by solar production capacity

        """)
        st.table(df[['Scenario', 'Consumption', 'Production', 'monthly_savings']])
    
    # Metric 2: Payback Period
    fig2, ax2 = plt.subplots(figsize=(10, 4))
    sns.barplot(data=df, x='Scenario', y='payback_period', ax=ax2)
    ax2.set_title("System Payback Period")
    ax2.set_ylabel("Years")
    st.pyplot(fig2)
    
    with st.expander("⏳ Payback Explanation"):
        st.markdown(f"""

        **Calculation Methodology:**

        - Total Investment: (Panels × {st.session_state.panel_price:,}Ksh) + (Batteries × {st.session_state.battery_price:,}Ksh)

        - Annual Savings: Monthly Savings × 12

        - Payback Period = Total Investment / Annual Savings

        """)
        st.table(df[['Scenario', 'payback_period']])
    
    # Consumption Breakdown
    st.header("Detailed Consumption Analysis")
    scenario_select = st.selectbox("Select Scenario", list(scenarios.keys()))
    
    selected_params = scenarios[scenario_select]
    breakdown_df = create_consumption_breakdown(
        selected_params["1br"], 
        selected_params["2br"], 
        selected_params["common"]
    )
    
    col1, col2 = st.columns(2)
    with col1:
        st.subheader("Energy Composition")
        fig3, ax3 = plt.subplots()
        breakdown_df.plot.pie(y='kWh', ax=ax3, autopct='%1.1f%%')
        st.pyplot(fig3)
    
    with col2:
        st.subheader("Component Breakdown")
        st.table(breakdown_df)
        
        analysis_text = f"""

        **Key Insights for {scenario_select}:**

        - Lighting contributes {breakdown_df.loc['Lighting', 'kWh']/breakdown_df.sum().values[0]*100:.1f}% of total consumption

        - Common areas account for {breakdown_df.loc['Common Areas', 'kWh']:.0f}kWh monthly

        - 2BR units dominate appliance usage at {selected_params['2br']*100}% occupancy

        """
        st.markdown(analysis_text)

if __name__ == "__main__":
    main()