OPT-34: the night charge keeps its level when the kept forecast ends (card 6ae5a8374232fa380cc57b40; from OPT-27 F-1).
Defect. Sensors silent from 17:05: the kept figure ended at 03:00, mid-charge, and Leftover solar's level went with it (rig: A 49.8 % at 07:00 against 79.9 % fresh).
Change (goodwe_controller/)
A night grid charge that has started keeps its planned level when the forecast goes (main.py_latch_charge, plan_targets, weather_held; store key night_charge_latch). A fresh figure still moves the level.
The evening's tomorrow figure is today's until 06:00 local (solarfc.pystand_in, _bell_start), not midnight + 3 h.
For that case up to 15 h old, only if it was at most 12 h old at midnight (KEPT_MORNING_MAX_AGE_S).
New screen line while a latched battery is below its level (homeview.py, EN/NL). "kept for tonight" unchanged.
DECISIONS/OPT-34, OPT-27 note updated, DOCS line, one CHANGELOG line. No version change.
Tests: test_opt34.py (whole nights through the real cycle; red on release/1.0, green here), test_opt27.py / test_modes_p4.py adjusted to the new window and the kept level.
OPT-34: the night charge keeps its level when the kept forecast ends (card 6ae5a8374232fa380cc57b40; from OPT-27 F-1).
**Defect.** Sensors silent from 17:05: the kept figure ended at 03:00, mid-charge, and Leftover solar's level went with it (rig: A 49.8 % at 07:00 against 79.9 % fresh).
**Change** (`goodwe_controller/`)
1. A night grid charge that has started keeps its planned level when the forecast goes (`main.py` `_latch_charge`, `plan_targets`, `weather_held`; store key `night_charge_latch`). A fresh figure still moves the level.
2. The evening's tomorrow figure is today's until 06:00 local (`solarfc.py` `stand_in`, `_bell_start`), not midnight + 3 h.
3. For that case up to 15 h old, only if it was at most 12 h old at midnight (`KEPT_MORNING_MAX_AGE_S`).
4. New screen line while a latched battery is below its level (`homeview.py`, EN/NL). "kept for tonight" unchanged.
5. DECISIONS/OPT-34, OPT-27 note updated, DOCS line, one CHANGELOG line. No version change.
Tests: `test_opt34.py` (whole nights through the real cycle; red on release/1.0, green here), `test_opt27.py` / `test_modes_p4.py` adjusted to the new window and the kept level.
Not merged; no tag.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
With the forecast sensors silent from 17:05 the kept evening figure ended at
midnight + 3 h, in the middle of the night grid charge, and Leftover solar's
planned level went with it (rig: A 49.8 % against 79.9 %).
- A night grid charge that has started keeps its planned level when the forecast
goes (Controller._latch_charge, store key night_charge_latch), and the narrow
price gap with it (weather_held). A fresh figure still moves the level.
- The evening's tomorrow figure is today's until the bell starts (06:00 local),
up to 15 h old but only if it was usable at midnight (solarfc.Hold.stand_in).
- Screen: "No solar forecast now. The charge under way goes on to its planned
level." (EN/NL) while a latched battery is below its level.
- test_opt34.py (whole nights through the real control cycle, mutants), test_opt27
and test_modes_p4 adjusted to the new window and the kept level.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
While a forecast is present and the cheap run holds, the night-charge latch is
rebuilt from the plan: a latched battery takes its current level whatever its
role this tick (a fresh figure may lower it below the SoC), one that left the
plan is dropped, a new one comes in only while it charges from the grid.
Test: a fresh brighter figure lowers A below its SoC, the sensors go quiet, A
does not charge back up. CHANGELOG summary says two fixes.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
test_opt34.py part 4 drives Controller._latch_charge() directly: a battery
that leaves the plan is dropped at once, does not rejoin while nothing
charges, an empty latch is cleared from the store, and the screen says the
charge goes on only while the latched battery is below its level. Catches
two reviewer mutants that survived the round-2 tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OPT-34 review (Opus): CHANGES REQUESTED. Not merged. Reviewed eee7616. The reviewer pushed tests only: 8f0af9f, then 57b0eb2 (CI 1475 checks/unit success, 1476 infra-pin success). Local suite 93/93 on eee7616 and on 57b0eb2.
Findings:
F1 Medium: app/main.py:2410 drops an expired latch only when no cheap run holds. plan_targets() (:2387) and _load_latch() (:224) never check until. So if the add-on is down when the latch ends and comes back inside a later cheap run with no forecast, the old latch comes back. Shown: a latch from 2 Nov (A 80 %) in the store, sensors unavailable all night on 3 Nov. A and B grid-charge 10 -> 25 % by 23:30 with the narrow gap, and the screen says "the charge under way goes on". Without the stale latch they stay at 10 % ("no_spread"). Fix (checked, test_opt34 stays green): drop the latch when now >= until whatever the run state, and make plan_targets() ignore an expired latch. Add a test.
F2 Low: app/homeview.py:538_latched_below() does not ask whether a run holds. From 07:00 to 07:15 (the grace slot) the Batteries line says "The charge under way goes on to its planned level" while A does not charge (Why "expensive"). UX-53.
F3 Low: app/main.py:2424 keeps a latched battery when there is no forecast even after its mode or use changes on the page. weather_held() then keeps the narrow gap for the other batteries' runs. Suggestion: drop batteries whose mode no longer plans a charge.
F4 Info: the latch has no night bound (it chains over runs with gaps of 15 minutes or less; with dynamic prices it is bounded only by that).
F5 Info: the dev's digests were made before round 2. I re-ran all 25 cases base deee98d against eee7616: 22 identical, 3 dark-silent cases changed by design (epex state and hourly now equal the fresh run).
Test added (57b0eb2): test_opt34 part 4 drives _latch_charge() directly. A battery that leaves the plan is dropped, does not rejoin while nothing charges, an empty latch is cleared from the store, and "latched" shows only while the battery is below its level. It catches 2 reviewer mutants that survived round 2. Dev mutants 1, 2, 5 and 11 re-run: all red.
Q2: keep "15 h and at most 12 h old at midnight". It is the same 12 h test on both sides of 00:00, so nothing comes back and nothing drops at midnight. The 15 h limit only bites for reads between 12:00 and 15:00.
Q3: the Forecast tab text "missing or too old. The levels return when it is back." is true from 06:00 to 07:00, so it is unchanged.
Report: reports/OPT-34-review-report.md
**OPT-34 review (Opus): CHANGES REQUESTED. Not merged.** Reviewed eee7616. The reviewer pushed tests only: 8f0af9f, then 57b0eb2 (CI 1475 checks/unit success, 1476 infra-pin success). Local suite 93/93 on eee7616 and on 57b0eb2.
Findings:
- **F1 Medium**: `app/main.py:2410` drops an expired latch only when no cheap run holds. `plan_targets()` (:2387) and `_load_latch()` (:224) never check `until`. So if the add-on is down when the latch ends and comes back inside a later cheap run with no forecast, the old latch comes back. Shown: a latch from 2 Nov (A 80 %) in the store, sensors unavailable all night on 3 Nov. A and B grid-charge 10 -> 25 % by 23:30 with the narrow gap, and the screen says "the charge under way goes on". Without the stale latch they stay at 10 % ("no_spread"). Fix (checked, test_opt34 stays green): drop the latch when `now >= until` whatever the run state, and make `plan_targets()` ignore an expired latch. Add a test.
- **F2 Low**: `app/homeview.py:538` `_latched_below()` does not ask whether a run holds. From 07:00 to 07:15 (the grace slot) the Batteries line says "The charge under way goes on to its planned level" while A does not charge (Why "expensive"). UX-53.
- **F3 Low**: `app/main.py:2424` keeps a latched battery when there is no forecast even after its mode or use changes on the page. `weather_held()` then keeps the narrow gap for the other batteries' runs. Suggestion: drop batteries whose mode no longer plans a charge.
- F4 Info: the latch has no night bound (it chains over runs with gaps of 15 minutes or less; with dynamic prices it is bounded only by that).
- F5 Info: the dev's digests were made before round 2. I re-ran all 25 cases base deee98d against eee7616: 22 identical, 3 dark-silent cases changed by design (epex state and hourly now equal the fresh run).
Test added (57b0eb2): test_opt34 part 4 drives `_latch_charge()` directly. A battery that leaves the plan is dropped, does not rejoin while nothing charges, an empty latch is cleared from the store, and "latched" shows only while the battery is below its level. It catches 2 reviewer mutants that survived round 2. Dev mutants 1, 2, 5 and 11 re-run: all red.
Q2: keep "15 h and at most 12 h old at midnight". It is the same 12 h test on both sides of 00:00, so nothing comes back and nothing drops at midnight. The 15 h limit only bites for reads between 12:00 and 15:00.
Q3: the Forecast tab text "missing or too old. The levels return when it is back." is true from 06:00 to 07:00, so it is unchanged.
Report: reports/OPT-34-review-report.md
- F1: an expired latch is dropped whatever the run state; plan_targets() and the
store loader ignore one that has ended (no stale latch after a restart).
- F2: the "charge goes on" line only while a cheap run is on.
- F3: a battery that is off or no longer Leftover solar leaves the latch.
- F4: a run carries the latch on only if it starts by the bell start (06:00
local) after the latch began (manager's call, 2026-10-31).
Tests: test_opt34 scenarios stale/stale_live and part 5; test_modes_p4 asks at a
moment inside the latch.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
admin
merged commit 8afadbdd9a into release/1.02026-11-01 00:19:10 +01:00
**OPT-34 re-review (round 3, bb57a85): PASS, merged** into release/1.0 as 8afadbdd9a450996c997ebd456c9a15f3d5ae299. CI 1477/1478 green.
- F1-F4 are fixed. The F1 owner-shape night now ends A and B at 10 %.
- The night bound is right across DST and does not cut a 22:00-07:00 night short.
- 7 mutants, all red.
- Local suite 93/93 green.
- 6 spot-check digests are identical to base.
Details: reports/OPT-34-review-report.md (Re-review).
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-34: the night charge keeps its level when the kept forecast ends (card 6ae5a8374232fa380cc57b40; from OPT-27 F-1).
Defect. Sensors silent from 17:05: the kept figure ended at 03:00, mid-charge, and Leftover solar's level went with it (rig: A 49.8 % at 07:00 against 79.9 % fresh).
Change (
goodwe_controller/)main.py_latch_charge,plan_targets,weather_held; store keynight_charge_latch). A fresh figure still moves the level.solarfc.pystand_in,_bell_start), not midnight + 3 h.KEPT_MORNING_MAX_AGE_S).homeview.py, EN/NL). "kept for tonight" unchanged.Tests:
test_opt34.py(whole nights through the real cycle; red on release/1.0, green here),test_opt27.py/test_modes_p4.pyadjusted to the new window and the kept level.Not merged; no tag.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
OPT-34 review (Opus): CHANGES REQUESTED. Not merged. Reviewed
eee7616. The reviewer pushed tests only:8f0af9f, then57b0eb2(CI 1475 checks/unit success, 1476 infra-pin success). Local suite 93/93 oneee7616and on57b0eb2.Findings:
app/main.py:2410drops an expired latch only when no cheap run holds.plan_targets()(:2387) and_load_latch()(:224) never checkuntil. So if the add-on is down when the latch ends and comes back inside a later cheap run with no forecast, the old latch comes back. Shown: a latch from 2 Nov (A 80 %) in the store, sensors unavailable all night on 3 Nov. A and B grid-charge 10 -> 25 % by 23:30 with the narrow gap, and the screen says "the charge under way goes on". Without the stale latch they stay at 10 % ("no_spread"). Fix (checked, test_opt34 stays green): drop the latch whennow >= untilwhatever the run state, and makeplan_targets()ignore an expired latch. Add a test.app/homeview.py:538_latched_below()does not ask whether a run holds. From 07:00 to 07:15 (the grace slot) the Batteries line says "The charge under way goes on to its planned level" while A does not charge (Why "expensive"). UX-53.app/main.py:2424keeps a latched battery when there is no forecast even after its mode or use changes on the page.weather_held()then keeps the narrow gap for the other batteries' runs. Suggestion: drop batteries whose mode no longer plans a charge.deee98dagainsteee7616: 22 identical, 3 dark-silent cases changed by design (epex state and hourly now equal the fresh run).Test added (
57b0eb2): test_opt34 part 4 drives_latch_charge()directly. A battery that leaves the plan is dropped, does not rejoin while nothing charges, an empty latch is cleared from the store, and "latched" shows only while the battery is below its level. It catches 2 reviewer mutants that survived round 2. Dev mutants 1, 2, 5 and 11 re-run: all red.Q2: keep "15 h and at most 12 h old at midnight". It is the same 12 h test on both sides of 00:00, so nothing comes back and nothing drops at midnight. The 15 h limit only bites for reads between 12:00 and 15:00.
Q3: the Forecast tab text "missing or too old. The levels return when it is back." is true from 06:00 to 07:00, so it is unchanged.
Report: reports/OPT-34-review-report.md
OPT-34 re-review (round 3,
bb57a85): PASS, merged into release/1.0 as8afadbdd9a. CI 1477/1478 green.Details: reports/OPT-34-review-report.md (Re-review).