From d24677eb840d785e8df843a0094e2e71f6e7652f Mon Sep 17 00:00:00 2001 From: Ken Sanislo Date: Fri, 17 Apr 2026 19:49:20 -0700 Subject: [PATCH] Don't misreport empty-ACK writes as failed (Setting.write) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HID++ 2.0 'set' operations (SetSidetone, SetAutoSleep, SetMicGain etc.) frequently respond with an empty ACK — just the echoed request_id with no data bytes after. device.feature_request() strips the request_id echo and returns the remaining payload, so our reply variable is b"" for these successful writes. The old check `if not reply:` evaluates b"" as falsy, so we returned None from Setting.write, which the GUI interpreted as "Read/write operation failed" — even though the device actually succeeded. Change the check to `if reply is None:` so empty bytes (success) pass through and only genuine transport failures (None return from base.request) are flagged as errors. Also add an INFO log on the real failure path so the user can tell from the log whether a write reached the device. This likely fixes the G522 sidetone / mic-gain / auto-sleep "Read/write operation failed" reports — all of those features return empty ACKs for set operations. --- lib/logitech_receiver/settings.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/logitech_receiver/settings.py b/lib/logitech_receiver/settings.py index a27d7b06..3842c917 100644 --- a/lib/logitech_receiver/settings.py +++ b/lib/logitech_receiver/settings.py @@ -172,8 +172,16 @@ class Setting: logger.debug("%s: prepare write(%s) => %r", self.name, value, data_bytes) reply = self._rw.write(self._device, data_bytes) - if not reply: - # tell whomever is calling that the write failed + # HID++ 2.0 "set" operations often return an empty ACK (b""). + # Treating empty bytes as failure (`not reply`) would misreport + # successful writes as errors to the GUI. Only report failure + # when the transport actually returned None (error or timeout). + if reply is None: + logger.info( + "%s: write on %s returned no reply (transport error/timeout)", + self.name, + self._device, + ) return None return value