v1.20.0 - Monitor Reliability, Security & Bug Fixes
Release rollup for PRs #722, #723, and #724.
Monitor (experimental) reliability
- Monitor now owns reconnection. Monitored devices are forced to fail fast on send errors (
socketRetryLimit = 0) so a broken connection can no longer block the reactor thread or silently open a replacement socket the selector never watches. - Heartbeat and queued-command send failures are detected and routed through the disconnect → auto-reconnect path.
- Command dispatch is gated on selector registration state rather than
device.socket, closing a reconnect handshake race. stop()returns promptly via interruptible backoff wait; can no longer spawn duplicate connector threads.- Retry limits are restored on device remove/stop. Selector unregisters by stored fd.
- Added first offline unit tests for
Monitor(37 total, 1 skipped).
Session crypto hardening
- AES-GCM nonces and v3.4/v3.5 session-key client nonce now use
os.urandom— eliminates nonce/IV reuse. - 6699/GCM frames that fail authentication tag are rejected.
Bug fixes
- Cloud token-refresh retry preserves query string; helpers return error dicts on failed/empty responses.
set_timer()selects timer DP numerically; timeout errors reportERR_TIMEOUT;received_wrong_cid_queuebounded.- Truncated frames raise
DecodeError;error_json()handles unknown codes;BulbDevicergb8 hue offset fixed. - Scanner no longer mutates caller dicts.
Full changelog: https://github.com/jasonacox/tinytuya/blob/master/RELEASE.md