Skip to content

fix(feedback): explain EV shortfalls with inferred site headroom - #1762

Draft
segran2 wants to merge 5 commits into
srcfl:easee-load-balancer-limitedfrom
segran2:fix/ev-inferred-site-headroom-1761
Draft

segran2 wants to merge 5 commits into
srcfl:easee-load-balancer-limitedfrom
segran2:fix/ev-inferred-site-headroom-1761

Conversation

@segran2

@segran2 segran2 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

When EV delivery stays below the command and Core has no stronger explanation, FTW can direct the owner to the charger app even though fresh site measurements show that the full commanded EV power would exceed the site's calculated working limit. This PR adds a conditional site-headroom projection, while preserving the underlying control verdict, dispatch and priorities.

For the recorded household example, about 4.2 kW EV delivery against 10.35 kW commanded, concurrent battery charging and the measured phase currents project the busiest phase to about 29.5 A if other loads stay unchanged. This is context, not proof of the charger’s limiting mechanism or the cause of delayed starting.

Dependency and merge order

Stacked on Core #1537, base easee-load-balancer-limited at b6d93cdf92e617cd0e3fd687cc143eec4030655e, with device-drivers#172 at aa0ee46ac071ae8400657b463845735316263cdc. Both dependencies remain open at this follow-up.

Keep the order driver #172 → Core #1537 → #1762; preserve newer driver fixes when integrating the pin. Rebase/retarget to master after the dependency lands, then refresh CI. Do not merge this stack independently. The later #1789 work also changes shared control feedback and needs integration review; it is not included here.

Implementation

  • Add optional calculated site_headroom context only for a settled EV power_below_target. Zero delivery, command failures, faults and stronger device/Core limiting reasons retain their own explanation.
  • Require explicitly configured and reported three-phase EV charging, healthy site-meter data no more than 15 seconds old, and meter/EV observations within 10 seconds.
  • Require finite phase currents and signed positive power on every phase. Missing phase power, export and mixed directions do not qualify merely because the meter reports positive current magnitudes.
  • Project the missing EV power with other loads unchanged. Require more than 0.5 A exceedance of the configured fuse budget after its safety margin. Single-phase/auto phase placement remains unknown.
  • Include battery charging only as qualified contextual information. OnlineBatteryControlPowers now performs health, receipt/source age, validity and availability checks under the telemetry lock; API code applies site-time alignment. No new direct cached-telemetry reads or waiver.
  • The rendered explanation keeps one decimal where needed and distinguishes the working limit after the margin from the fuse rating. A 24.8 A projection against a 24 A working limit no longer reads as “about 25 A, above the 25 A fuse budget”.
  • Identify the calculation as a projection, not a charger-reported cause. Do not deny that other charger-reported information exists merely because Core has not established it as the explanation.
  • No dispatch, protection timing, settings or goal changes. The installed app that copies web/control-feedback.js needs the matching update after integration.

Validation — head e38b8db, 23 October 2026

  • make verify: passed, including Go suites, script checks, vet and build. Docker-context and live Avahi checks skipped because no Docker daemon was available.
  • 869 web tests passed; no failures or skipped tests.
  • Focused API/telemetry race tests passed for the projection and qualified battery context.
  • Telemetry-read ratchet and git diff --check: passed.
  • Two new wording regressions fail before the correction and pass afterward: a projected current below the fuse rating but above the working limit, and a projection shown alongside raw vendor reason text.
  • Existing API cases cover asymmetric phases, sufficient headroom, freshness/skew, future readings, absent/nonfinite phase data, export/mixed flow, invalid margins, phase mapping and stronger-reason precedence.
  • Additional telemetry tests reject offline/faulted/missing-health, stale/future receipt, stale source, expired declared validity, unavailable/nonfinite power, invalid age and other DER kinds.
  • Actual before/after rendering was inspected in a local browser using this branch's real renderer and fixed fixtures. Cases include projected headroom, reported charger limits, zero delivery, waiting, command timeout, stale reports and return to plan with continued charging. This is not live hardware/UI acceptance.

