charagu-eric commited on
Commit
30bf09c
·
1 Parent(s): d1cd9d0
Files changed (1) hide show
  1. app.py +105 -74
app.py CHANGED
@@ -19,185 +19,215 @@ LIGHTS_1BR = 5
19
  LIGHTS_2BR = 8
20
  LIGHT_POWER = 6 # Watts per light
21
 
 
22
  def initialize_session_state():
23
  """Initialize session state variables"""
24
  defaults = {
25
- 'solar_panels': 100,
26
- 'batteries': 50,
27
- 'panel_price': 13000,
28
- 'battery_price': 39000,
29
- 'grid_price': 28.44
30
  }
31
  for key, value in defaults.items():
32
  if key not in st.session_state:
33
  st.session_state[key] = value
34
 
 
35
  def calculate_lighting_consumption(occupancy_1br: float, occupancy_2br: float) -> float:
36
  """Calculate daily lighting consumption"""
37
  return (
38
- (occupancy_1br * ONE_BR_UNITS * LIGHTS_1BR * LIGHT_POWER / 1000) +
39
- (occupancy_2br * TWO_BR_UNITS * LIGHTS_2BR * LIGHT_POWER / 1000)
40
  ) * 24 # Daily kWh
41
 
42
- def calculate_appliance_consumption(occupancy_1br: float, occupancy_2br: float) -> float:
 
 
 
43
  """Calculate daily appliance consumption"""
44
  return (
45
- (occupancy_1br * ONE_BR_UNITS * (250 - (LIGHTS_1BR * LIGHT_POWER * 24 / 1000))) +
46
- (occupancy_2br * TWO_BR_UNITS * (400 - (LIGHTS_2BR * LIGHT_POWER * 24 / 1000)))
 
47
  ) # Daily kWh
48
 
49
- def total_consumption(occupancy_1br: float, occupancy_2br: float, common_area: float) -> float:
 
 
 
50
  """Calculate total monthly consumption"""
51
  lighting = calculate_lighting_consumption(occupancy_1br, occupancy_2br)
52
  appliances = calculate_appliance_consumption(occupancy_1br, occupancy_2br)
53
  return (lighting + appliances + common_area) * 30 # Monthly kWh
54
 
 
55
  def solar_production(panels: int) -> float:
56
  """Monthly solar production with losses"""
57
  return panels * SOLAR_PANEL_RATING * 5 * 0.8 * 30 / 1000 # 5 sun hours
58
 
 
59
  def battery_storage(batteries: int) -> float:
60
  """Usable battery capacity"""
61
  return batteries * BATTERY_CAPACITY * BATTERY_VOLTAGE * 0.8 / 1000
62
 
 
63
  def financial_analysis(consumption: float, production: float, storage: float) -> Dict:
64
  """Detailed financial calculations"""
65
  solar_used = min(production, consumption)
66
  grid_purchased = max(consumption - solar_used - storage, 0)
67
-
68
  return {
69
- 'solar_contribution': solar_used / consumption * 100,
70
- 'grid_dependency': grid_purchased / consumption * 100,
71
- 'monthly_savings': (consumption * st.session_state.grid_price) -
72
- (grid_purchased * st.session_state.grid_price),
73
- 'payback_period': (st.session_state.solar_panels * st.session_state.panel_price +
74
- st.session_state.batteries * st.session_state.battery_price) /
75
- ((consumption - grid_purchased) * st.session_state.grid_price * 12)
 
 
76
  }
77
 
78
- def create_consumption_breakdown(occupancy_1br: float, occupancy_2br: float, common_area: float):
 
 
 
79
  """Create detailed consumption breakdown"""
80
  breakdown = {
81
- 'Lighting': calculate_lighting_consumption(occupancy_1br, occupancy_2br) * 30,
82
- 'Appliances': calculate_appliance_consumption(occupancy_1br, occupancy_2br) * 30,
83
- 'Common Areas': common_area * 30
 
84
  }
