From 7fdf93a17336edf6c74c908111d78ff40bf384d8 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 e964d41c..93a9d744 100644 --- a/lib/logitech_receiver/device.py +++ b/lib/logitech_receiver/device.py @@ -714,6 +714,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 066634fc..cb92a323 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)