#!/usr/bin/env python3 """Run the daily 24h-foresight oracle over the full window and write per-hour output.""" from __future__ import annotations import argparse from pathlib import Path from pluginbattery.sim import ( ECOFLOW_STREAM_AC, Battery, apply_nl_tariff, load_hourly, oracle_daily_schedule, simulate, ) # EcoFlow Stream AC retail price (incl. VAT) for payback math. ECOFLOW_STREAM_AC_PRICE_EUR = 699.0 def run(battery: Battery, price_eur: float, data_dir: Path, out_path: Path) -> None: df = load_hourly(data_dir) df = apply_nl_tariff(df) # eur_per_kwh now = consumer price (incl. VAT + tax) print(f"Loaded {len(df)} hours: {df.index[0]} → {df.index[-1]}") print(f"Battery: cap={battery.capacity_kwh} kWh, " f"P_in={battery.max_charge_kw} kW, P_out={battery.max_discharge_kw} kW, " f"η_rt={battery.round_trip_eff:.2f}, allows_export={battery.allows_export}") print(f"Price (incl. VAT) : €{price_eur:.0f}") print(f"Tariff: consumer = EPEX × 1.21 + 0.136 EUR/kWh") print("Solving daily 24h LPs...") schedule = oracle_daily_schedule(df, battery) print("Walking SoC...") out = simulate(df, battery, schedule) out_path.parent.mkdir(parents=True, exist_ok=True) out.to_csv(out_path) cost_no = out["cost_no_battery"].sum() cost_yes = out["cost_with_battery"].sum() savings = out["savings"].sum() cycles = out["discharge_kwh"].sum() / battery.capacity_kwh payback_years = price_eur / savings if savings > 0 else float("inf") print() print(f"Year cost without battery : €{cost_no:8.2f}") print(f"Year cost with battery : €{cost_yes:8.2f}") print(f"Annual savings (consumer) : €{savings:8.2f}") print(f"Equivalent full cycles : {cycles:7.1f}") print(f"Hours simulated : {len(out)}") print(f"Simple payback : {payback_years:6.2f} years") print(f"Output -> {out_path}") def main() -> None: p = argparse.ArgumentParser(description=__doc__) p.add_argument("--data", default="data/raw") p.add_argument("--out", default="data/processed/oracle_daily.csv") p.add_argument("--price", type=float, default=ECOFLOW_STREAM_AC_PRICE_EUR) args = p.parse_args() run(ECOFLOW_STREAM_AC, args.price, Path(args.data), Path(args.out)) if __name__ == "__main__": main()