OPT-23, OPT-28: the day plan counts the sun right, and the night charge covers the expensive-hour shortfall #218

Merged
admin merged 2 commits from OPT-23-28 into release/1.0 2026-10-30 02:55:56 +01:00
Owner

OPT-23 + OPT-28. Dev report: reports/OPT-23-28-dev-report.md (not in the repo).

  • OPT-23: a state-only forecast is read from now for every span (Forecast.between(since=)), so the plan's per-hour sun adds up to the day's figure, today and tomorrow. Hourly splits unchanged. The Forecast tab uses the same call.
  • OPT-28: a Leftover solar battery buys, from the floor, sum over expensive hours of max(0, house - trust x sun) / EFF. Several Leftover solar batteries hold it together by capacity; the ceiling passes the rest on; what none can hold is said (Plan.uncovered_kwh). Cheap hours still fills up; Solar first still never charges from the grid.
  • Screens: Home's grid block, the Batteries line and the mode help (EN + NL) say the level, what it covers, and that Leftover solar buys only what the sun will not give.
  • Tests: test_opt23_28.py (new); two pinned strings changed in test_modes_p4.py and test_ux54.py.
  • Not done: run length (OPT-25).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC

OPT-23 + OPT-28. Dev report: `reports/OPT-23-28-dev-report.md` (not in the repo). - OPT-23: a state-only forecast is read from now for every span (`Forecast.between(since=)`), so the plan's per-hour sun adds up to the day's figure, today and tomorrow. Hourly splits unchanged. The Forecast tab uses the same call. - OPT-28: a Leftover solar battery buys, from the floor, `sum over expensive hours of max(0, house - trust x sun) / EFF`. Several Leftover solar batteries hold it together by capacity; the ceiling passes the rest on; what none can hold is said (`Plan.uncovered_kwh`). Cheap hours still fills up; Solar first still never charges from the grid. - Screens: Home's grid block, the Batteries line and the mode help (EN + NL) say the level, what it covers, and that Leftover solar buys only what the sun will not give. - Tests: `test_opt23_28.py` (new); two pinned strings changed in `test_modes_p4.py` and `test_ux54.py`. - Not done: run length (OPT-25). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
admin added 1 commit 2026-10-29 21:02:31 +01:00
OPT-23, OPT-28: the day plan counts the sun right, and the night charge covers the expensive-hour shortfall
checks / unit (pull_request) Successful in 55m9s
infra-pin / fresh (pull_request) Successful in 1s
995028bc5d
OPT-23: a state-only forecast is read from now for every span
(Forecast.between since=), so the plan's per-hour sun adds up to the day's
figure, today and tomorrow. Hourly splits are unchanged. The Forecast tab
reads spans the same way.