85
- return pd.DataFrame.from_dict(breakdown, orient='index', columns=['kWh'])
 
86
 
87
  # Streamlit Interface
88
  def main():
89
  st.set_page_config("Solar Analysis Suite", "🌞", "wide")
90
  initialize_session_state()
91
-
92
  st.title("🌞 Advanced Solar Performance Analyzer")
93
-
94
  with st.sidebar:
95
  st.header("System Configuration")
96
- st.number_input("Solar Panels", 1, 1000, key='solar_panels')
97
- st.number_input("Batteries", 0, 500, key='batteries')
98
- st.number_input("Panel Price (Ksh)", 1000, 50000, key='panel_price')
99
- st.number_input("Battery Price (Ksh)", 5000, 100000, key='battery_price')
100
- st.number_input("Grid Price (Ksh/kWh)", 10.0, 50.0, key='grid_price')
101
-
102
  scenarios = {
103
  "Low Occupancy": {"1br": 0.0, "2br": 1.0, "common": 5.904},
104
  "Medium Occupancy": {"1br": 0.25, "2br": 1.0, "common": 5.904},
105
- "High Occupancy": {"1br": 0.5, "2br": 1.0, "common": 5.904}
106
  }
107
-
108
  analysis_data = []
109
  for name, params in scenarios.items():
110
- consumption = total_consumption(
111
- params["1br"], params["2br"], params["common"]
112
- )
113
  production = solar_production(st.session_state.solar_panels)
114
  storage = battery_storage(st.session_state.batteries)
115
  financials = financial_analysis(consumption, production, storage)
116
-
117
- analysis_data.append({
118
- "Scenario": name,
119
- "Consumption": consumption,
120
- "Production": production,
121
- **financials
122
- })
123
-
 
 
124
  df = pd.DataFrame(analysis_data)
125
-
126
  # Energy Flow Analysis
127
  st.header("Energy Flow Composition")
128
  fig, ax = plt.subplots(figsize=(10, 6))
