Cuts 0.15.0: config.yamlversion 0.14.0 -> 0.15.0 and a closed ## 0.15.0 CHANGELOG section. No code change.
Version: 0.15.0 (minor). Behaviour change from SAFETY-94 + SAFETY-97 (#171), at one inverter and at two. Same rule as 0.14.0 (new behaviour, no option change = minor).
Option diff vs 0.14.0 (02ed120): none.config.yaml differs only in version (83 options, 83 schema keys). app/validate.py and translations/ are unchanged, so there are no new start-up refusals. The only new persisted state is one store key per battery, unit/<name>/idle_w (learned, not an option).
Checks run locally (offline, goodwe-addon-checks:1, --network none, nothing live touched):
test_version_gate.py (part 11 included), test_docs.py, test_defaults_pin.py, test_validate.py, test_tool_inputs.py: all pass.
tools/predeploy_check.py --deployed-version 0.14.0 --options scratch/STAGE5/settings-v4.json (bare options, the current live options incl. the two-inverter roster): REFUSED (no-op: 3 runtime commits behind an unchanged version) before the bump, CLEARED after it ("live options pass this version's validator"). The deploy step re-exports fresh options and runs it again.
Deviations from docs/RELEASE.md (same as the 0.13.0 and 0.14.0 cuts)
Step 1 says "bump version: on release/1.0". release/1.0 is protected, so the bump goes through this PR (branch release-0.15.0).
RELEASE.md says nothing about the CHANGELOG. The section is written to the CI gate (test_version_gate.py part 11): heading = config.yaml version, exactly one "in merge order since" table, the three withdrawn price_provider ids named.
RELEASE.md says nothing about tags. No tag made; v0.15.0 is left to the manager.
RELEASE.md does not ask for predeploy_check.py at cut time. It was run anyway, offline only.
What the deploy needs (separate owner go)
Same pinned-branch flow as 0.13.0 / 0.14.0, after this PR is merged into release/1.0:
Create a deploy-0.15.0 branch at the release merge commit and open a PR deploy-0.15.0 -> master. No push to master.
Wait for checks / unit (pull_request) to be green (a skipped is not green).
Merge it, pinning head_commit_id, only after the owner's go. A merge to master is a deployment.
Before the update, export fresh live data.options and run predeploy_check.py with the deployed version read from the box.
ha store reload && ha addons update 68285ac7_goodwe_controller on the live HA (not local_goodwe_controller as RELEASE.md step 5 says). Needs the owner's go, which lifts the standing "no ha addons update" rule.
Watchdog stays on (SAFETY-61).
After the update each battery learns its rest reading after about two quiet minutes and saves it (unit/<name>/idle_w); until then the old 0 W centre applies.
Rollback: revert on release/1.0, bump again, take the same path (RELEASE.md §3).
CHANGELOG section (verbatim)
0.15.0
A minor bump: changed behaviour, and no option changes. No option was
added, removed or renamed, and no default changed (83 options). Options that
start 0.14.0 also start 0.15.0. The changes below apply with one inverter and
with two.
The add-on now learns and saves, per battery, what its power reading shows
at rest (unit/<name>/idle_w). It learns it after about two quiet minutes and
uses 0 W until then, as before. There is nothing to set.
Contents of this release, in merge order since 0.14.0 (02ed120):
cf705a9
No more false "battery power reading stopped changing" errors at a new command after a rest, or at a change of phase. Each one paused control for a few seconds (several a day on a live site). A healthy battery that lags or turns around is no longer held as refusing for up to 15 min. With two inverters, a refusing battery whose reading at rest is about −100 W is now caught too. The rest value used is limited to ±75 W (SAFETY-94, SAFETY-97, also fixes SAFETY-58)
3129dae
CI tests against a newer admin/goodwe (CI only) (CI-14)
Known issues
A false "Battery is not keeping up" can still show when the peak guard pauses a maintenance charge (SAFETY-92).
After a gap in the P1 meter, the peak guard is blind for the rest of that quarter hour (SAFETY-90).
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 ±170 W is still not caught when it refuses, as in 0.14.0 (SAFETY-97).
Two inverters: if one battery's drain stops early (e.g. switched Off), the other battery can jump to about 1.6 kW at once, and the surplus goes to the grid (SAFETY-95).
Two inverters: after one battery's link drops, control can stall until a safety stop (SAFETY-96).
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).
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.15.0**: `config.yaml` `version` 0.14.0 -> 0.15.0 and a closed `## 0.15.0` CHANGELOG section. No code change.
**Version: 0.15.0 (minor).** Behaviour change from SAFETY-94 + SAFETY-97 (#171), at one inverter and at two. Same rule as 0.14.0 (new behaviour, no option change = minor).
**Option diff vs 0.14.0 (`02ed120`): none.** `config.yaml` differs only in `version` (83 options, 83 schema keys). `app/validate.py` and `translations/` are unchanged, so there are no new start-up refusals. The only new persisted state is one store key per battery, `unit/<name>/idle_w` (learned, not an option).
**Checks run locally (offline, `goodwe-addon-checks:1`, `--network none`, nothing live touched):**
- `test_version_gate.py` (part 11 included), `test_docs.py`, `test_defaults_pin.py`, `test_validate.py`, `test_tool_inputs.py`: all pass.
- `tools/predeploy_check.py --deployed-version 0.14.0 --options scratch/STAGE5/settings-v4.json` (bare options, the current live options incl. the two-inverter roster): **REFUSED** (no-op: 3 runtime commits behind an unchanged version) before the bump, **CLEARED** after it ("live options pass this version's validator"). The deploy step re-exports fresh options and runs it again.
## Deviations from docs/RELEASE.md (same as the 0.13.0 and 0.14.0 cuts)
1. Step 1 says "bump `version:` on `release/1.0`". `release/1.0` is protected, so the bump goes through this PR (branch `release-0.15.0`).
2. RELEASE.md says nothing about the CHANGELOG. The section is written to the CI gate (`test_version_gate.py` part 11): heading = config.yaml version, exactly one "in merge order since" table, the three withdrawn `price_provider` ids named.
3. RELEASE.md says nothing about tags. No tag made; `v0.15.0` is left to the manager.
4. RELEASE.md does not ask for `predeploy_check.py` at cut time. It was run anyway, offline only.
## What the deploy needs (separate owner go)
Same pinned-branch flow as 0.13.0 / 0.14.0, after this PR is merged into `release/1.0`:
1. Create a `deploy-0.15.0` branch at the release merge commit and open a PR `deploy-0.15.0` -> `master`. No push to `master`.
2. Wait for `checks / unit (pull_request)` to be **green** (a `skipped` is not green).
3. Merge it, pinning `head_commit_id`, only after the owner's go. A merge to `master` is a deployment.
4. Before the update, export fresh live `data.options` and run `predeploy_check.py` with the deployed version read from the box.
5. `ha store reload && ha addons update 68285ac7_goodwe_controller` on the live HA (not `local_goodwe_controller` as RELEASE.md step 5 says). Needs the owner's go, which lifts the standing "no `ha addons update`" rule.
6. Watchdog stays on (SAFETY-61).
7. After the update each battery learns its rest reading after about two quiet minutes and saves it (`unit/<name>/idle_w`); until then the old 0 W centre applies.
8. Rollback: revert on `release/1.0`, bump again, take the same path (RELEASE.md §3).
## CHANGELOG section (verbatim)
## 0.15.0
**A minor bump: changed behaviour, and no option changes.** No option was
added, removed or renamed, and no default changed (83 options). Options that
start 0.14.0 also start 0.15.0. The changes below apply with one inverter and
with two.
The add-on now learns and saves, per battery, what its power reading shows
at rest (`unit/<name>/idle_w`). It learns it after about two quiet minutes and
uses 0 W until then, as before. There is nothing to set.
Contents of this release, in merge order since 0.14.0 (`02ed120`):
| | |
|---|---|
| `cf705a9` | No more false "battery power reading stopped changing" errors at a new command after a rest, or at a change of phase. Each one paused control for a few seconds (several a day on a live site). A healthy battery that lags or turns around is no longer held as refusing for up to 15 min. With two inverters, a refusing battery whose reading at rest is about −100 W is now caught too. The rest value used is limited to ±75 W ([[SAFETY-94]], [[SAFETY-97]], also fixes [[SAFETY-58]]) |
| `3129dae` | CI tests against a newer `admin/goodwe` (CI only) ([[CI-14]]) |
### Known issues
- A false "Battery is not keeping up" can still show when the peak guard pauses a maintenance charge ([[SAFETY-92]]).
- After a gap in the P1 meter, the peak guard is blind for the rest of that quarter hour ([[SAFETY-90]]).
- 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 ±170 W is still not caught when it refuses, as in 0.14.0 ([[SAFETY-97]]).
- Two inverters: if one battery's drain stops early (e.g. switched Off), the other battery can jump to about 1.6 kW at once, and the surplus goes to the grid ([[SAFETY-95]]).
- Two inverters: after one battery's link drops, control can stall until a safety stop ([[SAFETY-96]]).
- 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]]).
### 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_019DBUfvndgHwaV339Fvd2gr
config.yaml version 0.14.0 -> 0.15.0 (minor: behaviour change from
SAFETY-94/97, no option change). New `## 0.15.0` section with the contents
since 0.14.0 (cf705a9#171, 3129dae#172) and the known issues.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Minor bump is right. 02ed120 → 3129dae → f01152b: config.yaml differs only in version; app/validate.py and translations/ unchanged; no option default changed in code (the compute() change adds keyword args, not options). 83 options.
Contents table = exactly the two first-parent merges since 02ed120 (cf705a9#171, 3129dae#172).
"up to 15 min" (PROBE_EVERY_S = 900), "about −100 W" (B −95 to −118 W), "limited to ±75 W" (IDLE_MAX_W) match the code and DECISIONS.
"apply with one inverter and with two": true. The stale gate (freshness._oblige) is per inverter at every roster size, and _gave_nothing plus the idle centre are used at N=1 too.
Known issues: SAFETY-94 is gone (fixed), SAFETY-74 (not fixed, per DECISIONS) and SAFETY-98 (review T2: B's idle counted as circulating) are added. The rest are carried over.
Findings (I push the fixes myself):
F1. "Each one held a battery at 0 W for about 17 s (about 4 a day)" is not true. A stale trip makes the reading a missing input: control holds its last command for stale_input_s (15 s) and goes to 0 W only after that. It clears at the next register change. The 4 live trips of 10-03 all cleared within about 1–10 s (HA history in scratch/SAFETY-94/live-history-*.json: B's command went 268 → 479 W through its 15:39:16Z trip, and B's reading changed at 15:39:21Z). Nothing went to 0 W. 17 s is RELEASE_S, which plays no part here. Also, 10-04 had 4 more trips between 08:45 and 09:45, so "about 4 a day" is low. Fix: "Each one paused control for a few seconds (several a day on a live site)."
F2. "a battery that refuses is still caught, now also with two inverters" reads as if no refusal was caught with two inverters before. A refusing A was caught at N=2. Only a battery whose rest reading is about −100 W was never caught at N=2 (and at N=1, 0.14.0 caught it in 17–105 s). Fix: "With two inverters, a refusing battery whose reading at rest is about −100 W is now caught too." Also add to the paragraph above the table that it learns after about two quiet minutes and uses 0 W until then. The owner will see this right after the update.
F3 (manager request). Add a known issue. DECISIONS/SAFETY-97 "Cost": "A battery whose idle reading is beyond about ±170 W ... behaves as in 0.14.0 (not caught by this rule)" (75 W clamp + 100 W band). Line: "A battery whose reading at rest is beyond about ±170 W is still not caught when it refuses, as in 0.14.0 (SAFETY-97)."
**Review round 1 (REL-0.15.0), head f01152b.**
Checked and fine:
- Minor bump is right. 02ed120 → 3129dae → f01152b: `config.yaml` differs only in `version`; `app/validate.py` and `translations/` unchanged; no option default changed in code (the `compute()` change adds keyword args, not options). 83 options.
- Contents table = exactly the two first-parent merges since 02ed120 (`cf705a9` #171, `3129dae` #172).
- "up to 15 min" (`PROBE_EVERY_S = 900`), "about −100 W" (B −95 to −118 W), "limited to ±75 W" (`IDLE_MAX_W`) match the code and DECISIONS.
- "apply with one inverter and with two": true. The stale gate (`freshness._oblige`) is per inverter at every roster size, and `_gave_nothing` plus the idle centre are used at N=1 too.
- Known issues: SAFETY-94 is gone (fixed), SAFETY-74 (not fixed, per DECISIONS) and SAFETY-98 (review T2: B's idle counted as circulating) are added. The rest are carried over.
Findings (I push the fixes myself):
- **F1. "Each one held a battery at 0 W for about 17 s (about 4 a day)" is not true.** A stale trip makes the reading a missing input: control holds its last command for `stale_input_s` (15 s) and goes to 0 W only after that. It clears at the next register change. The 4 live trips of 10-03 all cleared within about 1–10 s (HA history in `scratch/SAFETY-94/live-history-*.json`: B's command went 268 → 479 W through its 15:39:16Z trip, and B's reading changed at 15:39:21Z). Nothing went to 0 W. 17 s is `RELEASE_S`, which plays no part here. Also, 10-04 had 4 more trips between 08:45 and 09:45, so "about 4 a day" is low. Fix: "Each one paused control for a few seconds (several a day on a live site)."
- **F2. "a battery that refuses is still caught, now also with two inverters" reads as if no refusal was caught with two inverters before.** A refusing A was caught at N=2. Only a battery whose rest reading is about −100 W was never caught at N=2 (and at N=1, 0.14.0 caught it in 17–105 s). Fix: "With two inverters, a refusing battery whose reading at rest is about −100 W is now caught too." Also add to the paragraph above the table that it learns after about two quiet minutes and uses 0 W until then. The owner will see this right after the update.
- **F3 (manager request). Add a known issue.** DECISIONS/SAFETY-97 "Cost": "A battery whose idle reading is beyond about ±170 W ... behaves as in 0.14.0 (not caught by this rule)" (75 W clamp + 100 W band). Line: "A battery whose reading at rest is beyond about ±170 W is still not caught when it refuses, as in 0.14.0 ([[SAFETY-97]])."
F1 fixed: "errors ... Each one paused control for a few seconds (several a day on a live site)."
F2 fixed: "With two inverters, a refusing battery whose reading at rest is about −100 W is now caught too." The paragraph above the table now says it learns after about two quiet minutes and uses 0 W until then.
F3 fixed: known issue "A battery whose reading at rest is beyond about ±170 W is still not caught when it refuses, as in 0.14.0 (SAFETY-97)."
Offline in goodwe-addon-checks:1 (--network none): test_version_gate, test_docs, test_defaults_pin, test_validate, test_tool_inputs all pass. Waiting for checks / unit (pull_request) on 8c6e5bc.
**Round 1 fixes pushed: 8c6e5bc** (CHANGELOG only; PR body's verbatim section updated to match).
- F1 fixed: "errors ... Each one paused control for a few seconds (several a day on a live site)."
- F2 fixed: "With two inverters, a refusing battery whose reading at rest is about −100 W is now caught too." The paragraph above the table now says it learns after about two quiet minutes and uses 0 W until then.
- F3 fixed: known issue "A battery whose reading at rest is beyond about ±170 W is still not caught when it refuses, as in 0.14.0 ([[SAFETY-97]])."
Offline in `goodwe-addon-checks:1` (`--network none`): test_version_gate, test_docs, test_defaults_pin, test_validate, test_tool_inputs all pass. Waiting for `checks / unit (pull_request)` on 8c6e5bc.
admin
merged commit 3ed3302d2f into release/1.02026-10-05 01:52:41 +02:00
Merged as 3ed3302 into release/1.0, pinned head_commit_id = 8c6e5bc (checks / unit (pull_request) success, run 1174). The merged tree is identical to the PR head. No tag, nothing on master, nothing deployed.
**Merged** as 3ed3302 into `release/1.0`, pinned `head_commit_id` = 8c6e5bc (`checks / unit (pull_request)` success, run 1174). The merged tree is identical to the PR head. No tag, nothing on `master`, nothing deployed.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Cuts 0.15.0:
config.yamlversion0.14.0 -> 0.15.0 and a closed## 0.15.0CHANGELOG section. No code change.Version: 0.15.0 (minor). Behaviour change from SAFETY-94 + SAFETY-97 (#171), at one inverter and at two. Same rule as 0.14.0 (new behaviour, no option change = minor).
Option diff vs 0.14.0 (
02ed120): none.config.yamldiffers only inversion(83 options, 83 schema keys).app/validate.pyandtranslations/are unchanged, so there are no new start-up refusals. The only new persisted state is one store key per battery,unit/<name>/idle_w(learned, not an option).Checks run locally (offline,
goodwe-addon-checks:1,--network none, nothing live touched):test_version_gate.py(part 11 included),test_docs.py,test_defaults_pin.py,test_validate.py,test_tool_inputs.py: all pass.tools/predeploy_check.py --deployed-version 0.14.0 --options scratch/STAGE5/settings-v4.json(bare options, the current live options incl. the two-inverter roster): REFUSED (no-op: 3 runtime commits behind an unchanged version) before the bump, CLEARED after it ("live options pass this version's validator"). The deploy step re-exports fresh options and runs it again.Deviations from docs/RELEASE.md (same as the 0.13.0 and 0.14.0 cuts)
version:onrelease/1.0".release/1.0is protected, so the bump goes through this PR (branchrelease-0.15.0).test_version_gate.pypart 11): heading = config.yaml version, exactly one "in merge order since" table, the three withdrawnprice_providerids named.v0.15.0is left to the manager.predeploy_check.pyat cut time. It was run anyway, offline only.What the deploy needs (separate owner go)
Same pinned-branch flow as 0.13.0 / 0.14.0, after this PR is merged into
release/1.0:deploy-0.15.0branch at the release merge commit and open a PRdeploy-0.15.0->master. No push tomaster.checks / unit (pull_request)to be green (askippedis not green).head_commit_id, only after the owner's go. A merge tomasteris a deployment.data.optionsand runpredeploy_check.pywith the deployed version read from the box.ha store reload && ha addons update 68285ac7_goodwe_controlleron the live HA (notlocal_goodwe_controlleras RELEASE.md step 5 says). Needs the owner's go, which lifts the standing "noha addons update" rule.unit/<name>/idle_w); until then the old 0 W centre applies.release/1.0, bump again, take the same path (RELEASE.md §3).CHANGELOG section (verbatim)
0.15.0
A minor bump: changed behaviour, and no option changes. No option was
added, removed or renamed, and no default changed (83 options). Options that
start 0.14.0 also start 0.15.0. The changes below apply with one inverter and
with two.
The add-on now learns and saves, per battery, what its power reading shows
at rest (
unit/<name>/idle_w). It learns it after about two quiet minutes anduses 0 W until then, as before. There is nothing to set.
Contents of this release, in merge order since 0.14.0 (
02ed120):cf705a93129daeadmin/goodwe(CI only) (CI-14)Known issues
If you are crossing from a version older than 0.10.0
## 0.10.0below can refuse an old config:slew_wabove its limit, and thewithdrawn
price_provideridsengie_dynamic,totalenergies_dynamicandeneco_eddy. Read it before you update. Runtools/predeploy_check.pywith thebare options (
jq '.data.options') first.🤖 Generated with Claude Code
https://claude.ai/code/session_019DBUfvndgHwaV339Fvd2gr
Review round 1 (REL-0.15.0), head
f01152b.Checked and fine:
02ed120→3129dae→f01152b:config.yamldiffers only inversion;app/validate.pyandtranslations/unchanged; no option default changed in code (thecompute()change adds keyword args, not options). 83 options.02ed120(cf705a9#171,3129dae#172).PROBE_EVERY_S = 900), "about −100 W" (B −95 to −118 W), "limited to ±75 W" (IDLE_MAX_W) match the code and DECISIONS.freshness._oblige) is per inverter at every roster size, and_gave_nothingplus the idle centre are used at N=1 too.Findings (I push the fixes myself):
stale_input_s(15 s) and goes to 0 W only after that. It clears at the next register change. The 4 live trips of 10-03 all cleared within about 1–10 s (HA history inscratch/SAFETY-94/live-history-*.json: B's command went 268 → 479 W through its 15:39:16Z trip, and B's reading changed at 15:39:21Z). Nothing went to 0 W. 17 s isRELEASE_S, which plays no part here. Also, 10-04 had 4 more trips between 08:45 and 09:45, so "about 4 a day" is low. Fix: "Each one paused control for a few seconds (several a day on a live site)."Round 1 fixes pushed:
8c6e5bc(CHANGELOG only; PR body's verbatim section updated to match).Offline in
goodwe-addon-checks:1(--network none): test_version_gate, test_docs, test_defaults_pin, test_validate, test_tool_inputs all pass. Waiting forchecks / unit (pull_request)on8c6e5bc.Merged as
3ed3302intorelease/1.0, pinnedhead_commit_id=8c6e5bc(checks / unit (pull_request)success, run 1174). The merged tree is identical to the PR head. No tag, nothing onmaster, nothing deployed.