* Fix WIRELESS_DEVICE_STATUS reconfiguration: push settings and ack with proper cookie
When a device sends WIRELESS_DEVICE_STATUS with config_needed=1, the host
should re-push settings and acknowledge via ConfigChange SetComplete. The
existing code relied on the push flag in changed(), but operator precedence
caused push=True to be ignored for devices that have the WIRELESS_DEVICE_STATUS
feature — the exact devices that send this notification.
Handle the reconfiguration entirely in the notification handler: explicitly
push settings and ack, rather than trying to overload the changed() condition.
Also replace hardcoded cookie 0x11 with proper GetCookie/SetComplete protocol:
read the device's current configuration cookie and echo it back, per the
ConfigChange (0x0020) specification.
* WIRELESS_DEVICE_STATUS reconfig: gate apply on ConfigChange cookie
Add a cookie-comparison gate so devices that emit multiple reconfig
notifications (PRO X 2 sends two on power-on) don't get their settings
re-applied for every one. The gate also benefits any path that calls
apply_settings_if_needed — devices that retain config through
power-save now skip the redundant apply.
New flow:
- Device.apply_settings_if_needed() reads ConfigChange (0x0020) cookie
via GetCookie. If the live value matches the cookie we stored after
the last successful sync (persister key `_config_cookie`), the
device hasn't drifted and we skip apply_all_settings entirely. On a
real apply, SetComplete echoes the cookie back and we persist it.
Devices without CONFIG_CHANGE bypass the gate (always apply).
- device.changed(active=True) calls apply_settings_if_needed in place
of the old apply_all_settings + signal_configuration_complete pair.
- WIRELESS_DEVICE_STATUS reconfig handler drops the redundant explicit
apply + ack (changed() already handles it on transition to active)
and instead calls apply_settings_if_needed to cover the case of
follow-up reconfig notifications on an already-active device — the
cookie gate makes the second/third call essentially free.
Protocol cleanup:
- set_configuration_complete no longer auto-increments the cookie
before echoing. The device owns the cookie and bumps it when its
config drifts; the host's job is to confirm which value it synced
with, not to advance the value. Host-side increment introduced a
needless race with device-side bumps.
- signal_configuration_complete gains an optional cookie= arg so the
caller can pass a value it already read (saves a redundant GetCookie
round-trip from inside the gated apply path).
Tests:
- get_configuration_cookie returns the two-byte cookie from fn 0.
- set_configuration_complete echoes a provided cookie unchanged.
- set_configuration_complete with cookie=None reads the live cookie
and echoes it (no increment).
* battery: Extract battery level estimation into function
Test battery level estimation with sharp edges based on predefined
steps. Rename variable for clarity and add type hints.
Related #2744
* battery: Interpolate battery level for some rechargeable devices in percent
Estimate remaining battery based on measured battery voltage. Use linear
interpolation to achieve a smooth line instead of 10 percent jumps.
Fixes#2744
* Refactor: test_named_ints_flag_names
Shorten test and clarify behavior using binary numbers.
* Introduce plain flag_names function
This replicates the NamedInts functionality as plain function.
* Refactor FeatureFlag to use IntFlag
Replace NamedInts implementation with IntFlag enum and plain flag_names
function.
Related #2273
* Refactor FirmwareKind to use IntEnum
- Move general FirmwareKind to common module.
- Replace NamedInts implementation with IntEnum.
- Harden related HIDPP 1.0 get_firmware test.
Related #2273
* Refactor CID_GROUP, CID_GROUP_BIT to use IntEnum
Related #2273