rishabh5752 commited on
Commit
5f9bd22
·
verified ·
1 Parent(s): d3bdeed

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +291 -0
app.py ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import math
3
+ import gradio as gr
4
+ import pandas as pd
5
+ from pathlib import Path
6
+ from dotenv import load_dotenv
7
+
8
+ load_dotenv()
9
+
10
+
11
+ def calculate_gridcoin(
12
+ owner,
13
+ pv_kw,
14
+ batt_kwh,
15
+ annual_load,
16
+ retail_rate,
17
+ upfront,
18
+ exp_actual,
19
+ exp_evc,
20
+ grid_fee,
21
+ peak_start,
22
+ peak_end,
23
+ coin_value,
24
+ peak_fraction,
25
+ dr_kwh
26
+ ):
27
+ """Calculate GridCoin metrics and generate results."""
28
+
29
+ # Core calculations
30
+ pv_yield = pv_kw * 1250
31
+ self_use_ratio = 0.65
32
+ self_used = pv_yield * self_use_ratio
33
+ exports = max(0, pv_yield - self_used - batt_kwh * 200)
34
+
35
+ peak_exports = exports * peak_fraction
36
+ coins_peak = peak_exports * 1.0
37
+ coins_dr = dr_kwh * 0.5
38
+ coins_total = coins_peak + coins_dr
39
+ coin_dollars = coins_total * coin_value
40
+
41
+ bill_nonder = annual_load * retail_rate
42
+ imports_der = max(0, annual_load - self_used)
43
+ exp_credit = exports * exp_actual
44
+ fee_der = grid_fee * pv_kw * 12
45
+ bill_der = imports_der * retail_rate + fee_der - exp_credit - coin_dollars
46
+
47
+ savings = max(0, bill_nonder - bill_der)
48
+ payback = upfront / savings if savings > 0 else math.inf
49
+
50
+ # Format results
51
+ gridcoins_earned = f"{coins_total:,.1f}"
52
+ gridcoin_value = f"${coin_dollars:,.2f}"
53
+
54
+ non_der_bill = f"${bill_nonder:,.0f}"
55
+ der_bill = f"${bill_der:,.0f}"
56
+ bill_savings = f"${bill_der - bill_nonder:,.0f}"
57
+ payback_period = f"{payback:.1f} yrs" if payback != math.inf else "N/A"
58
+
59
+ # AI Analysis
60
+ ai_summary = ""
61
+ if os.getenv("OPENAI_API_KEY"):
62
+ try:
63
+ import openai
64
+ openai.api_key = os.getenv("OPENAI_API_KEY")
65
+
66
+ prompt = (
67
+ f"Write a clear, well-formatted summary in 2-3 complete sentences with proper spacing:\n\n"
68
+ f"A {owner} with a {pv_kw} kW solar system and {batt_kwh} kWh battery "
69
+ f"earns {coins_total:.1f} GridCoins valued at ${coin_dollars:.2f} annually. "
70
+ f"Their annual electricity bill is ${bill_der:,.0f} (DER) compared to ${bill_nonder:,.0f} (Non-DER), "
71
+ f"with a payback period of {payback:.1f} years.\n\n"
72
+ "Explain the financial benefits clearly and concisely. Use proper sentence structure with spaces between words."
73
+ )
74
+
75
+ resp = openai.ChatCompletion.create(
76
+ model="gpt-4o",
77
+ messages=[
78
+ {"role": "system", "content": "You are a helpful energy policy assistant. Provide clear, concise summaries."},
79
+ {"role": "user", "content": prompt}
80
+ ],
81
+ max_tokens=150,
82
+ temperature=0.7
83
+ )
84
+ ai_summary = resp.choices[0].message.content.strip()
85
+ except Exception as e:
86
+ ai_summary = f"AI summary unavailable: {e}"
87
+ else:
88
+ ai_summary = "Set OPENAI_API_KEY to enable AI summaries."
89
+
90
+ return (
91
+ gridcoins_earned,
92
+ gridcoin_value,
93
+ non_der_bill,
94
+ der_bill,
95
+ bill_savings,
96
+ payback_period,
97
+ ai_summary
98
+ )
99
+
100
+
101
+ # Custom CSS for better styling
102
+ custom_css = """
103
+ .gradio-container {
104
+ font-family: 'Inter', sans-serif;
105
+ }
106
+ .output-text {
107
+ font-size: 1.2rem;
108
+ font-weight: 600;
109
+ }
110
+ """
111
+
112
+ # Create Gradio interface
113
+ with gr.Blocks(css=custom_css, title="GridCoin Calculator", theme=gr.themes.Soft()) as demo:
114
+ gr.Markdown("# ⚡ GridCoin — DER vs Non-DER Dashboard")
115
+
116
+ with gr.Row():
117
+ # Left column - Inputs
118
+ with gr.Column(scale=1):
119
+ gr.Markdown("### ⚙️ System Configuration")
120
+
121
+ with gr.Row():
122
+ with gr.Column():
123
+ owner = gr.Dropdown(
124
+ choices=["DER Homeowner", "Non-DER Homeowner"],
125
+ value="DER Homeowner",
126
+ label="Household type"
127
+ )
128
+ pv_kw = gr.Number(
129
+ value=7.0,
130
+ minimum=0.0,
131
+ maximum=50.0,
132
+ step=0.5,
133
+ label="Solar size (kW)"
134
+ )
135
+ batt_kwh = gr.Number(
136
+ value=0.0,
137
+ minimum=0.0,
138
+ maximum=40.0,
139
+ step=0.5,
140
+ label="Battery (kWh)"
141
+ )
142
+
143
+ with gr.Column():
144
+ annual_load = gr.Number(
145
+ value=12000,
146
+ minimum=500,
147
+ maximum=30000,
148
+ label="Annual use (kWh)"
149
+ )
150
+ retail_rate = gr.Number(
151
+ value=0.13,
152
+ minimum=0.01,
153
+ maximum=1.0,
154
+ step=0.001,
155
+ label="Retail rate ($/kWh)"
156
+ )
157
+ upfront = gr.Number(
158
+ value=25000,
159
+ minimum=0,
160
+ maximum=100000,
161
+ label="System cost ($)"
162
+ )
163
+
164
+ gr.Markdown("---")
165
+ gr.Markdown("### 💰 Policy & GridCoin Settings")
166
+
167
+ with gr.Row():
168
+ with gr.Column():
169
+ exp_actual = gr.Number(
170
+ value=0.075,
171
+ minimum=0.0,
172
+ maximum=1.0,
173
+ step=0.001,
174
+ label="Export credit ($/kWh)"
175
+ )
176
+ exp_evc = gr.Number(
177
+ value=0.123,
178
+ minimum=0.0,
179
+ maximum=1.0,
180
+ step=0.001,
181
+ label="EVC Bonus ($/kWh)"
182
+ )
183
+ grid_fee = gr.Number(
184
+ value=4.0,
185
+ minimum=0.0,
186
+ maximum=20.0,
187
+ label="Grid fee ($/kW-mo)"
188
+ )
189
+
190
+ with gr.Column():
191
+ peak_start = gr.Number(
192
+ value=17,
193
+ minimum=0,
194
+ maximum=23,
195
+ label="Peak start (hr)"
196
+ )
197
+ peak_end = gr.Number(
198
+ value=21,
199
+ minimum=0,
200
+ maximum=23,
201
+ label="Peak end (hr)"
202
+ )
203
+ coin_value = gr.Number(
204
+ value=0.05,
205
+ minimum=0.0,
206
+ maximum=1.0,
207
+ step=0.001,
208
+ label="GridCoin value ($)"
209
+ )
210
+
211
+ gr.Markdown("---")
212
+ gr.Markdown("### 🔋 GridCoin Calculator")
213
+
214
+ with gr.Row():
215
+ with gr.Column():
216
+ peak_fraction = gr.Slider(
217
+ minimum=0.0,
218
+ maximum=1.0,
219
+ value=0.30,
220
+ step=0.05,
221
+ label="Peak export share"
222
+ )
223
+
224
+ with gr.Column():
225
+ dr_kwh = gr.Number(
226
+ value=0.0,
227
+ minimum=0.0,
228
+ maximum=5000.0,
229
+ label="DR savings (kWh)"
230
+ )
231
+
232
+ calculate_btn = gr.Button("Calculate Results", variant="primary", size="lg")
233
+
234
+ # Right column - Outputs
235
+ with gr.Column(scale=1):
236
+ gr.Markdown("### 📊 Results Dashboard")
237
+
238
+ with gr.Row():
239
+ gridcoins_earned = gr.Textbox(label="GridCoins Earned", interactive=False)
240
+ gridcoin_value = gr.Textbox(label="GridCoin Value", interactive=False)
241
+
242
+ gr.Markdown("---")
243
+ gr.Markdown("### 💵 Annual Bill Comparison")
244
+
245
+ with gr.Row():
246
+ non_der_bill = gr.Textbox(label="Non-DER Bill", interactive=False)
247
+ der_bill = gr.Textbox(label="DER Bill", interactive=False)
248
+ bill_savings = gr.Textbox(label="Savings", interactive=False)
249
+
250
+ payback_period = gr.Textbox(label="Payback Period", interactive=False)
251
+
252
+ gr.Markdown("---")
253
+ gr.Markdown("### 🤖 AI Analysis")
254
+
255
+ ai_summary = gr.Textbox(
256
+ label="",
257
+ lines=5,
258
+ interactive=False,
259
+ show_label=False
260
+ )
261
+
262
+ # Connect the calculate button to the function
263
+ calculate_btn.click(
264
+ fn=calculate_gridcoin,
265
+ inputs=[
266
+ owner, pv_kw, batt_kwh, annual_load, retail_rate, upfront,
267
+ exp_actual, exp_evc, grid_fee, peak_start, peak_end, coin_value,
268
+ peak_fraction, dr_kwh
269
+ ],
270
+ outputs=[
271
+ gridcoins_earned, gridcoin_value, non_der_bill, der_bill,
272
+ bill_savings, payback_period, ai_summary
273
+ ]
274
+ )
275
+
276
+ # Auto-calculate on load
277
+ demo.load(
278
+ fn=calculate_gridcoin,
279
+ inputs=[
280
+ owner, pv_kw, batt_kwh, annual_load, retail_rate, upfront,
281
+ exp_actual, exp_evc, grid_fee, peak_start, peak_end, coin_value,
282
+ peak_fraction, dr_kwh
283
+ ],
284
+ outputs=[
285
+ gridcoins_earned, gridcoin_value, non_der_bill, der_bill,
286
+ bill_savings, payback_period, ai_summary
287
+ ]
288
+ )
289
+
290
+ if __name__ == "__main__":
291
+ demo.launch(share=False, server_name="127.0.0.1", server_port=7860)