Skip to content

v0.13.0

Choose a tag to compare

@github-actions github-actions released this 18 Sep 13:04
dff52f3

Concurrent live streams per station

  • Add maxLiveStreamsPerStation (1 to 4, default 1). Above 1, every further
    concurrent live camera on a station opens its own P2P session, keyed by
    station and channel, with its own STOP confirmation, 120-second cap, abort
    cleanup and disposal. The primary session keeps control, snapshots,
    recordings and the first stream. The same camera twice, a start beyond the
    limit, and recording transfers or mode commands during live still fail with
    station_busy. Default behaviour is unchanged.
  • Verified with two concurrent T8160 streams on one T8030, see
    the research note. Three or
    four streams are unverified on hardware.

Read-only local mower session

  • Add EufyClient.mowers.openLocalSession(id, { host }) for one authenticated Tuya
    LAN protocol 3.5 session to one discovered E15. queryStatus() returns a copied
    snapshot with source, local observedAt and raw dps. No data point is
    interpreted or written. There is no command, setting, retry, reconnect or
    automatic polling.
  • Borrow the private local key from the verified cloud binding only during key
    negotiation and erase it afterwards. Public results never contain the key,
    device ID or host. Every failure is a stable EufyError code without upstream
    detail, and failed or closed sessions release their socket and timers.
  • Record every protocol fact with its permitted public source, pinned revisions
    and file digests in Mower transport provenance.
    The frame codec and session-key derivation are reproduced byte for byte with
    tinytuya 1.20.0 and covered by synthetic peer tests. The subsequent
    E15 6.9.28 observations
    confirm bounded local queries, schema retrieval and session cleanup.

Typed mower telemetry

  • Add session.queryTelemetry() and the pure decodeMowerTelemetry() that turn
    one snapshot into status, battery, progress and network fields with
    source and observedAt, plus every reported data point typed by the device's
    own declared schema and the raw dps copy. Nothing is inferred from age or
    absence.
  • Retain the device's data-point schema from discovery and expose a copy as
    session.schema. Typed values come only from confirmed definitions that also
    conform to the declaration. The shipped E15 registry now includes independently
    observed battery percentage, Wifi and signal percentage. signalPercent is
    additive and keeps DP 109's declared % unit separate from signalDbm.
    Activity, mowing progress and unobserved network modes remain unconfirmed.
    Consumers may pass their own confirmed definitions. See
    typed mower telemetry.

Spontaneous mower reports

  • Add session.receiveReport() for bounded, authenticated command-8 reports.
    It preserves full-frame arrival time, distinguishes reports from query replies,
    and returns each report's own data points without merging older values.
  • Keep a pending report read alive with transport-only heartbeats. Preserve one
    operation per session, bounded buffering, cancellation, timeout and shutdown.
    No DP refresh, command write, retry or reconnect is added. See the
    report API.

E15 activity report contract

  • Establish the DP 107 robot_status envelope from the protocol owner's base64
    raw report path and the public Protocol Buffers encoding rules, verified
    against every retained raw value of the owner-operated windows. Add the pure
    bounded parseMowerWirePayload() and expose its structural result as
    fields[dp].wire for data points named by a wire definition.
  • Add the wire decode kind for evidence-gated candidate readings of a raw
    payload. Ship the mowing, paused and returning candidates for DP 107 at
    observed, so status now reports unconfirmed with that level and no
    activity value until three app-correlated reproductions exist. Battery,
    network and the report freshness rules are unchanged. See the
    contract receipt.

Cloud identity renewal

  • Discard the cached key-exchange identity and persist the cleared session when
    the Mega cloud answers with result code 4404 or 4416, also when that body
    arrives with a non-2xx status such as HTTP 463. That reset was unreachable
    before because every non-2xx response failed as http_error first, so a
    stored session whose identity had been invalidated elsewhere, for example by
    a key exchange on the same token from another host, failed every restore
    attempt. Observed with camera bridge client 0.12.3 on 2026-09-18 in #157.
  • The rejected call now fails with request_rejected, key_exchange_failed or
    authentication_rejected carrying the remote code instead of http_error.
    Every other non-2xx response keeps http_error. No automatic retry is added.
    The next explicit call performs a fresh key exchange.

Upgrade and compatibility

Existing camera and mower APIs, identifiers, persisted sessions and the map
acquisition adapter are unchanged. Consumers that matched http_error for a
rejected cloud identity now receive the remote result code instead. The
MowerAdapter contract is unchanged, so custom adapters keep working and report
mower_protocol_unavailable for local sessions. The local session interface gains schema, queryTelemetry() and receiveReport().
MowerTelemetryValue gains the optional wire property and status definitions gain
the wire decode kind. Consumers that matched status against { state: 'unconfirmed' }
exactly now also see level: 'observed'.
Use the compiled versioned 0.13.0 tarball and its verified integrity from the
GitHub release. maxLiveStreamsPerStation defaults to 1, so consumers keep one
live stream per station until they opt in. Retain the previous package and
lockfile for rollback. The camera bridge pins this release separately in
keesmod/ha-eufy-cam. References #145, #147, #149, #150, #153, #157, #159, #160
and #161.

Source commit: dff52f391a576921914df76c70a58f648b0d2e64

Validation: Validated 2026-09-18. Camera path: default behaviour unchanged, one live stream per station. The new maxLiveStreamsPerStation option was exercised on one T8030 HomeBase 3 (firmware 3.8.7.4) with two T8160 cameras (firmware 3.4.3.0): two concurrent 3840x2160 live streams for 20 seconds at about 15 frames per second each, STOP confirmed by the device on each stream's own session, the first stream unaffected by the second start and stop, a cancel before media confirmed, station telemetry and snapshots intact afterwards, with one controlling client. See docs/research/CONCURRENT_LIVE_2026-09-18.md. Mower additions (read-only local session, typed telemetry, spontaneous reports, DP 107 contract) rest on the owner-operated E15 observations of 2026-09-16 in docs/research. The cloud identity renewal is covered by a test reproducing the observed HTTP 463 with code 4404 and is not yet verified on the affected bridge, which still runs 0.12.3. Unverified: three or four concurrent streams, other station models.

Download checksums and exact component versions are included in the release assets.