Skip to content

fix(easee_cloud): reject out-of-order power observations - #183

Draft
segran2 wants to merge 1 commit into
srcfl:mainfrom
segran2:fix/easee-observation-order
Draft

segran2 wants to merge 1 commit into
srcfl:mainfrom
segran2:fix/easee-observation-order

Conversation

@segran2

@segran2 segran2 commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Problem

An older Easee Cloud TotalPower observation can replace a newer one. The regression harness reproduces a 10.242 kW reading followed by an older 0 W reading. This demonstrates the driver behavior. The cause of the individual incidents in srcfl/ftw#1674 still needs field evidence.

Fix

  • Port the observation-order fix to Easee Cloud 1.4.1 on main, where SignalR supplies live updates and REST supplies fallback snapshots and periodic confirmation. The ordering fix is independent of the load-balancer reporting in fix(easee_cloud): report a load-balancer limit while the car charges #172.
  • Use one RFC3339 parser for observation times. Reject older power, conflicting values at the same instant, and connected power readings without a valid timestamp. Confirm unchanged readings and accept a newer measured zero.
  • Reset power ordering on mode 1. Recover from a future timestamp or backwards clock jump when readings on the lower timeline advance after 30 seconds. Repetition of a cached sample cannot trigger recovery.
  • Bump Easee Cloud to 1.4.2 and regenerate the catalog metadata. The charging commands and 7 A start boost keep their existing policy.

Validation

  • make test-driver ID=easee_cloud passed with 43 tests and 15 skips. Coverage includes REST and SignalR ordering, equivalent timestamps, measured zero, clock recovery, mode-1 reset, and the existing start-boost regressions.
  • GitHub Actions for this candidate

Remaining acceptance

Verify on Easee hardware with SignalR and REST fallback, including normal charging, stop/reconnect, and 6 A starts with and without sufficient cap. Verify the step-down to 6 A and the bounded boost timeout. Keep the PR in draft until hardware validation. After merge, advance FTW's bundled-driver pin so the fix reaches offline gateways.

Vendor references: Get observations, observation IDs, SignalR stream.

segran2 commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

@frahlg Could you please update #172 (easee-load-balancer-reason) with current main, or merge #172 so this PR can be retargeted to main?

I merged current main into this PR branch in 4f434e3. The signed-channel version check now passes, as do the driver tests, public-boundary check and history-secret scan. Local make check: 4985 passed, 936 skipped.

The remaining CI failure is DCO: it reports missing Signed-off-by on upstream Pixii commit 4a17397a128d3471be44ecc8da75e59e55bb1dd5 (#180). That commit is already on main, but it is included in this PR's checked commit range because the stacked base branch is behind main. Updating the base branch should remove that upstream commit from the range without rewriting or adding a sign-off to someone else's commit.

CI run: https://github.com/srcfl/device-drivers/actions/runs/39050615490

@miravoss26 miravoss26 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Easee cloud driver 1.3.9: rejects out-of-order or conflicting power observations (compares RFC3339 source instants normalised to UTC), and adds a one-shot 7 A "start boost" for 6 A orders to work around the ~5 min Easee start delay.

  • Correctness, fine: power_time_key handles offsets, fractions and leap days, and the zero-padded key compares correctly as a string. Disconnect resets the ordering. Boost is bounded (90 s, once per start, gated on cap_amps_per_phase, max_a and the device limit all allowing 7 A) and start_boost: false turns it off. Tests cover both paths and CI is green.
  • Low, worth a thought: a charger that reboots while a car stays connected and restarts its clock behind the last accepted timestamp will have every poll rejected as "out-of-order" until it passes the old value. The disconnect reset covers the normal case, but there's no timeout or escape hatch for this one. Maybe a reset after N consecutive rejections.
  • Low: this PR carries two unrelated behaviours (observation ordering and start boost) under one version bump. Fine to ship together, just noting that a revert would take both.
  • Note: the boost deliberately offers 1 A above what Core ordered. The cap_amps_per_phase guard is what keeps that safe, and a Core that doesn't send the cap gets no boost. Good default.
  • Security screen: no secrets, no new hosts or dependencies, no authz changes.

Safe to merge from my read. The field-data claim (4 runs, 22 Oct) is the author's, so I couldn't verify it. The PR itself says the ordering fix isn't hardware-verified yet.

@frahlg

frahlg commented Nov 12, 2026

Copy link
Copy Markdown
Member

Review (Claude CLI, 2026-11-12): do not merge this PR as it stands.

Merging would squash into easee-load-balancer-reason (#172), which is still a draft and conflicts with main. The fix would not land on main and would not trigger ftw-drivers-release.

Blockers

  • Current main already has Easee 1.4.0 (SignalR) and 1.4.1. Observation validation now lives in note_observation / state_problem, and main already drops a REST sample older than a stream sample but otherwise applies REST so one bad stamp cannot hold a value. This PR's latching rejection is a different rule and must be re-implemented on that model (REST and stream), with a single time parser. easee_cloud.lua and the catalog files conflict with main.
  • The candidate version is still 1.3.9. A rebase needs ≥ 1.4.2 and regenerated hashes.

The ordering logic on this branch is otherwise sound (RFC3339 comparison, same-instant conflicts, measured-zero rules, disconnect reset). During the rebase, please also add an escape hatch for a bogus future timestamp or a charger clock that jumps backwards — today that can reject every later poll until disconnect — plus tests for that path and for a mode-1 reset.

CI being green on a7b6a3d only covers the stale #172 base, not current main.

@segran2
segran2 force-pushed the fix/easee-observation-order branch from a7b6a3d to a83417e Compare November 12, 2026 12:32
@segran2
segran2 changed the base branch from easee-load-balancer-reason to main November 12, 2026 12:32
@segran2
segran2 marked this pull request as draft November 12, 2026 12:32
Signed-off-by: Segran <goran@andersson-stehag.se>
@segran2
segran2 force-pushed the fix/easee-observation-order branch from a83417e to c9b4a88 Compare November 12, 2026 12:33

This branch has not been deployed

No deployments
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.

3 participants