Release 0.20.1: hotfix-0.20.1 -> master #232

Open
admin wants to merge 15 commits from hotfix-0.20.1 into master
Owner

Brings hotfix-0.20.1 to master as add-on version 0.20.1 (now 0.20.0 on master, 01e88a2). Owner 2026-11-02: OPT-36 "start work as a hotfix". The one change is OPT-36 (#229, 22d09f8, rig-tested 6/6); the version bump and CHANGELOG come in with the cut PR #230 (release-0.20.1 -> hotfix-0.20.1), reviewed and merged before this PR. Open it only after #230 is merged, with hotfix-0.20.1 as the head.

Review (REL-0.20.1): #230 reviewed and merged. Merge commit 3219aea9a0737dacd39c2fb982701839f599d69b (parents cfe1f06, 2fa14e2), merged with head_commit_id = 2fa14e2 after checks / unit (pull_request) run 1530 passed on it. The cut is right: only config.yaml (version) and CHANGELOG.md differ from the hotfix base, and the 0.20.0 section equals master. Two known-issue wording fixes were made in review (01eba51): SAFETY-132 (9.6 kW is a charge asked for in a test) and SAFETY-133 (the quarter is also over the 3 500 W limit).

Also included: TEST-37 (#231, cfe1f06), a test-only fix. test_opt34 now builds its Controller under the scenario clock, so the test no longer fails after 2026-11-04 (a date time bomb). No add-on code changes.

Patch bump, no option change. config.yaml options and schema, app/validate.py and translations/ (and build.yaml, Dockerfile, requirements.txt, run.sh) are byte-identical to master 0.20.0 (git diff 01e88a2..22d09f8 is empty for them; the cut changes only the version line). The OPT-36 screen text is in app/ui_text/*.json, not in options. Existing installs need no option change.

What the deploy needs

  • Green checks / unit (pull_request) on this PR (a real run, not skipped), then the owner merges. Nothing is deployed by the merge itself.
  • 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.
  • Run tools/predeploy_check.py --deployed-version 0.20.0 against a FRESH export of the live options (.data.options) on the merged tree. The dev did not run it (the manager runs it on a fresh export).
  • master must still be 01e88a2 when this opens; if it moved, rebase the hotfix first.
  • Rollback is a revert with a new bump (docs/RELEASE.md).

CHANGELOG section

0.20.1

A patch bump: Leftover solar no longer buys from the grid what other batteries will already cover. 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.0 also start 0.20.1. A site with one battery, with battery modes off, or with no Cheap hours only or Solar first battery plans as before.

Leftover solar counts the other batteries. At night, a Leftover solar battery used to buy for the whole of the expensive hours as if no other battery would give. It now counts what a Cheap hours only battery will hold when the expensive hours start, and what a Solar first battery will have left after the night's use, and buys only the rest. In a rig test of the live night (Leftover solar at 60 %, Cheap hours only at 94 %) it bought 0.00 kWh where 0.20.0 bought 5.40 kWh. The Batteries screen says "Other batteries cover the expensive hours. It does not charge from the grid."

Contents of this release, in merge order since 0.20.0 (01e88a2):

22d09f8 Leftover solar counts what Cheap hours only and Solar first batteries will still hold when the expensive hours start, and buys from the grid only the rest. The Batteries screen says when other batteries cover those hours, and the "rest" sentence now says it comes from the grid (OPT-36, #229)

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).
  • Control acts on Home Assistant readings that arrive late. With readings 10 s behind, the give run can swing and send up to 1.9 kW to the grid for about 50 s in a rig test; with readings 30 s behind, a battery can charge from the grid in an expensive period. Also in 0.19.2. A fix is made for the next release and is not in 0.20.1 (SAFETY-128).
  • 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 on 0.20.0 the add-on asked for a 9.6 kW charge (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 change in this release no longer triggers it in those replays, but the cause stays (OPT-37).
  • Home draws a battery's charge only for the current cheap run. On a flat night tariff the later night hours it will charge show up as the run rolls on, though control keeps charging (UX-77).

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.

Brings `hotfix-0.20.1` to `master` as add-on version 0.20.1 (now 0.20.0 on master, `01e88a2`). Owner 2026-11-02: OPT-36 "start work as a hotfix". The one change is OPT-36 (#229, `22d09f8`, rig-tested 6/6); the version bump and CHANGELOG come in with the cut PR #230 (`release-0.20.1` -> `hotfix-0.20.1`), reviewed and merged before this PR. Open it only after #230 is merged, with `hotfix-0.20.1` as the head. **Review (REL-0.20.1):** #230 reviewed and merged. Merge commit `3219aea9a0737dacd39c2fb982701839f599d69b` (parents `cfe1f06`, `2fa14e2`), merged with `head_commit_id` = `2fa14e2` after `checks / unit (pull_request)` run 1530 passed on it. The cut is right: only `config.yaml` (version) and `CHANGELOG.md` differ from the hotfix base, and the 0.20.0 section equals master. Two known-issue wording fixes were made in review (01eba51): SAFETY-132 (9.6 kW is a charge asked for in a test) and SAFETY-133 (the quarter is also over the 3 500 W limit). **Also included: TEST-37 (#231, `cfe1f06`), a test-only fix.** test_opt34 now builds its Controller under the scenario clock, so the test no longer fails after 2026-11-04 (a date time bomb). No add-on code changes. **Patch bump, no option change.** `config.yaml` options and schema, `app/validate.py` and `translations/` (and build.yaml, Dockerfile, requirements.txt, run.sh) are byte-identical to master 0.20.0 (`git diff 01e88a2..22d09f8` is empty for them; the cut changes only the version line). The OPT-36 screen text is in `app/ui_text/*.json`, not in options. Existing installs need no option change. ## What the deploy needs - Green `checks / unit (pull_request)` on this PR (a real run, not `skipped`), then the owner merges. Nothing is deployed by the merge itself. - 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. - Run `tools/predeploy_check.py --deployed-version 0.20.0` against a FRESH export of the live options (`.data.options`) on the merged tree. The dev did not run it (the manager runs it on a fresh export). - `master` must still be `01e88a2` when this opens; if it moved, rebase the hotfix first. - Rollback is a revert with a new bump (`docs/RELEASE.md`). ## CHANGELOG section ## 0.20.1 **A patch bump: Leftover solar no longer buys from the grid what other batteries will already cover. 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.0 also start 0.20.1. A site with one battery, with battery modes off, or with no Cheap hours only or Solar first battery plans as before. **Leftover solar counts the other batteries.** At night, a Leftover solar battery used to buy for the whole of the expensive hours as if no other battery would give. It now counts what a Cheap hours only battery will hold when the expensive hours start, and what a Solar first battery will have left after the night's use, and buys only the rest. In a rig test of the live night (Leftover solar at 60 %, Cheap hours only at 94 %) it bought 0.00 kWh where 0.20.0 bought 5.40 kWh. The Batteries screen says "Other batteries cover the expensive hours. It does not charge from the grid." Contents of this release, in merge order since 0.20.0 (`01e88a2`): | | | |---|---| | `22d09f8` | Leftover solar counts what Cheap hours only and Solar first batteries will still hold when the expensive hours start, and buys from the grid only the rest. The Batteries screen says when other batteries cover those hours, and the "rest" sentence now says it comes from the grid ([[OPT-36]], #229) | ### 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]]). - Control acts on Home Assistant readings that arrive late. With readings 10 s behind, the give run can swing and send up to 1.9 kW to the grid for about 50 s in a rig test; with readings 30 s behind, a battery can charge from the grid in an expensive period. Also in 0.19.2. A fix is made for the next release and is not in 0.20.1 ([[SAFETY-128]]). - 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 on 0.20.0 the add-on asked for a 9.6 kW charge ([[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 change in this release no longer triggers it in those replays, but the cause stays ([[OPT-37]]). - Home draws a battery's charge only for the current cheap run. On a flat night tariff the later night hours it will charge show up as the run rolls on, though control keeps charging ([[UX-77]]). ### 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.
admin added 15 commits 2026-11-05 14:20:37 +01:00
OPT-36: Leftover solar counts what Cheap hours and Solar first batteries will give before buying
checks / unit (pull_request) Failing after 59m31s
infra-pin / fresh (pull_request) Successful in 2s
05746c0564
Live 0.20.0: A (Leftover solar, 60 %) charged to 95 % while B (Cheap hours,
94 %) already covered the expensive hours. dayplan.plan() now takes off the
shortfall what Cheap hours batteries will hold when the hours start (the
ceiling or what their cheap run reaches under the peak aim) and what Solar
first batteries will still hold after the night's use. Home reads a give
block after the planned charge, plan_cover() is the plan's own figure, and
the Why line says other batteries cover.

Co-Authored-By: Claude <noreply@anthropic.com>
OPT-36: test a give block before tonight's charge, Solar first refusing and in maintenance
checks / unit (pull_request) Failing after 26m32s
infra-pin / fresh (pull_request) Successful in 4s
490f67924b
Co-Authored-By: Claude <noreply@anthropic.com>
OPT-36: test_opt36 reads possibly-missing values through nth()
checks / unit (pull_request) Failing after 35m3s
infra-pin / fresh (pull_request) Successful in 2s
60674e45ba
Co-Authored-By: Claude <noreply@anthropic.com>
OPT-36: test_opt34 and test_ux54 scenarios keep a shortfall B does not cover
checks / unit (pull_request) Successful in 27m17s
infra-pin / fresh (pull_request) Successful in 2s
6a527de851
With Cheap hours B counted, A buys only what B cannot reach. The OPT-34
night scenarios use a 1.6 x larger house profile, and the ux54 tab scenarios
a 4.8 kW evening (ux54_scenarios.make(evening=)), so A still charges; the
hard-coded levels become relations.

Co-Authored-By: Claude <noreply@anthropic.com>
OPT-36 round 2: test_opt34 keeps its tolerances; fresh sensors read the day they are on
checks / unit (pull_request) Successful in 20m36s
infra-pin / fresh (pull_request) Successful in 2s
3a18475a5a
The silent and fresh nights diverged only because the test's fresh sensors
kept reading the evening's 0.4 kWh 'left today' after midnight, while the
kept figure is the 4th's 6.0 kWh (solarfc.Hold.stand_in, as_today): two
different shortfalls (16.5 and 12.7 kWh) that A's ceiling hid until B was
counted. Fresh sensors now read 6.0 after midnight, so fresh and kept are
the same figure; the 0.3 tolerance is back, the other exact values are
recomputed. test_ux54 literals are recomputed too.

Co-Authored-By: Claude <noreply@anthropic.com>
OPT-36 round 3: B's charge counts the cheap time left; OPT-34 nights on their own shapes
checks / unit (pull_request) Failing after 36m29s
infra-pin / fresh (pull_request) Successful in 2s
e4b9dee699
The run is sized at the batteries' ratings, not the peak limit, so a run too
short to fill a Cheap hours battery is planned again later in the night.
Counting that run alone made B's give grow through the night and A's level
fall after A had bought (round 2: 55 -> 69 -> 41 -> 37 %, A to 56 %).
dayplan._cheap_give_kwh() now also counts the later firm slots before the
expensive hours that a run would still be worth charging in (price + the
spread control asks at most the give run's dearest slot); the Controller
passes the slots and the spread.

test_opt34: back to the original house shapes, fixture and expected values.
B is Off in the nights that test A's level (a Cheap hours B now covers
these hours); B's checks run in new `_b` nights; the 03:00 check runs in a
night from midnight; tail starts A at 60 %; late_fresh reads the kept 6.0.
test_opt36: slot cases, a whole night on one figure (level never moves),
F-1 with B counted (raised level reached and held). test_ux54: the run end
is read from the plan and asserted (02:30); the F1/F2 sweep uses a peak
limit that does not bind and reads a level shown as the target as at it.

Co-Authored-By: Claude <noreply@anthropic.com>
OPT-36 round 3: test_opt36 reads the mid_flat level through nth()
checks / unit (pull_request) Successful in 26m38s
infra-pin / fresh (pull_request) Successful in 2s
1ac7fe98d7
Co-Authored-By: Claude <noreply@anthropic.com>
OPT-36 round 4: count only charge control will make; Solar first drain at the night base
checks / unit (pull_request) Successful in 44m14s
infra-pin / fresh (pull_request) Successful in 2s
eb9ccc2730
Review F1: a slot after B's run counts only if no slot from the expensive
hours on is cheaper (control plans B's charge left in the cheapest window
ahead), and x 0.95 of B's charge is stored. Three-price night: 1ac7fe9 left
the expensive hours 2.61 kWh short; now 0.
Review F2: a Solar first battery's drain until the expensive hours reads each
hour at no less than the night base (the profile is net of the sun). Read net,
a dark morning drained the battery the plan still counted; A's level fell,
the cheap run moved and was lost before it started (+0.40 EUR per 3 days).
The two real-price replays now cost what 0.20.0 does.
F3: the ux54 sweep's peak limit is 15 kW (the option's top). F4: the rest
comes from the grid (EN/NL). F5: CHANGELOG and DECISIONS wording.

Co-Authored-By: Claude <noreply@anthropic.com>
Release 0.20.1
checks / unit (pull_request) Successful in 28m19s
infra-pin / fresh (pull_request) Successful in 1s
ec4ba49f45
Patch bump: OPT-36 (Leftover solar counts Cheap hours only and Solar first batteries). No option changes.

Co-Authored-By: Claude <noreply@anthropic.com>
REL-0.20.1 review: CHANGELOG known issues SAFETY-132/133 wording
checks / unit (pull_request) Failing after 22m19s
infra-pin / fresh (pull_request) Successful in 1s
01eba51dd7
SAFETY-132: the 9.6 kW is the charge the add-on asked for in a test,
not a measured grid figure. SAFETY-133: the quarter also ends over the
3 500 W limit; the guard sees the load late (0.20.1 has no lateness check).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TEST-37: test_opt34 builds the first Controller under the scenario clock
checks / unit (pull_request) Successful in 30m38s
infra-pin / fresh (pull_request) Successful in 2s
95bb214155
The stale_live scenario stores a latch ending 2026-11-04 07:15 CET. The first
Controller was built before the datetime patch, so Controller.__init__ judged
that latch against the real clock and it expired on 2026-11-04. Build it after
the patch (clock = scenario start), as the restart path already did. Test-only.

Co-Authored-By: Claude <noreply@anthropic.com>
Merge hotfix-0.20.1 (TEST-37 #231) into release-0.20.1
checks / unit (pull_request) Successful in 21m40s
infra-pin / fresh (pull_request) Successful in 2s
2fa14e23dc
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge pull request 'Release 0.20.1' (#230) from release-0.20.1 into hotfix-0.20.1
checks / unit (pull_request) Successful in 21m15s
infra-pin / fresh (pull_request) Successful in 1s
3219aea9a0
All checks were successful
checks / unit (pull_request) Successful in 21m15s
Required
Details
infra-pin / fresh (pull_request) Successful in 1s
You are not authorized to merge this pull request.
This pull request can be merged automatically.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin hotfix-0.20.1:hotfix-0.20.1
git checkout hotfix-0.20.1
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#232