Commit Graph
24 Commits
Author SHA1 Message Date
Rene Nulsch 4ad41e9977 Merge pull request #7 from ReneNulschDE/fix/reduce-recorder-load
Stop flooding the recorder with timestamp and false-precision noise
v1.0.3
2026-08-28 08:42:51 +02:00
Rene NulschandClaude Opus 5 62bc1c150a Stop flooding the recorder with timestamp and false-precision noise
Measured on a real installation with two bikes: the two "Last Seen"
sensors were the number one and number two writers in the entire Home
Assistant database, ahead of a three-phase energy meter. The integration
accounted for 26.5% of all recorder writes on that system.

Last Seen moved on every BLE notification, about once a second, or 2834
rows an hour per bike. The entity exists to say how fresh the values are,
which needs nothing near that resolution, so it now advances at
LAST_SEEN_RESOLUTION granularity. `self._last_seen` stays exact - that is
what gets persisted and restored - only the entity is throttled. Measured
after: 120 rows an hour, the theoretical maximum for a 30s window.

The distance sensors carried four decimals of false precision, because
the ebikemotion frames divide by 10000: a range that is really "14.6" was
reported as 14.6065, then 14.6529, then 14.6297, each one another state
write and another database row. They are rounded to 0.1 km now.

Home Assistant offers integrations no way to exclude an entity from the
recorder - `entity_filter` comes from user configuration only, and
`_unrecorded_attributes` covers attributes rather than states - so
reducing how often the state changes is the only fix that works without
asking every user to edit configuration.yaml.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FyabWZzd7HoLpyBwEa5Zzh
2026-08-28 08:36:09 +02:00
Rene Nulsch a38b2efef5 Merge pull request #6 from ReneNulschDE/fix/reconnect-latency-and-advertisement-storm
Reconnect right after a dropped link instead of waiting out the poll
v1.0.1
2026-08-28 00:33:34 +02:00
Rene NulschandClaude Opus 5 7c1a23a8b4 Reconnect right after a dropped link instead of waiting out the poll
Measured on a real bike: after every unexpected disconnect the integration
sat idle for 26.5s before reconnecting, in a suspiciously tight band across
nine consecutive drops.

Two causes, both introduced with the restore work:

`async_set_updated_data` runs on every BLE notification, which reschedules
the coordinator's next poll to now + SCAN_INTERVAL. The last notification
lands just before the link dies, bleak reports the disconnect ~3.5s later,
so the poll that would reconnect is still ~26.5s out.

The advertisement watch was supposed to cover exactly this, but does not:
instrumenting the callback showed one advertisement in seven minutes across
five drop cycles. These bikes stop advertising after an unexpected link
loss, so the watch only helps when the bike is switched on fresh.

The disconnected callback now starts a reconnect itself. A link that did
not survive MIN_LINK_SECONDS_FOR_FAST_RECONNECT is left to the poll so a
bike that cannot hold a connection at all does not spin. Measured after
the change: 0.7s instead of 26.5s.

Also fixes an advertisement storm. Home Assistant invokes bluetooth
callbacks on every advertisement, and this bike advertises every 0.27s, so
while disconnected the callback queued a background task several times a
second - roughly a hundred per reconnect window - all serialising behind
_connect_lock, each running a full establish_connection retry cycle against
a proxy already struggling to hold the link. A claim guard reduces that to
one attempt in flight at a time; the test covers 50 advertisements.

Keeps the advertisement counter as debug output - it is what made the
second cause visible, and it is the first thing to look at when a bike
reconnects slowly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FyabWZzd7HoLpyBwEa5Zzh
2026-08-28 00:24:42 +02:00
Rene NulschandClaude Opus 5 76c3d91ff9 Bring README in line with v0.0.7
The connection switch is called Auto-connect now, the sensor list was
three entries short and counted 11 instead of 14, and the minimum Home
Assistant version disagreed with hacs.json.

