Repository navigation
EV charging cycles to zero under import ceiling despite low phase currents #1674
Description
On v0.145.2-beta.1, an Easee Cloud charger repeatedly started and stopped on 16 October 2026 around 23:45–23:47 CEST. The UI reported “protect the main fuse”.
Observed evidence
- Main fuse configuration: 25 A, 230 V, three phases.
- Retained phase-current maxima over the incident: 10.01 / 11.19 / 10.02 A. These samples do not show a physical fuse overload.
- Configured peak-import ceiling: 7,500 W.
- Planned EV demand: 10,350 W; offered charge was repeatedly reduced to 6,210 W, then 0 W.
- Minimum supported charging step: 4,140 W.
- At 23:45:13 and 23:45:18, logs say
loadpoint fuse-clamp: below minimum step ... fuse_cap_w=0 min_step_w=4140; analogous stop/start sequences recur at 23:45:43, 23:46:13, 23:46:48 and 23:47:18. - Around each start, grid import rises to about 7.0–7.1 kW while the retained charger power sometimes still says zero; around a stop, the inverse disagreement occurs. The snapshot clocks are asynchronous.
- At 23:56, FTW again requested and offered 9 A / 6,210 W, but actual EV power remained zero. Easee was online, connected,
ready(mode 6), with reason 78, “limited by dynamic charger current”. This does not establish which charger/vehicle state prevents recovery.
Investigation, not yet a proven cause
EVFuseBudget bounds a common balance by the latest site observation. When replacement credit for a managed EV cannot yet be confirmed, an approximately 7.1 kW site reading under the 7.5 kW import ceiling leaves only approximately 0.4 kW for a new offer, below the 4.14 kW minimum. This is a plausible start/stop mechanism, not a reconstruction of the internal budget verdict at each field tick: those intermediate values were not persisted.
A household load increase and an EV start with delayed charger telemetry can initially look identical. A fix must not simply credit requested EV power as measured power, reuse stale EV credit, or weaken phase/fuse or configured import limits.
Expected result
- Reproduce the low-load, delayed-telemetry start/stop case with deterministic observations.
- Expose which bound, raw/common observations, managed-EV replacement credit and pending battery power produced a stop.
- Distinguish the configured import ceiling from a physical main-fuse overload in diagnosis.
- Validate stable recovery without permitting a delayed EV start to overlap a new household load beyond the protected limits.
This is separate from the daily-history repair in #1667/#1668. No charging configuration or safety limit was changed during this investigation.
Follow-up: 17 October, 00:13–00:20 CEST
The two screenshots show Charge now requesting 15 A / 10,350 W, FTW offering 10 A / 6,900 W, and actual EV power 0 W. The second screenshot shows approximately 1 kW household consumption covered by the battery and near-zero grid exchange.
Rechecked logs from 00:10–00:21:30: 132 clamp records, 131 at 6,900 W and one at 7,590 W; no zero cap, pause or cooldown. At 00:13:13 and 00:19:53 the records both contain want_w=10350 fuse_cap_w=6900 snapped_w=6900. The 7,500 W configured import ceiling is consistent with the 10 A step. This positive cap explains the reduced offer, but does not explain zero delivery. Subsequent charger telemetry remained online/connected, ready (mode 6), reason 78, with a 10 A offer and no measured charging.
Two concrete core problems are addressed in #1675:
- A positive site clamp took precedence over sustained zero delivery, hiding the no-power response behind “main fuse” wording. After confirmation grace, fresh accepted positive offers with persistent zero power now report not-following/not-drawing; the lower allowed rate remains available as context. Wording identifies site fuse/import limits without asserting a physical overload.
- Recovery after FTW's own zero offer discarded its resume proof on HTTP acknowledgement. It now waits for measured delivery, retries at 30-second intervals up to three acknowledged attempts, and logs exhaustion. Existing session/device/generation and current safety/plan gates remain authoritative.
Regression tests reproduce the accepted 10 A / actual 0 W case and acknowledgement-without-delivery recovery, including intentional zero, freshness, grace, charging, session changes and safety/plan stops. Full make verify and all 729 web tests pass on e7b210d.
The initial 23:45 start/stop budget cause remains unproven; the bounded budget diagnostics are retained. Recovery is now tested in software, but requires validation on affected hardware. The running installation has not been updated by this PR.
Diagnostic build: 17 October 01:32–01:37 CEST
The local e7b210d-derived build still cycles. At 01:32:37 the common balance reserves 9,009.628 W of battery increase with 6.832 W grid import, while latest-site reservation is 0.628 W. At 01:34:42 common EV credit is 286 W versus latest credit 7,527 W, common cap 607.745 W versus latest cap 7,813.744 W. These are direct decision records, not later status reconstructions.
Code probes reproduce two mechanisms: a missing after-bracket makes the common battery baseline fall back to the configured -10 kW discharge bound even where the latest-site calculation can use a preceding fresh battery reading; and a later EV low sample retroactively reduces credit for an older bracketed site observation. This establishes the arithmetic mechanisms, not every underlying physical sample's accuracy.
Follow-up in #1675: align the fallback reservation with the latest site bound and keep historical EV brackets historical in the common balance, while retaining the independent latest-site and phase bounds and conservative later-stop handling there. Add regressions for observed stop/restart, true household increases, pending battery orders, and unknown/stale readings. Hardware validation remains required.
Budget fix available: 815e305 / PR #1675
The common EV balance now evaluates its historical brackets without a later stop/restart retroactively removing that site's credit. Independent latest-site and phase bounds remain authoritative and retain later-stop handling. The no-common-bracket battery path uses a fresh preceding measurement instead of inventing a full configured discharge loss; a first battery sample after the site read retains its conservative unknown-history fallback. Pending loss-of-discharge orders remain reserved.
Regression tests fail on the prior revision and pass with this fix. Entire control suite and full make verify pass on both PR and cumulative v0.145.2-beta.1 personal trees; web tests pass (729 / 731, TZ=UTC). Linux ARM64 personal patch revision 2 is built. Hardware validation and human review of earlier UI changes remain pending; no installation or charging command was performed for this budget revision.
Revision 2 field result and latest-site fallback correction
Revision 2 (815e305-derived ARM64 build) was installed and its executable checksum verified. FTW restarted at 01:52:54 CEST. Stable charging is not validated: it still emitted zero offers. At 01:55:36 the common path used grid 6,587 W with EV credit 0 W, yielding 913 W, while latest-site EV credit was 6,820 W and cap 7,733 W. At 01:58:16 an older 6,640 W grid sample with zero EV credit constrained the offer to 821.932 W while latest grid was -99.39 W.
New regressions reproduce both paths. When no common bracket is found, the fallback now retains EV credit already qualified by the existing latest-site guard; it previously left that field zero. When no positive eligible EV measurement exists, obsolete older site candidates are skipped rather than retaining grid demand from before an EV stop. Freshness, missing-data, latest-site, phase and pending-battery limits remain authoritative. Tests include a real household increase, a later EV reading that cannot fund an earlier site reading, unavailable EV data, and the worst-phase bound. Hardware validation of this follow-up remains pending.
Revision 3 source fix is pushed as 1fe1195 in #1675. Full local verification passes on both source trees, and all executed GitHub CI checks pass. Personal revision 3 ARM64 package is built, copied/extracted on the RPi and checksum-verified. It is not installed; stable charging is still unverified.
Further investigation after revision 3 field failure
The 02:19 incident contains a real household increase: history changes from approximately 0.9 kW household demand / 7.1 kW grid with 6.183 kW EV to approximately 2.0 kW household / 8.15 kW grid. Reducing the EV offer under the 7.5 kW import ceiling was justified. Offers then fell from 9 A to 8 A at 02:19:41 and 7 A at 02:19:46, before the zero-cap verdict at 02:19:51. This is not evidence of physical 25 A fuse overload. History aggregates cannot reconstruct every decision's raw source sample.
Two additional code defects are reproduced locally by focused probes, without changing the running installation or PR production source:
recordControlObservationclears the observation ring when sourceAtis over 10 seconds old, even whenControlPowerObservationreturns known=true with freshConfirmedAt. The probe uses 6183 W source age one minute, confirmation age one second: current reading is valid but the ring is empty. Repeated same-source confirmations are also discarded rather than updating the anchor, andcopyControlPointsfilters on source time alone. A steady change-only source can therefore lose its pre-transition evidence. Retaining one confirmed anchor must not manufacture multiple physical samples or a usable response window; unavailable/unconfirmed data and observed stops must still invalidate/bound proof.resumeAfterZeroOfferdeletes recovery evidence after any sample >=DeliveringW(100 W). A 130 W startup pulse clears it despite a 4140 W minimum charge step. The history includes ~130 W startup pulses. A focused probe reproduces proof deletion. Recovery should require sustained meaningful delivery rather than one low transient; do not globally change the shared delivery threshold without assessing its other consumers.
These are verified code behaviors and plausible contributors. Raw Easee source/confirmation times from the exact stop ticks were not retained, so they are not claimed as a complete field replay. Reason 78 remains observed during refusal to resume, but does not identify the underlying vehicle/contactor condition. The user's cable disconnect/reconnect, rather than demonstrated FTW recovery, started the successful charge.
The new probes are retained outside the source checkout as investigation artifacts; no intentionally failing tests were committed. Revision 3 is still not a validated charging fix. No fourth package or further control mutation was installed during this investigation.
Two further fixes implemented: revision 4 / 8a02c0a
The confirmed-power buffer now keeps one sample at its original source time and advances only its confirmation time. Freshness of that confirmation prevents an unchanged change-only sample from being discarded solely for an old source timestamp. Missing/unconfirmed data and contradictory values at one source time invalidate proof; stops remain in the bounded ring. A separate confirmed-window view serves time-aligned power bounds; independent response verification still uses physical source samples, so repeated confirmations cannot manufacture measurement windows.
Recovery after FTW's own zero offer now requires ten seconds of fresh, advancing meaningful delivery (90% of the lower of configured minimum and actual offer). 130/800 W pulses, one high sample and cached/unavailable observations do not clear it. The shared DeliveringW constant, existing session/safety gates and three-acknowledgement/30-second retry bound remain unchanged.
New before/after and integration tests pass, including a steady confirmed EV followed by a rate decrease, real household increases, missing data, observed stops, one-phase offers and sustained delivery. Full make verify passes on PR and cumulative personal source. Linux ARM64 revision 4 is built; installation and hardware validation remain pending. No automatic reboot or new authorization commands are introduced.
Revision 4 validation update: all executed GitHub checks on 8a02c0a pass, including core (Go) and go test + vet in 38988812967. Final focused regressions pass 20 repeats. The ARM64 revision 4 package is copied to the RPi, extracted and checksum-verified. It has since been installed and checksum-verified; see the revision 4 field-test update below for the current result.
Revision 4 installed: controlled stop/recovery test — 17 October 2026 (CEST)
The personal cumulative v0.145.2-beta.1 ARM64 revision 4, derived from 8a02c0a, is now installed. The running executable SHA-256 matches the revision 4 manifest. FTW restarted at 03:08:08.
Observed on the affected Easee/Pixii installation:
- Before the test, with the import cap disabled: 10.315 kW measured charging, 15 A offered, at 03:09:54.
- With 7,500 W import cap: at 03:13:20, measured EV 6.209 kW, offer 9 A / 6,210 W, grid 7.058 kW, phase currents 9.85 / 11.16 / 9.88 A. Initial offers varied between 6–10 A, then held 9 A for approximately the last minute. No zero offer was recorded in that cap-on interval.
- With 3,000 W cap: at 03:14:02, FTW offered 0 A, actual EV 0 W, grid 851 W. Easee reason 52, max dynamic charger current too low, was consistent with the intentional zero offer. The below-minimum diagnostic reported approximately 2.16 kW available against the 4.14 kW charging minimum.
- After the user disabled the cap, without disconnecting the cable or manually sending Start/Resume: at 03:15:19, offer 15 A / 10,350 W, actual 10.328 kW, charging mode 3. Reason 78 was no longer reported. At 03:16:49, charging remained 10.328 kW, status Following, with no new stop logged in that follow-up interval.
This controlled cap-reduction / below-minimum stop / automatic-recovery scenario passed. It does not establish long-term stability, recovery from every charger state, or correct response to a separate real household load step. The observations do not isolate which individual revision 4 change caused the improved result or establish whether the bounded resume retry path was needed. Human review of the earlier UI changes also remains pending.
Leave the issue open and PR draft. The user has no current peak-tariff requirement, so the import ceiling is disabled for normal charging; configured 25 A per-phase protection remains active. Next validation is a longer charging period and inspection of history around these transitions. History coverage/invalid_balance work remains separately tracked in #1667/#1668; this charging test does not verify that fix.
Activity
segran2 commentedon Oct 17, 2026
Longer field/history check — 17 October 2026, 12:27 CEST
The car now reports the requested 80% SoC (vehicle reading about 105 minutes old at inspection), and retained session delivery is approximately 42.73 kWh. Current command and actual charging are both zero; the command reason is
no_plan_budget. The service has continued running since revision 4 installation. No exhausted-resume warning was found in the inspected post-test journal.This is not a continuous, interruption-free charging result. At 05:49:15, with the import ceiling disabled, the controller issued a below-minimum zero offer: grid 12,323 W, eligible EV credit 0 W, phase bound approximately 2,449.5 W, minimum 4,140 W. Aggregated history shows EV zero from 05:49:25 through 05:50:25 and positive power again at 05:50:40 (10.230 kW by 05:50:45). This documents later recovery in telemetry; it does not independently establish whether any user action occurred or whether that zero decision was physically justified. Other short zero/low-power intervals also exist. The initial controlled test remains passed, but long-term stability and that later decision's raw alignment/phase evidence still need investigation.
History API review (
range=12h&points=4320, 10-second aggregated rows):complete.balance_mismatch/invalid_balancerow.balance_mismatch, the remainder complete. These are aggregate rows, not counts of original failed measurements; averaged columns and last embedded driver values must not be treated as simultaneous raw samples.Thus #1668's deployed daily estimate is present while rejected instantaneous rows remain visible; live balance failures are not eliminated. This API inspection does not independently audit every estimate-table entry, exact missing interval or database provenance. No database repair or hardware/configuration change was made in this check.
segran2 commentedon Oct 17, 2026
05:49 zero-credit investigation and remaining uncertainty
The retained per-driver series adds an important ordering detail. The Easee
ev_w10-second bucket has two samples, first receipt 05:49:13.164 and last receipt 05:49:18.275, min 0 W, max/last 10,241.9996 W. Thus the first sample was zero before the FTW zero-offer decision at 05:49:15.240;ev_dynamic_current_awas 15 A at both receipts. The preceding power sample at 05:49:08.117 was 10,241.9996 W. These timestamps are local recording/receipt times, not original Easee physical sample times.Pixii's first receipt at 05:49:14.910 recorded 12,323 W and phase currents 20.45 / 17.05 / 15.87 A. The decision log used zero eligible EV credit and a 2,449.5 W phase bound, below the 4,140 W minimum. No sampled phase here exceeded the configured 25 A. This explains the conservative stop arithmetic; it does not prove a charger fault, physical pause or delayed/out-of-order cloud response. The zero was received from the Easee driver, not vehicle SoC telemetry.
Add per-EV evidence to the bounded DEBUG budget record using the same reading considered by the calculation: raw/control power, source time, receipt time, confirmation time, source validity, qualification, driver telemetry health, retained-point count and latest-site credit. Reasons distinguish observed nonpositive power, invalid/unavailable source, stale/future receipts or control observations, offline telemetry, and absent brackets/observed stops. No requested power is used as measured credit, and zero observations are not ignored.
This closes a diagnostic gap, not the uncertainty in the historical event or the runtime stop mechanism. Preventing that stop by retaining a previous positive EV value without contemporaneous proof could authorize excess current after a real EV stop plus household increase. No such hold/filter/debounce is introduced. A future recurrence must capture the new evidence with DEBUG enabled in a diagnostic build before a prevention fix can be justified. The currently installed personal revision 4 has not been replaced by this code.
Implemented on
cde5cdbin #1675. Regression tests retain the declared source timestamp even when a source is unavailable, distinguish confirmed zero from unavailable data, and retain the below-minimum safety verdict. Fullmake verifypasses (tests, vet and build). Hardware validation of this diagnostic addition is pending.fix(control): the EV guard trusts only the site meter and our own com…
frahlg commentedon Oct 17, 2026
v0.147.2-beta.1 is out with a new EV guard (#1695). Please move from your personal build to this beta and tell us about any stop.
What changed: the EV hard limit now reads only the site meter and FTW's own commands. It never uses the Easee's power readings.
In the simulated replay of your 05:49 case the offer holds at 10,350 W. The 23:45 case under the 7.5 kW ceiling starts once and no longer cycles. Nobody has run it on hardware yet, so your site is the first real test.
Not in this beta: the resume check, the not-following status and the diagnostics from #1675. #1675 needs a rebase onto the new master.
To install, on the box:
Check that the last
ftw statusnames v0.147.2-beta.1. Ifftw updaterefuses because of your personal build, please post the output.Please report any stop or start/stop cycle with:
EV hard limit: site meter over limitlines fromjournalctl -u ftwaround it,If you can, try one charge with the 7.5 kW import ceiling on as well, since that is where the cycling started.
Known limits, also listed in #1695:
fix(control): the import ceiling caps each clock hour's mean import (#…
fix(control): one reading over the hour's ceiling no longer stops the…
fix(control): the EV guard gives the main fuse a heat budget (#1674)
fix(control): an EV rise waits for the fuse heat as well (#1674)
test(control): a total import the phases contradict does not cut the …
fix(control): the import ceiling caps each clock hour's mean import (#…
fix(control): the EV guard gives the main fuse a heat budget (#1674)
fix(control): an EV rise waits for the fuse heat as well (#1674)
test(control): a total import the phases contradict does not cut the …
fix(api): a ceiling the box cannot save is not applied (#1674)
fix(control): the battery leaves the hour's overage to the EV cut Cor…
fix(control): the fuse heat counts a meter gap at the last current se…
fix(control): the battery leaves the hour's overage to the EV cut Cor…
fix(web): switching the import ceiling on applies the box's last value (
fix(control): the EV guard gives the main fuse a heat budget (#1674) (#…
fix(control): the battery leaves the hour's overage to the EV cut Cor…
fix(control): the battery leaves the hour's overage to the EV cut Cor…
frahlg commentedon Oct 17, 2026
v0.150.0-beta.1 is out. Could you test it with the 7.5 kW import ceiling on?
Changes since v0.147.2-beta.1, all from your dumps:
To install, on the box:
Check that
ftw statusnames v0.150.0-beta.1.Please report any stop or start/stop cycle with the time and the
EV hard limitlines fromjournalctl -u ftwaround it. If you can, also includepeak_import_limit_wandpeak_import_hour_left_whfrom/api/status. Nobody has run this on hardware yet.fix(control): an unplugged car is no EV cut the battery waits for (#1674
fix(control): keep a pending EV cut per charger when another car leav…
fix(control): an unplugged car is no EV cut the battery waits for (#1674
frahlg commentedon Oct 18, 2026
Review update, 18 October:
e89f27a2) is the recovery/feedback candidate. fix(ev): preserve confirmed power history and verify charging recovery #1675 is now closed as superseded; its full head remains an ancestor of fix(ev): recover stalled charging without interrupting measured delivery #1719. The replacement retains master's meter-only guard and removes the old confirmed-EV-credit model.78674490). The latest display uses charger session-energy intervals and integrates the other sources over the same period, with visible period and age. It does not enter safety or recovery.make verifyplus 775 web tests. API, OCPP, control and forecast retry regressions also pass repeated race runs.Keep this incident and #1718 open. The supplied records do not establish the physical cause of the 23:32 stop, and the startup pulse is a separate unresolved case. No customer box, database or release was changed. The field checklist is in #1719.