Earlier validation at dbf47b5b included an initial failure in unchanged TestUnsupportedBootTriggerLeavesIdentityUnknown, followed by focused repeats and a full pass on that code. That earlier unexplained failure remains recorded; no OCPP code/test was changed here to remove it.

Remaining acceptance

Keep draft. The owner inspected the preview and asked what a technical test-case label meant; that label was clarified to “Information from the charger — the cause is not yet established”. This does not establish final acceptance of every product message.

Older manual continuation wording while waiting and the earlier driver-command-failure versus charger-hardware-fault classification remain separately identified; this projection PR does not claim to fix them. Human final UI review, dependency integration, matching app copy and affected-hardware acceptance remain open.

The 23 October evidence comment distinguishes Core's requested current, Easee allocation/pilot and actual delivery. Those hardware runs used a separate local environment and do not validate this PR's exact fallback or establish the cause of Easee’s reduced allocation or 6 A delay. This follow-up changes no software or control on the household FTW.

Closes #1761.

Signed-off-by: Segran <goran@andersson-stehag.se>

segran2 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

Real-hardware follow-up — 2026-10-20 (Europe/Stockholm)

Tested Charge now → Return to plan with Easee Cloud, Audi e-tron 55 (2022), and Pixii Home charging concurrently.

Step Pixii charging EV charging Observation
Scheduled battery charging ~6.5 kW 0 kW Normal plan
Charge now (15 A requested) Decreasing 0 kW At 12 s FTW displayed: Site power limits cap this charge at 0 W right now (15 A requested). (12 s)
After allocation settled ~1.8 kW ~5.5 kW EV started automatically without Easee-app intervention
Return to plan Increasing gradually 0 kW Pixii ramped back up, reportedly subject to FTW safety limits

The observed reduction in Pixii charging (~4.7 kW) coincided with EV delivery rising to ~5.5 kW. This confirms that FTW can redistribute charging power between battery and EV and recover on Return to plan in this test.

Interpretation / limits: The initial 0 W here was explicitly attributed by FTW to site power limits; it should not be conflated with an unresponsive charger. A separate earlier Charge now attempt showed Easee Waiting for over two minutes before charging began automatically, but its root cause is still unverified. This follow-up is field-test evidence, not proof that all under-delivery cases are fixed, and does not establish the cause of the earlier delay. It supports making the site-limitation explanation clearly distinguishable from device-reported limitations and no-power-response states. No code change is requested based solely on this observation.

Next planned check: scheduled EV charging on 2026-10-21 at 02:30 local time.

Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>

segran2 commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Feedback evidence update — 22 October 2026

Companion to the latest released-v0.155.1-beta.1 hardware report in #1763. This PR remains unmerged; the observations below are not a validation or rejection of this PR's exact inferred-headroom fallback.

Real waiting versus inferred explanation
On v0.155.1-beta.1, a 6 A request after verified pause reached the first resume acknowledgement in approximately 12 seconds (16:48:44), but positive 6 A pilot did not arrive until 16:54:31; actual power then approximately 4147 W. The normal no-charge warning had appeared at 16:50:18. This is evidence that a no-response warning can precede eventual delivery; it does not by itself establish the right universal timeout or justify weakening protection. Distinguish Core withholding admission, a command acknowledged, a reported current limit and actual delivered power.

The prior controlled single-resume test also started after about five minutes. A current-limit reason or a site-headroom projection alone must not be presented as the proven cause of this delay.

Captured contradictions still need explicit UI verification
The owner's screenshot from 03:37:34, during an actual no-power wait, simultaneously showed:

  • “Not following” / “The charger has not said why”;
  • “Waiting for the car to start drawing” / “limited by charger max current”;
  • continuation text “until the car stops drawing” although drawing had not begun.

