From cff0110f81e7097aa2ad6ffd94e3d434e1feb082 Mon Sep 17 00:00:00 2001 From: "Peter F. Patel-Schneider" Date: Thu, 30 Oct 2025 06:01:51 -0400 Subject: [PATCH] settings: add scroll ratchet force setting --- docs/devices/MX Master 4.text | Bin 0 -> 7969 bytes lib/logitech_receiver/settings_templates.py | 36 ++++++++++++++++++++ lib/logitech_receiver/settings_validator.py | 9 ++--- 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 docs/devices/MX Master 4.text diff --git a/docs/devices/MX Master 4.text b/docs/devices/MX Master 4.text new file mode 100644 index 0000000000000000000000000000000000000000..aedfc34ae2d0430cbad0fb903dea635068a66f99 GIT binary patch literal 7969 zcmdrR+iu!Obf5DT=Vg^trK!i5o26X|g9&W8L^es9r^tbUSOFW^CMiPw_dVn547O8( zR#mj*0qk?XpPBgX%CbCop`LHM4v+5ei$upsPmOFfF9` z6CvCs1Z_R!jPGPJWZwjNtVv&kRJa=$`cOB` zBx2?iLv6yIbQP^2v^5nvlW}iw1)Y9-e8uU8n#nAENGMRytm8Thd%5+j0Q&~Um$0ao ze=^!SN;B@SrxSEpY)AaXq_NaHl-5W+*E0tCxI4Uu*oDkFn4R^AkX1)WiJ z1d2{E1!l0JUmFw5lgW5$Ook@hDxr`)!E8qv_3$aRgFSttyRX_d2ynQxXDnBIxbUqP zI{$>_GP39M6@>_{j##4y;T?0=>{&$M-c+FHde~s*B8K>~g4N3yUs0bm&IDC_tbn<; zu#C+odl9JI?+Wy-O<>Q|#90!NT3lHdn;80m4X^*7iCsHc7Rusi(B*bzd1CC+mtt_# z^nGEFQYaUZj3kasj8qzwOyjb!q++<-%EbHzjR|(`xcT-crZ|vEld#&tL4_ZowmMIi zv!u{>{UEjsGmfbCoG$DiDJH@G&X}4o822U#V)(sB-fZ#|@D7-sQ83BS+>g%cEkqwOlNH!GWM#s|A;-}1qBu&M(U#;&)<9r`tN z)!JnZTQHB|;>>3r1pn2>A32(NysXEH4c%A3b=6&M88h7G58$}jf`ft<_AJ~b1aX3E zx|oUK2+1PXvsTI3AQo3b5kqn9eVf9_G)>#v@g&De$vV=pLNbaH83b38Y5!)V6=p?P zONWO5vP#6#-Yq{VS@*Tr*>xte`K+-2Np= zU17)T7A~K1c7nj-7fx;1$0a$xr#A#iM*#1Use#*suDWW;t)>L+o;88Mk?ED+pLCS=L{#OB>WCCJ=C zfHbSZE?kvP(gCY6v#KRTw?&TSC^a+BSNStRvn_CJAI*`EWtBfO=#pSHMqN+*6y*e` z375GA>p3gyiFY`w z_)OMwXRuRrz)Vj4)T|3Jub&okF4J4G6dhKR*wtET4>^q88-C(49XSd*;xY0BjtZCQ zt?FT3w%Aoun5)O@sBoFyQgS-7?fShOxf(!@LIz86>lBV$O|-E5qM$@w3;md0M!dsn zz9yQQz)?FXdlbGVnz=iJ_s$cxOSW(~+<5NNv({_t5$^(?>F(fab4V9Kd}!yK!hTi& zPdXMZws45wC_Kl9uM?|I)Pt-wNERsaeY;)z|wQK z8P37QB6!XPzu?g!z zxVRC5z}ZxA$CIL>P37QYY{Gv)Jp9<9G%q*qZaWg(VJQd!3L?}=h>#S*KQ zyE8~A;_sZ@#i*&>Mc@x=H})3sT7)+}XLm7bYIhO%gW8Q9u;`*HvYxYByj|p-1Aumy zgFmR min_value self.min_value = min_value self.max_value = max_value + self.read_skip_byte_count = read_skip_byte_count + self.write_prefix_bytes = write_prefix_bytes self.needs_current_value = True # read and check before write (needed for ADC power and probably a good idea anyway) - self._byte_count = math.ceil(math.log(max_value + 1, 256)) if byte_count: assert self._byte_count <= byte_count @@ -544,7 +545,7 @@ class RangeValidator(Validator): assert self._byte_count < 8 def validate_read(self, reply_bytes): - reply_value = common.bytes2int(reply_bytes[: self._byte_count]) + reply_value = common.bytes2int(reply_bytes[self.read_skip_byte_count : self.read_skip_byte_count + self._byte_count]) assert reply_value >= self.min_value, f"{self.__class__.__name__}: failed to validate read value {reply_value:02X}" assert reply_value <= self.max_value, f"{self.__class__.__name__}: failed to validate read value {reply_value:02X}" return reply_value @@ -553,7 +554,7 @@ class RangeValidator(Validator): if new_value < self.min_value or new_value > self.max_value: raise ValueError(f"invalid choice {new_value!r}") current_value = self.validate_read(current_value) if current_value is not None else None - to_write = common.int2bytes(new_value, self._byte_count) + to_write = self.write_prefix_bytes + common.int2bytes(new_value, self._byte_count) # current value is known and same as value to be written return None to signal not to write it return None if current_value is not None and current_value == new_value else to_write