Release 0.21.0: release/1.0 -> master #242

Merged
admin merged 33 commits from release/1.0 into master 2026-11-08 17:27:33 +01:00
Owner

Brings release/1.0 to master as add-on version 0.21.0 (master is 0.20.1, d53f70f, live). Owner go 2026-11-08: "Release". The cut PR #241 (release-0.21.0 -> release/1.0) carries the version bump and the CHANGELOG; this PR is opened by the reviewer after #241 merges, and the owner merges it.

Minor bump, no option change. config.yaml options and schema (86 options), translations/, build.yaml, Dockerfile, requirements.txt and run.sh are identical to master 0.20.1 (git diff d53f70f..b3cfcf2 is empty for them; the cut changes only the version line). app/validate.py changes only to accept the SMA-2 driver keys, which are deliberately not in the schema, so the Supervisor form is unchanged. It is minor because control acts differently when readings come late (SAFETY-128/129) and when the add-on stops (SAFETY-137, SMA-10). SMA-2 and SMA-10 change nothing for a GoodWe site. PR #224 (MAINT-20-2) is not part of this release.

Review and merge of the cut (#241)

  • Cut PR #241 merged into release/1.0 as 16029d7cb81c715e7a3ae53b895f173b265597f5 (parents b3cfcf2, 8e26574), pinned to the reviewed head 8e26574 after a real green checks / unit (pull_request) run 1574. This PR's head is that merge.
  • Independent review (Opus): only config.yaml (version: "0.21.0") and CHANGELOG.md changed; minor is right; options and schema equal master d53f70f; contents table and known issues checked against the reports and the cards. Two known-issue lines reworded in 8e26574 (SAFETY-136 contradiction, SAFETY-138 timer is the ESPHome board's). Details: #241 comment 2517.
  • The deploy needs a fresh export of the live options. The predeploy file used below is from 2026-09-24, before the second inverter; run tools/predeploy_check.py --deployed-version 0.20.1 on a new export before the update.

What the deploy needs

  • Green checks / unit (pull_request) on this PR (a real run, not skipped), then the owner merges. Merging deploys nothing.
  • No tag has been made. The deploy is a separate step with its own owner go (docs/RELEASE.md): ha store reload, then the update of the add-on on the box. Not run by the dev agent.
  • Existing options need no change. Run tools/predeploy_check.py --deployed-version 0.20.1 against a FRESH export of the live options (.data.options) on the merged tree: the copy used for the check below is from 2026-09-24.
  • master must still be d53f70f when this opens; if it moved, stop and re-check.
  • Watch after the deploy: the "readings late" row and the READINGS_LATE warning should not show on a site whose readings are on time (none seen in any rig or review run with on-time readings); the peak notifications for a few nights; a clean stop and restart of the add-on.
  • Rollback is a revert with a new bump (docs/RELEASE.md).

Predeploy check

predeploy_check.py --deployed-version 0.20.1 --options <live-options-now.json .data.options> in goodwe-addon-checks:1, --network none, read-only mounts:

  • before the bump (b3cfcf2): REFUSED, "the deploy would be a no-op" (version 0.20.1 on both sides, 16 runtime commits since the last version change). That is the expected result.
  • after the bump (0f208a0): "live options pass this version's validator" and "CLEARED for deploy". No warnings.
  • Limit: the options file is dated 2026-09-24 and is older than the live options (for example it predates the second inverter, installed 2026-10-02, and later settings). It shows that those options start 0.21.0; it says nothing about options changed since. Hence the fresh export above.

CHANGELOG section

0.21.0

A minor bump: control now holds the batteries when Home Assistant readings come late, Home draws the whole night's grid charge, and the shutdown 0 W is sent last. No option changes.
No option was added, removed or renamed, and no default changed (86 options). Existing installs need no option change: options that start 0.20.1 also start 0.21.0, and the Supervisor form is the same. It is a minor bump because control acts differently when readings come late and when the add-on stops; every saved setting still starts.

Late Home Assistant readings are held, not followed. When Home Assistant passes readings on late, control used to correct a mistake its last command had already fixed, so the give run could swing and send power to the grid. It now waits until the battery shows its last power request, and the peak limit no longer asks for full power on late readings. A row on the page says so, and if the readings stay too late every inverter goes to 0 W. With readings on time, the commands are the same as before.

  • With a 2 s meter, readings 10 s late were found in 43 s in a rig test.
  • With a 5 s meter, readings 30 s late are now found in about 90 s (88 s in a simulation, 75 s in a rig test), where they took about 3 minutes. Readings 10 s late at a 5 s meter are not found (SAFETY-136).

Home draws the whole night's grid charge. Home used to draw a battery's grid charge only for the cheap run under way. It now draws every hour the add-on will charge it tonight, and shares the peak room between batteries as control does. It shows the plan and changes no command.

Tomorrow's forecast stays in the afternoon. If one of the tomorrow solar forecast sensors stops updating, tomorrow's forecast now stays instead of vanishing until 20:00.

The shutdown 0 W is sent last. When the add-on stops, the 0 W now waits up to 2 s for a command already on its way, so it is the last thing each inverter hears. A command slower than that can still land after it (SAFETY-138).

Contents of this release, in merge order since 0.20.1 (d53f70f):

371961e When Home Assistant passes readings on late, control no longer corrects a mistake its last command has already fixed. It waits until the battery shows its last power request, and the peak limit no longer asks for full power on late readings. The page says so, and if the readings stay too late every inverter goes to 0 W (SAFETY-128, #228)
af2d0d2 History only: brings 0.20.1, already live, into this branch. Nothing else is new (#233)
47c89a1, c66aa7f Home draws a battery's grid charge for every hour the add-on will charge it tonight, not only the cheap run under way, and shares the peak room between batteries as control does. It shows the plan and changes no command (UX-77, #234, with its second round #235)
b291262 With a 5 s meter, readings 30 s late are found in about 90 s, not about 3 minutes. Readings 10 s late are not found at a 5 s meter; the owner accepted this and it has its own card (SAFETY-129, #236, SAFETY-136)
23ff9d0 If one of the tomorrow solar forecast sensors stops updating in the afternoon, tomorrow's forecast now stays on the Forecast tab instead of vanishing until 20:00. The night plan can use it in that time (OPT-38, #237)
57c8d1b Each inverter is now reached through a driver. This prepares support for other inverter makes; there is no change for GoodWe sites (SMA-2, #238)
dbdc37b When the add-on stops, an inverter that can steer itself can be handed back instead of held at 0 W. This prepares support for other inverter makes; there is no change for GoodWe sites (SMA-10, #239)
b3cfcf2 When the add-on stops, the 0 W now waits up to 2 s for a command already on its way, so it is the last thing each inverter hears. In a rig test, 0 of 111 stops ended on a value other than 0 W, against 4 of 110 before. A slower command can still land after it (SAFETY-137, #240, SAFETY-138)

Known issues

  • A false "Battery is not keeping up" can still show when the peak guard pauses a maintenance charge (SAFETY-92).
  • A battery capped at a low limit with a perfectly flat reading can still trip the stale check (SAFETY-74).
  • A battery whose reading at rest is beyond about ±175 W is still not caught when it refuses (SAFETY-97).
  • The peak guard can still back off near the end of a 15-minute period when a meter reading is late, by less than 30 s. This is about the guard's discharge only; a grid charge is cut back since 0.19.2 (SAFETY-99).
  • Two inverters: the maintenance charge can switch on and off while the house is above the peak aim (SAFETY-88).
  • Two inverters: the "circulating" figure counts a battery's reading at rest (SAFETY-98).
  • Two inverters: a drain that starts during a big step in house use can send the other battery to full power, and about 1 kW goes to the grid for about 10 s (SAFETY-104).
  • Two inverters: when a battery comes back during a maintenance charge, the grid can step by several kW at once (SAFETY-101).
  • Two inverters: when a battery drops out during a solar surplus, the others can swing by up to 1.5 kW in a simulation (SAFETY-105).
  • Two inverters: after a drain ends, a change in house use can go unanswered for about 9 s, because some readings are old (SAFETY-106).
  • Two inverters: when one battery's level is missing, both batteries are held at 0 W, and for about 15 s the last command stays on (SAFETY-108).
  • Two inverters: if one battery's level stays missing for 12 h, the other battery's cycle can be marked failed, with a 7-day wait and a notice, though it is healthy. This comes from reading the code; it has not been seen on a site (MAINT-17).
  • When the 15-minute demand forecast sensor counts the battery's own charge, the maintenance charge runs at about half the power the peak limit leaves, so it takes about twice as long. Seen on a site: about 1.2 kW instead of 2.5 kW, and the peak limit was kept (SAFETY-111).
  • One inverter: after a link drop, the battery's own safety stop to 0 W can be taken as a refusal, and the site stays at 0 W for up to 15 min (SAFETY-102).
  • After a Home Assistant restart, control still waits until Home Assistant has finished starting, which can take several minutes, though the readings are already there (SAFETY-115).
  • While Home Assistant is not answering, the page can list inverters as refusing commands and sensors as missing, and send you to Developer Tools, though they are fine (UX-37).
  • If Home Assistant hangs or stops, the page keeps saying "Waiting for Home Assistant" and never turns into an alarm (SAFETY-113).
  • Right after Home Assistant has started, the page can say for about 4 s that an inverter cannot be controlled, and the first command can come late (SAFETY-114).
  • After a Home Assistant restart, the controller status sensor can still say "running" while the add-on cannot control. It was seen once, and the cause is not known (SAFETY-116).
  • Battery modes on: after a planned top-up from the grid, the Batteries screen can say "Enough sun is forecast" (UX-32).
  • Battery modes on: the forecast line "we count on" can show more sun than the plan counts, because the plan takes house use off first (UX-33).
  • Battery modes on: before a planned top-up, the Today list shows a smaller "gives" amount than the plan will use; it grows as the charge happens (UX-34).
  • Two inverters, battery modes on: while the other battery is in its maintenance charge, a battery's card can say it charges from the grid while it stays at 0 W (OPT-18).
  • Two inverters, battery modes on: while a battery refuses to charge in a cheap run, the action log on the page gets about 8 lines an hour for its retries, and the page hint says "waiting for a better price" (UX-38).
  • A battery in a safety stop, or one the add-on cannot reach, can still be started for a cycle, and its drain then waits about 12 h and ends in a failed-cycle notice. This comes from reading the code; it has not been seen on a site (MAINT-19).
  • On the Settings page, the rows of the solar forecast lists are labelled "Phase 1", "Phase 2" instead of "Sensor 1", "Sensor 2" (UX-27).
  • In the solar forecast list, a blank or repeated row makes "source 2 of 2" count differently from the rows on the Settings page (UX-28).
  • The solar forecast message says "has no reading" also when the sensor shows a number that is too old or in the wrong unit (UX-29).
  • If you use only the forecast lists, two Settings notes sit on the single-sensor field, and one of them tells you to set that field (UX-30).
  • After a restart during a price outage, the "No prices" message can say "yet" when prices did come in earlier (UX-39).
  • On the new settings page, you cannot see whether a price service token is set. Check the Configuration tab (UX-41).
  • On the classic settings page, the first click on Save after editing a field can do nothing. Click again (UX-42).
  • A steady overload on a 1 s meter can warn, and send the Home Assistant notification, 2 or 3 times at the start of each 15-minute period instead of once. The peak limit is still kept (SAFETY-122).
  • A fixed tariff is priced once per hour, so a price window that starts or ends at :15, :30 or :45 gets the wrong price for part of that hour. Windows that start and end on the hour are right (TARIFF-23).
  • Step 6 of the setup wizard stays empty because of an error in the page, in English and in Dutch (UX-51).
  • On Dutch pages, refusal texts, the last-event line under the Home buttons, the installer details and the trading status sentences are still English, and a few Dutch texts read badly, such as "1 metingen geweigerd" (UX-52).
  • Some price texts say "hour" where the add-on acts on a 15-minute period, such as "cheapest hour" (UX-47).
  • After the add-on restarts, the Home price chart shows no price for the earlier part of today, and the setup check can say "12 of 24 hours", though the prices are known (UX-48).
  • With battery modes on and only batteries on "Leftover solar", the Home price chart can mark a cheap period where no battery charges (UX-49).
  • On a phone, the bars of the Home price chart are too thin to tap one 15-minute period. The arrow keys work (UX-50).
  • In the last second of a 15-minute period, being a few watts over the aim can make the peak guard ask a battery for full power for one second. When a charge ends on a period edge, the last-second give can fade out over about 10 s, and a rig test exported up to 7.4 kW for about 8 s (SAFETY-124).
  • During the night grid charge, a 15-minute period can end 6 to 14 W over the peak aim, because the battery charges harder than asked. This was seen in simulation; a rig test saw 2 to 8 W (OPT-35).
  • The test rig could not bring back the false peak alarm that SAFETY-126 fixes, so that fix is shown in simulation only. Watch the notifications for a few nights (TEST-35).
  • The night cheap run is sized for the batteries' full charging power, not for what the peak limit leaves. Under a tight limit the run can end before the batteries reach their level, and Home can show a level they do not reach (79.9 % against a shown 95 % in a rig test) (OPT-25).
  • By day, a Leftover solar plan that has only a daily forecast figure counts the sun from now, not from when the figure was read. It counts about 22 % too much for a figure one hour old; the night plan is not affected (OPT-30).
  • The night charge can buy too much in a house that uses more at night than by day, such as one with a car charger or heat pump, and on a sunny day, because spare sun in one expensive hour does not count for the later ones (OPT-31).
  • A cheap run that has already started can overlap a new give run after a re-plan, so a battery can charge from the grid at the dearest price for part of an hour. This was seen in a test case, not on a site. Also in 0.19.2 (OPT-32).
  • If the solar forecast sensors stop updating before 17:00, as in winter or further north, there is no forecast from three hours after their last update until 20:00 (OPT-33).
  • With a forecast that gives only a daily total, the sun is spread an hour off on the two clock-change days after the change. The day's total is right (OPT-24).
  • The add-on learns the house's use only once a solar forecast is set, so a site that adds a forecast later waits one more day for its first plan (OPT-26).
  • Home says "No trading on price yet: no prices have arrived" when every battery is on Solar first, though the prices are shown (UX-55).
  • The Home plan header can say "Charges in the cheapest hour, gives power in the dearest" when Home draws no charge, and it says "hour" for 15-minute prices (UX-56).
  • While the peak guard holds back charging, Home hides the rest of the cheap run and gives no reason. The charge starts again when the guard lets go (UX-57).
  • With battery modes on and selling on, Home can draw a "Sells up to" block when the add-on judges the trade not worth it, and then it will not sell (UX-58).
  • Home, the plan and the Forecast tab stop drawing a battery's give at the trading floor, though control goes on giving down to the battery's cut-out (UX-59).
  • During a price outage, the Batteries screen says "Prices differ too little" and Home says "The price gap is too small" (UX-60).
  • With battery modes on and no meter, or a meter that is a Home Assistant entity, a grid charge is not possible and nothing says so (UX-61).
  • On the Batteries screen, a charge the add-on refused in a cheap run reads as "Saves its power for ...", for up to 15 minutes (UX-62).
  • A Leftover solar battery with no capacity set never charges from the grid when a solar forecast is set, and nothing warns about it (UX-63).
  • The "How the modes work" box on the Batteries screen does not describe Cheap hours only (UX-64).
  • With battery modes on, Settings still shows "Trade on the price spread", which the modes ignore. A site with modes on and no price source starts, and the Batteries screen says "No prices, so it follows the house" without pointing to Settings (UX-65).
  • With battery modes off and several equal prices in a row, Home and the Forecast tab draw one price quarter, while the add-on trades every quarter of the run (UX-67).
  • Late in the day, the Forecast tab's "now" line and last bars sit over the axis labels at the right edge (UX-68).
  • The Forecast tab's level curve charges at each battery's full rating. Under a peak limit the levels it draws are too high and a charge block can end early (54.6 % shown against 39.7 % in a rig test) (UX-70).
  • The peak forecast check says maintenance charging is not kept under the peak limit when no peak forecast is set, but since 0.19.2 it is (UX-73).
  • The peak guard row can show the same figure twice, such as "at this rate 3 500 W, over 3 500 W". Also in 0.19.2 (UX-74).
  • If the inverter's setpoint entity appears in Home Assistant after the add-on has started, the page keeps saying "Inverter control: not found in Home Assistant" and the batteries say "An alarm stopped control" until a restart, though control runs (UX-75).
  • In the last minute of a 15-minute period, with Home Assistant readings 30 s late, the period can end about 80 W over the peak aim and over the limit: 3 530 W against a 3 450 W aim and a 3 500 W limit in a rig test with a 2 kW load added 45 s before the end. The peak guard sees the load too late to hold it back (SAFETY-133).
  • With Home Assistant readings 10 s late, the grid charge in a cheap run can swing by several kW. In a test the add-on asked for an 8.7 kW charge (9.6 kW on 0.20.0) (SAFETY-132).
  • A plan rebuilt while the battery levels are missing for a moment can drop a cheap run that has not started yet, so the battery does not charge that day. Seen in a replay of real prices, where it cost about EUR 0.40 of extra grid use; the Leftover solar change in 0.20.1 no longer triggers it in those replays, but the cause stays (OPT-37).
  • On a 5 s meter, Home Assistant readings 10 s late are not caught, and readings 15 s late only after about 4 minutes. With a changing load such as an oven or a kettle, 21 to 142 Wh can go to the grid in a simulation, against 2 to 27 Wh with readings on time (SAFETY-136).
  • With readings 10 to 15 s late, the hold can end in the middle of the delay and the swing can come back. Seen in rig tests with a 2 s and a 5 s meter (SAFETY-134).
  • With readings 10 s late on a 1 s meter, the grid can still move between -422 and +340 W while the batteries are held. With a very long delay (30 to 90 s) the request can swing by about 900 W every few seconds. Seen in review tests (SAFETY-130).
  • A battery that answers very slowly (10 s or more) can be taken for late Home Assistant readings and held, and the page then blames Home Assistant. A GoodWe battery settles in about 6 s and this has not been seen on one (SAFETY-131).
  • The page row for late readings reads awkwardly in English ("Home Assistant readings show requests about N seconds late, so control holds the batteries"), and the Dutch text misses a word (UX-78).
  • On a night grid charge held to the peak limit, the peak guard can stop the charge 1 to 3 s into a 15-minute period and keep it paused for that whole period. In a rig test this cost up to about 0.27 kWh of grid charge per run; it may come from the sped-up rig clock (SAFETY-135).
  • When the add-on stops, a write that takes more than 2 s can still land after the 0 W, and the 30 s safety timer on the ESPHome board then sets 0 W. After the Stop button, a cycle that had already decided can send its share (560 to 670 W) just after the 0 W; the next cycle sends 0 W again (SAFETY-138).
  • In the last hour of a cheap run, Home can draw a battery's grid charge up to an hour past the time control stops charging it. It only draws too much, never too little (UX-79).
  • A tomorrow solar forecast sensor that reports just after midnight with yesterday's value can be used as the new day's forecast for up to 12 hours. This has not been seen on a site (OPT-39).
  • During a cheap-hours charge, at some 15-minute boundaries the add-on sends 0 W for one tick ("no trade (headroom)") and then goes on. Seen in a rig test, in 5 of 8 cases; once, with a frozen battery reading, it left a battery at 0 W until 23:45 (OPT-40).

If you are crossing from a version older than 0.10.0

## 0.10.0 below can refuse an old config: slew_w above its limit, and the
withdrawn price_provider ids engie_dynamic, totalenergies_dynamic and
eneco_eddy. Read it before you update. Run tools/predeploy_check.py with the
bare options (jq '.data.options') first.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC

Brings `release/1.0` to `master` as add-on version 0.21.0 (master is 0.20.1, `d53f70f`, live). Owner go 2026-11-08: "Release". The cut PR #241 (`release-0.21.0` -> `release/1.0`) carries the version bump and the CHANGELOG; this PR is opened by the reviewer after #241 merges, and the owner merges it. **Minor bump, no option change.** `config.yaml` options and schema (86 options), `translations/`, `build.yaml`, `Dockerfile`, `requirements.txt` and `run.sh` are identical to master 0.20.1 (`git diff d53f70f..b3cfcf2` is empty for them; the cut changes only the version line). `app/validate.py` changes only to accept the SMA-2 driver keys, which are deliberately not in the schema, so the Supervisor form is unchanged. It is minor because control acts differently when readings come late (SAFETY-128/129) and when the add-on stops (SAFETY-137, SMA-10). SMA-2 and SMA-10 change nothing for a GoodWe site. PR #224 (`MAINT-20-2`) is not part of this release. ## Review and merge of the cut (#241) - Cut PR #241 merged into `release/1.0` as **`16029d7cb81c715e7a3ae53b895f173b265597f5`** (parents `b3cfcf2`, `8e26574`), pinned to the reviewed head `8e26574` after a real green `checks / unit (pull_request)` run 1574. This PR's head is that merge. - Independent review (Opus): only config.yaml (`version: "0.21.0"`) and CHANGELOG.md changed; minor is right; options and schema equal master `d53f70f`; contents table and known issues checked against the reports and the cards. Two known-issue lines reworded in `8e26574` (SAFETY-136 contradiction, SAFETY-138 timer is the ESPHome board's). Details: #241 comment 2517. - **The deploy needs a fresh export of the live options.** The predeploy file used below is from 2026-09-24, before the second inverter; run `tools/predeploy_check.py --deployed-version 0.20.1` on a new export before the update. ## What the deploy needs - Green `checks / unit (pull_request)` on this PR (a real run, not `skipped`), then the owner merges. Merging deploys nothing. - No tag has been made. The deploy is a separate step with its own owner go (`docs/RELEASE.md`): `ha store reload`, then the update of the add-on on the box. Not run by the dev agent. - Existing options need no change. Run `tools/predeploy_check.py --deployed-version 0.20.1` against a FRESH export of the live options (`.data.options`) on the merged tree: the copy used for the check below is from 2026-09-24. - `master` must still be `d53f70f` when this opens; if it moved, stop and re-check. - Watch after the deploy: the "readings late" row and the `READINGS_LATE` warning should not show on a site whose readings are on time (none seen in any rig or review run with on-time readings); the peak notifications for a few nights; a clean stop and restart of the add-on. - Rollback is a revert with a new bump (`docs/RELEASE.md`). ## Predeploy check `predeploy_check.py --deployed-version 0.20.1 --options <live-options-now.json .data.options>` in `goodwe-addon-checks:1`, `--network none`, read-only mounts: - before the bump (`b3cfcf2`): REFUSED, "the deploy would be a no-op" (version 0.20.1 on both sides, 16 runtime commits since the last version change). That is the expected result. - after the bump (`0f208a0`): "live options pass this version's validator" and "CLEARED for deploy". No warnings. - Limit: the options file is dated 2026-09-24 and is older than the live options (for example it predates the second inverter, installed 2026-10-02, and later settings). It shows that those options start 0.21.0; it says nothing about options changed since. Hence the fresh export above. ## CHANGELOG section ## 0.21.0 **A minor bump: control now holds the batteries when Home Assistant readings come late, Home draws the whole night's grid charge, and the shutdown 0 W is sent last. No option changes.** No option was added, removed or renamed, and no default changed (86 options). **Existing installs need no option change:** options that start 0.20.1 also start 0.21.0, and the Supervisor form is the same. It is a minor bump because control acts differently when readings come late and when the add-on stops; every saved setting still starts. **Late Home Assistant readings are held, not followed.** When Home Assistant passes readings on late, control used to correct a mistake its last command had already fixed, so the give run could swing and send power to the grid. It now waits until the battery shows its last power request, and the peak limit no longer asks for full power on late readings. A row on the page says so, and if the readings stay too late every inverter goes to 0 W. With readings on time, the commands are the same as before. - With a 2 s meter, readings 10 s late were found in 43 s in a rig test. - With a 5 s meter, readings 30 s late are now found in about 90 s (88 s in a simulation, 75 s in a rig test), where they took about 3 minutes. Readings 10 s late at a 5 s meter are not found ([[SAFETY-136]]). **Home draws the whole night's grid charge.** Home used to draw a battery's grid charge only for the cheap run under way. It now draws every hour the add-on will charge it tonight, and shares the peak room between batteries as control does. It shows the plan and changes no command. **Tomorrow's forecast stays in the afternoon.** If one of the tomorrow solar forecast sensors stops updating, tomorrow's forecast now stays instead of vanishing until 20:00. **The shutdown 0 W is sent last.** When the add-on stops, the 0 W now waits up to 2 s for a command already on its way, so it is the last thing each inverter hears. A command slower than that can still land after it ([[SAFETY-138]]). Contents of this release, in merge order since 0.20.1 (`d53f70f`): | | | |---|---| | `371961e` | When Home Assistant passes readings on late, control no longer corrects a mistake its last command has already fixed. It waits until the battery shows its last power request, and the peak limit no longer asks for full power on late readings. The page says so, and if the readings stay too late every inverter goes to 0 W ([[SAFETY-128]], #228) | | `af2d0d2` | History only: brings 0.20.1, already live, into this branch. Nothing else is new (#233) | | `47c89a1`, `c66aa7f` | Home draws a battery's grid charge for every hour the add-on will charge it tonight, not only the cheap run under way, and shares the peak room between batteries as control does. It shows the plan and changes no command ([[UX-77]], #234, with its second round #235) | | `b291262` | With a 5 s meter, readings 30 s late are found in about 90 s, not about 3 minutes. Readings 10 s late are not found at a 5 s meter; the owner accepted this and it has its own card ([[SAFETY-129]], #236, [[SAFETY-136]]) | | `23ff9d0` | If one of the tomorrow solar forecast sensors stops updating in the afternoon, tomorrow's forecast now stays on the Forecast tab instead of vanishing until 20:00. The night plan can use it in that time ([[OPT-38]], #237) | | `57c8d1b` | Each inverter is now reached through a driver. This prepares support for other inverter makes; there is no change for GoodWe sites ([[SMA-2]], #238) | | `dbdc37b` | When the add-on stops, an inverter that can steer itself can be handed back instead of held at 0 W. This prepares support for other inverter makes; there is no change for GoodWe sites ([[SMA-10]], #239) | | `b3cfcf2` | When the add-on stops, the 0 W now waits up to 2 s for a command already on its way, so it is the last thing each inverter hears. In a rig test, 0 of 111 stops ended on a value other than 0 W, against 4 of 110 before. A slower command can still land after it ([[SAFETY-137]], #240, [[SAFETY-138]]) | ### Known issues - A false "Battery is not keeping up" can still show when the peak guard pauses a maintenance charge ([[SAFETY-92]]). - A battery capped at a low limit with a perfectly flat reading can still trip the stale check ([[SAFETY-74]]). - A battery whose reading at rest is beyond about ±175 W is still not caught when it refuses ([[SAFETY-97]]). - The peak guard can still back off near the end of a 15-minute period when a meter reading is late, by less than 30 s. This is about the guard's discharge only; a grid charge is cut back since 0.19.2 ([[SAFETY-99]]). - Two inverters: the maintenance charge can switch on and off while the house is above the peak aim ([[SAFETY-88]]). - Two inverters: the "circulating" figure counts a battery's reading at rest ([[SAFETY-98]]). - Two inverters: a drain that starts during a big step in house use can send the other battery to full power, and about 1 kW goes to the grid for about 10 s ([[SAFETY-104]]). - Two inverters: when a battery comes back during a maintenance charge, the grid can step by several kW at once ([[SAFETY-101]]). - Two inverters: when a battery drops out during a solar surplus, the others can swing by up to 1.5 kW in a simulation ([[SAFETY-105]]). - Two inverters: after a drain ends, a change in house use can go unanswered for about 9 s, because some readings are old ([[SAFETY-106]]). - Two inverters: when one battery's level is missing, both batteries are held at 0 W, and for about 15 s the last command stays on ([[SAFETY-108]]). - Two inverters: if one battery's level stays missing for 12 h, the other battery's cycle can be marked failed, with a 7-day wait and a notice, though it is healthy. This comes from reading the code; it has not been seen on a site ([[MAINT-17]]). - When the 15-minute demand forecast sensor counts the battery's own charge, the maintenance charge runs at about half the power the peak limit leaves, so it takes about twice as long. Seen on a site: about 1.2 kW instead of 2.5 kW, and the peak limit was kept ([[SAFETY-111]]). - One inverter: after a link drop, the battery's own safety stop to 0 W can be taken as a refusal, and the site stays at 0 W for up to 15 min ([[SAFETY-102]]). - After a Home Assistant restart, control still waits until Home Assistant has finished starting, which can take several minutes, though the readings are already there ([[SAFETY-115]]). - While Home Assistant is not answering, the page can list inverters as refusing commands and sensors as missing, and send you to Developer Tools, though they are fine ([[UX-37]]). - If Home Assistant hangs or stops, the page keeps saying "Waiting for Home Assistant" and never turns into an alarm ([[SAFETY-113]]). - Right after Home Assistant has started, the page can say for about 4 s that an inverter cannot be controlled, and the first command can come late ([[SAFETY-114]]). - After a Home Assistant restart, the controller status sensor can still say "running" while the add-on cannot control. It was seen once, and the cause is not known ([[SAFETY-116]]). - Battery modes on: after a planned top-up from the grid, the Batteries screen can say "Enough sun is forecast" ([[UX-32]]). - Battery modes on: the forecast line "we count on" can show more sun than the plan counts, because the plan takes house use off first ([[UX-33]]). - Battery modes on: before a planned top-up, the Today list shows a smaller "gives" amount than the plan will use; it grows as the charge happens ([[UX-34]]). - Two inverters, battery modes on: while the other battery is in its maintenance charge, a battery's card can say it charges from the grid while it stays at 0 W ([[OPT-18]]). - Two inverters, battery modes on: while a battery refuses to charge in a cheap run, the action log on the page gets about 8 lines an hour for its retries, and the page hint says "waiting for a better price" ([[UX-38]]). - A battery in a safety stop, or one the add-on cannot reach, can still be started for a cycle, and its drain then waits about 12 h and ends in a failed-cycle notice. This comes from reading the code; it has not been seen on a site ([[MAINT-19]]). - On the Settings page, the rows of the solar forecast lists are labelled "Phase 1", "Phase 2" instead of "Sensor 1", "Sensor 2" ([[UX-27]]). - In the solar forecast list, a blank or repeated row makes "source 2 of 2" count differently from the rows on the Settings page ([[UX-28]]). - The solar forecast message says "has no reading" also when the sensor shows a number that is too old or in the wrong unit ([[UX-29]]). - If you use only the forecast lists, two Settings notes sit on the single-sensor field, and one of them tells you to set that field ([[UX-30]]). - After a restart during a price outage, the "No prices" message can say "yet" when prices did come in earlier ([[UX-39]]). - On the new settings page, you cannot see whether a price service token is set. Check the Configuration tab ([[UX-41]]). - On the classic settings page, the first click on Save after editing a field can do nothing. Click again ([[UX-42]]). - A steady overload on a 1 s meter can warn, and send the Home Assistant notification, 2 or 3 times at the start of each 15-minute period instead of once. The peak limit is still kept ([[SAFETY-122]]). - A fixed tariff is priced once per hour, so a price window that starts or ends at :15, :30 or :45 gets the wrong price for part of that hour. Windows that start and end on the hour are right ([[TARIFF-23]]). - Step 6 of the setup wizard stays empty because of an error in the page, in English and in Dutch ([[UX-51]]). - On Dutch pages, refusal texts, the last-event line under the Home buttons, the installer details and the trading status sentences are still English, and a few Dutch texts read badly, such as "1 metingen geweigerd" ([[UX-52]]). - Some price texts say "hour" where the add-on acts on a 15-minute period, such as "cheapest hour" ([[UX-47]]). - After the add-on restarts, the Home price chart shows no price for the earlier part of today, and the setup check can say "12 of 24 hours", though the prices are known ([[UX-48]]). - With battery modes on and only batteries on "Leftover solar", the Home price chart can mark a cheap period where no battery charges ([[UX-49]]). - On a phone, the bars of the Home price chart are too thin to tap one 15-minute period. The arrow keys work ([[UX-50]]). - In the last second of a 15-minute period, being a few watts over the aim can make the peak guard ask a battery for full power for one second. When a charge ends on a period edge, the last-second give can fade out over about 10 s, and a rig test exported up to 7.4 kW for about 8 s ([[SAFETY-124]]). - During the night grid charge, a 15-minute period can end 6 to 14 W over the peak aim, because the battery charges harder than asked. This was seen in simulation; a rig test saw 2 to 8 W ([[OPT-35]]). - The test rig could not bring back the false peak alarm that [[SAFETY-126]] fixes, so that fix is shown in simulation only. Watch the notifications for a few nights ([[TEST-35]]). - The night cheap run is sized for the batteries' full charging power, not for what the peak limit leaves. Under a tight limit the run can end before the batteries reach their level, and Home can show a level they do not reach (79.9 % against a shown 95 % in a rig test) ([[OPT-25]]). - By day, a Leftover solar plan that has only a daily forecast figure counts the sun from now, not from when the figure was read. It counts about 22 % too much for a figure one hour old; the night plan is not affected ([[OPT-30]]). - The night charge can buy too much in a house that uses more at night than by day, such as one with a car charger or heat pump, and on a sunny day, because spare sun in one expensive hour does not count for the later ones ([[OPT-31]]). - A cheap run that has already started can overlap a new give run after a re-plan, so a battery can charge from the grid at the dearest price for part of an hour. This was seen in a test case, not on a site. Also in 0.19.2 ([[OPT-32]]). - If the solar forecast sensors stop updating before 17:00, as in winter or further north, there is no forecast from three hours after their last update until 20:00 ([[OPT-33]]). - With a forecast that gives only a daily total, the sun is spread an hour off on the two clock-change days after the change. The day's total is right ([[OPT-24]]). - The add-on learns the house's use only once a solar forecast is set, so a site that adds a forecast later waits one more day for its first plan ([[OPT-26]]). - Home says "No trading on price yet: no prices have arrived" when every battery is on Solar first, though the prices are shown ([[UX-55]]). - The Home plan header can say "Charges in the cheapest hour, gives power in the dearest" when Home draws no charge, and it says "hour" for 15-minute prices ([[UX-56]]). - While the peak guard holds back charging, Home hides the rest of the cheap run and gives no reason. The charge starts again when the guard lets go ([[UX-57]]). - With battery modes on and selling on, Home can draw a "Sells up to" block when the add-on judges the trade not worth it, and then it will not sell ([[UX-58]]). - Home, the plan and the Forecast tab stop drawing a battery's give at the trading floor, though control goes on giving down to the battery's cut-out ([[UX-59]]). - During a price outage, the Batteries screen says "Prices differ too little" and Home says "The price gap is too small" ([[UX-60]]). - With battery modes on and no meter, or a meter that is a Home Assistant entity, a grid charge is not possible and nothing says so ([[UX-61]]). - On the Batteries screen, a charge the add-on refused in a cheap run reads as "Saves its power for ...", for up to 15 minutes ([[UX-62]]). - A Leftover solar battery with no capacity set never charges from the grid when a solar forecast is set, and nothing warns about it ([[UX-63]]). - The "How the modes work" box on the Batteries screen does not describe Cheap hours only ([[UX-64]]). - With battery modes on, Settings still shows "Trade on the price spread", which the modes ignore. A site with modes on and no price source starts, and the Batteries screen says "No prices, so it follows the house" without pointing to Settings ([[UX-65]]). - With battery modes off and several equal prices in a row, Home and the Forecast tab draw one price quarter, while the add-on trades every quarter of the run ([[UX-67]]). - Late in the day, the Forecast tab's "now" line and last bars sit over the axis labels at the right edge ([[UX-68]]). - The Forecast tab's level curve charges at each battery's full rating. Under a peak limit the levels it draws are too high and a charge block can end early (54.6 % shown against 39.7 % in a rig test) ([[UX-70]]). - The peak forecast check says maintenance charging is not kept under the peak limit when no peak forecast is set, but since 0.19.2 it is ([[UX-73]]). - The peak guard row can show the same figure twice, such as "at this rate 3 500 W, over 3 500 W". Also in 0.19.2 ([[UX-74]]). - If the inverter's setpoint entity appears in Home Assistant after the add-on has started, the page keeps saying "Inverter control: not found in Home Assistant" and the batteries say "An alarm stopped control" until a restart, though control runs ([[UX-75]]). - In the last minute of a 15-minute period, with Home Assistant readings 30 s late, the period can end about 80 W over the peak aim and over the limit: 3 530 W against a 3 450 W aim and a 3 500 W limit in a rig test with a 2 kW load added 45 s before the end. The peak guard sees the load too late to hold it back ([[SAFETY-133]]). - With Home Assistant readings 10 s late, the grid charge in a cheap run can swing by several kW. In a test the add-on asked for an 8.7 kW charge (9.6 kW on 0.20.0) ([[SAFETY-132]]). - A plan rebuilt while the battery levels are missing for a moment can drop a cheap run that has not started yet, so the battery does not charge that day. Seen in a replay of real prices, where it cost about EUR 0.40 of extra grid use; the Leftover solar change in 0.20.1 no longer triggers it in those replays, but the cause stays ([[OPT-37]]). - On a 5 s meter, Home Assistant readings 10 s late are not caught, and readings 15 s late only after about 4 minutes. With a changing load such as an oven or a kettle, 21 to 142 Wh can go to the grid in a simulation, against 2 to 27 Wh with readings on time ([[SAFETY-136]]). - With readings 10 to 15 s late, the hold can end in the middle of the delay and the swing can come back. Seen in rig tests with a 2 s and a 5 s meter ([[SAFETY-134]]). - With readings 10 s late on a 1 s meter, the grid can still move between -422 and +340 W while the batteries are held. With a very long delay (30 to 90 s) the request can swing by about 900 W every few seconds. Seen in review tests ([[SAFETY-130]]). - A battery that answers very slowly (10 s or more) can be taken for late Home Assistant readings and held, and the page then blames Home Assistant. A GoodWe battery settles in about 6 s and this has not been seen on one ([[SAFETY-131]]). - The page row for late readings reads awkwardly in English ("Home Assistant readings show requests about N seconds late, so control holds the batteries"), and the Dutch text misses a word ([[UX-78]]). - On a night grid charge held to the peak limit, the peak guard can stop the charge 1 to 3 s into a 15-minute period and keep it paused for that whole period. In a rig test this cost up to about 0.27 kWh of grid charge per run; it may come from the sped-up rig clock ([[SAFETY-135]]). - When the add-on stops, a write that takes more than 2 s can still land after the 0 W, and the 30 s safety timer on the ESPHome board then sets 0 W. After the Stop button, a cycle that had already decided can send its share (560 to 670 W) just after the 0 W; the next cycle sends 0 W again ([[SAFETY-138]]). - In the last hour of a cheap run, Home can draw a battery's grid charge up to an hour past the time control stops charging it. It only draws too much, never too little ([[UX-79]]). - A tomorrow solar forecast sensor that reports just after midnight with yesterday's value can be used as the new day's forecast for up to 12 hours. This has not been seen on a site ([[OPT-39]]). - During a cheap-hours charge, at some 15-minute boundaries the add-on sends 0 W for one tick ("no trade (headroom)") and then goes on. Seen in a rig test, in 5 of 8 cases; once, with a frozen battery reading, it left a battery at 0 W until 23:45 ([[OPT-40]]). ### If you are crossing from a version older than 0.10.0 `## 0.10.0` below can refuse an old config: `slew_w` above its limit, and the withdrawn `price_provider` ids `engie_dynamic`, `totalenergies_dynamic` and `eneco_eddy`. Read it before you update. Run `tools/predeploy_check.py` with the bare options (`jq '.data.options'`) first. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
admin added 33 commits 2026-11-08 10:47:02 +01:00
SAFETY-128: control does not act on late Home Assistant readings
checks / unit (pull_request) Successful in 19m36s
infra-pin / fresh (pull_request) Successful in 1s
09e1fbb898
Readings that Home Assistant delivers late but still changing passed
every staleness gate, so the loop corrected again each cycle an error
its last command had already fixed (10 s late: the give run swung and
exported to -1.9 kW), and the peak guard pushed to the inverter limit
on the same late figures (OPT-34 F-2).

app/lateness.py fits how long after a power request the meter shows
it. Over 8 s the readings are late: a request the battery reading has
not answered holds the loop (it may not lead the reading by more than
100 W) and caps the peak guard at what stands; unanswered for 23 s it
holds, then 0 W after stale_input_s. An amber row and one log line per
episode say so. With readings on time nothing changes (digests equal).

DECISIONS/SAFETY-128-late-readings.md; test_safety128.py.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
SAFETY-128 round 2: find late readings from the batteries, not the meter alone
checks / unit (pull_request) Successful in 26m50s
infra-pin / fresh (pull_request) Successful in 2s
d3f4f9f48b
Review B1: the meter fit took repeating house loads (ovens, a heat pump)
for late readings on healthy 1-2 s sites, about 9 % of the recorded
house. B2: at a 5 s meter it never ran. M1: no hysteresis. M2: an
unbounded check.

lateness.Delay now fits how long each battery's reading takes to show
its own request, which the house does not move, from the 1 s reads
(read_inputs -> Answer.watch). The meter fit stays for speed at 1-3 s
meters, but counts only when an ask was slow to start and no battery
fit said on time. Late from 9.5 s after 2 fits, on time under 6.5 s,
dropped after 120 s without a fit. Fits are bounded (a few ms).

Readings on time: no verdict in any reviewer scenario (22 shapes at
1/2/5 s meters, 7 harm runs) nor in 2 days of the recorded house at
1, 2 and 5 s ticks; digests equal to 77fe31b. Late: found 36-68 s after
the start at 1-2 s, about 3 min at 5 s. The row gives the batteries'
delay, or no figure while only the meter has shown it.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
SAFETY-128 review: DECISIONS states the slow-battery limit as measured
checks / unit (pull_request) Successful in 32m0s
infra-pin / fresh (pull_request) Successful in 1s
7de77a5a09
Round 2 review: a 10 s dead time reads late at 1-2 s meters, and a 15-20 s
lag gives late fits; the note said 3-20 s and 6-10 s gave none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
Merge origin/master (0.20.1) into release/1.0
checks / unit (pull_request) Successful in 32m4s
infra-pin / fresh (pull_request) Successful in 2s
4f96397a60
Brings OPT-36 (#229) and TEST-37 (#231) onto release/1.0, which keeps
SAFETY-128 (#228). No textual conflicts. CHANGELOG: the SAFETY-128 entry
moved out of the released 0.20.0 section into "Not in a release yet" above
## 0.20.1; the 0.20.0 and 0.20.1 sections are identical to master.

Co-Authored-By: Claude <noreply@anthropic.com>
UX-77: Home draws today's grid charge for the hours control will really charge
checks / unit (pull_request) Successful in 27m7s
infra-pin / fresh (pull_request) Successful in 1s
45535e19d7
The cheap run is sized at the full rating, so under the peak limit a battery is
still short when it ends, and control plans the next run then. Home drew only
the run under way. `cheaproll` rolls the run on the way control does
(`modetrade.energy()` + `priceruns.plan()` at each run end, lifted from
`dayview._levels()`), reading the levels at the charge power the peak limit
leaves (peak aim less the house, else the rating). `homeview.mode_runs()` and
`price_windows()` use it for today: the grid block, the Today line and the
chart's cheap bars run to where control stops, each battery's block to its
own stop. Display only: no control change.

test_ux54: today's grid block of the night-before scenario now follows the roll.

Co-Authored-By: Claude <noreply@anthropic.com>
UX-77: Home's roll shares the peak room by room left to full, as control does
checks / unit (pull_request) Successful in 26m34s
infra-pin / fresh (pull_request) Successful in 2s
6d2b9b5335
The cheap-run roll (cheaproll._Charge) shared the peak room by rating, control
shares it by room left to full (packshare.weights). With unequal levels one
battery's drawn block ended too early (rig F-1). The roll now uses
packshare.weights over the simulated levels, each battery capped at its rating,
a full one dropping out. test_ux77 gains two unequal-level walks and a
by-rating mutant; its walks model control's split by room too.

Co-Authored-By: Claude <noreply@anthropic.com>
The meter's delay fit needed 16 new values in 60 s, so at the owner's 5 s P1
only the batteries' fit ran and 30 s late was found after about 3 minutes
(export to -420 W). A meter that slow is now also fitted over 120 s; it calls
a delay late only over 16 s, on two fits in a row, with the same corroboration
as before, and never ends a verdict, so a slow battery (R2-1) runs as before.
Found about 90 s after the start, export above -200 W. 10 s late at a 5 s
meter is not found (nothing swings; it cannot be told from a 10 s battery).

Co-Authored-By: Claude <noreply@anthropic.com>
SAFETY-129: the 5 s row no longer waits for the batteries' figure
checks / unit (pull_request) Successful in 23m52s
infra-pin / fresh (pull_request) Successful in 1s
2667cf0dda
At a 5 s meter the slow meter fit now finds 30 s late first, and the hold leaves
the batteries' fit nothing to measure, so the row says it without a figure.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
SAFETY-129 round 2: next() with a default in test_safety129
checks / unit (pull_request) Successful in 23m26s
infra-pin / fresh (pull_request) Successful in 2s
03541a1eee
Co-Authored-By: Claude <noreply@anthropic.com>
SAFETY-129 round 3: the real reason for the 16 s limit, a slow-start check, the row's tail
checks / unit (pull_request) Successful in 23m1s
infra-pin / fresh (pull_request) Successful in 1s
c70eeb6916
Co-Authored-By: Claude <noreply@anthropic.com>
OPT-38: a kept tomorrow forecast reading stands in at any hour
checks / unit (pull_request) Successful in 22m54s
infra-pin / fresh (pull_request) Successful in 1s
c43873b142
One stale Forecast.Solar tomorrow sensor dropped the whole OPT-17 sum from
17:54 to 20:00. Today readings and the OPT-34 morning rules are unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
OPT-38 round 2: a kept tomorrow reading is flagged kept only from 20:00
checks / unit (pull_request) Successful in 23m11s
infra-pin / fresh (pull_request) Successful in 1s
0bacafadf0
Before the bell ends it replaced today's Home line and the event log with
the kept-for-tonight wording. stand_in() docstring covers the tomorrow case.

Co-Authored-By: Claude <noreply@anthropic.com>
SMA-2: each inverter is reached through a driver; GoodWe behaviour unchanged
checks / unit (pull_request) Successful in 23m14s
infra-pin / fresh (pull_request) Successful in 2s
e56eeef8f0
app/drivers.py holds one Driver per roster entry (configured, actuator_id,
limits, read, write, release, probe, link_stale_s, batt_bound, settle_s, brand,
words). GoodWeEsphomeDriver makes the calls the code it replaced made, in the
same order. Inverter gets driver; has_writer, is_live and link_note read it. The
SoC/power read, the write, the device range (run_control, amain, the settings
panel), rule 2 per unit and the SAFETY-28 census go through it.

setpoint_entity is optional per entry beside driver, host, port, unit_id and
maintenance; only goodwe_esphome is selectable, the rest are checked and unused.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
SMA-2 round 2: keep the driver keys out of the schema, translations and labels
checks / unit (pull_request) Successful in 23m13s
infra-pin / fresh (pull_request) Successful in 1s
c015230452
Owner decision 2026-11-07: clients see nothing new until SMA-4. config.yaml,
translations, labels and the page layout are back to 23ff9d0's. The validation
of the keys stays for callers that skip the schema.

Co-Authored-By: Claude <noreply@anthropic.com>
SMA-10: two idle states, hold 0 W or hand the inverter back
checks / unit (pull_request) Successful in 24m9s
infra-pin / fresh (pull_request) Successful in 1s
a1be9c48b3
A driver now says whether its release() hands the inverter back
(Driver.hands_back; GoodWe is False, so release() stays write(0) and the
Controller never calls it). command_site_release() sits next to
command_site_zero(): the Stop button and shutdown() (so SIGTERM, restart,
control task death and a late config refusal) hand a hand-back unit back,
once, and zero every other unit as before. Safety stops and refusals still
hold 0 W for every unit. Shadow mode releases a hand-back unit. After a
release nothing is written to the unit (heartbeat and cycle included) until
control starts again. release() is bounded by RELEASE_BUDGET_S (= the write
budget), runs concurrently per unit, and a raising or hanging release on one
unit does not stop the others.

The "set to 0 W" sentences for Stop, restart, shadow mode and the stopped
banner are built from the roster (app/handback.py, EN and NL, words from the
driver); a GoodWe-only roster keeps every old literal. A handed-back unit
shows "Back under <its control>" on Home.

Existing test edited: test_messages.py (two classification entries for the
CRITICAL line that moved into a roster builder, and the new release bound).

Co-Authored-By: Claude <noreply@anthropic.com>
SMA-10 round 2: a failed release sends 0 W once, retries at heartbeat pace
checks / unit (pull_request) Successful in 23m37s
infra-pin / fresh (pull_request) Successful in 2s
d26cc573fe
When release() fails (False, raises or hangs past RELEASE_BUDGET_S) the unit
gets one bounded write(0) through the new Driver.release_fallback() hook
(default write(0)), then nothing more, so the inverter's own fallback timer is
not reset. The release is retried once per heartbeat, not on every idle
write. One error line and one action-log event per failure streak, one line on
recovery. Dutch default "terug naar de eigen sturing". DECISIONS says what a
unit is left at.

test_messages.py: the RELEASE_BUDGET_S data entry is gone again (the line
that needed it is gone).

Co-Authored-By: Claude <noreply@anthropic.com>
SMA-10 round 3: Start clears a failed hand-back streak; the hook is tested
checks / unit (pull_request) Successful in 23m23s
infra-pin / fresh (pull_request) Successful in 2s
313503724d
When control takes the unit again, release_fails, release_retry_at and
release_zero_sent are reset, so the next Stop is a new streak with its own one
0 W, error line and event. Tests: a streak that Start interrupts without a
recovery; a driver that overrides release_fallback(). _BACK_NL "de eigen
sturing" (round 2) is kept.

Co-Authored-By: Claude <noreply@anthropic.com>
SMA-10 round 4: pin the Dutch default "de eigen sturing"
checks / unit (pull_request) Successful in 30m41s
infra-pin / fresh (pull_request) Successful in 2s
6cae5a2f8f
The NL default for a hand-back driver without words (handback._BACK_NL) was
changed to "de eigen sturing" in round 2 at the PR #239 review's request
(comment 2495: the article as in the generic clause). The brief does not name
it, so DECISIONS now says where it came from and a test checks the exact Dutch
sentence. No app code change.

Co-Authored-By: Claude <noreply@anthropic.com>
SAFETY-137: the shutdown and Stop 0 W is the last write every unit hears
checks / unit (pull_request) Successful in 22m59s
infra-pin / fresh (pull_request) Successful in 1s
8953be0362
The 0 W of shutdown and of the Stop button now waits (bounded, 2 s) for a
write already on its way to the same unit, for every driver, GoodWe included.
Once shutdown has begun, cycle, heartbeat and safety-stop writes are dropped
right before the write is created. One shared wait (_await_inflight) serves
the 0 W and SMA-10's _release_last.

Co-Authored-By: Claude <noreply@anthropic.com>
Release 0.21.0: version bump and CHANGELOG
checks / unit (pull_request) Successful in 33m53s
infra-pin / fresh (pull_request) Successful in 2s
0f208a0500
Minor bump, no option changes. Folds "Not in a release yet" into a new
0.21.0 section, adds the contents table for the nine merges on release/1.0
since master 0.20.1, updates the known issues, and rewrites the 0.20.1
SAFETY-128 known issue to say it ships in 0.21.0.

Co-Authored-By: Claude <noreply@anthropic.com>
Release 0.21.0: CHANGELOG wording (SAFETY-136, SAFETY-138 known issues)
checks / unit (pull_request) Successful in 24m11s
infra-pin / fresh (pull_request) Successful in 2s
8e26574b03
SAFETY-136: the line said 10 to 15 s late is not caught, then that 15 s late
is caught after about 4 minutes. It now says 10 s is not caught and 15 s only
after about 4 minutes, as the card says.
SAFETY-138: the 30 s timer that zeroes a late write is the ESPHome board's
watchdog (README), not the inverter's own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge pull request 'Release 0.21.0' (#241) from release-0.21.0 into release/1.0
infra-pin / fresh (push) Successful in 2s
checks / unit (pull_request) Successful in 23m41s
infra-pin / fresh (pull_request) Successful in 2s
16029d7cb8
admin merged commit 5e00cbbd79 into master 2026-11-08 17:27:33 +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#242