Also documents that values are only stored once the bike has connected
at least once, and adds the passive-proxy case to troubleshooting - a
bike seen only by a Shelly looks identical to a bike that is switched
off unless you read the log.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FyabWZzd7HoLpyBwEa5Zzh
2026-08-27 23:27:58 +02:00
Rene Nulsch 5d658d6d9e Merge pull request #5 from ReneNulschDE/feat/restore-state-across-restarts
Keep showing last known values when the bike is out of range
v1.0.0
2026-08-27 23:23:43 +02:00
Rene NulschandClaude Opus 5 ac0baffe74 Keep showing last known values when the bike is out of range
Setup no longer depends on the bike being reachable. The coordinator is
built from an address and resolves the BLEDevice per connect attempt, so
a parked or switched-off bike loads the entry instead of raising
ConfigEntryNotReady and leaving every entity unavailable.

Parser state is persisted through helpers.storage.Store and restored
before the platforms are set up, so entities carry their last values and
the VIN on their first state write. What survives is a whitelist:
battery and EBM counters yes, motor and assist no - a restored speed
reading is indistinguishable from live data on a parked bike. The
connection switch position is restored too, so a restart no longer wakes
a bike the user deliberately disconnected.

Also fixes three defects found while building this:

- Store.async_delay_save debounces rather than throttles, so re-arming on
  every notification postponed the write for as long as the bike stayed
  connected and nothing reached disk except on a clean shutdown.
- establish_connection had no disconnected_callback, so a dropped link
  left _is_connected True: the connectivity sensor lied and the poll
  never retried.
- _connect read self._client back across the 200ms handshake, which a
  concurrent teardown could clear underneath it.

Connecting now starts on the bike's advertisement instead of the next
poll tick, and an unreachable bike says why - distinguishing "switched
off" from "seen only by a passive proxy that cannot connect".

Renames the connection switch to Auto-connect and drops the hardcoded
English name on the connectivity sensor, which had been defeating its
translation key.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FyabWZzd7HoLpyBwEa5Zzh
2026-08-27 22:45:21 +02:00
Rene Nulsch c539823c1a Fix repository URL in README.md 2026-06-28 15:18:33 +02:00
Rene Nulsch 28bf64baad Update: message parser, trip handling v0.0.6 2026-04-30 13:00:56 +02:00
Rene Nulsch 52178a219b Add x20 parser logic v0.0.5 2026-04-30 10:00:59 +02:00
Rene Nulsch 0afd8243bc Discover HUS-prefixed BLE devices alongside iWoc v0.0.4 2026-04-30 07:40:52 +02:00
Rene Nulsch 0638c4b244 Add Orbea to tested bikes v0.0.3 2025-11-22 16:47:17 +01:00
Rene Nulsch 70fa0aa72d Add HACS badge to readme 2025-11-22 15:31:22 +01:00
Rene Nulsch 43e6c0d99e CLeanup logging 2025-11-22 14:39:28 +01:00
Rene Nulsch e8f91dc1cd add badges to readme 2025-11-22 14:08:57 +01:00
Rene Nulsch 0e459bec15 fix release badge 2025-11-22 09:09:15 +01:00
Rene Nulsch ed11d647f6 add filename to hacs v0.0.2 2025-11-21 23:14:19 +01:00
Rene Nulsch 812c0e5ae5 fix hacs, remove hacs badge 2025-11-21 23:11:15 +01:00
Rene Nulsch 4b773eede3 fix manifest sorting 2025-11-21 23:06:50 +01:00
Rene Nulsch e9399aa8a6 hacs errors 2025-11-21 23:04:32 +01:00
Rene Nulsch b265a03dac fix manifest 2025-11-21 23:01:19 +01:00
Rene Nulsch 44cba4ab80 fix translations 2025-11-21 22:58:21 +01:00
Rene Nulsch 7265d939dc adjust readme 2025-11-21 22:50:04 +01:00
Rene Nulsch 4e66d2563b inital commit 2025-11-21 22:38:55 +01:00