Files
signal_bridge_remote/phone/relay_client.py
Aletheia 7c61ecb410 fix: pattern lifecycle — indefinite durations, escalate hold contract, monotonic clocks
Ports the Android relay engine's pattern semantics (its 2026-06/2026-07
fix batches) to both Python relay clients:

- duration <= 0 on pulse/wave now runs the pattern until an explicit
  stop, matching how plain commands treat duration=0. Previously the
  loop condition was already false at start, so the pattern silently
  did nothing.
- escalate now honours its documented hold contract: hold_seconds <= 0
  suspends at peak until cancelled, > 0 holds then stops. Both paths
  run through a finally that stops the device, so an error mid-ramp can
  no longer leave hardware running at the last intensity it reached.
  (The naive finally alone would stop the device the moment the ramp
  finished — the same regression the Android app shipped and fixed.)
- Pattern timing uses time.monotonic() instead of time.time(): an NTP
  wall-clock jump could stretch, truncate, or instantly end a pattern.
- relay_client.py now keys pattern tasks by device (one pattern per
  device, as in the Android engine) instead of device:pattern, which
  let a wave and a pulse fight over the same actuator.
- Duplicate same-model devices get suffixed short names (lush, lush_2)
  instead of silently replacing each other.
- Dropped the unsolicited device_list push after auth — the server
  requests a scan on connect and the scan handler answers it; the
  double-send raced session registration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 20:14:32 +02:00

29 KiB