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.
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
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
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
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.
Medium, fixed in ae0cd54.app/ui_text/en.json:363, nl.json:303solar.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.02026-10-30 02:55:56 +01:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
OPT-23 + OPT-28. Dev report:
reports/OPT-23-28-dev-report.md(not in the repo).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.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.test_opt23_28.py(new); two pinned strings changed intest_modes_p4.pyandtest_ux54.py.🤖 Generated with Claude Code
https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
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 asae0cd54; it merges after its own green run (1448).What I checked, all reproduced by me:
Findings (full report:
reports/OPT-23-28-review-report.md):ae0cd54.app/ui_text/en.json:363,nl.json:303solar.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.app/dayplan.py:238,268,app/dayview.py:50: a state-only span is read fromnow, not fromForecast.at, when the figure was taken.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.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.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 %.test_opt23_28.py:plan_cover()is tested only with no sun before the run: mutation "cover leaves out the share" survives._spread's pass-through is never used fromplan(), 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.