Release 0.18.1 #196

Merged
admin merged 2 commits from release-0.18.1 into release/1.0 2026-10-16 13:46:25 +02:00
Owner

Cuts 0.18.1: config.yaml version 0.18.0 -> 0.18.1 and a closed ## 0.18.1 CHANGELOG section. No code change. Not merged, no tag, no deploy.

Version: 0.18.1 (patch). Two settings-page fixes: UX-43 (#194, tariff price fields take 5 decimals) and UX-44 (#195, contract label says every 15 minutes). Checked a0e091c..release/1.0: config.yaml, translations/ and app/validate.py are not in the diff, and the only app/ changes are uilayout.py (step 0.01 -> 0.00001 on the four tariff fields), ui_text/en.json / nl.json (hints and the label) and static/settings.js (reads the step from the field). No option added, removed or renamed, no default changed (86 options). Existing installs need no option change.

Offline checks (goodwe-addon-checks:1, --network none): test_version_gate, test_docs, test_defaults_pin, test_validate, test_tool_inputs pass. predeploy_check.py --deployed-version 0.18.0 on the live options: REFUSED before the bump (no-op, 3 runtime commits), CLEARED after it, no warnings.

Release note (owner, "F2 in 0.18.1"): from UX-43 test check 1, on 0.18.0 fixed, day and night prices were rounded to 2 decimals on save; the CHANGELOG tells users to enter them again.

Known issues: the 0.18.0 list is kept (all still open). Added SAFETY-118 and UX-45. Left out: AUDIT-01 (an audit card, no visible effect). UX-43 and UX-44 are Done.

Deviations from docs/RELEASE.md (same as 0.18.0)

  1. release/1.0 is protected, so the bump goes through this PR.
  2. The CHANGELOG section is written to the CI gate (test_version_gate part 11).
  3. No tag made.

CHANGELOG section (verbatim)

0.18.1

A patch bump: two small fixes to the settings page, and 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.18.0 also
start 0.18.1. The changes below apply with one inverter or two.

Price rounding on 0.18.0. On 0.18.0, the new settings page saved the fixed,
day and night prices rounded to 2 decimals (0.34512 became 0.35); prices in time
windows kept their decimals. If you typed more than 2 decimals in those
fields on 0.18.0, enter them again.

Contents of this release, in merge order since 0.18.0 (a0e091c):

b703aaa The four tariff price fields on the new settings page (fixed, day, night and time windows) take 5 decimals, for example 0.34512 €/kWh, and are saved as typed. A short hint says to divide the c€/kWh on your bill by 100 (UX-43, #194)
8e02a09 The dynamic contract choice on the new settings page now says "Dynamic, every 15 minutes" ("Dynamisch, per kwartier") instead of "hourly". The choice works as before, and one line in the docs no longer calls dynamic prices hourly (UX-44, #195)

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 (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).
  • If the 15-minute demand forecast sensor reads in kW, the settings page warns that its number is taken as watts and asks for a sensor in W. The add-on does turn kW into W, so a kW sensor works (SAFETY-118).
  • The price chart on the Home page shows one bar per hour, the average of four 15-minute prices, while the add-on decides on the 15-minute prices (UX-45).

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.

Cuts **0.18.1**: `config.yaml` `version` 0.18.0 -> 0.18.1 and a closed `## 0.18.1` CHANGELOG section. No code change. Not merged, no tag, no deploy. **Version: 0.18.1 (patch).** Two settings-page fixes: UX-43 (#194, tariff price fields take 5 decimals) and UX-44 (#195, contract label says every 15 minutes). Checked a0e091c..release/1.0: `config.yaml`, `translations/` and `app/validate.py` are not in the diff, and the only `app/` changes are `uilayout.py` (step 0.01 -> 0.00001 on the four tariff fields), `ui_text/en.json` / `nl.json` (hints and the label) and `static/settings.js` (reads the step from the field). No option added, removed or renamed, no default changed (86 options). **Existing installs need no option change.** **Offline checks (`goodwe-addon-checks:1`, `--network none`):** test_version_gate, test_docs, test_defaults_pin, test_validate, test_tool_inputs pass. `predeploy_check.py --deployed-version 0.18.0` on the live options: REFUSED before the bump (no-op, 3 runtime commits), CLEARED after it, no warnings. **Release note (owner, "F2 in 0.18.1"):** from UX-43 test check 1, on 0.18.0 fixed, day and night prices were rounded to 2 decimals on save; the CHANGELOG tells users to enter them again. **Known issues:** the 0.18.0 list is kept (all still open). Added SAFETY-118 and UX-45. Left out: AUDIT-01 (an audit card, no visible effect). UX-43 and UX-44 are Done. ## Deviations from docs/RELEASE.md (same as 0.18.0) 1. `release/1.0` is protected, so the bump goes through this PR. 2. The CHANGELOG section is written to the CI gate (test_version_gate part 11). 3. No tag made. ## CHANGELOG section (verbatim) ## 0.18.1 **A patch bump: two small fixes to the settings page, and 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.18.0 also start 0.18.1. The changes below apply with one inverter or two. **Price rounding on 0.18.0.** On 0.18.0, the new settings page saved the fixed, day and night prices rounded to 2 decimals (0.34512 became 0.35); prices in time windows kept their decimals. If you typed more than 2 decimals in those fields on 0.18.0, enter them again. Contents of this release, in merge order since 0.18.0 (`a0e091c`): | | | |---|---| | `b703aaa` | The four tariff price fields on the new settings page (fixed, day, night and time windows) take 5 decimals, for example 0.34512 €/kWh, and are saved as typed. A short hint says to divide the c€/kWh on your bill by 100 ([[UX-43]], #194) | | `8e02a09` | The dynamic contract choice on the new settings page now says "Dynamic, every 15 minutes" ("Dynamisch, per kwartier") instead of "hourly". The choice works as before, and one line in the docs no longer calls dynamic prices hourly ([[UX-44]], #195) | ### 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 ([[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]]). - If the 15-minute demand forecast sensor reads in kW, the settings page warns that its number is taken as watts and asks for a sensor in W. The add-on does turn kW into W, so a kW sensor works ([[SAFETY-118]]). - The price chart on the Home page shows one bar per hour, the average of four 15-minute prices, while the add-on decides on the 15-minute prices ([[UX-45]]). ### 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 1 commit 2026-10-16 12:09:07 +02:00
Release 0.18.1
checks / unit (pull_request) Successful in 40m39s
infra-pin / fresh (pull_request) Successful in 2s
dec8e7b69f
Version 0.18.0 -> 0.18.1 (patch, no option changes) and a closed 0.18.1 CHANGELOG section.

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

Model-router verdict T56 (dev round 1, Sonnet): PASS from the Opus verifier. Head dec8e7b69f (ls-remote checked); CI run 1307 checks/unit and run 1308 infra-pin green. Next: Opus review.

Model-router verdict T56 (dev round 1, Sonnet): PASS from the Opus verifier. Head dec8e7b69fc8fae2c3de59de7ee3f7cff18bb076 (ls-remote checked); CI run 1307 checks/unit and run 1308 infra-pin green. Next: Opus review.
admin added 1 commit 2026-10-16 13:05:23 +02:00
Release 0.18.1 review: CHANGELOG text fixes
checks / unit (pull_request) Successful in 40m18s
infra-pin / fresh (pull_request) Successful in 1s
0ee3c3468b
SAFETY-118 line: the add-on already turns a kW forecast into W
(main.py read_inputs, abs(raw) < 50), so only the settings-page warning is
wrong. Rounding note and rows: the new settings page; UX-44 also changed
one DOCS line.

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

Review of #196 (REL-0.18.1). Reviewed head dec8e7b. Findings are CHANGELOG text only; fixed in 0ee3c34 (one commit on dec8e7b, verified with ls-remote). PR body's verbatim section updated to match.

  • F1 (medium, CHANGELOG.md:56, SAFETY-118 line): the line is not true on the code. main.py:3450-3453 (read_inputs, on 8e02a09 and since the first add-on commit) reads peak_forecast_entity with "Accept kW or W": raw * 1000 if abs(raw) < 50 else raw. So 0.82 kW is used as 820 W, not 0.82 W, and the forecast steps (maintenance_charge_floor, peak_at_risk / shaping_suspended) get watts. Live evidence agrees: SAFETY-111 saw peak_fc 2254 W from the same sensor.piek_prognose_kwartier on 0.17.0, with the charge set to exactly 3450 - 2254 W. What is real: the settings-page note (validate.py:1828-1831, _entity_notes, shown via config_notes) says a kW sensor "is taken as watts, so pick a sensor in W". New text: "If the 15-minute demand forecast sensor reads in kW, the settings page warns that its number is taken as watts and asks for a sensor in W. The add-on does turn kW into W, so a kW sensor works." "Pick a sensor that reads in W" is dropped: it is not needed, and a W sensor reading 1-49 W would be taken as kW by the same rule (code reading only). The card SAFETY-118 itself rests on the warning text, not the code; that is for the manager.
  • F2 (low, CHANGELOG.md:10-12, rounding note): the rounding was on the new settings page (settings.js stored() rounds to the field step 0.01 on input, and that value is saved; the classic page saves static_profile as text). "rounded ... when you saved" became "the new settings page saved ... rounded to 2 decimals". Fields, example and the time-window exception match UX-43 test check 1 and the 0.18.0 code (window row uses +price.value, no rounding). Still says nothing about versions before 0.18.0.
  • F3 (low, CHANGELOG.md:20, UX-44 row): "Nothing else changes" was not exact: UX-44 also changed one DOCS line ("hourly pricing" -> "dynamic pricing"). Now: "The choice works as before, and one line in the docs no longer calls dynamic prices hourly."
  • F4 (low, rows at :19-20): "the settings page" -> "the new settings page", as in the 0.18.0 known issues (UX-41 / UX-42), since the classic page has its own Save.

Checked and OK: diff is config.yaml + the new section only; heading = version; patch is right (config.yaml, translations/, validate.py unchanged a0e091c..8e02a09; 86/86 options; only field steps changed); contents table = exactly b703aaa and 8e02a09; "saved as typed" holds for all four fields (UX-43 test check 2); hint wording matches en/nl.json; 32 kept known issues word for word, all To Do except SAFETY-97 (Done, line stays as in 0.18.0); UX-45 matches app.js:184 and homeview.hour_bars; AUDIT-01 left out: agree. Offline tests and predeploy (CLEARED, rc 0, no warnings) pass on 0ee3c34; heading and version mutations each fail test_version_gate.

Merging once checks / unit (pull_request) is green on 0ee3c34.

**Review of #196 (REL-0.18.1).** Reviewed head `dec8e7b`. Findings are CHANGELOG text only; fixed in `0ee3c34` (one commit on dec8e7b, verified with ls-remote). PR body's verbatim section updated to match. - **F1 (medium, CHANGELOG.md:56, SAFETY-118 line): the line is not true on the code.** `main.py:3450-3453` (read_inputs, on 8e02a09 and since the first add-on commit) reads `peak_forecast_entity` with "Accept kW or W": `raw * 1000 if abs(raw) < 50 else raw`. So 0.82 kW is used as 820 W, not 0.82 W, and the forecast steps (`maintenance_charge_floor`, `peak_at_risk` / `shaping_suspended`) get watts. Live evidence agrees: SAFETY-111 saw `peak_fc` 2254 W from the same `sensor.piek_prognose_kwartier` on 0.17.0, with the charge set to exactly 3450 - 2254 W. What is real: the settings-page note (`validate.py:1828-1831`, `_entity_notes`, shown via `config_notes`) says a kW sensor "is taken as watts, so pick a sensor in W". New text: "If the 15-minute demand forecast sensor reads in kW, the settings page warns that its number is taken as watts and asks for a sensor in W. The add-on does turn kW into W, so a kW sensor works." "Pick a sensor that reads in W" is dropped: it is not needed, and a W sensor reading 1-49 W would be taken as kW by the same rule (code reading only). The card SAFETY-118 itself rests on the warning text, not the code; that is for the manager. - **F2 (low, CHANGELOG.md:10-12, rounding note):** the rounding was on the new settings page (`settings.js` `stored()` rounds to the field step 0.01 on input, and that value is saved; the classic page saves `static_profile` as text). "rounded ... when you saved" became "the new settings page saved ... rounded to 2 decimals". Fields, example and the time-window exception match UX-43 test check 1 and the 0.18.0 code (window row uses `+price.value`, no rounding). Still says nothing about versions before 0.18.0. - **F3 (low, CHANGELOG.md:20, UX-44 row):** "Nothing else changes" was not exact: UX-44 also changed one DOCS line ("hourly pricing" -> "dynamic pricing"). Now: "The choice works as before, and one line in the docs no longer calls dynamic prices hourly." - **F4 (low, rows at :19-20):** "the settings page" -> "the new settings page", as in the 0.18.0 known issues (UX-41 / UX-42), since the classic page has its own Save. Checked and OK: diff is config.yaml + the new section only; heading = version; patch is right (config.yaml, translations/, validate.py unchanged a0e091c..8e02a09; 86/86 options; only field steps changed); contents table = exactly b703aaa and 8e02a09; "saved as typed" holds for all four fields (UX-43 test check 2); hint wording matches en/nl.json; 32 kept known issues word for word, all To Do except SAFETY-97 (Done, line stays as in 0.18.0); UX-45 matches `app.js:184` and `homeview.hour_bars`; AUDIT-01 left out: agree. Offline tests and predeploy (CLEARED, rc 0, no warnings) pass on 0ee3c34; heading and version mutations each fail test_version_gate. Merging once `checks / unit (pull_request)` is green on 0ee3c34.
admin merged commit 780c1f67bb into release/1.0 2026-10-16 13:46:25 +02:00
Author
Owner

Merged with head_commit_id = 0ee3c34 after checks / unit (pull_request) succeeded on it (run 1309, 13:05-13:45, a real run; infra-pin / fresh run 1310 also succeeded). Merge commit 780c1f6 (parents 8e02a09, 0ee3c34; its tree is the same as 0ee3c34). ls-remote: release/1.0 780c1f6, release-0.18.1 0ee3c34, master 3b7d6b7 (unchanged). No tag, no master PR, no deploy.

Merged with `head_commit_id` = 0ee3c34 after `checks / unit (pull_request)` succeeded on it (run 1309, 13:05-13:45, a real run; `infra-pin / fresh` run 1310 also succeeded). Merge commit `780c1f6` (parents 8e02a09, 0ee3c34; its tree is the same as 0ee3c34). ls-remote: release/1.0 780c1f6, release-0.18.1 0ee3c34, master 3b7d6b7 (unchanged). No tag, no master PR, no deploy.
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#196