From 10b1d8baff669bdf50e96bec0647c4a339990a22 Mon Sep 17 00:00:00 2001 From: Ken Sanislo Date: Sat, 18 Apr 2026 02:19:44 -0700 Subject: [PATCH] Add diagnostic logs for HeadsetMicGain fallback + bridge TX payloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the HeadsetMicGain GetInfo probe goes wrong, we were silently falling back to the int8 default range with no log. Now we log each fallback path distinctly so field diagnostics can tell: - Exception during GetInfo (transport error) - GetInfo returned non-None but too short (truncated response) - GetInfo returned nonsense range (max <= min, probably wrong feature format) Separately, centurion_bridge_request now logs outgoing sub-messages at INFO level showing sub_idx, function, sw_id, and payload hex. This pairs with the existing "bridge sub-device error" INFO log so when a NACK fires we can see both the rejected value and the device's error code in one place. Verbose during normal operation — dial back to DEBUG once the G522 writes are confirmed working. --- lib/logitech_receiver/device.py | 11 +++++++++++ lib/logitech_receiver/settings_templates.py | 13 ++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/logitech_receiver/device.py b/lib/logitech_receiver/device.py index 4a1f8a45..3fb7092b 100644 --- a/lib/logitech_receiver/device.py +++ b/lib/logitech_receiver/device.py @@ -722,6 +722,17 @@ class Device: timeout = base.DEFAULT_TIMEOUT with base.acquire_timeout(base.handle_lock(handle), handle, timeout): + # Log the outgoing sub-message at INFO so field diagnostics can + # correlate bridge NACKs with the exact payload we sent (e.g. to + # verify mic-gain byte landed in the device's accepted range). + if logger.isEnabledFor(logging.INFO): + logger.info( + "bridge TX: sub_idx=%d func=0x%02X sw_id=%d payload=%s", + sub_feat_idx, + sub_function, + sw_id, + sub_params.hex() if sub_params else "", + ) if sub_len <= first_chunk: # Single-frame path layer3 = bridge_prefix + bridge_hdr + sub_msg diff --git a/lib/logitech_receiver/settings_templates.py b/lib/logitech_receiver/settings_templates.py index 44b4741e..eb8d940d 100644 --- a/lib/logitech_receiver/settings_templates.py +++ b/lib/logitech_receiver/settings_templates.py @@ -1680,12 +1680,19 @@ class HeadsetMicGain(settings.Setting): # LGHUB caches these once at startup to rescale SetMicGain writes. try: info = device.feature_request(cls.feature, 0x00) - except Exception: + except Exception as e: + logger.info("HeadsetMicGain: GetInfo raised %s, using fallback int8 range", e) info = None if info and len(info) >= 2: min_gain = struct.unpack("b", bytes([info[0]]))[0] max_gain = struct.unpack("b", bytes([info[1]]))[0] if max_gain <= min_gain: # sanity — fall back to class defaults + logger.info( + "HeadsetMicGain: GetInfo returned nonsense range [%d, %d] (hex=%s), using fallback int8 range", + min_gain, + max_gain, + info.hex(), + ) min_gain, max_gain = cls.min_value, cls.max_value else: logger.info( @@ -1694,6 +1701,10 @@ class HeadsetMicGain(settings.Setting): max_gain, ) else: + logger.info( + "HeadsetMicGain: GetInfo returned %s, using fallback int8 range", + info.hex() if info else info, + ) min_gain, max_gain = cls.min_value, cls.max_value rw = settings.FeatureRW(cls.feature, **cls.rw_options) validator = settings_validator.RangeValidator(min_value=min_gain, max_value=max_gain, byte_count=1, signed=True)