import os import math import streamlit as st import pandas as pd from pathlib import Path from dotenv import load_dotenv load_dotenv() st.set_page_config(page_title="GridCoin Calculator", layout="wide", page_icon="⚡") st.markdown(""" """, unsafe_allow_html=True) st.title("GridCoin — DER vs Non-DER Dashboard") left_col, right_col = st.columns([1, 1]) with left_col: st.subheader("⚙️ System Configuration") c1, c2 = st.columns(2) with c1: owner = st.selectbox("Household type", ["DER Homeowner", "Non-DER Homeowner"]) pv_kw = st.number_input("Solar size (kW)", 0.0, 50.0, 7.0, step=0.5) batt_kwh = st.number_input("Battery (kWh)", 0.0, 40.0, 0.0, step=0.5) with c2: annual_load = st.number_input("Annual use (kWh)", 500, 30000, 12000) retail_rate = st.number_input("Retail rate ($/kWh)", 0.01, 1.0, 0.13, format="%.3f") upfront = st.number_input("System cost ($)", 0, 100000, 25000) st.markdown("---") st.subheader("💰 Policy & GridCoin Settings") c3, c4 = st.columns(2) with c3: exp_actual = st.number_input("Export credit ($/kWh)", 0.0, 1.0, 0.075, format="%.3f") exp_evc = st.number_input("EVC Bonus ($/kWh)", 0.0, 1.0, 0.123, format="%.3f") grid_fee = st.number_input("Grid fee ($/kW-mo)", 0.0, 20.0, 4.0) with c4: peak_start = st.number_input("Peak start (hr)", 0, 23, 17) peak_end = st.number_input("Peak end (hr)", 0, 23, 21) coin_value = st.number_input("GridCoin value ($)", 0.0, 1.0, 0.05, format="%.3f") st.markdown("---") st.subheader("🔋 GridCoin Calculator") c5, c6 = st.columns(2) with c5: peak_fraction = st.slider("Peak export share", 0.0, 1.0, 0.30, 0.05) with c6: dr_kwh = st.number_input("DR savings (kWh)", 0.0, 5000.0, 0.0) pv_yield = pv_kw * 1250 self_use_ratio = 0.65 self_used = pv_yield * self_use_ratio exports = max(0, pv_yield - self_used - batt_kwh * 200) peak_exports = exports * peak_fraction coins_peak = peak_exports * 1.0 coins_dr = dr_kwh * 0.5 coins_total = coins_peak + coins_dr coin_dollars = coins_total * coin_value bill_nonder = annual_load * retail_rate imports_der = max(0, annual_load - self_used) exp_credit = exports * exp_actual fee_der = grid_fee * pv_kw * 12 bill_der = imports_der * retail_rate + fee_der - exp_credit - coin_dollars savings = max(0, bill_nonder - bill_der) payback = upfront / savings if savings > 0 else math.inf with right_col: st.subheader("📊 Results Dashboard") m1, m2 = st.columns(2) m1.metric("GridCoins Earned", f"{coins_total:,.1f}") m2.metric("GridCoin Value", f"${coin_dollars:,.2f}") st.markdown("---") st.markdown("### 💵 Annual Bill Comparison") b1, b2, b3 = st.columns(3) b1.metric("Non-DER Bill", f"${bill_nonder:,.0f}") b2.metric("DER Bill", f"${bill_der:,.0f}", delta=f"${bill_der-bill_nonder:,.0f}") b3.metric("Payback Period", f"{payback:.1f} yrs" if payback != math.inf else "N/A")