OPT-34: the night charge keeps its level when the kept forecast ends #222

Merged
admin merged 5 commits from OPT-34 into release/1.0 2026-11-01 00:19:10 +01:00
Owner

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.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC

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
admin added 1 commit 2026-10-31 17:00:42 +01:00
OPT-34: the night charge keeps its level when the kept forecast ends
checks / unit (pull_request) Successful in 18m59s
infra-pin / fresh (pull_request) Successful in 1s
412e47f111
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
admin added 1 commit 2026-10-31 19:17:24 +01:00
OPT-34 round 2: the latch follows the plan, up or down, and drops what left it
checks / unit (pull_request) Successful in 18m37s
infra-pin / fresh (pull_request) Successful in 1s
eee7616022
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
admin added 1 commit 2026-10-31 20:50:04 +01:00
OPT-34 review: test that a battery leaving the plan leaves the latch
checks / unit (pull_request) Failing after 19m32s
infra-pin / fresh (pull_request) Successful in 1s
8f0af9f318
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>
admin added 1 commit 2026-10-31 21:19:02 +01:00
OPT-34 review: read the inverter in part 4 with a default
checks / unit (pull_request) Successful in 23m57s
infra-pin / fresh (pull_request) Successful in 2s
57b0eb2f20
test_named_absence.py flagged next() without a default (CI run 1473).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Owner

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
admin added 1 commit 2026-10-31 23:04:39 +01:00
OPT-34 round 3: the latch ends on time, with the run, with the mode, and with the night
checks / unit (pull_request) Successful in 20m15s
infra-pin / fresh (pull_request) Successful in 1s
bb57a85b35
- 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.0 2026-11-01 00:19:10 +01:00
Author
Owner

OPT-34 re-review (round 3, bb57a85): PASS, merged into release/1.0 as 8afadbdd9a. 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).

**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).
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#222