129
- sns.barplot(df.melt(id_vars=['Scenario'],
130
- value_vars=['solar_contribution', 'grid_dependency'],
131
- x='Scenario', y='value', hue='variable', ax=ax)
 
 
 
 
 
 
 
132
  ax.set_ylabel("Percentage (%)")
133
  ax.set_title("Energy Contribution Breakdown")
134
  st.pyplot(fig)
135
-
136
  with st.expander("🔍 Energy Flow Interpretation"):
137
- st.markdown("""
 
138
  **Understanding the Chart:**
139
  - **Solar Contribution**: Percentage of total energy needs met by solar production
140
  - **Grid Dependency**: Remaining energy required from grid
141
  - Ideal scenario shows high solar contribution with minimal grid dependency
142
- """)
143
-
 
144
  # Financial Analysis
145
  st.header("Financial Performance Metrics")
146
-
147
  # Metric 1: Monthly Savings
148
  fig1, ax1 = plt.subplots(figsize=(10, 4))
149
- sns.barplot(data=df, x='Scenario', y='monthly_savings', ax=ax1)
150
  ax1.set_title("Monthly Cost Savings")
151
  ax1.set_ylabel("Ksh")
152
  st.pyplot(fig1)
153
-
154
  with st.expander("💵 Savings Analysis"):
155
- st.markdown(f"""
 
156
  **Key Observations:**
157
  - Savings calculated as: `(Total Consumption × Grid Price) - (Grid Purchased × Grid Price)`
158
  - Current Grid Price: Ksh {st.session_state.grid_price}/kWh
159
  - Maximum potential savings limited by solar production capacity
160
- """)
161
- st.table(df[['Scenario', 'Consumption', 'Production', 'monthly_savings']])
162
-
 
163
  # Metric 2: Payback Period
164
  fig2, ax2 = plt.subplots(figsize=(10, 4))
165
- sns.barplot(data=df, x='Scenario', y='payback_period', ax=ax2)
166
  ax2.set_title("System Payback Period")
167
  ax2.set_ylabel("Years")
168
  st.pyplot(fig2)
169
-
170
  with st.expander("⏳ Payback Explanation"):
171
- st.markdown(f"""
 
172
  **Calculation Methodology:**
173
  - Total Investment: (Panels × {st.session_state.panel_price:,}Ksh) + (Batteries × {st.session_state.battery_price:,}Ksh)
174
  - Annual Savings: Monthly Savings × 12
175
  - Payback Period = Total Investment / Annual Savings
176
- """)
177
- st.table(df[['Scenario', 'payback_period']])
178
-
 
179
  # Consumption Breakdown
180
  st.header("Detailed Consumption Analysis")
181
  scenario_select = st.selectbox("Select Scenario", list(scenarios.keys()))
182
-
183
  selected_params = scenarios[scenario_select]
184
  breakdown_df = create_consumption_breakdown(
185
- selected_params["1br"],
186
- selected_params["2br"],
187
- selected_params["common"]
188
  )
189
-
190
  col1, col2 = st.columns(2)
191
  with col1:
192
  st.subheader("Energy Composition")
193
  fig3, ax3 = plt.subplots()
194
- breakdown_df.plot.pie(y='kWh', ax=ax3, autopct='%1.1f%%')
195
  st.pyplot(fig3)
196
-
197
  with col2:
198
  st.subheader("Component Breakdown")
199
  st.table(breakdown_df)
200
-
201
  analysis_text = f"""
202
  **Key Insights for {scenario_select}:**
203
  - Lighting contributes {breakdown_df.loc['Lighting', 'kWh']/breakdown_df.sum().values[0]*100:.1f}% of total consumption
@@ -206,5 +236,6 @@ def main():
206
  """
207
  st.markdown(analysis_text)
208
 
 
209
  if __name__ == "__main__":
210
  main()
 
19
  LIGHTS_2BR = 8
20
  LIGHT_POWER = 6 # Watts per light
21
 
22
+
23
  def initialize_session_state():
24
  """Initialize session state variables"""
25
  defaults = {
26
+ "solar_panels": 100,
27
+ "batteries": 50,
28
+ "panel_price": 13000,
29
+ "battery_price": 39000,
30
+ "grid_price": 28.44,
31
  }
32
  for key, value in defaults.items():
33
  if key not in st.session_state:
34
  st.session_state[key] = value
35
 
36
+
37
  def calculate_lighting_consumption(occupancy_1br: float, occupancy_2br: float) -> float:
38
  """Calculate daily lighting consumption"""
39
  return (
40
+ (occupancy_1br * ONE_BR_UNITS * LIGHTS_1BR * LIGHT_POWER / 1000)
41
+ + (occupancy_2br * TWO_BR_UNITS * LIGHTS_2BR * LIGHT_POWER / 1000)
42
  ) * 24 # Daily kWh
43
 
44
+
45
+ def calculate_appliance_consumption(
46
+ occupancy_1br: float, occupancy_2br: float
47
+ ) -> float:
48
  """Calculate daily appliance consumption"""
49
  return (
50
+ occupancy_1br * ONE_BR_UNITS * (250 - (LIGHTS_1BR * LIGHT_POWER * 24 / 1000))
51
+ ) + (
52
+ occupancy_2br * TWO_BR_UNITS * (400 - (LIGHTS_2BR * LIGHT_POWER * 24 / 1000))
53
  ) # Daily kWh
54
 
55
+
56
+ def total_consumption(
57
+ occupancy_1br: float, occupancy_2br: float, common_area: float
58
+ ) -> float:
59
  """Calculate total monthly consumption"""
60
  lighting = calculate_lighting_consumption(occupancy_1br, occupancy_2br)
61
  appliances = calculate_appliance_consumption(occupancy_1br, occupancy_2br)
62
  return (lighting + appliances + common_area) * 30 # Monthly kWh
63
 
64
+
65
  def solar_production(panels: int) -> float:
66
  """Monthly solar production with losses"""
67
  return panels * SOLAR_PANEL_RATING * 5 * 0.8 * 30 / 1000 # 5 sun hours
68
 
69
+
70
  def battery_storage(batteries: int) -> float:
71
  """Usable battery capacity"""
72
  return batteries * BATTERY_CAPACITY * BATTERY_VOLTAGE * 0.8 / 1000
73
 
74
+
75
  def financial_analysis(consumption: float, production: float, storage: float) -> Dict:
76
  """Detailed financial calculations"""
77
  solar_used = min(production, consumption)
78
  grid_purchased = max(consumption - solar_used - storage, 0)
79
+
80
  return {
81
+ "solar_contribution": solar_used / consumption * 100,
82
+ "grid_dependency": grid_purchased / consumption * 100,
83
+ "monthly_savings": (consumption * st.session_state.grid_price)
84
+ - (grid_purchased * st.session_state.grid_price),
85
+ "payback_period": (
86
+ st.session_state.solar_panels * st.session_state.panel_price
87
+ + st.session_state.batteries * st.session_state.battery_price
88
+ )
89
+ / ((consumption - grid_purchased) * st.session_state.grid_price * 12),
90
  }
91
 
92
+
93
+ def create_consumption_breakdown(
94
+ occupancy_1br: float, occupancy_2br: float, common_area: float
95
+ ):
96
  """Create detailed consumption breakdown"""
97
  breakdown = {
98
+ "Lighting": calculate_lighting_consumption(occupancy_1br, occupancy_2br) * 30,
99
+ "Appliances": calculate_appliance_consumption(occupancy_1br, occupancy_2br)
100
+ * 30,
101
+ "Common Areas": common_area * 30,
102
  }
103
+ return pd.DataFrame.from_dict(breakdown, orient="index", columns=["kWh"])
104
+
105
 
106
  # Streamlit Interface
107
  def main():
108
  st.set_page_config("Solar Analysis Suite", "🌞", "wide")
109
  initialize_session_state()
110
+
111
  st.title("🌞 Advanced Solar Performance Analyzer")
112
+
113
  with st.sidebar:
114
  st.header("System Configuration")
115
+ st.number_input("Solar Panels", 1, 1000, key="solar_panels")
116
+ st.number_input("Batteries", 0, 500, key="batteries")
117
+ st.number_input("Panel Price (Ksh)", 1000, 50000, key="panel_price")
118
+ st.number_input("Battery Price (Ksh)", 5000, 100000, key="battery_price")
119
+ st.number_input("Grid Price (Ksh/kWh)", 10.0, 50.0, key="grid_price")
120
+
121
  scenarios = {
122
  "Low Occupancy": {"1br": 0.0, "2br": 1.0, "common": 5.904},
123
  "Medium Occupancy": {"1br": 0.25, "2br": 1.0, "common": 5.904},
124
+ "High Occupancy": {"1br": 0.5, "2br": 1.0, "common": 5.904},
125
  }
126
+
127
  analysis_data = []
128
  for name, params in scenarios.items():
129
+ consumption = total_consumption(params["1br"], params["2br"], params["common"])
 
 
130
  production = solar_production(st.session_state.solar_panels)
131
  storage = battery_storage(st.session_state.batteries)
132
  financials = financial_analysis(consumption, production, storage)
133
+
134
+ analysis_data.append(
135
+ {
136
+ "Scenario": name,
137
+ "Consumption": consumption,
138
+ "Production": production,
139
+ **financials,
140
+ }
141
+ )
142
+
143
  df = pd.DataFrame(analysis_data)
144
+
145
  # Energy Flow Analysis
146
  st.header("Energy Flow Composition")
147
  fig, ax = plt.subplots(figsize=(10, 6))
148
+ sns.barplot(
149
+ df.melt(
150
+ id_vars=["Scenario"],
151
+ value_vars=["solar_contribution", "grid_dependency"],
152
+ x="Scenario",
153
+ y="value",
154
+ hue="variable",
155
+ ax=ax,
156
+ )
157
+ )
158
  ax.set_ylabel("Percentage (%)")
159
  ax.set_title("Energy Contribution Breakdown")
160
  st.pyplot(fig)
161
+
162
  with st.expander("🔍 Energy Flow Interpretation"):
163
+ st.markdown(
164
+ """
165
  **Understanding the Chart:**
166
  - **Solar Contribution**: Percentage of total energy needs met by solar production
167
  - **Grid Dependency**: Remaining energy required from grid
168
  - Ideal scenario shows high solar contribution with minimal grid dependency
169
+ """
170
+ )
171
+
172
  # Financial Analysis
173
  st.header("Financial Performance Metrics")
174
+
175
  # Metric 1: Monthly Savings
176
  fig1, ax1 = plt.subplots(figsize=(10, 4))
177
+ sns.barplot(data=df, x="Scenario", y="monthly_savings", ax=ax1)
178
  ax1.set_title("Monthly Cost Savings")
179
  ax1.set_ylabel("Ksh")
180
  st.pyplot(fig1)
181
+
182
  with st.expander("💵 Savings Analysis"):
183
+ st.markdown(
184
+ f"""
185
  **Key Observations:**
186
  - Savings calculated as: `(Total Consumption × Grid Price) - (Grid Purchased × Grid Price)`
187
  - Current Grid Price: Ksh {st.session_state.grid_price}/kWh
188
  - Maximum potential savings limited by solar production capacity
189
+ """
190
+ )
191
+ st.table(df[["Scenario", "Consumption", "Production", "monthly_savings"]])
192
+
193
  # Metric 2: Payback Period
194
  fig2, ax2 = plt.subplots(figsize=(10, 4))
195
+ sns.barplot(data=df, x="Scenario", y="payback_period", ax=ax2)
196
  ax2.set_title("System Payback Period")
197
  ax2.set_ylabel("Years")
198
  st.pyplot(fig2)
199
+
200
  with st.expander("⏳ Payback Explanation"):
201
+ st.markdown(
202
+ f"""
203
  **Calculation Methodology:**
204
  - Total Investment: (Panels × {st.session_state.panel_price:,}Ksh) + (Batteries × {st.session_state.battery_price:,}Ksh)
205
  - Annual Savings: Monthly Savings × 12
206
  - Payback Period = Total Investment / Annual Savings
207
+ """
208
+ )
209
+ st.table(df[["Scenario", "payback_period"]])
210
+
211
  # Consumption Breakdown
212
  st.header("Detailed Consumption Analysis")
213
  scenario_select = st.selectbox("Select Scenario", list(scenarios.keys()))
214
+
215
  selected_params = scenarios[scenario_select]
216
  breakdown_df = create_consumption_breakdown(
217
+ selected_params["1br"], selected_params["2br"], selected_params["common"]
 
 
218
  )
219
+
220
  col1, col2 = st.columns(2)
221
  with col1:
222
  st.subheader("Energy Composition")
223
  fig3, ax3 = plt.subplots()
224
+ breakdown_df.plot.pie(y="kWh", ax=ax3, autopct="%1.1f%%")
225
  st.pyplot(fig3)
226
+
227
  with col2:
228
  st.subheader("Component Breakdown")
229
  st.table(breakdown_df)
230
+
231
  analysis_text = f"""
232
  **Key Insights for {scenario_select}:**
233
  - Lighting contributes {breakdown_df.loc['Lighting', 'kWh']/breakdown_df.sum().values[0]*100:.1f}% of total consumption
 
236
  """
237
  st.markdown(analysis_text)
238
 
239
+
240
  if __name__ == "__main__":
241
  main()