That screenshot predates the actual pilot transition at 03:40:09; it is not evidence of stale app rendering after startup. The screenshot came from the earlier version; these exact strings/transitions were not visually revalidated after updating.

Transport/command failure is not necessarily a charger-reported hardware fault
The excluded 04:17:27 Lua diagnostic run deliberately returned false for a suppressed duplicate resume. Core correctly escalated the failed actuation and entered autonomous default; the UI described it as “The charger reports a fault: driver command may have run: driver_command returned false”. This was an induced integration-command failure, not a confirmed vendor hardware fault. Keep provenance clear. The Lua experiment was rolled back and is not part of the successful single-resume evidence.

What was verified on the new release
During a short 7500 W import-ceiling scenario, Core reported import_limit while offering 7590 W and measuring approximately 7539 W EV delivery. This supports the limiting-reason path in that tested case, not all fallback explanations. No ignored-stop, deliberate non-following charger or fault-rendering test was performed on v0.155.1-beta.1. Its release notes describe related feedback corrections, but do not alone establish that the screenshot contradictions or this PR's projected-headroom message are resolved.

The test hold was removed, the ceiling restored to disabled and ordinary plan control verified. No protection timing changes were made. Remaining acceptance: consistent top-level/detail messages, source-labelled faults, accurate waiting-to-delivery transitions and this PR's specific headroom fallback under qualified evidence.

segran2 commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

Feedback evidence — 23 October 2026: distinguish requested, allocated and delivered current

Companion to the new hardware/command-trace report in #1763. These measurements came from local Core v0.155.1-beta.9002 (released v0.155.1-beta.1 plus #1763 and additional local reservation/transition changes), not this PR checkout. They do not validate this PR's exact inferred-headroom fallback or its rendered UI.

The latest test provides a concrete distinction for feedback provenance:

23 October, Europe/Stockholm Core request / dynamic-current readback Easee allocation (observations 70–72) / pilot (114) Actual delivery
01:54:22, battery idle 15 A 12 A Subsequently about 8.3 kW
01:55:14, battery still idle 15 A 15 A Rose to about 10.37 kW
02:00:21, highest battery-request step 15 A 14 A Falling
02:00:32 15 A 13 A Subsequently about 8.85 kW

The full FTW driver POST trace is continuous and shows no pause, lower/zero-current or phase-setting write between startup completion and test cleanup; successful 15 A writes continued through the allocation reduction. This localizes the discrepancy beyond the recorded FTW offer to Easee's reported allocation, but does not explain the internal decision or exclude another controller. A transport acknowledgement, dynamic limit, allocated/pilot limit and actual power are distinct evidence.

Implications for this PR's wording and remaining acceptance:

  • A conditional site-headroom calculation must remain labelled as a projection. It cannot establish that the site budget caused Easee's allocation change, even when the change occurs during battery charging.
  • The lower 12 A startup allocation occurred with Pixii at 0 W. Do not universally attribute a lower EV draw to concurrent battery charging.
  • Vendor reason 77 was recorded at 01:56:25, before the later 14/13 A transitions. An old last-change reason can remain valid, but it cannot by itself prove why a later transition occurred.
  • Fresh maximum temperature was 32–34 °C, without positive derating evidence; Equalizer details, peer count and individual temperature sensors were unavailable. Missing fields must remain unknown rather than being inferred as absent devices or constraints.
  • Actual maximum measured phase current in the final test was 24.13 A on the 25 A site. That neither proves a projected overload nor establishes that a 24 A working margin held throughout.
  • Ordinary-plan EV charging continued after the manual holds were released. Return-to-plan should not be described as necessarily returning to 0 W.

Original Easee driver was restored, both manual holds inactive, health ok. No protection waiting times were changed. The earlier contradictory card/detail strings, source-labelled command failures and this PR's qualified headroom fallback still need their own explicit UI acceptance. No new visual/UI pass is claimed here. Keep the PR draft/dependency conditions and remaining acceptance open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants