solar/docs/WORKFLOW_VERIFICATION.md

5.2 KiB

Workflow verification: scenario → optimizer → API → frontend

This document describes how scenario parameters flow through the system so you can verify that all fields update accordingly.

1. Scenario definition (scenarios.py)

Each ScenarioProfile defines:

Field Used by Purpose
location_id, weekly_km_target, days, primary_charging_window Preview + Optimizer Plan horizon and EV context
ev_battery_capacity_kwh, ev_consumption_kwh_per_100km, ev_max_charging_power_kw, ev_start_soc, ev_min_morning_soc Preview + Optimizer EV weekly plan and SoC trajectory
solar_kwp Preview + Optimizer Solar production (kWh) and solar-for-EV share
home_battery_capacity_kwh, home_battery_power_kw Optimizer only Home battery SoC trajectory (capacity/power)
household_daily_kwh, household_annual_kwh Preview (household summary) + Optimizer (home battery demand) Household consumption in model

2. API endpoints

GET /trading/scenarios

  • Returns list of ScenarioInfo with all of the above fields.
  • Frontend uses this for scenario selector and for displaying “Scenario definition” (location, km, household kWh, etc.).

POST /trading/scenario/preview

  • Body: { "scenario_id": "…" }.
  • Calls build_weekly_plan_preview(…, household_daily_kwh, household_annual_kwh, solar_kwp_override=scenario.solar_kwp, …).
  • Response includes ev, prices, solar (when available), and household (daily_kwh, weekly_kwh, annual_kwh) when household params are set.
  • Does not call the optimizer; no home battery trajectory here.

POST /trading/scenario/optimized

  • Body: { "scenario_id": "…" }.
  • Calls build_weekly_optimized_plan(…, home_battery_capacity_kwh=scenario.home_battery_capacity_kwh, home_battery_power_kw=scenario.home_battery_power_kw, household_daily_kwh=scenario.household_daily_kwh, …) (plus EV and solar params).
  • Response includes:
    • EV: schedule, daily_summaries, optimized_soc_trajectory, costs, weekly_solar_for_ev_kwh, weekly_cost_with_solar_eur.
    • Home battery (when scenario has capacity and solar data exist): home_battery_capacity_kwh, home_battery_soc_trajectory (per-day: day_index, soc_start, soc_after_charge, soc_end, energy_in_kwh, energy_out_kwh).

POST /trading/weekly-plan/optimized (generic, no scenario)

  • No scenario; home battery params are not sent.
  • Response always includes home_battery_capacity_kwh and home_battery_soc_trajectory; they are null unless you later add optional body params.

3. Optimizer logic (weekly_optimizer.py)

  • EV: Unchanged: price pattern → cheapest hours → schedule and EV optimized_soc_trajectory.
  • Solar coupling: For each day, solar_for_ev = min(expected_solar_kwh, energy_charge_kwh); stored in daily_solar_for_ev_kwh and used for:
    • weekly_solar_for_ev_kwh and weekly_cost_with_solar_eur.
    • Home battery demand: per-day demand = household_daily_kwh + daily_solar_for_ev_kwh[day].
  • Home battery SoC (when home_battery_capacity_kwh > 0 and solar daily data exist):
    • Start SoC default 50%.
    • Per day: solar → charge (capped by headroom and efficiency); then discharge for household + EV solar share.
    • Output: home_battery_soc_trajectory and home_battery_capacity_kwh (the capacity used).

4. Frontend

  • UseCaseView (Real-life example):
    • Loads scenarios from GET /trading/scenarios (all fields, including household_daily_kwh, home_battery_*).
    • Fetches POST /trading/scenario/preview and POST /trading/scenario/optimized for the selected scenario.
    • Displays EV SoC table from optimized_soc_trajectory.
    • Displays Home battery state (SoC) table when optimized.home_battery_soc_trajectory?.length > 0, with capacity from optimized.home_battery_capacity_kwh.
  • WeeklyPlanView: Same response shape; shows home battery table when the optimized response contains home_battery_soc_trajectory (typically only when using a scenario-based endpoint or future body params).

5. Accuracy checks

  • Scenario list: Every scenario includes home_battery_capacity_kwh, home_battery_power_kw, household_daily_kwh, household_annual_kwh; at least one scenario has non-null home battery and household (tests: test_list_scenarios_includes_home_battery_and_household_fields).
  • No-pattern optimized: Response has home_battery_capacity_kwh: null, home_battery_soc_trajectory: null (test: test_weekly_plan_optimized_structure_no_pattern).
  • Scenario optimized: When status 200, response has home_battery_capacity_kwh and home_battery_soc_trajectory; when trajectory is non-empty, its length equals daily_summaries and each row has the required keys (test: test_scenario_optimized_response_shape).

6. How to run verification

From repo root, with backend and DB running:

docker compose run --rm backend python -m pytest tests/test_weekly_optimizer.py tests/test_api_scenarios.py -v

Expected: test_weekly_plan_optimized_structure_no_pattern, test_list_scenarios_*, and test_scenario_optimized_response_shape pass; the two skipped tests remain skipped unless you enable them with a proper async DB.