Spaces:
Build error
Build error
| import gradio as gr | |
| TITLE = "EV Home Charging: Time & Cost Estimator" | |
| DESCRIPTION = ( | |
| "Calculate how long it takes to charge your EV at home and how much it costs. " | |
| "Enter your battery size, current/target state-of-charge (SoC), charger power, " | |
| "efficiency, and your electricity price." | |
| ) | |
| def compute(ev_battery_kwh: float, soc_current: float, soc_target: float, | |
| power_choice: str, custom_power_kw: float, | |
| efficiency_pct: float, | |
| pricing_mode: str, | |
| flat_rate_rs_per_kwh: float, | |
| peak_rate_rs_per_kwh: float, | |
| off_rate_rs_per_kwh: float, | |
| peak_share_pct: float): | |
| # sanitize inputs | |
| soc_current = max(0.0, min(100.0, soc_current)) | |
| soc_target = max(0.0, min(100.0, soc_target)) | |
| if soc_target <= soc_current: | |
| return ( | |
| "Target SoC must be greater than current SoC.", | |
| None, None, None, None | |
| ) | |
| efficiency = max(1e-3, min(100.0, efficiency_pct)) / 100.0 | |
| # determine charger power (kW) | |
| if power_choice == "2.3 kW (10A, single-phase)": | |
| charger_kw = 2.3 | |
| elif power_choice == "3.3 kW (15A, single-phase)": | |
| charger_kw = 3.3 | |
| elif power_choice == "7.4 kW (32A, single-phase)": | |
| charger_kw = 7.4 | |
| elif power_choice == "11 kW (3-phase)": | |
| charger_kw = 11.0 | |
| elif power_choice == "22 kW (3-phase)": | |
| charger_kw = 22.0 | |
| else: # custom | |
| charger_kw = max(0.1, custom_power_kw) | |
| # energy needed on battery side (kWh) | |
| energy_battery_kwh = ev_battery_kwh * (soc_target - soc_current) / 100.0 | |
| # account for charging losses -> wall energy | |
| energy_wall_kwh = energy_battery_kwh / efficiency | |
| # time (hours) | |
| charge_hours = energy_wall_kwh / charger_kw | |
| # price calculation | |
| if pricing_mode == "Flat rate": | |
| cost_rs = energy_wall_kwh * max(0.0, flat_rate_rs_per_kwh) | |
| breakdown = ( | |
| f"Flat: {energy_wall_kwh:.2f} kWh × ₹{flat_rate_rs_per_kwh:.2f}/kWh" | |
| ) | |
| else: | |
| peak_share = max(0.0, min(100.0, peak_share_pct)) / 100.0 | |
| blended_rate = peak_share * max(0.0, peak_rate_rs_per_kwh) + (1 - peak_share) * max(0.0, off_rate_rs_per_kwh) | |
| cost_rs = energy_wall_kwh * blended_rate | |
| breakdown = ( | |
| f"ToD blended rate: peak {peak_share*100:.0f}% at ₹{peak_rate_rs_per_kwh:.2f}/kWh, " | |
| f"off-peak {100-peak_share*100:.0f}% at ₹{off_rate_rs_per_kwh:.2f}/kWh" | |
| ) | |
| summary = ( | |
| f"Battery energy added: {energy_battery_kwh:.2f} kWh | |
| " | |
| f"Wall energy consumed (incl. losses): {energy_wall_kwh:.2f} kWh | |
| " | |
| f"Estimated charging time: {charge_hours:.2f} hours (at {charger_kw:.2f} kW) | |
| " | |
| f"Estimated session cost: ₹{cost_rs:.2f} | |
| " | |
| f"Pricing: {breakdown}" | |
| ) | |
| # structured outputs | |
| return ( | |
| summary, | |
| energy_battery_kwh, | |
| energy_wall_kwh, | |
| charge_hours, | |
| cost_rs | |
| ) | |
| with gr.Blocks(title=TITLE) as demo: | |
| gr.Markdown(f"# {TITLE} | |
| {DESCRIPTION}") | |
| with gr.Row(): | |
| with gr.Column(): | |
| ev_battery_kwh = gr.Number(label="Battery capacity (kWh)", value=50.0, precision=2) | |
| soc_current = gr.Slider(label="Current SoC (%)", minimum=0, maximum=100, value=20, step=1) | |
| soc_target = gr.Slider(label="Target SoC (%)", minimum=1, maximum=100, value=80, step=1) | |
| with gr.Column(): | |
| power_choice = gr.Radio( | |
| label="Home charger power", | |
| choices=[ | |
| "2.3 kW (10A, single-phase)", | |
| "3.3 kW (15A, single-phase)", | |
| "7.4 kW (32A, single-phase)", | |
| "11 kW (3-phase)", | |
| "22 kW (3-phase)", | |
| "Custom (kW)" | |
| ], | |
| value="7.4 kW (32A, single-phase)" | |
| ) | |
| custom_power_kw = gr.Number(label="Custom power (kW)", value=3.5, precision=2) | |
| efficiency_pct = gr.Slider(label="Charging efficiency (%)", minimum=70, maximum=100, value=90, step=1) | |
| with gr.Row(): | |
| with gr.Column(): | |
| pricing_mode = gr.Radio(label="Pricing mode", choices=["Flat rate", "Time-of-Day (ToD)"] , value="Flat rate") | |
| flat_rate = gr.Number(label="Flat rate (₹/kWh)", value=7.00, precision=2) | |
| with gr.Column(): | |
| peak_rate = gr.Number(label="Peak rate (₹/kWh)", value=8.50, precision=2, visible=False) | |
| off_rate = gr.Number(label="Off-peak rate (₹/kWh)", value=6.00, precision=2, visible=False) | |
| peak_share = gr.Slider(label="Share of charging during peak (%)", minimum=0, maximum=100, value=30, step=1, visible=False) | |
| btn = gr.Button("Estimate") | |
| summary = gr.Textbox(label="Results", lines=6) | |
| energy_battery = gr.Number(label="Battery energy added (kWh)") | |
| energy_wall = gr.Number(label="Wall energy consumed (kWh)") | |
| time_hours = gr.Number(label="Charging time (hours)") | |
| cost_rs = gr.Number(label="Session cost (₹)") | |
| def toggle_inputs(pricing_mode): | |
| show_tod = pricing_mode == "Time-of-Day (ToD)" | |
| return ( | |
| gr.update(visible=show_tod), | |
| gr.update(visible=show_tod), | |
| gr.update(visible=show_tod) | |
| ) | |
| pricing_mode.change(toggle_inputs, inputs=[pricing_mode], outputs=[peak_rate, off_rate, peak_share]) | |
| btn.click( | |
| compute, | |
| inputs=[ev_battery_kwh, soc_current, soc_target, power_choice, custom_power_kw, efficiency_pct, | |
| pricing_mode, flat_rate, peak_rate, off_rate, peak_share], | |
| outputs=[summary, energy_battery, energy_wall, time_hours, cost_rs] | |
| ) | |
| gr.Markdown(""" | |
| ### Notes | |
| - **Charging efficiency** accounts for AC charging losses (cable, converter, battery). Typical values are 88–95%. | |
| - **Home charger power** is the sustained AC power delivered to the car. Real-world values may vary due to voltage, wiring, and thermal limits. | |
| - **Tariffs** vary by state/utility and may be slab-based or ToD. Use your latest bill for accurate rates. | |
| - **This tool estimates** session time & cost; it does not model tapering at very high SoC. | |
| """) | |
| if __name__ == "__main__": | |
| demo.launch() | |