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()