Release candidate for 1.3.1, with infrared-control fixes since 1.3.1-rc.6.
What's changed
- Read infrared mode and brightness from a channel's
Lighting_V2row where available. This addresses cameras that accept and storeLightingwrites while their physical infrared emitters follow a different table. (#1083, addresses #647) - Keep v1 as the first write path, then try v2 in the same action when a fresh readback confirms v1 was accepted but ignored. Preserve each table's brightness bank and the camera's active profile.
- Require a new lighting sample and a successful overall refresh before learning that an accepted write was ignored. A read timeout or failed poll cannot permanently disable a working infrared path. Keep an accepted-but-ignored final path retryable, and make fallback warnings describe the next path being tried.
The recorder-specific case in #647 remains outside this change. Hardware behavior was measured by the issue reporter; validation here used automated regression tests.
Validation
All 4,752 tests passed locally on Python 3.14. Formatting passed across 322 Python files, and all GitHub CI checks passed on the reviewed commit before merge. Regression tests cover read timeouts and a successful lighting read discarded by a failed overall poll, including recovery on the next action.
Changes since the previous candidate: 1.3.1-rc.6...1.3.1-rc.7
Full changelog since stable: 1.3.0...1.3.1-rc.7