Commit Graph
581 Commits
Author SHA1 Message Date
admin 8a17711f60 MAINT-13: a full pack that stops at 98-99 % is not a failed charge (#181)
infra-pin / fresh (push) Successful in 2s
2026-10-08 13:45:10 +02:00
adminandClaude Opus 5.5 ea31289ec0 MAINT-13 review: tests for a stale charge record and a clock step back; DOCS names the 7 day end
infra-pin / fresh (pull_request) Successful in 2s
checks / unit (pull_request) Successful in 34m49s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 13:08:40 +02:00
glenn schrooyenandClaude Opus 5.5 6836f61bd4 MAINT-13 round 3: provider site, hourly fixed-tariff check, faster tests
checks / unit (pull_request) Successful in 34m52s
infra-pin / fresh (pull_request) Successful in 1s
- A price-provider site with no fixed tariff is not a gate (its plan never
  sets `cheap`); DECISIONS §3 says so and a test pins it.
- The fixed-tariff check is worked out once an hour, not every tick.
- test_maint13: run() steps really are `step` minutes; the long loops use
  5-minute steps (the per-tick cap); wall backstop checked "not before".
- test_safety93: the drain bound is the rig's configured drain rate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 12:03:55 +02:00
glenn schrooyenandClaude Sonnet 5.5 f7b83cc75c MAINT-13 round 2: read the price gate without a new main.py option read
checks / unit (pull_request) Successful in 34m35s
infra-pin / fresh (pull_request) Successful in 1s
test_static_tariff forbids main.py reading `static_profile`; a small
static_gated() in static_tariff.py answers it, and the Controller keeps the
answer in `_price_gated` beside `cheap`.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
2026-10-08 11:10:33 +02:00
glenn schrooyenandClaude Sonnet 5.5 6f05b2e4be MAINT-13 round 2: gate open when nothing holds the charge back; safety93 scenario restored
checks / unit (pull_request) Failing after 34m45s
infra-pin / fresh (pull_request) Successful in 2s
- gate_open is true with no price gate set up, in a cheap window, or while the
  pack is taking charge; the stall rule and timeout now work on a no-tariff site.
- reset the save timer on a phase change; exact 5 min gap-cap test.
- test_safety93: original timeout scenario kept (B finished) plus a case where a
  due B takes the slot after A's failure.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
2026-10-08 10:29:46 +02:00
glenn schrooyenandClaude Opus 5.5 28eff568b5 MAINT-13: a full pack that stops at 98-99 % is not a failed charge
checks / unit (pull_request) Successful in 34m21s
infra-pin / fresh (pull_request) Successful in 1s
A charge is complete at SoC >= target, or at >= target - 3 once the SoC has
made no new high for 60 min of allowed charging, or when the charging time
runs out at >= target - 3. The 36 h timeout counts only the minutes the price
gate let the pack charge (plus a 7 day wall-clock backstop). A cycle that
fails (stuck drain, charge below target - 3) backs off 7 days, tells the
operator once (EN + NL), and no cycle starts on that pack in that time unless
the operator forces one. State survives a restart; old state files load.

No option added. DECISIONS/MAINT-13-full-pack-is-complete.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 09:36:06 +02:00
admin b527e99f13 SAFETY-103: no swing on old battery readings after a drain ends (#180)
infra-pin / fresh (push) Successful in 2s
2026-10-08 04:48:26 +02:00
adminandClaude Opus 5.5 c6f23a69d4 SAFETY-103 review: correct the swing after a refusal or lost link in DECISIONS
checks / unit (pull_request) Successful in 34m52s
infra-pin / fresh (pull_request) Successful in 2s
The test table gives 1.5 kW at N=2 and 3.9 kW summed at N=3 under a
surplus, and about 1 kW after a lost link without one; not 1.9 kW.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 04:13:08 +02:00
adminandClaude Opus 5.5 98dd110a4f SAFETY-103: test a dropped battery is not counted; guard a read
checks / unit (pull_request) Successful in 34m26s
infra-pin / fresh (pull_request) Successful in 1s
Mutation M13 (a battery out of the split counted in the house point)
survived; a direct check now kills it. win[0] is read through a guard
(test_named_absence).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 03:12:03 +02:00
adminandClaude Opus 5.5 138e45b53f SAFETY-103: no swing on old battery readings after a drain ends
checks / unit (pull_request) Failing after 35m9s
infra-pin / fresh (pull_request) Successful in 2s
While a battery settles from its ended drain (SAFETY-95), the house point
was grid + every battery's reading. A register can be 10 s older than the
meter, so B swung 860 -> 1650 -> 870 W on A's old reading (rig check 5).

Now the house point is held and moved only as far as the meter proves:
each battery is between its last changed reading and its commands since
(a reading that changed this cycle, or a refused side, as it reads).
N=1 and 1 s registers are byte-identical to release/1.0.

DECISIONS/SAFETY-103-old-readings-after-a-drain.md, test_safety103.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 02:25:55 +02:00
admin 451729c9b5 Release 0.16.0 (#178)
infra-pin / fresh (push) Successful in 1s
checks / unit (pull_request) Successful in 32m56s
infra-pin / fresh (pull_request) Successful in 2s
2026-10-08 01:02:20 +02:00
goodwe-review 1c607a961a REL-0.16.0 review: CHANGELOG wording fixes
checks / unit (pull_request) Successful in 32m48s
infra-pin / fresh (pull_request) Successful in 1s
SAFETY-103 swing 'by about 800 W for about 5 s'; SAFETY-99 'late, by less
than 30 s'; MAINT-10 row: one-at-a-time is not new; SAFETY-96: drop the
test-only 800 W; SAFETY-90 and MAINT-10 rows trimmed to two sentences.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 00:09:08 +02:00
glenn schrooyenandClaude Opus 5.5 756b50ddbb Release 0.16.0
checks / unit (pull_request) Successful in 32m41s
infra-pin / fresh (pull_request) Successful in 1s
version 0.15.0 -> 0.16.0 and a closed ## 0.16.0 CHANGELOG section.
No code change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 23:25:14 +02:00
admin 340c7eef42 Merge pull request 'SAFETY-95: a maintenance drain that ends hands back smoothly' (#177) from safety-95-drain-end-reseed into release/1.0
infra-pin / fresh (push) Successful in 1s
2026-10-07 17:48:53 +02:00
glenn schrooyenandClaude Opus 5.5 4707d37019 SAFETY-95 review: test the stale-link and contradiction legs; refusal +1 only
checks / unit (pull_request) Successful in 32m34s
infra-pin / fresh (pull_request) Successful in 1s
F1: test_safety95 checks that a dropped draining battery is this rule's
(stale link, N=3, 4000 W: grid import 676 W vs base 786 W); kills R2.
F2: _charge_track tested directly with a contradicting drain (SAFETY-91's
pin as a floor against a closed pack); kills R3. Today a drain contradicts
only through a refusal; the clause stays, as a contradiction sends 0 W.
F3: a drain ends on a refusal only when the battery will not give
(refused > 0, as _held_back()); one that will not take still drains.
Tested both signs; kills R8.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 16:41:16 +02:00
glenn schrooyenandClaude Opus 5.5 9c0314a826 SAFETY-95: N=1 identity for every drain end; plainer DOCS line
checks / unit (pull_request) Successful in 32m35s
infra-pin / fresh (pull_request) Successful in 2s
test_safety95.py: the N=1 byte-identity now covers all six drain ends
(Off and stale link were missing); end_at()/measure() read through a
default, so test_named_absence.py passes (it failed on bdec66e); a check
that a dropped battery's start is 0 W even under a pinned charge (it
kills a mutation that survived).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 14:36:36 +02:00
glenn schrooyenandClaude Opus 5.5 bdec66e97a SAFETY-95: a maintenance drain that ends hands back smoothly (N>=2)
When a battery's drain ended (done, Off, timeout, abort, stale link,
refusal), its drain floor stayed in the site target and landed on the
others: B 0 -> +1600 W in one cycle at a 1200 W house, exporting; under a
solar surplus B gave into the export.

Now, on that cycle, the loop starts from what the others stood at plus the
battery's new command, raised to the house's own point when the house needs
more (never above last cycle's start). While the battery settles, the loop
counts the batteries at its start instead of chasing the drain's tail on
the meter. Then one slew step a cycle. N=1 is unchanged.

test_safety95.py; DECISIONS/SAFETY-95-drain-end.md; one DOCS line.
test_modes.py: opt11 n2_maint re-pinned on purpose (its drain ends by a
refusal at 1655 s; B now stays at the house's 1420 W instead of 2500 W).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 12:44:25 +02:00
admin b2f55732b6 Merge pull request 'SAFETY-96: a battery the loop cannot move does not freeze it' (#176) from safety-96-stale-unit-site-total into release/1.0
infra-pin / fresh (push) Successful in 1s
2026-10-06 06:19:12 +02:00
glenn schrooyenandClaude Opus 5.5 956711b801 SAFETY-96 review: keep the refusal count over a refused write; test a fast board
checks / unit (pull_request) Successful in 31m53s
infra-pin / fresh (pull_request) Successful in 2s
F1: resetting the count on each refused write hid a battery that really
refuses behind a link refusing 1 write in 3 (never learned; learned at
358 s with the count kept). F2: a board at 0 W before its link is stale
learned no refusal untested (mutation R7 survived); now a 1 s-lag case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 05:46:32 +02:00
glenn schrooyenandClaude Opus 5.5 88b9cd470a SAFETY-96: a battery the loop cannot move does not freeze it
checks / unit (pull_request) Successful in 31m44s
infra-pin / fresh (pull_request) Successful in 2s
At N>=2 a battery out of the split (stale link), with refused writes, or
settling after a step the loop did not make (a charge end, a rejoin) now
counts in the freeze test at its command, not its reading. Its real power
still reaches the loop through the meter. At a drop its share leaves the
loop's start point (the others take over one slew step a cycle); at a
rejoin it enters at its reading. No refusal is learned while a battery's
writes are refused. N=1 and the 46 identity digests are byte-identical.

test_safety78 part 2: the dropped-drain case now rests at B 1510 W (grid at
its -10 W aim) instead of 1500 W; the drop no longer sends B to 2500 W.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 04:02:03 +02:00
admin 1bf6b7f9a7 Merge pull request 'MAINT-10: maintenance start hour in local time, default 19:00' (#159) from maint-10-local-start-hour into release/1.0
infra-pin / fresh (push) Successful in 2s
2026-10-05 23:56:19 +02:00
glenn schrooyenandClaude Opus 5.5 1d28daf8a0 MAINT-10 review: warn when HA did not answer and TZ is UTC; test the 3 s budget
checks / unit (pull_request) Successful in 31m18s
infra-pin / fresh (pull_request) Successful in 1s
HA can take minutes to start (2026-10-05, 502 from the proxy). Then TZ holds,
which the Supervisor sets from HA's zone, so the hour stays right; only a TZ
of UTC there now logs a WARNING asking for a restart. A test pins the 3 s
budget on the zone request (a mutant without it survived).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 23:24:02 +02:00
glenn schrooyenandClaude Opus 5.5 0b6b34f563 MAINT-10: every pack at N=2, the next DST days, plainer upgrade note
checks / unit (pull_request) Successful in 31m20s
infra-pin / fresh (pull_request) Successful in 1s
test_maint10.py part 10: at two inverters both packs get the site zone, the
real Controller is identical for 11 UTC and 13 Brussels, and two due packs
across 24/25 Oct 2026 and 27/28 Mar 2027 start at the local hour on
successive days; a pack freed in the repeated hour does not start there.
Part 3 adds 28 Mar 2027. DOCS: an existing install keeps its saved hour, now
read as local time; an hour set to make up for UTC goes back to 19.
DECISIONS: the SAFETY-83 gate is met; section on two inverters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 21:51:15 +02:00
glenn schrooyenandClaude Opus 5.5 08fb1235fc Merge release/1.0 (0.15.0 + SAFETY-90) into maint-10-local-start-hour
Conflicts: main.py's maintenance import (base added CHARGE, HOLD; branch added
site_zone) - both kept. DOCS maintenance table: base's longer drain-rate row
kept, start hour row at 19 / local.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 21:51:04 +02:00
admin 7ef73474dc Merge pull request 'SAFETY-90: the peak guard goes on after a P1 meter gap' (#175) from safety-90-peak-guard-gap into release/1.0
infra-pin / fresh (push) Successful in 2s
SAFETY-90: the peak guard goes on after a P1 meter gap (#175)
2026-10-05 13:23:32 +02:00
Claude (SAFETY-90 review) 24dbbd18ad SAFETY-90 review: test that a second gap does not price the first one down
checks / unit (pull_request) Successful in 31m12s
infra-pin / fresh (pull_request) Successful in 1s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:39:28 +02:00
Claude (SAFETY-90 review) 8dfe91e1d2 SAFETY-90 review: count the start-up seconds like a gap
While the add-on is down the batteries are at 0 W (it sets 0 W when it
stops; the ESP32 watchdog after 30 s), so the import before its first
reading was the house, not the aim. Those seconds now count at
gap_w(limit, the import seen first), and after a restart the restored
reading's held 30 s is topped up the same way. Status row: "counted as
high use". Tests take the pre-start import as the house (batteries at
0 W) and add restarts of 10/60/150 s with a restored averager.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:24:33 +02:00
Claude (SAFETY-90 dev) 9d3fbe1be9 SAFETY-90: the peak guard goes on after a P1 meter gap
checks / unit (pull_request) Successful in 31m10s
infra-pin / fresh (pull_request) Successful in 1s
A meter gap past meter_max_age_s left seconds the quarter average never
counted, so the guard was blind for the rest of the quarter (rig case 7b:
3964.8 W against a 3450 W aim). Once readings are back, the missed seconds
now count at the higher of the limit and the import seen just before and
just after the gap with the batteries at 0 W (peakguard.gap_w/fill_gaps);
the gap's first meter_max_age_s is topped up to that too. Seconds before
the add-on's first reading count at the aim, and the page says part of the
period was not measured (EN/NL). The bill record is unchanged; no option.

DECISIONS/SAFETY-90-peak-guard-after-a-gap.md, test_safety90.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 11:46:58 +02:00
admin 3ed3302d2f Merge pull request 'Release 0.15.0' (#173) from release-0.15.0 into release/1.0
infra-pin / fresh (push) Successful in 1s
checks / unit (pull_request) Successful in 29m8s
infra-pin / fresh (pull_request) Successful in 1s
Release 0.15.0 (#173)
2026-10-05 01:52:40 +02:00
glenn schrooyenandClaude Opus 5.5 8c6e5bca2e Release 0.15.0: correct the SAFETY-94/97 row, add the ±170 W known issue
checks / unit (pull_request) Successful in 29m6s
infra-pin / fresh (pull_request) Successful in 1s
Review round 1 (F1-F3) on PR #173.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 01:23:03 +02:00
adminandClaude Opus 5.5 f01152b113 Release 0.15.0: bump version and close the CHANGELOG section
checks / unit (pull_request) Successful in 29m1s
infra-pin / fresh (pull_request) Successful in 1s
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>
2026-10-05 00:48:04 +02:00
admin 3129daed62 Merge pull request 'CI-14: infra-pin to admin/goodwe 3b4ff84 (WITNESS-09)' (#172) from ci-14-infra-pin-3b4ff84 into release/1.0
infra-pin / fresh (push) Successful in 2s
2026-10-05 00:45:15 +02:00
glenn schrooyenandClaude Opus 5.5 64dddd64bf CI-14: infra-pin to admin/goodwe 3b4ff84 (WITNESS-09)
checks / unit (pull_request) Successful in 29m18s
infra-pin / fresh (pull_request) Successful in 1s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 00:13:01 +02:00
admin cf705a9058 SAFETY-94 + SAFETY-97: no false stale or refusal on a lagging battery; refusals graded against each battery's idle reading (#171)
infra-pin / fresh (push) Failing after 2s
2026-10-04 17:27:20 +02:00
adminandClaude Opus 5.5 7d06aa674d SAFETY-97: centre the band on the idle reading clamped to 75 W
checks / unit (pull_request) Successful in 29m26s
infra-pin / fresh (pull_request) Failing after 2s
Owner decision 2026-10-04 (review R1). A wrong idle reading more than
about 100 W off hid every refusal on that battery. Clamped under the band,
the band keeps 0 W +-25 W, so a battery reading about 0 W while refusing is
caught whatever was learned or restored. Samples are still taken to 250 W.
Beyond about +-170 W of idle a battery behaves as in 0.14.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 16:57:16 +02:00
adminandClaude Opus 5.5 88ebf3a5a6 SAFETY-97 review: tests for four surviving mutants
checks / unit (pull_request) Successful in 28m57s
infra-pin / fresh (pull_request) Failing after 2s
The N=1 stale-path refusal and SAFETY-42's parked test are centred on the
idle reading; learning stops while control is stopped or the sign watchdog
has latched. Each had no check (review mutants X7, X8, X13, X14).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 14:29:27 +02:00
adminandClaude Opus 5.5 3db2b6392f SAFETY-97: test the centred stale-path refusal (mutant S10 survived)
checks / unit (pull_request) Successful in 29m7s
infra-pin / fresh (pull_request) Failing after 1s
At a 5 s meter a register frozen at rest on B trips the stale gate before
the 12-cycle evidence; its refusal must be centred on B's idle reading,
or the site stops and re-trips instead of refusing B.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DBUfvndgHwaV339Fvd2gr
2026-10-04 13:07:06 +02:00
adminandClaude Opus 5.5 80bfc5721e SAFETY-97: point test_safety97 at MUTATION.md; record the DC-entity option
checks / unit (pull_request) Successful in 29m9s
infra-pin / fresh (pull_request) Failing after 1s
test_bytecode requires every suite to name MUTATION.md (CI run 1158).
DECISIONS: why the integration's DC battery power entity is not the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DBUfvndgHwaV339Fvd2gr
2026-10-04 12:51:52 +02:00
adminandClaude Opus 5.5 6918e154c8 SAFETY-97: "gives nothing" is graded against each battery's idle reading
checks / unit (pull_request) Failing after 29m7s
infra-pin / fresh (pull_request) Failing after 2s
B's power reading shows -95 to -118 W at idle (standby draw), so the
|reading| < 100 W refusal band never held a refusing B: never at N=2,
and since SAFETY-94's shared rule not at N=1 either (review F1).

Each unit now learns its idle reading (app/idle.py): only while control
runs, the unit is not refused/stale/tripped and its command has stayed
within 50 W for 120 s; first value a 120 s mean, then a 30 min follow;
samples beyond 250 W dropped, value clamped to 250 W; saved per unit and
restored. The shared refusal evidence, compute()'s N=1 engage and end,
the unit refusal ends, the stale-path refusal and SAFETY-42's "parked"
test are centred on it. Until learned it is 0 W, the rule as it was.

Refusing B caught at N=1 28/28/65 s and N=2 24/24/60 s (1/2/5 s
meters), before never; refusing A unchanged. Healthy B with its offset,
SAFETY-94's scenarios, 96 runs: 0 stale, 0 refused. Live replay: 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019DBUfvndgHwaV339Fvd2gr
2026-10-04 12:21:24 +02:00
glenn schrooyenandClaude Opus 5.5 dd5eb6fdc8 SAFETY-94 review: tests for three surviving mutants; record two gaps
checks / unit (pull_request) Successful in 28m7s
infra-pin / fresh (pull_request) Failing after 2s
- test_safety94 part 4: time under 250 W is not counted; a command that
  swaps direction every cycle is never refusal evidence; a reading moving
  away from the ask does not restart the evidence. These kill review
  mutants R1, R3 and R6, which survived the PR's tests.
- DECISIONS: at N=1 a battery with B's standby offset no longer latches
  a refusal (SAFETY-97 now covers N=1); a part-time ask is caught after
  35/d s of wall time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 01:17:52 +02:00
adminandClaude Opus 5.5 6759d21ea5 SAFETY-94: a healthy battery that lags or reverses is not flagged as frozen or refusing
checks / unit (pull_request) Successful in 28m10s
infra-pin / fresh (pull_request) Failing after 2s
The stale-reading gate counted its 35 s from the register's last change, so
after a rest the first read after a new command tripped it (SAFETY-58; live
2026-10-03, four trips 1 s after the command). It now counts only the time
the command asked the register to move.

At N=1 the refusal engaged after 12 frozen cycles if the reading was under
100 W at that moment, which a battery reversing through its lag passes at a
1 s meter. The refusal now needs the N>1 evidence at every roster size: under
100 W, one way, for 12 cycles spanning 22 s, restarting when the reading
moves 50 W towards the ask.

DECISIONS/SAFETY-94-lagging-battery.md; test_safety94.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 00:15:42 +02:00
admin 02ed1200dc Merge pull request 'Release 0.14.0' (#169) from release-0.14.0 into release/1.0
infra-pin / fresh (push) Successful in 1s
checks / unit (pull_request) Successful in 27m3s
infra-pin / fresh (pull_request) Successful in 2s
2026-10-03 11:29:13 +02:00
Claude f13dab1407 Release 0.14.0: changelog review fixes
checks / unit (pull_request) Successful in 26m57s
infra-pin / fresh (pull_request) Successful in 1s
Slew step not one house's 400 W; three two-inverter known issues, not
four; commissioning reference covers a new install; SoC example holds
for decimal sensors; SAFETY-95 states the jump, not the export.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 11:01:44 +02:00
glenn schrooyenandClaude Opus 5.5 b307db1049 Release 0.14.0: version bump and changelog
checks / unit (pull_request) Successful in 27m2s
infra-pin / fresh (pull_request) Successful in 2s
Two inverters are now supported for maintenance and the peak guard
(SAFETY-91, SAFETY-93). No option changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 10:30:25 +02:00
admin e51e3e02b2 Merge pull request 'CI-13: infra-pin to admin/goodwe 0c04488 (FW-05, WITNESS-08)' (#168) from ci-13-infra-pin-0c04488 into release/1.0
infra-pin / fresh (push) Successful in 1s
2026-10-03 10:27:02 +02:00
glenn schrooyenandClaude Opus 5.5 69dc1f0e7b CI: bump infra pin to 0c04488 (admin/goodwe#62 FW-05, #63 WITNESS-08)
checks / unit (pull_request) Successful in 27m26s
infra-pin / fresh (pull_request) Successful in 1s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 09:56:36 +02:00
admin 858f77cfb5 Merge pull request 'SAFETY-93: the maintenance charge end hands back smoothly, with no grid charging at a high house' (#167) from safety-93-no-grid-charge-at-charge-end into release/1.0
infra-pin / fresh (push) Failing after 2s
2026-10-03 00:58:37 +02:00
adminandClaude Opus 5.5 214051d1a8 SAFETY-93 review: a charge that ends by a stale link or a refusal hands back smoothly too
checks / unit (pull_request) Successful in 27m5s
infra-pin / fresh (pull_request) Failing after 1s
A battery still in CHARGE but dropped by the allocator (stale link, or a
SAFETY-73 refusal contradicting its charge) left its -2000 W in the loop's
start point, and B went 0 -> -1600 W in one cycle. The end is now noted
after the unit claims are filed: in CHARGE, live and not contradicted.
Tests: part 6 (stale link, refusal) and a spy on the guard suspension.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 00:10:21 +02:00
adminandClaude Opus 5.5 05eb93f139 SAFETY-93: the maintenance charge end hands back smoothly, with no grid charging at a high house
checks / unit (pull_request) Successful in 26m55s
infra-pin / fresh (pull_request) Failing after 1s
At N>=2, when a battery's maintenance charge ended, its watts stayed in the
loop's start point and landed on the other battery (B 0 -> -1600 W in one
cycle, charging from the grid at a 6000 W house). On the cycle a charge
ends, the loop now starts from what the others stood at plus that
battery's new command. N=1 and all identity digests unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:38:42 +02:00
admin f3e409cf76 Merge pull request 'SAFETY-91: a held battery is drawn only after the others are full' (#165) from safety-91-held-battery-last into release/1.0
infra-pin / fresh (push) Successful in 2s
2026-10-02 15:53:33 +02:00