Executed battery-dispatch run over the full 2018-2020 Attachment 2 series (225.9s, 1096 rolling-horizon windows) and committed the results: outputs/ (dispatch.csv, annual/monthly summaries, summary.json, four figures), README.md (setup, run instructions, assumptions, the one-paragraph approach summary) and RESULTS.md (headline numbers, per-year table, charts, commentary). The full run surfaced three real issues, all fixed rather than papered over: - validate_schedule's soc_within_bounds check used a fixed 1e-6 MWh tolerance for the "state of charge below zero" case, while its sibling soc_matches_power_flows check already scales its tolerance with sqrt(n) for the same reason (CBC's own solver precision accumulating over a long cumulative sum). Over 52,608 half-hours this false-failed on a 5.1e-6 MWh solver-noise dip, not a real violation. Scaled it the same way. - cli.py's summary printed net_of_opex_gbp under the label "Less fixed opex", so the terminal output showed the post-opex profit (£193k) where a reader would expect the opex figure itself (£15k). Split into two correctly-labelled lines. - plots.py's monthly revenue chart stacked Market 1 (always negative here) and Market 2 (always positive) with a single running `bottom`, which is only correct for same-signed series: Market 2's bar completely overlapped and painted over Market 1's, hiding the -£297k Market 1 loss entirely. Now accumulates positive and negative contributions on separate baselines and marks the net. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"solver": {
|
||||
"commit_hours": 24,
|
||||
"degradation_cost_gbp_per_mwh": 0.0,
|
||||
"milp_fallbacks": 1096,
|
||||
"mode": "auto",
|
||||
"window_hours": 48,
|
||||
"windows": 1096
|
||||
},
|
||||
"summary": {
|
||||
"average_captured_spread_gbp_per_mwh": 15.816025,
|
||||
"capacity_end_mwh": 3.861279,
|
||||
"capacity_retained_fraction": 0.96532,
|
||||
"capacity_start_mwh": 4.0,
|
||||
"charged_market_1_mwh": 11297.137749,
|
||||
"charged_market_2_mwh": 3305.034144,
|
||||
"cycle_budget": 5000.0,
|
||||
"cycle_budget_used_fraction": 0.693603,
|
||||
"days": 1096.0,
|
||||
"discharged_market_1_mwh": 1952.341071,
|
||||
"discharged_market_2_mwh": 11226.119067,
|
||||
"end": "2020-12-31 23:30:00",
|
||||
"energy_charged_from_grid_mwh": 14602.171893,
|
||||
"energy_discharged_to_grid_mwh": 13178.460138,
|
||||
"equivalent_full_cycles": 3468.015826,
|
||||
"equivalent_full_cycles_per_year": 1155.741588,
|
||||
"fixed_opex_gbp": 15003.422313,
|
||||
"gross_profit_per_year_gbp": 69461.10309,
|
||||
"gross_trading_profit_gbp": 208430.852803,
|
||||
"half_hours": 52608,
|
||||
"implied_life_years": 4.326227,
|
||||
"net_of_opex_gbp": 193427.430489,
|
||||
"profit_market_1_gbp": -297418.057114,
|
||||
"profit_market_2_gbp": 505848.909916,
|
||||
"profit_share_market_1": -1.426939,
|
||||
"profit_share_market_2": 2.426939,
|
||||
"round_trip_efficiency": 0.9025,
|
||||
"start": "2018-01-01 00:00:00"
|
||||
},
|
||||
"validation": {
|
||||
"checks": {
|
||||
"charge_within_limit": true,
|
||||
"discharge_within_limit": true,
|
||||
"hourly_commitment_constant": true,
|
||||
"no_simultaneous_charge_discharge": true,
|
||||
"revenue_matches_prices_and_powers": true,
|
||||
"soc_matches_power_flows": true,
|
||||
"soc_within_bounds": true
|
||||
},
|
||||
"details": {
|
||||
"hours_checked": 26304.0,
|
||||
"max_hourly_commitment_gap_mw": 0.0,
|
||||
"max_revenue_error_gbp": 0.0,
|
||||
"max_soc_above_capacity_mwh": 0.000413531614,
|
||||
"max_soc_below_zero_mwh": 5.101628e-06,
|
||||
"max_soc_drift_mwh": 5.14322e-06,
|
||||
"max_total_charge_mw": 2.00000005,
|
||||
"max_total_discharge_mw": 2.0000001,
|
||||
"simultaneous_half_hours": 0.0
|
||||
},
|
||||
"failures": [],
|
||||
"ok": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user