OPT-28: a Leftover solar battery buys, from the floor, the sum over the
expensive hours of max(0, house - trust x sun), / EFF. Several Leftover
solar batteries hold it together by capacity, the ceiling passes the rest
on, and what none can hold is said (Plan.uncovered_kwh). Home's grid block,
the Batteries line and the mode help (EN + NL) say the level, what it
covers, and that Leftover solar buys only what the sun will not give.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
admin added 1 commit 2026-10-29 23:21:36 +01:00
OPT-23-28 review: the unheld-shortfall line says another battery or the grid
checks / unit (pull_request) Successful in 50m6s
infra-pin / fresh (pull_request) Successful in 1s
ae0cd542c0
With A on Leftover solar and B on Cheap hours (the dynamic scenario, and the
owner's planned setup), the line said "The batteries cannot hold it all. The
grid covers N kWh", while B holds a full charge for the same hours. It now
says "The expensive hours need more than Leftover solar can hold. The rest,
N kWh, comes from another battery or the grid." (NL likewise). DOCS,
DECISIONS and the dayplan/homeview docstrings say the same. Text only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
Author
Owner

Opus review of PR #218 (OPT-23 + OPT-28): approve, merge pending CI on ae0cd54.

Reviewed head 995028b. Run 1440 on it is green. I pushed one text fix as ae0cd54; it merges after its own green run (1448).

What I checked, all reproduced by me:

  • Local suite: 87/87 on both shas, offline, with HWSIM.
  • OPT-23: the per-hour sums equal the figure today, tomorrow and on DST days.
  • OPT-28: the shortfall sum, the batteries table, and the rig repro (Leftover + Leftover at 3 450 W ends 03:26 at 48.1 / 53.4 %; Leftover + Solar first at 5 413 W ends 00:51).
  • Digests: the 3 changed cases are all Leftover solar on a state-only forecast. The rest are identical.
  • Mutations: 7 of 9 caught.

Findings (full report: reports/OPT-23-28-review-report.md):

  • Medium, fixed in ae0cd54. app/ui_text/en.json:363, nl.json:303 solar.uncovered: "The grid covers N kWh" was false with A on Leftover solar and B on Cheap hours. That is this test's own "dynamic" scenario, and the owner's planned setup. It now says: "The expensive hours need more than Leftover solar can hold. The rest, N kWh, comes from another battery or the grid." The NL text, DOCS, DECISIONS and the test say the same.
  • Medium, follow-up. app/dayplan.py:238,268, app/dayview.py:50: a state-only span is read from now, not from Forecast.at, when the figure was taken.
    • An hour-old 12:00 figure planned at 13:00 is over-counted by 22 %. A 3 h old one is over-counted by up to 116 %.
    • Daytime plans only. The night plan for tomorrow is not affected. It is far smaller than the bug fixed.
  • Low, follow-up. app/dayplan.py:270-271: lifting sunny hours to the night base over-buys for a house with a high night base (EV or heat pump at night). Example: 29.9 against 7.9 kWh, with a false "not held" figure. No effect on the owner's shape.
  • Low, follow-up. app/dayplan.py:264-273: surplus sun in one expensive hour, or in a gap between runs, is not credited to later hours. A June day/night plan still buys 5.75 kWh that the noon sun would cover. This is the card's formula, so it is not a defect of this PR.
  • Low, into OPT-25. app/homeview.py:475-483: "to 95 %" is shown where the peak room cannot reach it. Leftover + Cheap hours at 3 450 W ends at 76.4 / 76.4 %.
  • Low, tests. test_opt23_28.py:
    • No plan has two expensive runs: mutation "only the first run counts" survives. The code is right; my probe gives 9.31 kWh for morning + evening.
    • plan_cover() is tested only with no sun before the run: mutation "cover leaves out the share" survives.
  • Info.
    • With a site-wide floor and ceiling, _spread's pass-through is never used from plan(), and the batteries fill together, as the owner chose.
    • hold() can leave A about 0.8 kWh under the raw plan. The screen shows the held level, so it stays true to control. Card.
**Opus review of PR #218 (OPT-23 + OPT-28): approve, merge pending CI on `ae0cd54`.** Reviewed head `995028b`. Run 1440 on it is green. I pushed one text fix as `ae0cd54`; it merges after its own green run (1448). What I checked, all reproduced by me: - **Local suite:** 87/87 on both shas, offline, with HWSIM. - **OPT-23:** the per-hour sums equal the figure today, tomorrow and on DST days. - **OPT-28:** the shortfall sum, the batteries table, and the rig repro (Leftover + Leftover at 3 450 W ends 03:26 at 48.1 / 53.4 %; Leftover + Solar first at 5 413 W ends 00:51). - **Digests:** the 3 changed cases are all Leftover solar on a state-only forecast. The rest are identical. - **Mutations:** 7 of 9 caught. Findings (full report: `reports/OPT-23-28-review-report.md`): - **Medium, fixed in `ae0cd54`.** `app/ui_text/en.json:363`, `nl.json:303` `solar.uncovered`: "The grid covers N kWh" was false with A on Leftover solar and B on Cheap hours. That is this test's own "dynamic" scenario, and the owner's planned setup. It now says: "The expensive hours need more than Leftover solar can hold. The rest, N kWh, comes from another battery or the grid." The NL text, DOCS, DECISIONS and the test say the same. - **Medium, follow-up.** `app/dayplan.py:238,268`, `app/dayview.py:50`: a state-only span is read from `now`, not from `Forecast.at`, when the figure was taken. - An hour-old 12:00 figure planned at 13:00 is over-counted by 22 %. A 3 h old one is over-counted by up to 116 %. - Daytime plans only. The night plan for tomorrow is not affected. It is far smaller than the bug fixed. - **Low, follow-up.** `app/dayplan.py:270-271`: lifting sunny hours to the night base over-buys for a house with a high night base (EV or heat pump at night). Example: 29.9 against 7.9 kWh, with a false "not held" figure. No effect on the owner's shape. - **Low, follow-up.** `app/dayplan.py:264-273`: surplus sun in one expensive hour, or in a gap between runs, is not credited to later hours. A June day/night plan still buys 5.75 kWh that the noon sun would cover. This is the card's formula, so it is not a defect of this PR. - **Low, into OPT-25.** `app/homeview.py:475-483`: "to 95 %" is shown where the peak room cannot reach it. Leftover + Cheap hours at 3 450 W ends at 76.4 / 76.4 %. - **Low, tests.** `test_opt23_28.py`: - No plan has two expensive runs: mutation "only the first run counts" survives. The code is right; my probe gives 9.31 kWh for morning + evening. - `plan_cover()` is tested only with no sun before the run: mutation "cover leaves out the share" survives. - **Info.** - With a site-wide floor and ceiling, `_spread`'s pass-through is never used from `plan()`, and the batteries fill together, as the owner chose. - `hold()` can leave A about 0.8 kWh under the raw plan. The screen shows the held level, so it stays true to control. Card.
admin merged commit b6be31286a into release/1.0 2026-10-30 02:55:56 +01:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/goodwe-addon#218