pre-commit: initial fix

Signed-off-by: Filipe Laíns <lains@archlinux.org>
This commit is contained in:
Filipe Laíns 2020-07-02 14:24:08 +01:00 committed by Filipe Laíns
parent 63fa581d13
commit 33521558ed
71 changed files with 804 additions and 816 deletions

View File

@ -7,7 +7,7 @@
* Update French translation * Update French translation
* Update installation documentation * Update installation documentation
1.0.2rc2: 1.0.2rc2:
* Remove packaging directory tree as it is not maintained * Remove packaging directory tree as it is not maintained
* Pip installs udev rule and solaar autostart when doing install without --user flag * Pip installs udev rule and solaar autostart when doing install without --user flag
* Use Solaar icon instead of a missing battery icon * Use Solaar icon instead of a missing battery icon

2
docs/.gitignore vendored
View File

@ -3,4 +3,4 @@
.jekyll-metadata .jekyll-metadata
Gemfile Gemfile
Gemfile.lock Gemfile.lock
_site/ _site/

View File

@ -1,4 +1,4 @@
# Documentation Readme # Documentation Readme
This project's documentation is hosted using GitHub pages, which serves static pages using Jeykll. This project's documentation is hosted using GitHub pages, which serves static pages using Jeykll.
[Please refer to the official documentation for instructions for how to build the site locally.](https://help.github.com/articles/setting-up-your-github-pages-site-locally-with-jekyll/) [Please refer to the official documentation for instructions for how to build the site locally.](https://help.github.com/articles/setting-up-your-github-pages-site-locally-with-jekyll/)

View File

@ -104,11 +104,11 @@ several heuristics to determine which icon names to use for this purpose,
but as more and more battery icon schemes have been developed this has but as more and more battery icon schemes have been developed this has
become impossible to do well. Solaar now uses the eleven standard become impossible to do well. Solaar now uses the eleven standard
battery icon names `battery-{full,good,low,critical,empty}[-charging]` and battery icon names `battery-{full,good,low,critical,empty}[-charging]` and
`battery-missing`. `battery-missing`.
Solaar will use the symbolic versions of these icons if started with the Solaar will use the symbolic versions of these icons if started with the
option `--battery-icons=symbolic`. Because of bugs external to Solaar option `--battery-icons=symbolic`. Because of bugs external to Solaar
these symbolic icons may be nearly invisible in dark themes. these symbolic icons may be nearly invisible in dark themes.
[solaar]: https://github.com/pwr-Solaar/Solaar [solaar]: https://github.com/pwr-Solaar/Solaar
[logitech]: https://www.logitech.com [logitech]: https://www.logitech.com

View File

@ -10,8 +10,8 @@ features are supported by Solaar. The information in these tables is
incomplete, based on what devices users have been able to test Solaar with. incomplete, based on what devices users have been able to test Solaar with.
The HID++ column specifies the device's HID++ version. Some devices report The HID++ column specifies the device's HID++ version. Some devices report
version 4.5, but that is the same as version 2.0 as listed here. version 4.5, but that is the same as version 2.0 as listed here.
For devices what support HID++ 2.0 or greater, Solaar is able to discover For devices what support HID++ 2.0 or greater, Solaar is able to discover
the features the device supports. the features the device supports.
The Battery column specifies if Solaar is able to read the device's battery The Battery column specifies if Solaar is able to read the device's battery
@ -21,7 +21,7 @@ For mice, the DPI column specifies if the mouse's sensitivity is fixed (`-`),
can only be read (`R`), or can be read and changed by Solaar (`R/W`). can only be read (`R`), or can be read and changed by Solaar (`R/W`).
The reprog(rammable) keys feature is currently not fully supported by Solaar. The reprog(rammable) keys feature is currently not fully supported by Solaar.
You are able to read this feature using command-line interface of Solaar, You are able to read this feature using command-line interface of Solaar,
but it is not possible to assign different keys. but it is not possible to assign different keys.

View File

@ -8,12 +8,12 @@
Firmware: RQM 62.00.B0013 Firmware: RQM 62.00.B0013
The power switch is located on the base. The power switch is located on the base.
Supports 22 HID++ 2.0 features: Supports 22 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: RESET {0020} 4: RESET {0020}
5: BATTERY STATUS {1000} 5: BATTERY STATUS {1000}
6: unknown:1802 {1802} internal, hidden 6: unknown:1802 {1802} internal, hidden
7: unknown:1810 {1810} internal, hidden 7: unknown:1810 {1810} internal, hidden
8: unknown:1830 {1830} internal, hidden 8: unknown:1830 {1830} internal, hidden
@ -21,28 +21,28 @@
10: unknown:1890 {1890} internal, hidden 10: unknown:1890 {1890} internal, hidden
11: unknown:18A0 {18A0} internal, hidden 11: unknown:18A0 {18A0} internal, hidden
12: unknown:18B1 {18B1} internal, hidden 12: unknown:18B1 {18B1} internal, hidden
13: REPROG CONTROLS V4 {1B04} 13: REPROG CONTROLS V4 {1B04}
14: WIRELESS DEVICE STATUS {1D4B} 14: WIRELESS DEVICE STATUS {1D4B}
15: unknown:1DF0 {1DF0} hidden 15: unknown:1DF0 {1DF0} hidden
16: unknown:1DF3 {1DF3} internal, hidden 16: unknown:1DF3 {1DF3} internal, hidden
17: unknown:1E00 {1E00} hidden 17: unknown:1E00 {1E00} hidden
18: unknown:1EB0 {1EB0} internal, hidden 18: unknown:1EB0 {1EB0} internal, hidden
19: unknown:1F03 {1F03} internal, hidden 19: unknown:1F03 {1F03} internal, hidden
20: LOWRES WHEEL {2130} 20: LOWRES WHEEL {2130}
21: POINTER SPEED {2205} 21: POINTER SPEED {2205}
Has 7 reprogrammable keys: Has 7 reprogrammable keys:
0: LEFT CLICK , default: LeftClick => LEFT CLICK 0: LEFT CLICK , default: LeftClick => LEFT CLICK
divertable, mse, pos:0, group:1, gmask:1 divertable, mse, pos:0, group:1, gmask:1
1: RIGHT CLICK , default: RightClick => RIGHT CLICK 1: RIGHT CLICK , default: RightClick => RIGHT CLICK
divertable, mse, pos:0, group:1, gmask:1 divertable, mse, pos:0, group:1, gmask:1
2: MIDDLE BUTTON , default: MiddleMouseButton => MIDDLE BUTTON 2: MIDDLE BUTTON , default: MiddleMouseButton => MIDDLE BUTTON
divertable, mse, reprogrammable, pos:0, group:2, gmask:3 divertable, mse, reprogrammable, pos:0, group:2, gmask:3
3: LEFT SCROLL AS AC PAN , default: HorzScrollLeftSet => LEFT SCROLL AS AC PAN 3: LEFT SCROLL AS AC PAN , default: HorzScrollLeftSet => LEFT SCROLL AS AC PAN
divertable, mse, reprogrammable, pos:0, group:2, gmask:3 divertable, mse, reprogrammable, pos:0, group:2, gmask:3
4: RIGHT SCROLL AS AC PAN , default: HorzScrollRightSet => RIGHT SCROLL AS AC PAN 4: RIGHT SCROLL AS AC PAN , default: HorzScrollRightSet => RIGHT SCROLL AS AC PAN
divertable, mse, reprogrammable, pos:0, group:2, gmask:3 divertable, mse, reprogrammable, pos:0, group:2, gmask:3
5: BACK AS BUTTON 4 , default: BackEx => BACK AS BUTTON 4 5: BACK AS BUTTON 4 , default: BackEx => BACK AS BUTTON 4
divertable, mse, reprogrammable, pos:0, group:2, gmask:3 divertable, mse, reprogrammable, pos:0, group:2, gmask:3
6: FORWARD AS BUTTON 5 , default: BrowserForwardEx => FORWARD AS BUTTON 5 6: FORWARD AS BUTTON 5 , default: BrowserForwardEx => FORWARD AS BUTTON 5
divertable, mse, reprogrammable, pos:0, group:2, gmask:3 divertable, mse, reprogrammable, pos:0, group:2, gmask:3
Battery: 70%, discharging. Battery: 70%, discharging.

View File

@ -19,22 +19,22 @@ Unifying Receiver
Bootloader: BOT 23.00.B0007 Bootloader: BOT 23.00.B0007
Firmware: MPM 02.00.B0007 Firmware: MPM 02.00.B0007
Firmware: MPM 02.00.B0007 Firmware: MPM 02.00.B0007
Other: Other:
The power switch is located on the base. The power switch is located on the base.
Supports 26 HID++ 2.0 features: Supports 26 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: WIRELESS DEVICE STATUS {1D4B} 4: WIRELESS DEVICE STATUS {1D4B}
5: RESET {0020} 5: RESET {0020}
6: BATTERY STATUS {1000} 6: BATTERY STATUS {1000}
7: CHANGE HOST {1814} 7: CHANGE HOST {1814}
8: REPROG CONTROLS V4 {1B04} 8: REPROG CONTROLS V4 {1B04}
9: ADJUSTABLE DPI {2201} 9: ADJUSTABLE DPI {2201}
10: VERTICAL SCROLLING {2100} 10: VERTICAL SCROLLING {2100}
11: HIRES WHEEL {2121} 11: HIRES WHEEL {2121}
12: DFUCONTROL 2 {00C1} 12: DFUCONTROL 2 {00C1}
13: unknown:1813 {1813} internal, hidden 13: unknown:1813 {1813} internal, hidden
14: unknown:1830 {1830} internal, hidden 14: unknown:1830 {1830} internal, hidden
15: unknown:1890 {1890} internal, hidden 15: unknown:1890 {1890} internal, hidden

View File

@ -111,4 +111,3 @@ Unifying Receiver
23: unknown:0034 , default: Do Nothing One => unknown:0034 23: unknown:0034 , default: Do Nothing One => unknown:0034
nonstandard, pos:0, group:0, gmask:0 nonstandard, pos:0, group:0, gmask:0
Battery: 0%, full. Battery: 0%, full.

View File

@ -18,18 +18,18 @@ Unifying Receiver
Firmware: RQK 35.00.B0017 Firmware: RQK 35.00.B0017
The power switch is located on the top case. The power switch is located on the top case.
Supports 12 HID++ 2.0 features: Supports 12 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: unknown:1820 {1820} hidden 5: unknown:1820 {1820} hidden
6: REPROG CONTROLS {1B00} 6: REPROG CONTROLS {1B00}
7: WIRELESS DEVICE STATUS {1D4B} 7: WIRELESS DEVICE STATUS {1D4B}
8: unknown:1DF0 {1DF0} hidden 8: unknown:1DF0 {1DF0} hidden
9: unknown:1DF3 {1DF3} hidden 9: unknown:1DF3 {1DF3} hidden
10: ENCRYPTION {4100} 10: ENCRYPTION {4100}
11: KEYBOARD LAYOUT {4520} 11: KEYBOARD LAYOUT {4520}
Has 8 reprogrammable keys: Has 8 reprogrammable keys:
0: Play/Pause => Play/Pause nonstandard 0: Play/Pause => Play/Pause nonstandard
1: Mute => Mute nonstandard 1: Mute => Mute nonstandard
@ -40,4 +40,3 @@ Unifying Receiver
6: SLEEP => Sleep nonstandard, reprogrammable 6: SLEEP => Sleep nonstandard, reprogrammable
7: Calculator => Calculator nonstandard, reprogrammable 7: Calculator => Calculator nonstandard, reprogrammable
Battery: 90%, discharging. Battery: 90%, discharging.

View File

@ -58,19 +58,19 @@ Total number of HID++ 2.0 features: 12
Firmware : RQK 36.00.B0007 Firmware : RQK 36.00.B0007
The power switch is located on the top case The power switch is located on the top case
Supports 13 HID++ 2.0 features: Supports 13 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: unknown:1820 {1820} hidden 5: unknown:1820 {1820} hidden
6: REPROG CONTROLS {1B00} 6: REPROG CONTROLS {1B00}
7: WIRELESS DEVICE STATUS {1D4B} 7: WIRELESS DEVICE STATUS {1D4B}
8: unknown:1DF0 {1DF0} hidden 8: unknown:1DF0 {1DF0} hidden
9: unknown:1DF3 {1DF3} hidden 9: unknown:1DF3 {1DF3} hidden
10: FN INVERSION {40A0} 10: FN INVERSION {40A0}
11: ENCRYPTION {4100} 11: ENCRYPTION {4100}
12: KEYBOARD LAYOUT {4520} 12: KEYBOARD LAYOUT {4520}
Has 18 reprogrammable keys: Has 18 reprogrammable keys:
0: MY HOME => HomePage FN sensitive, is FN, reprogrammable 0: MY HOME => HomePage FN sensitive, is FN, reprogrammable
1: Mail => Mail FN sensitive, is FN, reprogrammable 1: Mail => Mail FN sensitive, is FN, reprogrammable

View File

@ -12,17 +12,17 @@
Bootloader: DFU 00.02.B0003 Bootloader: DFU 00.02.B0003
The power switch is located on the edge of top right corner. The power switch is located on the edge of top right corner.
Supports 11 HID++ 2.0 features: Supports 11 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: REPROG CONTROLS {1B00} 4: REPROG CONTROLS {1B00}
5: WIRELESS DEVICE STATUS {1D4B} 5: WIRELESS DEVICE STATUS {1D4B}
6: unknown:1DF3 {1DF3} hidden 6: unknown:1DF3 {1DF3} hidden
7: FN INVERSION {40A0} 7: FN INVERSION {40A0}
8: ENCRYPTION {4100} 8: ENCRYPTION {4100}
9: SOLAR DASHBOARD {4301} 9: SOLAR DASHBOARD {4301}
10: KEYBOARD LAYOUT {4520} 10: KEYBOARD LAYOUT {4520}
Has 12 reprogrammable keys: Has 12 reprogrammable keys:
0: MY HOME => HomePage FN sensitive, is FN, reprogrammable 0: MY HOME => HomePage FN sensitive, is FN, reprogrammable
1: Mail => Email FN sensitive, is FN, reprogrammable 1: Mail => Email FN sensitive, is FN, reprogrammable

View File

@ -7,27 +7,27 @@
Serial number: 4D71FEE1 Serial number: 4D71FEE1
Bootloader: BOT 25.00.B0005 Bootloader: BOT 25.00.B0005
Firmware: MPK 01.00.B0018 Firmware: MPK 01.00.B0018
Other: Other:
The power switch is located on the edge of top right corner. The power switch is located on the edge of top right corner.
Supports 31 HID++ 2.0 features: Supports 31 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: WIRELESS DEVICE STATUS {1D4B} 4: WIRELESS DEVICE STATUS {1D4B}
5: RESET {0020} 5: RESET {0020}
6: unknown:0007 {0007} 6: unknown:0007 {0007}
7: BATTERY STATUS {1000} 7: BATTERY STATUS {1000}
8: CHANGE HOST {1814} 8: CHANGE HOST {1814}
9: unknown:1815 {1815} 9: unknown:1815 {1815}
10: REPROG CONTROLS V4 {1B04} 10: REPROG CONTROLS V4 {1B04}
11: unknown:1C00 {1C00} 11: unknown:1C00 {1C00}
12: NEW FN INVERSION {40A2} 12: NEW FN INVERSION {40A2}
13: ENCRYPTION {4100} 13: ENCRYPTION {4100}
14: KEYBOARD DISABLE {4521} 14: KEYBOARD DISABLE {4521}
15: unknown:4531 {4531} 15: unknown:4531 {4531}
16: LOCK KEY STATE {4220} 16: LOCK KEY STATE {4220}
17: unknown:00C2 {00C2} 17: unknown:00C2 {00C2}
18: unknown:1803 {1803} internal, hidden 18: unknown:1803 {1803} internal, hidden
19: unknown:1806 {1806} internal, hidden 19: unknown:1806 {1806} internal, hidden
20: unknown:1805 {1805} internal, hidden 20: unknown:1805 {1805} internal, hidden

View File

@ -77,43 +77,43 @@ Unifying Receiver
Bootloader: BOT 56.10.B0005 Bootloader: BOT 56.10.B0005
Firmware: MPM 12.10.B0005 Firmware: MPM 12.10.B0005
Firmware: MPM 12.10.B0005 Firmware: MPM 12.10.B0005
Other: Other:
The power switch is located on the base. The power switch is located on the base.
Supports 32 HID++ 2.0 features: Supports 32 HID++ 2.0 features:
16:01:47,214 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000B 000000] 16:01:47,214 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000B 000000]
16:01:47,311 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000B 00000100000000000000000000000000] 16:01:47,311 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000B 00000100000000000000000000000000]
0: ROOT {0000} 0: ROOT {0000}
16:01:47,312 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000C 000100] 16:01:47,312 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000C 000100]
16:01:47,333 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000C 01000100000000000000000000000000] 16:01:47,333 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000C 01000100000000000000000000000000]
1: FEATURE SET {0001} 1: FEATURE SET {0001}
16:01:47,334 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000F 000300] 16:01:47,334 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000F 000300]
16:01:47,431 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000F 02000200000000000000000000000000] 16:01:47,431 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000F 02000200000000000000000000000000]
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
16:01:47,431 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011C 030000] 16:01:47,431 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011C 030000]
16:01:47,453 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011C 00050000000000000000000000000000] 16:01:47,453 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011C 00050000000000000000000000000000]
16:01:47,454 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000F 000500] 16:01:47,454 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000F 000500]
16:01:47,475 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000F 03000000000000000000000000000000] 16:01:47,475 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000F 03000000000000000000000000000000]
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
16:01:47,475 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0119 040000] 16:01:47,475 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0119 040000]
16:01:47,575 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0119 1D4B0000000000000000000000000000] 16:01:47,575 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0119 1D4B0000000000000000000000000000]
16:01:47,575 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000A 1D4B00] 16:01:47,575 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000A 1D4B00]
16:01:47,593 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000A 04000000000000000000000000000000] 16:01:47,593 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000A 04000000000000000000000000000000]
4: WIRELESS DEVICE STATUS {1D4B} 4: WIRELESS DEVICE STATUS {1D4B}
16:01:47,593 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011A 050000] 16:01:47,593 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011A 050000]
16:01:47,617 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011A 00200000000000000000000000000000] 16:01:47,617 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011A 00200000000000000000000000000000]
16:01:47,617 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0009 002000] 16:01:47,617 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0009 002000]
16:01:47,715 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0009 05000000000000000000000000000000] 16:01:47,715 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0009 05000000000000000000000000000000]
5: RESET {0020} 5: RESET {0020}
16:01:47,715 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011E 060000] 16:01:47,715 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011E 060000]
16:01:47,735 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011E 00210000000000000000000000000000] 16:01:47,735 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011E 00210000000000000000000000000000]
16:01:47,735 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000B 002100] 16:01:47,735 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000B 002100]
16:01:47,755 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000B 06000000000000000000000000000000] 16:01:47,755 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000B 06000000000000000000000000000000]
6: unknown:0021 {0021} 6: unknown:0021 {0021}
16:01:47,755 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011C 070000] 16:01:47,755 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011C 070000]
16:01:47,775 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011C 10000000000000000000000000000000] 16:01:47,775 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011C 10000000000000000000000000000000]
16:01:47,775 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000C 100000] 16:01:47,775 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000C 100000]
16:01:47,795 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000C 07000000000000000000000000000000] 16:01:47,795 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000C 07000000000000000000000000000000]
7: BATTERY STATUS {1000} 7: BATTERY STATUS {1000}
16:01:47,795 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011F 080000] 16:01:47,795 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011F 080000]
16:01:47,815 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011F 18066000000000000000000000000000] 16:01:47,815 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011F 18066000000000000000000000000000]
16:01:47,815 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000C 180600] 16:01:47,815 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000C 180600]
@ -123,22 +123,22 @@ Unifying Receiver
16:01:47,855 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0119 18140001000000000000000000000000] 16:01:47,855 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0119 18140001000000000000000000000000]
16:01:47,855 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000A 181400] 16:01:47,855 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000A 181400]
16:01:47,875 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000A 09000100000000000000000000000000] 16:01:47,875 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000A 09000100000000000000000000000000]
9: CHANGE HOST {1814} 9: CHANGE HOST {1814}
16:01:47,875 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011A 0A0000] 16:01:47,875 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011A 0A0000]
16:01:47,895 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011A 1B040003000000000000000000000000] 16:01:47,895 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011A 1B040003000000000000000000000000]
16:01:47,895 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000A 1B0400] 16:01:47,895 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000A 1B0400]
16:01:47,915 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000A 0A000300000000000000000000000000] 16:01:47,915 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000A 0A000300000000000000000000000000]
10: REPROG CONTROLS V4 {1B04} 10: REPROG CONTROLS V4 {1B04}
16:01:47,915 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011E 0B0000] 16:01:47,915 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011E 0B0000]
16:01:47,935 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011E 22010001000000000000000000000000] 16:01:47,935 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011E 22010001000000000000000000000000]
16:01:47,935 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000E 220100] 16:01:47,935 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000E 220100]
16:01:47,957 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000E 0B000100000000000000000000000000] 16:01:47,957 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000E 0B000100000000000000000000000000]
11: ADJUSTABLE DPI {2201} 11: ADJUSTABLE DPI {2201}
16:01:47,957 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011A 0C0000] 16:01:47,957 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011A 0C0000]
16:01:47,977 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011A 21000000000000000000000000000000] 16:01:47,977 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011A 21000000000000000000000000000000]
16:01:47,977 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0009 210000] 16:01:47,977 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0009 210000]
16:01:47,997 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0009 0C000000000000000000000000000000] 16:01:47,997 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0009 0C000000000000000000000000000000]
12: VERTICAL SCROLLING {2100} 12: VERTICAL SCROLLING {2100}
16:01:47,998 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0C0C 000000] 16:01:47,998 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0C0C 000000]
16:01:48,017 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0C0C 03180000000000000000000000000000] 16:01:48,017 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0C0C 03180000000000000000000000000000]
Roller type: 3G Roller type: 3G
@ -148,12 +148,12 @@ Unifying Receiver
16:01:48,037 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011A 21100000000000000000000000000000] 16:01:48,037 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011A 21100000000000000000000000000000]
16:01:48,037 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0008 211000] 16:01:48,037 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0008 211000]
16:01:48,057 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0008 0D000000000000000000000000000000] 16:01:48,057 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0008 0D000000000000000000000000000000]
13: SMART SHIFT {2110} 13: SMART SHIFT {2110}
16:01:48,057 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011C 0E0000] 16:01:48,057 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011C 0E0000]
16:01:48,077 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011C 21210000000000000000000000000000] 16:01:48,077 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011C 21210000000000000000000000000000]
16:01:48,077 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000C 212100] 16:01:48,077 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000C 212100]
16:01:48,097 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000C 0E000000000000000000000000000000] 16:01:48,097 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000C 0E000000000000000000000000000000]
14: HIRES WHEEL {2121} 14: HIRES WHEEL {2121}
16:01:48,097 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0E09 000000] 16:01:48,097 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0E09 000000]
16:01:48,117 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0E09 080C0000000000000000000000000000] 16:01:48,117 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0E09 080C0000000000000000000000000000]
16:01:48,117 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0E1D 000000] 16:01:48,117 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0E1D 000000]
@ -171,12 +171,12 @@ Unifying Receiver
16:01:48,179 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011F 65010000000000000000000000000000] 16:01:48,179 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011F 65010000000000000000000000000000]
16:01:48,179 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000A 650100] 16:01:48,179 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 000A 650100]
16:01:48,199 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000A 0F000000000000000000000000000000] 16:01:48,199 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 000A 0F000000000000000000000000000000]
15: GESTURE 2 {6501} 15: GESTURE 2 {6501}
16:01:48,199 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0119 100000] 16:01:48,199 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0119 100000]
16:01:48,219 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0119 00C20000000000000000000000000000] 16:01:48,219 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0119 00C20000000000000000000000000000]
16:01:48,219 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0009 00C200] 16:01:48,219 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0009 00C200]
16:01:48,239 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0009 10000000000000000000000000000000] 16:01:48,239 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0009 10000000000000000000000000000000]
16: unknown:00C2 {00C2} 16: unknown:00C2 {00C2}
16:01:48,240 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011B 110000] 16:01:48,240 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 011B 110000]
16:01:48,259 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011B 18136000000000000000000000000000] 16:01:48,259 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 011B 18136000000000000000000000000000]
16:01:48,259 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0009 181300] 16:01:48,259 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0009 181300]
@ -259,49 +259,49 @@ Unifying Receiver
16:01:48,885 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1C 00500038010001010000000000000000] 16:01:48,885 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1C 00500038010001010000000000000000]
16:01:48,885 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2B 005000] 16:01:48,885 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2B 005000]
16:01:48,905 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2B 00500000000000000000000000000000] 16:01:48,905 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2B 00500000000000000000000000000000]
0: LEFT CLICK , default: LeftClick => LEFT CLICK 0: LEFT CLICK , default: LeftClick => LEFT CLICK
mse, pos:0, group:1, gmask:1 mse, pos:0, group:1, gmask:1
16:01:48,905 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1D 010000] 16:01:48,905 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1D 010000]
16:01:48,925 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1D 00510039010001010000000000000000] 16:01:48,925 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1D 00510039010001010000000000000000]
16:01:48,925 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A28 005100] 16:01:48,925 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A28 005100]
16:01:48,945 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A28 00510000000000000000000000000000] 16:01:48,945 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A28 00510000000000000000000000000000]
1: RIGHT CLICK , default: RightClick => RIGHT CLICK 1: RIGHT CLICK , default: RightClick => RIGHT CLICK
mse, pos:0, group:1, gmask:1 mse, pos:0, group:1, gmask:1
16:01:48,945 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1B 020000] 16:01:48,945 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1B 020000]
16:01:48,965 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1B 0052003A310003070100000000000000] 16:01:48,965 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1B 0052003A310003070100000000000000]
16:01:48,965 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2B 005200] 16:01:48,965 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2B 005200]
16:01:48,985 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2B 00520000000000000000000000000000] 16:01:48,985 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2B 00520000000000000000000000000000]
2: MIDDLE BUTTON , default: MiddleMouseButton => MIDDLE BUTTON 2: MIDDLE BUTTON , default: MiddleMouseButton => MIDDLE BUTTON
mse, reprogrammable, divertable, pos:0, group:3, gmask:7 mse, reprogrammable, divertable, pos:0, group:3, gmask:7
16:01:48,985 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1E 030000] 16:01:48,985 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1E 030000]
16:01:49,005 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1E 0053003C310002030100000000000000] 16:01:49,005 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1E 0053003C310002030100000000000000]
16:01:49,006 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A28 005300] 16:01:49,006 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A28 005300]
16:01:49,027 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A28 00530000000000000000000000000000] 16:01:49,027 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A28 00530000000000000000000000000000]
3: BACK AS BUTTON 4 , default: BackEx => BACK AS BUTTON 4 3: BACK AS BUTTON 4 , default: BackEx => BACK AS BUTTON 4
mse, reprogrammable, divertable, pos:0, group:2, gmask:3 mse, reprogrammable, divertable, pos:0, group:2, gmask:3
16:01:49,027 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1B 040000] 16:01:49,027 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1B 040000]
16:01:49,047 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1B 0056003E310002030100000000000000] 16:01:49,047 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1B 0056003E310002030100000000000000]
16:01:49,047 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2F 005600] 16:01:49,047 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2F 005600]
16:01:49,067 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2F 00560000000000000000000000000000] 16:01:49,067 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2F 00560000000000000000000000000000]
4: FORWARD AS BUTTON 5 , default: BrowserForwardEx => FORWARD AS BUTTON 5 4: FORWARD AS BUTTON 5 , default: BrowserForwardEx => FORWARD AS BUTTON 5
mse, reprogrammable, divertable, pos:0, group:2, gmask:3 mse, reprogrammable, divertable, pos:0, group:2, gmask:3
16:01:49,067 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1C 050000] 16:01:49,067 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1C 050000]
16:01:49,087 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1C 00C300A9310003070100000000000000] 16:01:49,087 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1C 00C300A9310003070100000000000000]
16:01:49,087 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2A 00C300] 16:01:49,087 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2A 00C300]
16:01:49,107 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2A 00C30000000000000000000000000000] 16:01:49,107 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2A 00C30000000000000000000000000000]
5: unknown:00C3 , default: unknown:00A9 => unknown:00C3 5: unknown:00C3 , default: unknown:00A9 => unknown:00C3
mse, reprogrammable, divertable, pos:0, group:3, gmask:7 mse, reprogrammable, divertable, pos:0, group:3, gmask:7
16:01:49,107 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1A 060000] 16:01:49,107 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1A 060000]
16:01:49,127 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1A 00C4009D310003070100000000000000] 16:01:49,127 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1A 00C4009D310003070100000000000000]
16:01:49,127 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2C 00C400] 16:01:49,127 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2C 00C400]
16:01:49,147 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2C 00C40000000000000000000000000000] 16:01:49,147 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2C 00C40000000000000000000000000000]
6: unknown:00C4 , default: unknown:009D => unknown:00C4 6: unknown:00C4 , default: unknown:009D => unknown:00C4
mse, reprogrammable, divertable, pos:0, group:3, gmask:7 mse, reprogrammable, divertable, pos:0, group:3, gmask:7
16:01:49,147 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1C 070000] 16:01:49,147 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A1C 070000]
16:01:49,167 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1C 00D700B4A00004000300000000000000] 16:01:49,167 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A1C 00D700B4A00004000300000000000000]
16:01:49,167 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2C 00D700] 16:01:49,167 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 0A2C 00D700]
16:01:49,187 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2C 00D70000000000000000000000000000] 16:01:49,187 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 0A2C 00D70000000000000000000000000000]
7: unknown:00D7 , default: unknown:00B4 => unknown:00D7 7: unknown:00D7 , default: unknown:00B4 => unknown:00D7
divertable, virtual, pos:0, group:4, gmask:0 divertable, virtual, pos:0, group:4, gmask:0
16:01:49,187 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 070B 000000] 16:01:49,187 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 01 070B 000000]
16:01:49,207 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 070B 32140000000000000000000000000000] 16:01:49,207 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 01 070B 32140000000000000000000000000000]
@ -341,63 +341,63 @@ Unifying Receiver
Supports 25 HID++ 2.0 features: Supports 25 HID++ 2.0 features:
16:01:49,487 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000F 000000] 16:01:49,487 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000F 000000]
16:01:49,527 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000F 00000100000000000000000000000000] 16:01:49,527 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000F 00000100000000000000000000000000]
0: ROOT {0000} 0: ROOT {0000}
16:01:49,527 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000F 000100] 16:01:49,527 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000F 000100]
16:01:49,567 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000F 01000100000000000000000000000000] 16:01:49,567 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000F 01000100000000000000000000000000]
1: FEATURE SET {0001} 1: FEATURE SET {0001}
16:01:49,568 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000C 000300] 16:01:49,568 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000C 000300]
16:01:49,607 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000C 02000200000000000000000000000000] 16:01:49,607 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000C 02000200000000000000000000000000]
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
16:01:49,607 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011A 030000] 16:01:49,607 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011A 030000]
16:01:49,647 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011A 00050000000000000000000000000000] 16:01:49,647 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011A 00050000000000000000000000000000]
16:01:49,647 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000D 000500] 16:01:49,647 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000D 000500]
16:01:49,687 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000D 03000000000000000000000000000000] 16:01:49,687 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000D 03000000000000000000000000000000]
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
16:01:49,687 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011C 040000] 16:01:49,687 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011C 040000]
16:01:49,729 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011C 1D4B0000000000000000000000000000] 16:01:49,729 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011C 1D4B0000000000000000000000000000]
16:01:49,729 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000D 1D4B00] 16:01:49,729 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000D 1D4B00]
16:01:49,770 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000D 04000000000000000000000000000000] 16:01:49,770 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000D 04000000000000000000000000000000]
4: WIRELESS DEVICE STATUS {1D4B} 4: WIRELESS DEVICE STATUS {1D4B}
16:01:49,770 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0119 050000] 16:01:49,770 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0119 050000]
16:01:49,809 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0119 00200000000000000000000000000000] 16:01:49,809 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0119 00200000000000000000000000000000]
16:01:49,809 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000D 002000] 16:01:49,809 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000D 002000]
16:01:49,849 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000D 05000000000000000000000000000000] 16:01:49,849 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000D 05000000000000000000000000000000]
5: RESET {0020} 5: RESET {0020}
16:01:49,849 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0118 060000] 16:01:49,849 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0118 060000]
16:01:49,889 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0118 10000000000000000000000000000000] 16:01:49,889 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0118 10000000000000000000000000000000]
16:01:49,889 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0009 100000] 16:01:49,889 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0009 100000]
16:01:49,929 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0009 06000000000000000000000000000000] 16:01:49,929 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0009 06000000000000000000000000000000]
6: BATTERY STATUS {1000} 6: BATTERY STATUS {1000}
16:01:49,929 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011D 070000] 16:01:49,929 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011D 070000]
16:01:49,969 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011D 19830000000000000000000000000000] 16:01:49,969 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011D 19830000000000000000000000000000]
16:01:49,969 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000B 198300] 16:01:49,969 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000B 198300]
16:01:50,009 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000B 07000000000000000000000000000000] 16:01:50,009 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000B 07000000000000000000000000000000]
7: unknown:1983 {1983} 7: unknown:1983 {1983}
16:01:50,010 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011F 080000] 16:01:50,010 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011F 080000]
16:01:50,051 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011F 1B040003000000000000000000000000] 16:01:50,051 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011F 1B040003000000000000000000000000]
16:01:50,051 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000E 1B0400] 16:01:50,051 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000E 1B0400]
16:01:50,091 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000E 08000300000000000000000000000000] 16:01:50,091 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000E 08000300000000000000000000000000]
8: REPROG CONTROLS V4 {1B04} 8: REPROG CONTROLS V4 {1B04}
16:01:50,091 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0119 090000] 16:01:50,091 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0119 090000]
16:01:50,131 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0119 40A00000000000000000000000000000] 16:01:50,131 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0119 40A00000000000000000000000000000]
16:01:50,131 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0009 40A000] 16:01:50,131 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0009 40A000]
16:01:50,171 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0009 09000000000000000000000000000000] 16:01:50,171 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0009 09000000000000000000000000000000]
9: FN INVERSION {40A0} 9: FN INVERSION {40A0}
16:01:50,171 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011C 0A0000] 16:01:50,171 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011C 0A0000]
16:01:50,211 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011C 41000000000000000000000000000000] 16:01:50,211 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011C 41000000000000000000000000000000]
16:01:50,211 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000A 410000] 16:01:50,211 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000A 410000]
16:01:50,251 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000A 0A000000000000000000000000000000] 16:01:50,251 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000A 0A000000000000000000000000000000]
10: ENCRYPTION {4100} 10: ENCRYPTION {4100}
16:01:50,251 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0118 0B0000] 16:01:50,251 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0118 0B0000]
16:01:50,293 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0118 45210000000000000000000000000000] 16:01:50,293 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0118 45210000000000000000000000000000]
16:01:50,293 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000F 452100] 16:01:50,293 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000F 452100]
16:01:50,333 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000F 0B000000000000000000000000000000] 16:01:50,333 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000F 0B000000000000000000000000000000]
11: KEYBOARD DISABLE {4521} 11: KEYBOARD DISABLE {4521}
16:01:50,334 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011E 0C0000] 16:01:50,334 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 011E 0C0000]
16:01:50,373 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011E 00C20000000000000000000000000000] 16:01:50,373 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 011E 00C20000000000000000000000000000]
16:01:50,373 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000F 00C200] 16:01:50,373 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 000F 00C200]
16:01:50,413 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000F 0C000000000000000000000000000000] 16:01:50,413 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 000F 0C000000000000000000000000000000]
12: unknown:00C2 {00C2} 12: unknown:00C2 {00C2}
16:01:50,414 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0118 0D0000] 16:01:50,414 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0118 0D0000]
16:01:50,453 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0118 18036000000000000000000000000000] 16:01:50,453 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0118 18036000000000000000000000000000]
16:01:50,454 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0008 180300] 16:01:50,454 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0008 180300]
@ -465,93 +465,93 @@ Unifying Receiver
16:01:51,461 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081C 0022001A3A0100000000000000000000] 16:01:51,461 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081C 0022001A3A0100000000000000000000]
16:01:51,462 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082F 002200] 16:01:51,462 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082F 002200]
16:01:51,501 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082F 00220000000000000000000000000000] 16:01:51,501 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082F 00220000000000000000000000000000]
0: MY HOME , default: HomePage => MY HOME 0: MY HOME , default: HomePage => MY HOME
is FN, FN sensitive, reprogrammable, divertable, pos:1, group:0, gmask:0 is FN, FN sensitive, reprogrammable, divertable, pos:1, group:0, gmask:0
16:01:51,502 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0819 010000] 16:01:51,502 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0819 010000]
16:01:51,541 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0819 000E000E3A0200000000000000000000] 16:01:51,541 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0819 000E000E3A0200000000000000000000]
16:01:51,542 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0829 000E00] 16:01:51,542 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0829 000E00]
16:01:51,581 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0829 000E0000000000000000000000000000] 16:01:51,581 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0829 000E0000000000000000000000000000]
1: Mail , default: Email => Mail 1: Mail , default: Email => Mail
is FN, FN sensitive, reprogrammable, divertable, pos:2, group:0, gmask:0 is FN, FN sensitive, reprogrammable, divertable, pos:2, group:0, gmask:0
16:01:51,582 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0818 020000] 16:01:51,582 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0818 020000]
16:01:51,621 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0818 003E002D3A0300000000000000000000] 16:01:51,621 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0818 003E002D3A0300000000000000000000]
16:01:51,622 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0828 003E00] 16:01:51,622 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0828 003E00]
16:01:51,661 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0828 003E0000000000000000000000000000] 16:01:51,661 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0828 003E0000000000000000000000000000]
2: SEARCH , default: SearchForFiles => SEARCH 2: SEARCH , default: SearchForFiles => SEARCH
is FN, FN sensitive, reprogrammable, divertable, pos:3, group:0, gmask:0 is FN, FN sensitive, reprogrammable, divertable, pos:3, group:0, gmask:0
16:01:51,662 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081B 030000] 16:01:51,662 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081B 030000]
16:01:51,701 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081B 000800083A0400000000000000000000] 16:01:51,701 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081B 000800083A0400000000000000000000]
16:01:51,702 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082E 000800] 16:01:51,702 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082E 000800]
16:01:51,743 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082E 00080000000000000000000000000000] 16:01:51,743 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082E 00080000000000000000000000000000]
3: Application Switcher , default: Application Switcher => Application Switcher 3: Application Switcher , default: Application Switcher => Application Switcher
is FN, FN sensitive, reprogrammable, divertable, pos:4, group:0, gmask:0 is FN, FN sensitive, reprogrammable, divertable, pos:4, group:0, gmask:0
16:01:51,744 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081D 040000] 16:01:51,744 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081D 040000]
16:01:51,784 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081D 00E200C12A0500000000000000000000] 16:01:51,784 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081D 00E200C12A0500000000000000000000]
16:01:51,784 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082E 00E200] 16:01:51,784 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082E 00E200]
16:01:51,824 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082E 00E20000000000000000000000000000] 16:01:51,824 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082E 00E20000000000000000000000000000]
4: unknown:00E2 , default: unknown:00C1 => unknown:00E2 4: unknown:00E2 , default: unknown:00C1 => unknown:00E2
is FN, FN sensitive, divertable, pos:5, group:0, gmask:0 is FN, FN sensitive, divertable, pos:5, group:0, gmask:0
16:01:51,824 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081A 050000] 16:01:51,824 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081A 050000]
16:01:51,864 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081A 00E300C22A0600000000000000000000] 16:01:51,864 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081A 00E300C22A0600000000000000000000]
16:01:51,864 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082B 00E300] 16:01:51,864 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082B 00E300]
16:01:51,904 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082B 00E30000000000000000000000000000] 16:01:51,904 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082B 00E30000000000000000000000000000]
5: unknown:00E3 , default: unknown:00C2 => unknown:00E3 5: unknown:00E3 , default: unknown:00C2 => unknown:00E3
is FN, FN sensitive, divertable, pos:6, group:0, gmask:0 is FN, FN sensitive, divertable, pos:6, group:0, gmask:0
16:01:51,904 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0818 060000] 16:01:51,904 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0818 060000]
16:01:51,943 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0818 0040002F3A0800000000000000000000] 16:01:51,943 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0818 0040002F3A0800000000000000000000]
16:01:51,944 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082E 004000] 16:01:51,944 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082E 004000]
16:01:51,984 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082E 00400000000000000000000000000000] 16:01:51,984 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082E 00400000000000000000000000000000]
6: SLEEP , default: Sleep => SLEEP 6: SLEEP , default: Sleep => SLEEP
is FN, FN sensitive, reprogrammable, divertable, pos:8, group:0, gmask:0 is FN, FN sensitive, reprogrammable, divertable, pos:8, group:0, gmask:0
16:01:51,984 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081D 070000] 16:01:51,984 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081D 070000]
16:01:52,025 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081D 0028001D3A0900000000000000000000] 16:01:52,025 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081D 0028001D3A0900000000000000000000]
16:01:52,026 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0828 002800] 16:01:52,026 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0828 002800]
16:01:52,065 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0828 00280000000000000000000000000000] 16:01:52,065 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0828 00280000000000000000000000000000]
7: MEDIA PLAYER , default: Music => MEDIA PLAYER 7: MEDIA PLAYER , default: Music => MEDIA PLAYER
is FN, FN sensitive, reprogrammable, divertable, pos:9, group:0, gmask:0 is FN, FN sensitive, reprogrammable, divertable, pos:9, group:0, gmask:0
16:01:52,066 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081F 080000] 16:01:52,066 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081F 080000]
16:01:52,106 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081F 000600062A0A00000000000000000000] 16:01:52,106 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081F 000600062A0A00000000000000000000]
16:01:52,106 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0828 000600] 16:01:52,106 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0828 000600]
16:01:52,145 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0828 00060000000000000000000000000000] 16:01:52,145 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0828 00060000000000000000000000000000]
8: Previous , default: Previous => Previous 8: Previous , default: Previous => Previous
is FN, FN sensitive, divertable, pos:10, group:0, gmask:0 is FN, FN sensitive, divertable, pos:10, group:0, gmask:0
16:01:52,146 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081F 090000] 16:01:52,146 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081F 090000]
16:01:52,186 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081F 000400042A0B00000000000000000000] 16:01:52,186 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081F 000400042A0B00000000000000000000]
16:01:52,186 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082B 000400] 16:01:52,186 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082B 000400]
16:01:52,225 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082B 00040000000000000000000000000000] 16:01:52,225 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082B 00040000000000000000000000000000]
9: Play/Pause , default: Play/Pause => Play/Pause 9: Play/Pause , default: Play/Pause => Play/Pause
is FN, FN sensitive, divertable, pos:11, group:0, gmask:0 is FN, FN sensitive, divertable, pos:11, group:0, gmask:0
16:01:52,226 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081B 0A0000] 16:01:52,226 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081B 0A0000]
16:01:52,265 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081B 000500052A0C00000000000000000000] 16:01:52,265 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081B 000500052A0C00000000000000000000]
16:01:52,266 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0829 000500] 16:01:52,266 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0829 000500]
16:01:52,308 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0829 00050000000000000000000000000000] 16:01:52,308 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0829 00050000000000000000000000000000]
10: Next , default: Next => Next 10: Next , default: Next => Next
is FN, FN sensitive, divertable, pos:12, group:0, gmask:0 is FN, FN sensitive, divertable, pos:12, group:0, gmask:0
16:01:52,308 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0818 0B0000] 16:01:52,308 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0818 0B0000]
16:01:52,348 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0818 00010001240000000000000000000000] 16:01:52,348 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0818 00010001240000000000000000000000]
16:01:52,348 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082C 000100] 16:01:52,348 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082C 000100]
16:01:52,387 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082C 00010000000000000000000000000000] 16:01:52,387 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082C 00010000000000000000000000000000]
11: Volume Up , default: Volume Up => Volume Up 11: Volume Up , default: Volume Up => Volume Up
nonstandard, divertable, pos:0, group:0, gmask:0 nonstandard, divertable, pos:0, group:0, gmask:0
16:01:52,388 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081C 0C0000] 16:01:52,388 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081C 0C0000]
16:01:52,427 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081C 00020002240000000000000000000000] 16:01:52,427 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081C 00020002240000000000000000000000]
16:01:52,428 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082C 000200] 16:01:52,428 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082C 000200]
16:01:52,468 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082C 00020000000000000000000000000000] 16:01:52,468 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082C 00020000000000000000000000000000]
12: Volume Down , default: Volume Down => Volume Down 12: Volume Down , default: Volume Down => Volume Down
nonstandard, divertable, pos:0, group:0, gmask:0 nonstandard, divertable, pos:0, group:0, gmask:0
16:01:52,468 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0819 0D0000] 16:01:52,468 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 0819 0D0000]
16:01:52,507 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0819 00030003240000000000000000000000] 16:01:52,507 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 0819 00030003240000000000000000000000]
16:01:52,508 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082D 000300] 16:01:52,508 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082D 000300]
16:01:52,547 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082D 00030000000000000000000000000000] 16:01:52,547 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082D 00030000000000000000000000000000]
13: Mute , default: Mute => Mute 13: Mute , default: Mute => Mute
nonstandard, divertable, pos:0, group:0, gmask:0 nonstandard, divertable, pos:0, group:0, gmask:0
16:01:52,548 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081B 0E0000] 16:01:52,548 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 081B 0E0000]
16:01:52,589 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081B 000A000A340000000000000000000000] 16:01:52,589 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 081B 000A000A340000000000000000000000]
16:01:52,590 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082F 000A00] 16:01:52,590 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 082F 000A00]
16:01:52,630 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082F 000A0000000000000000000000000000] 16:01:52,630 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 082F 000A0000000000000000000000000000]
14: Calculator , default: Calculator => Calculator 14: Calculator , default: Calculator => Calculator
nonstandard, reprogrammable, divertable, pos:0, group:0, gmask:0 nonstandard, reprogrammable, divertable, pos:0, group:0, gmask:0
16:01:52,630 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 060C 000000] 16:01:52,630 DEBUG [MainThread] logitech_receiver.base: (3) <= w[10 02 060C 000000]
16:01:52,670 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 060C 32140000000000000000000000000000] 16:01:52,670 DEBUG [MainThread] logitech_receiver.base: (3) => r[11 02 060C 32140000000000000000000000000000]
16:01:52,670 DEBUG [MainThread] logitech_receiver.hidpp20: device 2 battery 50% charged, next level 20% charge, status 0 = discharging 16:01:52,670 DEBUG [MainThread] logitech_receiver.hidpp20: device 2 battery 50% charged, next level 20% charge, status 0 = discharging
Battery: 50%, discharging. Battery: 50%, discharging.

View File

@ -11,22 +11,22 @@
Firmware: RQK 56.00.B0020 Firmware: RQK 56.00.B0020
The power switch is located on the edge of top right corner. The power switch is located on the edge of top right corner.
Supports 27 HID++ 2.0 features: Supports 27 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: WIRELESS DEVICE STATUS {1D4B} 4: WIRELESS DEVICE STATUS {1D4B}
5: unknown:0020 {0020} 5: unknown:0020 {0020}
6: BATTERY STATUS {1000} 6: BATTERY STATUS {1000}
7: BACKLIGHT {1981} 7: BACKLIGHT {1981}
8: unknown:1B04 {1B04} 8: unknown:1B04 {1B04}
9: unknown:2005 {2005} 9: unknown:2005 {2005}
10: NEW FN INVERSION {40A2} 10: NEW FN INVERSION {40A2}
11: ENCRYPTION {4100} 11: ENCRYPTION {4100}
12: unknown:4521 {4521} 12: unknown:4521 {4521}
13: TOUCHPAD RAW XY {6100} hidden 13: TOUCHPAD RAW XY {6100} hidden
14: unknown:6501 {6501} 14: unknown:6501 {6501}
15: unknown:00C1 {00C1} 15: unknown:00C1 {00C1}
16: unknown:1811 {1811} internal, hidden 16: unknown:1811 {1811} internal, hidden
17: unknown:1830 {1830} internal, hidden 17: unknown:1830 {1830} internal, hidden
18: unknown:1890 {1890} internal, hidden 18: unknown:1890 {1890} internal, hidden

View File

@ -18,15 +18,15 @@ Device path : /dev/hidraw3
Firmware: RQM 64.00.B0008 Firmware: RQM 64.00.B0008
The power switch is located on the base. The power switch is located on the base.
Supports 20 HID++ 2.0 features: Supports 20 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: RESET {0020} 4: RESET {0020}
5: REPROG CONTROLS V4 {1B04} 5: REPROG CONTROLS V4 {1B04}
6: WIRELESS DEVICE STATUS {1D4B} 6: WIRELESS DEVICE STATUS {1D4B}
7: LOWRES WHEEL {2130} 7: LOWRES WHEEL {2130}
8: POINTER SPEED {2205} 8: POINTER SPEED {2205}
9: unknown:1802 {1802} internal, hidden 9: unknown:1802 {1802} internal, hidden
10: unknown:1810 {1810} internal, hidden 10: unknown:1810 {1810} internal, hidden
11: unknown:1830 {1830} internal, hidden 11: unknown:1830 {1830} internal, hidden
@ -39,11 +39,10 @@ Device path : /dev/hidraw3
18: unknown:1F03 {1F03} internal, hidden 18: unknown:1F03 {1F03} internal, hidden
19: unknown:1E80 {1E80} internal, hidden 19: unknown:1E80 {1E80} internal, hidden
Has 3 reprogrammable keys: Has 3 reprogrammable keys:
0: LEFT CLICK , default: LeftClick => LEFT CLICK 0: LEFT CLICK , default: LeftClick => LEFT CLICK
mse, reprogrammable, pos:0, group:1, gmask:1 mse, reprogrammable, pos:0, group:1, gmask:1
1: RIGHT CLICK , default: RightClick => RIGHT CLICK 1: RIGHT CLICK , default: RightClick => RIGHT CLICK
mse, reprogrammable, pos:0, group:1, gmask:1 mse, reprogrammable, pos:0, group:1, gmask:1
2: MIDDLE BUTTON , default: MiddleMouseButton => MIDDLE BUTTON 2: MIDDLE BUTTON , default: MiddleMouseButton => MIDDLE BUTTON
divertable, mse, reprogrammable, pos:0, group:2, gmask:3 divertable, mse, reprogrammable, pos:0, group:2, gmask:3
Battery status unavailable. Battery status unavailable.

View File

@ -18,12 +18,12 @@ Unifying Receiver
Firmware: RQM 65.00.B0003 Firmware: RQM 65.00.B0003
The power switch is located on the base. The power switch is located on the base.
Supports 22 HID++ 2.0 features: Supports 22 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: RESET {0020} 4: RESET {0020}
5: BATTERY STATUS {1000} 5: BATTERY STATUS {1000}
6: unknown:1810 {1810} internal, hidden 6: unknown:1810 {1810} internal, hidden
7: unknown:1830 {1830} internal, hidden 7: unknown:1830 {1830} internal, hidden
8: unknown:1802 {1802} internal, hidden 8: unknown:1802 {1802} internal, hidden
@ -31,21 +31,20 @@ Unifying Receiver
10: unknown:1890 {1890} internal, hidden 10: unknown:1890 {1890} internal, hidden
11: unknown:18A0 {18A0} internal, hidden 11: unknown:18A0 {18A0} internal, hidden
12: unknown:18B1 {18B1} internal, hidden 12: unknown:18B1 {18B1} internal, hidden
13: REPROG CONTROLS V4 {1B04} 13: REPROG CONTROLS V4 {1B04}
14: WIRELESS DEVICE STATUS {1D4B} 14: WIRELESS DEVICE STATUS {1D4B}
15: unknown:1DF0 {1DF0} hidden 15: unknown:1DF0 {1DF0} hidden
16: unknown:1DF3 {1DF3} internal, hidden 16: unknown:1DF3 {1DF3} internal, hidden
17: unknown:1E00 {1E00} hidden 17: unknown:1E00 {1E00} hidden
18: unknown:1EB0 {1EB0} internal, hidden 18: unknown:1EB0 {1EB0} internal, hidden
19: unknown:1F03 {1F03} internal, hidden 19: unknown:1F03 {1F03} internal, hidden
20: LOWRES WHEEL {2130} 20: LOWRES WHEEL {2130}
21: POINTER SPEED {2205} 21: POINTER SPEED {2205}
Has 3 reprogrammable keys: Has 3 reprogrammable keys:
0: LEFT CLICK , default: LeftClick => LEFT CLICK 0: LEFT CLICK , default: LeftClick => LEFT CLICK
mse, reprogrammable, pos:0, group:1, gmask:1 mse, reprogrammable, pos:0, group:1, gmask:1
1: RIGHT CLICK , default: RightClick => RIGHT CLICK 1: RIGHT CLICK , default: RightClick => RIGHT CLICK
mse, reprogrammable, pos:0, group:1, gmask:1 mse, reprogrammable, pos:0, group:1, gmask:1
2: MIDDLE BUTTON , default: MiddleMouseButton => MIDDLE BUTTON 2: MIDDLE BUTTON , default: MiddleMouseButton => MIDDLE BUTTON
divertable, mse, reprogrammable, pos:0, group:2, gmask:3 divertable, mse, reprogrammable, pos:0, group:2, gmask:3
Battery: 5%, discharging. Battery: 5%, discharging.

View File

@ -8,19 +8,19 @@ Serial number: ABB05E01
Firmware: RQM 27.02.B0028 Firmware: RQM 27.02.B0028
The power switch is located on the base. The power switch is located on the base.
Supports 13 HID++ 2.0 features: Supports 13 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: WIRELESS DEVICE STATUS {1D4B} 5: WIRELESS DEVICE STATUS {1D4B}
6: unknown:1DF3 {1DF3} hidden 6: unknown:1DF3 {1DF3} hidden
7: REPROG CONTROLS {1B00} 7: REPROG CONTROLS {1B00}
8: unknown:1DF0 {1DF0} hidden 8: unknown:1DF0 {1DF0} hidden
9: unknown:1F03 {1F03} hidden 9: unknown:1F03 {1F03} hidden
10: VERTICAL SCROLLING {2100} 10: VERTICAL SCROLLING {2100}
11: HI RES SCROLLING {2120} 11: HI RES SCROLLING {2120}
12: MOUSE POINTER {2200} 12: MOUSE POINTER {2200}
Has 5 reprogrammable keys: Has 5 reprogrammable keys:
0: LEFT CLICK => LeftClick mse, reprogrammable 0: LEFT CLICK => LeftClick mse, reprogrammable
1: RIGHT CLICK => RightClick mse, reprogrammable 1: RIGHT CLICK => RightClick mse, reprogrammable

View File

@ -40,17 +40,17 @@ Total number of HID++ 2.0 features: 12
Firmware: RQM 27.02.B0028 Firmware: RQM 27.02.B0028
The power switch is located on the base. The power switch is located on the base.
Supports 13 HID++ 2.0 features: Supports 13 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: WIRELESS DEVICE STATUS {1D4B} 5: WIRELESS DEVICE STATUS {1D4B}
6: unknown:1DF3 {1DF3} hidden 6: unknown:1DF3 {1DF3} hidden
7: REPROG CONTROLS {1B00} 7: REPROG CONTROLS {1B00}
8: unknown:1DF0 {1DF0} hidden 8: unknown:1DF0 {1DF0} hidden
9: unknown:1F03 {1F03} hidden 9: unknown:1F03 {1F03} hidden
10: VERTICAL SCROLLING {2100} 10: VERTICAL SCROLLING {2100}
11: HI RES SCROLLING {2120} 11: HI RES SCROLLING {2120}
12: MOUSE POINTER {2200} 12: MOUSE POINTER {2200}
Battery: 90%, discharging, Battery: 90%, discharging,

View File

@ -34,19 +34,19 @@ Total number of HID++ 2.0 features: 12
Firmware: RQM 27.02.B0028 Firmware: RQM 27.02.B0028
The power switch is located on the base. The power switch is located on the base.
Supports 13 HID++ 2.0 features: Supports 13 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: WIRELESS DEVICE STATUS {1D4B} 5: WIRELESS DEVICE STATUS {1D4B}
6: unknown:1DF3 {1DF3} hidden 6: unknown:1DF3 {1DF3} hidden
7: REPROG CONTROLS {1B00} 7: REPROG CONTROLS {1B00}
8: unknown:1DF0 {1DF0} hidden 8: unknown:1DF0 {1DF0} hidden
9: unknown:1F03 {1F03} hidden 9: unknown:1F03 {1F03} hidden
10: VERTICAL SCROLLING {2100} 10: VERTICAL SCROLLING {2100}
11: HI RES SCROLLING {2120} 11: HI RES SCROLLING {2120}
12: MOUSE POINTER {2200} 12: MOUSE POINTER {2200}
Has 5 reprogrammable keys: Has 5 reprogrammable keys:
0: LEFT CLICK => LeftClick mse, reprogrammable 0: LEFT CLICK => LeftClick mse, reprogrammable
1: RIGHT CLICK => RightClick mse, reprogrammable 1: RIGHT CLICK => RightClick mse, reprogrammable

View File

@ -8,28 +8,28 @@
Firmware: RQM 48.00.B0015 Firmware: RQM 48.00.B0015
The power switch is located on the base. The power switch is located on the base.
Supports 22 HID++ 2.0 features: Supports 22 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: unknown:1830 {1830} internal, hidden 5: unknown:1830 {1830} internal, hidden
6: unknown:1850 {1850} internal, hidden 6: unknown:1850 {1850} internal, hidden
7: unknown:1860 {1860} internal, hidden 7: unknown:1860 {1860} internal, hidden
8: unknown:1890 {1890} internal, hidden 8: unknown:1890 {1890} internal, hidden
9: unknown:18A0 {18A0} internal, hidden 9: unknown:18A0 {18A0} internal, hidden
10: REPROG CONTROLS V3 {1B03} 10: REPROG CONTROLS V3 {1B03}
11: WIRELESS DEVICE STATUS {1D4B} 11: WIRELESS DEVICE STATUS {1D4B}
12: unknown:1DF3 {1DF3} internal, hidden 12: unknown:1DF3 {1DF3} internal, hidden
13: REPROG CONTROLS {1B00} 13: REPROG CONTROLS {1B00}
14: unknown:1DF0 {1DF0} hidden 14: unknown:1DF0 {1DF0} hidden
15: unknown:1E00 {1E00} hidden 15: unknown:1E00 {1E00} hidden
16: unknown:18B0 {18B0} internal, hidden 16: unknown:18B0 {18B0} internal, hidden
17: unknown:1E90 {1E90} internal, hidden 17: unknown:1E90 {1E90} internal, hidden
18: unknown:1F03 {1F03} internal, hidden 18: unknown:1F03 {1F03} internal, hidden
19: VERTICAL SCROLLING {2100} 19: VERTICAL SCROLLING {2100}
20: HI RES SCROLLING {2120} 20: HI RES SCROLLING {2120}
21: MOUSE POINTER {2200} 21: MOUSE POINTER {2200}
Has 7 reprogrammable keys: Has 7 reprogrammable keys:
0: LEFT CLICK => LeftClick mse, reprogrammable 0: LEFT CLICK => LeftClick mse, reprogrammable
1: RIGHT CLICK => RightClick mse, reprogrammable 1: RIGHT CLICK => RightClick mse, reprogrammable

View File

@ -22,4 +22,3 @@ Unifying Receiver
The power switch is located on the base. The power switch is located on the base.
Notifications: battery status (0x100000). Notifications: battery status (0x100000).
Battery: 100%, discharging. Battery: 100%, discharging.

View File

@ -80,4 +80,3 @@ Unifying Receiver
7: unknown:00D7 , default: unknown:00B4 => unknown:00D7 7: unknown:00D7 , default: unknown:00B4 => unknown:00D7
divertable, virtual, pos:0, group:3, gmask:0 divertable, virtual, pos:0, group:3, gmask:0
Battery: 50%, discharging. Battery: 50%, discharging.

View File

@ -15,16 +15,16 @@ Unifying Receiver
Serial number: 00000000 Serial number: 00000000
Firmware: RQK 49.00.B0029 Firmware: RQK 49.00.B0029
Supports 18 HID++ 2.0 features: Supports 18 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: REPROG CONTROLS {1B00} 5: REPROG CONTROLS {1B00}
6: WIRELESS DEVICE STATUS {1D4B} 6: WIRELESS DEVICE STATUS {1D4B}
7: FN INVERSION {40A0} 7: FN INVERSION {40A0}
8: ENCRYPTION {4100} 8: ENCRYPTION {4100}
9: KEYBOARD LAYOUT {4520} 9: KEYBOARD LAYOUT {4520}
10: unknown:1810 {1810} internal, hidden 10: unknown:1810 {1810} internal, hidden
11: unknown:1830 {1830} internal, hidden 11: unknown:1830 {1830} internal, hidden
12: unknown:1890 {1890} internal, hidden 12: unknown:1890 {1890} internal, hidden
@ -47,8 +47,8 @@ Unifying Receiver
10: Volume Up => Volume Up is FN, FN sensitive 10: Volume Up => Volume Up is FN, FN sensitive
Battery: 30%, discharging. Battery: 30%, discharging.
2: Wireless Mouse 2: Wireless Mouse
Codename : Codename :
Kind : mouse Kind : mouse
Wireless PID : 4022 Wireless PID : 4022
Protocol : HID++ 2.0 Protocol : HID++ 2.0
@ -56,15 +56,15 @@ Unifying Receiver
Serial number: 00000000 Serial number: 00000000
Firmware: RQM 38.00.B0044 Firmware: RQM 38.00.B0044
Supports 18 HID++ 2.0 features: Supports 18 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: REPROG CONTROLS {1B00} 5: REPROG CONTROLS {1B00}
6: WIRELESS DEVICE STATUS {1D4B} 6: WIRELESS DEVICE STATUS {1D4B}
7: VERTICAL SCROLLING {2100} 7: VERTICAL SCROLLING {2100}
8: MOUSE POINTER {2200} 8: MOUSE POINTER {2200}
9: unknown:1810 {1810} internal, hidden 9: unknown:1810 {1810} internal, hidden
10: unknown:1830 {1830} internal, hidden 10: unknown:1830 {1830} internal, hidden
11: unknown:1850 {1850} internal, hidden 11: unknown:1850 {1850} internal, hidden
@ -79,4 +79,3 @@ Unifying Receiver
1: RIGHT CLICK => RightClick mse, reprogrammable 1: RIGHT CLICK => RightClick mse, reprogrammable
2: MIDDLE BUTTON => MiddleMouseButton mse, reprogrammable 2: MIDDLE BUTTON => MiddleMouseButton mse, reprogrammable
Battery: 30%, discharging. Battery: 30%, discharging.

View File

@ -16,22 +16,22 @@ Unifying Receiver
Firmware: RQM 29.00.B0010 Firmware: RQM 29.00.B0010
The power switch is located on the base. The power switch is located on the base.
Supports 16 HID++ 2.0 features: Supports 16 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: unknown:1850 {1850} hidden 4: unknown:1850 {1850} hidden
5: unknown:1860 {1860} hidden 5: unknown:1860 {1860} hidden
6: BATTERY STATUS {1000} 6: BATTERY STATUS {1000}
7: WIRELESS DEVICE STATUS {1D4B} 7: WIRELESS DEVICE STATUS {1D4B}
8: unknown:1DF3 {1DF3} hidden 8: unknown:1DF3 {1DF3} hidden
9: REPROG CONTROLS {1B00} 9: REPROG CONTROLS {1B00}
10: unknown:1DF0 {1DF0} hidden 10: unknown:1DF0 {1DF0} hidden
11: unknown:1E00 {1E00} hidden 11: unknown:1E00 {1E00} hidden
12: unknown:1E80 {1E80} hidden 12: unknown:1E80 {1E80} hidden
13: unknown:1F03 {1F03} hidden 13: unknown:1F03 {1F03} hidden
14: VERTICAL SCROLLING {2100} 14: VERTICAL SCROLLING {2100}
15: MOUSE POINTER {2200} 15: MOUSE POINTER {2200}
Has 3 reprogrammable keys: Has 3 reprogrammable keys:
0: LEFT CLICK => LeftClick mse, reprogrammable 0: LEFT CLICK => LeftClick mse, reprogrammable
1: RIGHT CLICK => RightClick mse, reprogrammable 1: RIGHT CLICK => RightClick mse, reprogrammable
@ -47,20 +47,20 @@ Unifying Receiver
Serial number: 5BB1D72E Serial number: 5BB1D72E
Firmware: RQK 37.00.B0011 Firmware: RQK 37.00.B0011
Supports 14 HID++ 2.0 features: Supports 14 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: FEATURE INFO {0002} 2: FEATURE INFO {0002}
3: DEVICE FW VERSION {0003} 3: DEVICE FW VERSION {0003}
4: DEVICE NAME {0005} 4: DEVICE NAME {0005}
5: BATTERY STATUS {1000} 5: BATTERY STATUS {1000}
6: unknown:1820 {1820} hidden 6: unknown:1820 {1820} hidden
7: REPROG CONTROLS {1B00} 7: REPROG CONTROLS {1B00}
8: REPROG CONTROLS V2 {1B01} 8: REPROG CONTROLS V2 {1B01}
9: WIRELESS DEVICE STATUS {1D4B} 9: WIRELESS DEVICE STATUS {1D4B}
10: unknown:1DF0 {1DF0} hidden 10: unknown:1DF0 {1DF0} hidden
11: unknown:1DF3 {1DF3} hidden 11: unknown:1DF3 {1DF3} hidden
12: ENCRYPTION {4100} 12: ENCRYPTION {4100}
13: KEYBOARD LAYOUT {4520} 13: KEYBOARD LAYOUT {4520}
Has 12 reprogrammable keys: Has 12 reprogrammable keys:
0: FN F1 => Do Nothing One is FN, reprogrammable 0: FN F1 => Do Nothing One is FN, reprogrammable
1: FN F2 => Do Nothing One is FN, reprogrammable 1: FN F2 => Do Nothing One is FN, reprogrammable
@ -75,4 +75,3 @@ Unifying Receiver
10: Volume Down => Volume Down is FN 10: Volume Down => Volume Down is FN
11: Volume Up => Volume Up is FN 11: Volume Up => Volume Up is FN
Battery: 90%, discharging. Battery: 90%, discharging.

View File

@ -18,16 +18,16 @@ Unifying Receiver (NOTE: NOT claimed to be supporting Unifying from the package
Serial number: 4BBBBA4A Serial number: 4BBBBA4A
Firmware: RQK 49.00.B0029 Firmware: RQK 49.00.B0029
Supports 18 HID++ 2.0 features: Supports 18 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: REPROG CONTROLS {1B00} 5: REPROG CONTROLS {1B00}
6: WIRELESS DEVICE STATUS {1D4B} 6: WIRELESS DEVICE STATUS {1D4B}
7: FN INVERSION {40A0} 7: FN INVERSION {40A0}
8: ENCRYPTION {4100} 8: ENCRYPTION {4100}
9: KEYBOARD LAYOUT {4520} 9: KEYBOARD LAYOUT {4520}
10: unknown:1810 {1810} internal, hidden 10: unknown:1810 {1810} internal, hidden
11: unknown:1830 {1830} internal, hidden 11: unknown:1830 {1830} internal, hidden
12: unknown:1890 {1890} internal, hidden 12: unknown:1890 {1890} internal, hidden
@ -59,15 +59,15 @@ Unifying Receiver (NOTE: NOT claimed to be supporting Unifying from the package
Serial number: 00000000 Serial number: 00000000
Firmware: RQM 38.00.B0044 Firmware: RQM 38.00.B0044
Supports 18 HID++ 2.0 features: Supports 18 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: REPROG CONTROLS {1B00} 5: REPROG CONTROLS {1B00}
6: WIRELESS DEVICE STATUS {1D4B} 6: WIRELESS DEVICE STATUS {1D4B}
7: VERTICAL SCROLLING {2100} 7: VERTICAL SCROLLING {2100}
8: MOUSE POINTER {2200} 8: MOUSE POINTER {2200}
9: unknown:1810 {1810} internal, hidden 9: unknown:1810 {1810} internal, hidden
10: unknown:1830 {1830} internal, hidden 10: unknown:1830 {1830} internal, hidden
11: unknown:1850 {1850} internal, hidden 11: unknown:1850 {1850} internal, hidden
@ -92,36 +92,36 @@ Dj Api Version : 2, 50, 25
接收器(Receiver) 接收器(Receiver)
Name : 無線接收器(Wireless Receiver) Name : 無線接收器(Wireless Receiver)
ModelId : 0x46dc534 ModelId : 0x46dc534
Serial Number : Serial Number :
Handle : 0xff000001 Handle : 0xff000001
Wireless Status : 0x3 Wireless Status : 0x3
Firmware version : 029.001.00016 Firmware version : 029.001.00016
Bootloader version : Bootloader version :
Dfu Status : 0x1 Dfu Status : 0x1
Is Dfu Cancellable : Yes Is Dfu Cancellable : Yes
Max Device Capacity : 6 Max Device Capacity : 6
滑鼠(Mouse) 滑鼠(Mouse)
Name : Name :
ModelId : 0x0 ModelId : 0x0
Serial Number : 4022-00-00-00-00 Serial Number : 4022-00-00-00-00
Handle : 0x2000003 Handle : 0x2000003
Wireless Status : 0x0 Wireless Status : 0x0
Firmware version : 038.000.00044 Firmware version : 038.000.00044
Bootloader version : Bootloader version :
Dfu Status : 0x1 Dfu Status : 0x1
Is Dfu Cancellable : No Is Dfu Cancellable : No
Battery Status : 0x2 Battery Status : 0x2
Parent Handle : 0xff000001 Parent Handle : 0xff000001
鍵盤(Keyboard) 鍵盤(Keyboard)
Name : Name :
ModelId : 0x0 ModelId : 0x0
Serial Number : 4023-4B-BB-BA-4A Serial Number : 4023-4B-BB-BA-4A
Handle : 0x1000002 Handle : 0x1000002
Wireless Status : 0x0 Wireless Status : 0x0
Firmware version : 049.000.00029 Firmware version : 049.000.00029
Bootloader version : Bootloader version :
Dfu Status : 0x1 Dfu Status : 0x1
Is Dfu Cancellable : No Is Dfu Cancellable : No
Battery Status : 0x2 Battery Status : 0x2

View File

@ -6,7 +6,7 @@ Unifying Receiver
Has 2 paired device(s) out of a maximum of 6. Has 2 paired device(s) out of a maximum of 6.
Notifications: (none) Notifications: (none)
1: Wireless Keyboard 1: Wireless Keyboard
Codename : MK270 Codename : MK270
Kind : keyboard Kind : keyboard
Wireless PID : 4023 Wireless PID : 4023
@ -15,16 +15,16 @@ Unifying Receiver
Serial number: 00000000 Serial number: 00000000
Firmware: RQK 49.00.B0029 Firmware: RQK 49.00.B0029
Supports 18 HID++ 2.0 features: Supports 18 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: REPROG CONTROLS {1B00} 5: REPROG CONTROLS {1B00}
6: WIRELESS DEVICE STATUS {1D4B} 6: WIRELESS DEVICE STATUS {1D4B}
7: FN INVERSION {40A0} 7: FN INVERSION {40A0}
8: ENCRYPTION {4100} 8: ENCRYPTION {4100}
9: KEYBOARD LAYOUT {4520} 9: KEYBOARD LAYOUT {4520}
10: unknown:1810 {1810} internal, hidden 10: unknown:1810 {1810} internal, hidden
11: unknown:1830 {1830} internal, hidden 11: unknown:1830 {1830} internal, hidden
12: unknown:1890 {1890} internal, hidden 12: unknown:1890 {1890} internal, hidden
@ -47,7 +47,7 @@ Unifying Receiver
10: Volume Up => Volume Up FN sensitive, is FN 10: Volume Up => Volume Up FN sensitive, is FN
Battery: 30%, discharging. Battery: 30%, discharging.
2: Wireless Mouse 2: Wireless Mouse
Codename : M185 Codename : M185
Kind : mouse Kind : mouse
Wireless PID : 4038 Wireless PID : 4038
@ -56,31 +56,30 @@ Unifying Receiver
Serial number: 00000000 Serial number: 00000000
Firmware: RQM 54.00.B0004 Firmware: RQM 54.00.B0004
Supports 22 HID++ 2.0 features: Supports 22 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: unknown:1830 {1830} internal, hidden 5: unknown:1830 {1830} internal, hidden
6: unknown:1850 {1850} internal, hidden 6: unknown:1850 {1850} internal, hidden
7: unknown:1860 {1860} internal, hidden 7: unknown:1860 {1860} internal, hidden
8: unknown:1890 {1890} internal, hidden 8: unknown:1890 {1890} internal, hidden
9: unknown:18A0 {18A0} internal, hidden 9: unknown:18A0 {18A0} internal, hidden
10: unknown:18C0 {18C0} internal, hidden 10: unknown:18C0 {18C0} internal, hidden
11: WIRELESS DEVICE STATUS {1D4B} 11: WIRELESS DEVICE STATUS {1D4B}
12: unknown:1DF3 {1DF3} internal, hidden 12: unknown:1DF3 {1DF3} internal, hidden
13: REPROG CONTROLS {1B00} 13: REPROG CONTROLS {1B00}
14: unknown:1DF0 {1DF0} hidden 14: unknown:1DF0 {1DF0} hidden
15: unknown:1E00 {1E00} hidden 15: unknown:1E00 {1E00} hidden
16: unknown:1E80 {1E80} internal, hidden 16: unknown:1E80 {1E80} internal, hidden
17: unknown:1E90 {1E90} internal, hidden 17: unknown:1E90 {1E90} internal, hidden
18: unknown:1F03 {1F03} internal, hidden 18: unknown:1F03 {1F03} internal, hidden
19: VERTICAL SCROLLING {2100} 19: VERTICAL SCROLLING {2100}
20: MOUSE POINTER {2200} 20: MOUSE POINTER {2200}
21: unknown:18B0 {18B0} internal, hidden 21: unknown:18B0 {18B0} internal, hidden
Has 3 reprogrammable keys: Has 3 reprogrammable keys:
0: LEFT CLICK => LeftClick mse, reprogrammable 0: LEFT CLICK => LeftClick mse, reprogrammable
1: RIGHT CLICK => RightClick mse, reprogrammable 1: RIGHT CLICK => RightClick mse, reprogrammable
2: MIDDLE BUTTON => MiddleMouseButton mse, reprogrammable 2: MIDDLE BUTTON => MiddleMouseButton mse, reprogrammable
Battery: 70%, discharging. Battery: 70%, discharging.

View File

@ -19,27 +19,27 @@ Unifying Receiver
Firmware: RQM 40.01.B0017 Firmware: RQM 40.01.B0017
The power switch is located on the base. The power switch is located on the base.
Supports 21 HID++ 2.0 features: Supports 21 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: BATTERY STATUS {1000} 4: BATTERY STATUS {1000}
5: unknown:1830 {1830} internal, hidden 5: unknown:1830 {1830} internal, hidden
6: unknown:1850 {1850} internal, hidden 6: unknown:1850 {1850} internal, hidden
7: unknown:1860 {1860} internal, hidden 7: unknown:1860 {1860} internal, hidden
8: unknown:1890 {1890} internal, hidden 8: unknown:1890 {1890} internal, hidden
9: unknown:18A0 {18A0} internal, hidden 9: unknown:18A0 {18A0} internal, hidden
10: unknown:18C0 {18C0} internal, hidden 10: unknown:18C0 {18C0} internal, hidden
11: WIRELESS DEVICE STATUS {1D4B} 11: WIRELESS DEVICE STATUS {1D4B}
12: unknown:1DF3 {1DF3} internal, hidden 12: unknown:1DF3 {1DF3} internal, hidden
13: REPROG CONTROLS {1B00} 13: REPROG CONTROLS {1B00}
14: unknown:1DF0 {1DF0} hidden 14: unknown:1DF0 {1DF0} hidden
15: unknown:1E00 {1E00} hidden 15: unknown:1E00 {1E00} hidden
16: unknown:1E80 {1E80} internal, hidden 16: unknown:1E80 {1E80} internal, hidden
17: unknown:1E90 {1E90} internal, hidden 17: unknown:1E90 {1E90} internal, hidden
18: unknown:1F03 {1F03} internal, hidden 18: unknown:1F03 {1F03} internal, hidden
19: VERTICAL SCROLLING {2100} 19: VERTICAL SCROLLING {2100}
20: MOUSE POINTER {2200} 20: MOUSE POINTER {2200}
Has 3 reprogrammable keys: Has 3 reprogrammable keys:
0: LEFT CLICK => LeftClick mse, reprogrammable 0: LEFT CLICK => LeftClick mse, reprogrammable
1: RIGHT CLICK => RightClick mse, reprogrammable 1: RIGHT CLICK => RightClick mse, reprogrammable
@ -58,4 +58,3 @@ Unifying Receiver
The power switch is located on the top case. The power switch is located on the top case.
Notifications: (none). Notifications: (none).
Battery: full, discharging. Battery: full, discharging.

View File

@ -18,23 +18,23 @@ Unifying Receiver
Serial number: B0C9EC6E Serial number: B0C9EC6E
Bootloader: BOT 95.00.B0013 Bootloader: BOT 95.00.B0013
Firmware: MPM 19.00.B0013 Firmware: MPM 19.00.B0013
Other: Other:
The power switch is located on the base. The power switch is located on the base.
Supports 34 HID++ 2.0 features: Supports 34 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: WIRELESS DEVICE STATUS {1D4B} 4: WIRELESS DEVICE STATUS {1D4B}
5: RESET {0020} 5: RESET {0020}
6: unknown:0021 {0021} 6: unknown:0021 {0021}
7: BATTERY STATUS {1000} 7: BATTERY STATUS {1000}
8: REPROG CONTROLS V4 {1B04} 8: REPROG CONTROLS V4 {1B04}
9: CHANGE HOST {1814} 9: CHANGE HOST {1814}
10: unknown:2250 {2250} 10: unknown:2250 {2250}
11: ADJUSTABLE DPI {2201} 11: ADJUSTABLE DPI {2201}
12: SMART SHIFT {2110} 12: SMART SHIFT {2110}
13: HIRES WHEEL {2121} 13: HIRES WHEEL {2121}
Multiplier: 15 Multiplier: 15
Has invert Has invert
Normal wheel motion Normal wheel motion
@ -42,9 +42,9 @@ Unifying Receiver
Normal wheel mode Normal wheel mode
Low resolution mode Low resolution mode
HID notification HID notification
14: unknown:2150 {2150} 14: unknown:2150 {2150}
15: unknown:2251 {2251} 15: unknown:2251 {2251}
16: unknown:00C2 {00C2} 16: unknown:00C2 {00C2}
17: unknown:1802 {1802} internal, hidden 17: unknown:1802 {1802} internal, hidden
18: unknown:1803 {1803} internal, hidden 18: unknown:1803 {1803} internal, hidden
19: unknown:1806 {1806} internal, hidden 19: unknown:1806 {1806} internal, hidden
@ -63,21 +63,20 @@ Unifying Receiver
32: unknown:9205 {9205} internal, hidden 32: unknown:9205 {9205} internal, hidden
33: unknown:9300 {9300} internal, hidden 33: unknown:9300 {9300} internal, hidden
Has 8 reprogrammable keys: Has 8 reprogrammable keys:
0: LEFT CLICK , default: LeftClick => LEFT CLICK 0: LEFT CLICK , default: LeftClick => LEFT CLICK
mse, pos:0, group:1, gmask:1 mse, pos:0, group:1, gmask:1
1: RIGHT CLICK , default: RightClick => RIGHT CLICK 1: RIGHT CLICK , default: RightClick => RIGHT CLICK
mse, pos:0, group:1, gmask:1 mse, pos:0, group:1, gmask:1
2: MIDDLE BUTTON , default: MiddleMouseButton => MIDDLE BUTTON 2: MIDDLE BUTTON , default: MiddleMouseButton => MIDDLE BUTTON
divertable, mse, reprogrammable, pos:0, group:3, gmask:7 divertable, mse, reprogrammable, pos:0, group:3, gmask:7
3: BACK AS BUTTON 4 , default: BackEx => BACK AS BUTTON 4 3: BACK AS BUTTON 4 , default: BackEx => BACK AS BUTTON 4
divertable, mse, reprogrammable, pos:0, group:2, gmask:3 divertable, mse, reprogrammable, pos:0, group:2, gmask:3
4: FORWARD AS BUTTON 5 , default: BrowserForwardEx => FORWARD AS BUTTON 5 4: FORWARD AS BUTTON 5 , default: BrowserForwardEx => FORWARD AS BUTTON 5
divertable, mse, reprogrammable, pos:0, group:2, gmask:3 divertable, mse, reprogrammable, pos:0, group:2, gmask:3
5: unknown:00C3 , default: unknown:00A9 => unknown:00C3 5: unknown:00C3 , default: unknown:00A9 => unknown:00C3
divertable, mse, reprogrammable, pos:0, group:3, gmask:7 divertable, mse, reprogrammable, pos:0, group:3, gmask:7
6: unknown:00C4 , default: unknown:009D => unknown:00C4 6: unknown:00C4 , default: unknown:009D => unknown:00C4
divertable, mse, reprogrammable, pos:0, group:3, gmask:7 divertable, mse, reprogrammable, pos:0, group:3, gmask:7
7: unknown:00D7 , default: unknown:00B4 => unknown:00D7 7: unknown:00D7 , default: unknown:00B4 => unknown:00D7
divertable, virtual, pos:0, group:4, gmask:0 divertable, virtual, pos:0, group:4, gmask:0
Battery: 100%, discharging. Battery: 100%, discharging.

View File

@ -19,24 +19,24 @@ Unifying Receiver
Bootloader: BOT 18.00.B0012 Bootloader: BOT 18.00.B0012
Firmware: MPM 11.00.B0012 Firmware: MPM 11.00.B0012
Firmware: MPM 11.00.B0012 Firmware: MPM 11.00.B0012
Other: Other:
The power switch is located on the base. The power switch is located on the base.
Supports 29 HID++ 2.0 features: Supports 29 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: DEVICE FW VERSION {0003} 2: DEVICE FW VERSION {0003}
3: DEVICE NAME {0005} 3: DEVICE NAME {0005}
4: WIRELESS DEVICE STATUS {1D4B} 4: WIRELESS DEVICE STATUS {1D4B}
5: RESET {0020} 5: RESET {0020}
6: BATTERY STATUS {1000} 6: BATTERY STATUS {1000}
7: CHANGE HOST {1814} 7: CHANGE HOST {1814}
8: REPROG CONTROLS V4 {1B04} 8: REPROG CONTROLS V4 {1B04}
9: ADJUSTABLE DPI {2201} 9: ADJUSTABLE DPI {2201}
10: VERTICAL SCROLLING {2100} 10: VERTICAL SCROLLING {2100}
11: SMART SHIFT {2110} 11: SMART SHIFT {2110}
12: HIRES WHEEL {2121} 12: HIRES WHEEL {2121}
13: GESTURE 2 {6501} 13: GESTURE 2 {6501}
14: DFUCONTROL 2 {00C1} 14: DFUCONTROL 2 {00C1}
15: unknown:1813 {1813} internal, hidden 15: unknown:1813 {1813} internal, hidden
16: unknown:1830 {1830} internal, hidden 16: unknown:1830 {1830} internal, hidden
17: unknown:1890 {1890} internal, hidden 17: unknown:1890 {1890} internal, hidden
@ -51,4 +51,4 @@ Unifying Receiver
26: unknown:9200 {9200} internal, hidden 26: unknown:9200 {9200} internal, hidden
27: unknown:9240 {9240} internal, hidden 27: unknown:9240 {9240} internal, hidden
28: unknown:1805 {1805} internal, hidden 28: unknown:1805 {1805} internal, hidden
Battery: 50%, discharging. Battery: 50%, discharging.

View File

@ -7,7 +7,7 @@
>> ( 1.097) [10 01 8101 020000] '\x10\x01\x81\x01\x02\x00\x00' >> ( 1.097) [10 01 8101 020000] '\x10\x01\x81\x01\x02\x00\x00'
# battery (07 means full) # battery (07 means full)
<< ( 7.335) [10 01 8107 000000] '\x10\x01\x81\x07\x00\x00\x00' << ( 7.335) [10 01 8107 000000] '\x10\x01\x81\x07\x00\x00\x00'
>> ( 7.382) [10 01 8107 070000] '\x10\x01\x81\x07\x07\x00\x00' >> ( 7.382) [10 01 8107 070000] '\x10\x01\x81\x07\x07\x00\x00'
# Set LEDS - ab cd 00, where a/b/c/d values are 1=off, 2=on, 3=flash # Set LEDS - ab cd 00, where a/b/c/d values are 1=off, 2=on, 3=flash

View File

@ -67,16 +67,16 @@ Unifying Receiver
Firmware: RQM 39.00.B0029 Firmware: RQM 39.00.B0029
Bootloader: BL 03.00 Bootloader: BL 03.00
Hardware: 72 Hardware: 72
Other: Other:
The power switch is located on the base. The power switch is located on the base.
Supports 28 HID++ 2.0 features: Supports 28 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: FEATURE INFO {0002} 2: FEATURE INFO {0002}
3: DEVICE FW VERSION {0003} 3: DEVICE FW VERSION {0003}
4: DEVICE NAME {0005} 4: DEVICE NAME {0005}
5: DFUCONTROL {00C0} 5: DFUCONTROL {00C0}
6: BATTERY STATUS {1000} 6: BATTERY STATUS {1000}
7: unknown:1802 {1802} internal, hidden 7: unknown:1802 {1802} internal, hidden
8: unknown:1810 {1810} internal, hidden 8: unknown:1810 {1810} internal, hidden
9: unknown:1830 {1830} internal, hidden 9: unknown:1830 {1830} internal, hidden
@ -85,19 +85,19 @@ Unifying Receiver
12: unknown:1890 {1890} internal, hidden 12: unknown:1890 {1890} internal, hidden
13: unknown:18A0 {18A0} internal, hidden 13: unknown:18A0 {18A0} internal, hidden
14: unknown:18E3 {18E3} internal, hidden 14: unknown:18E3 {18E3} internal, hidden
15: REPROG CONTROLS {1B00} 15: REPROG CONTROLS {1B00}
16: WIRELESS DEVICE STATUS {1D4B} 16: WIRELESS DEVICE STATUS {1D4B}
17: unknown:1DF3 {1DF3} internal, hidden 17: unknown:1DF3 {1DF3} internal, hidden
18: unknown:1E00 {1E00} hidden 18: unknown:1E00 {1E00} hidden
19: unknown:1E80 {1E80} internal, hidden 19: unknown:1E80 {1E80} internal, hidden
20: unknown:1F03 {1F03} internal, hidden 20: unknown:1F03 {1F03} internal, hidden
21: unknown:1F04 {1F04} internal, hidden 21: unknown:1F04 {1F04} internal, hidden
22: VERTICAL SCROLLING {2100} 22: VERTICAL SCROLLING {2100}
23: unknown:2101 {2101} hidden 23: unknown:2101 {2101} hidden
24: HI RES SCROLLING {2120} 24: HI RES SCROLLING {2120}
25: MOUSE POINTER {2200} 25: MOUSE POINTER {2200}
26: TOUCHMOUSE RAW POINTS {6110} hidden 26: TOUCHMOUSE RAW POINTS {6110} hidden
27: REPROG CONTROLS V3 {1B03} 27: REPROG CONTROLS V3 {1B03}
Has 7 reprogrammable keys: Has 7 reprogrammable keys:
0: LEFT CLICK => LeftClick mse, reprogrammable 0: LEFT CLICK => LeftClick mse, reprogrammable
1: RIGHT CLICK => RightClick mse, reprogrammable 1: RIGHT CLICK => RightClick mse, reprogrammable
@ -105,5 +105,5 @@ Unifying Receiver
3: METRO START SCREEN => MetroStartScreen mse, reprogrammable 3: METRO START SCREEN => MetroStartScreen mse, reprogrammable
4: ZOOMIN => Do Nothing mse, reprogrammable 4: ZOOMIN => Do Nothing mse, reprogrammable
5: ZOOMOUT => Do Nothing mse, reprogrammable 5: ZOOMOUT => Do Nothing mse, reprogrammable
6: BACK HSCROLL => TouchBackForwardHorzScroll 6: BACK HSCROLL => TouchBackForwardHorzScroll
Battery: 100%, discharging. Battery: 100%, discharging.

View File

@ -62,28 +62,28 @@ Unifying Receiver
Firmware: RQM 41.01.B0037 Firmware: RQM 41.01.B0037
Bootloader: BL 03.00 Bootloader: BL 03.00
Hardware: 72 Hardware: 72
Other: Other:
The power switch is located on the base. The power switch is located on the base.
Supports 23 HID++ 2.0 features: Supports 23 HID++ 2.0 features:
0: ROOT {0000} 0: ROOT {0000}
1: FEATURE SET {0001} 1: FEATURE SET {0001}
2: FEATURE INFO {0002} 2: FEATURE INFO {0002}
3: DEVICE FW VERSION {0003} 3: DEVICE FW VERSION {0003}
4: DEVICE NAME {0005} 4: DEVICE NAME {0005}
5: BATTERY STATUS {1000} 5: BATTERY STATUS {1000}
6: WIRELESS DEVICE STATUS {1D4B} 6: WIRELESS DEVICE STATUS {1D4B}
7: unknown:1DF3 {1DF3} internal, hidden 7: unknown:1DF3 {1DF3} internal, hidden
8: REPROG CONTROLS {1B00} 8: REPROG CONTROLS {1B00}
9: unknown:1F03 {1F03} internal, hidden 9: unknown:1F03 {1F03} internal, hidden
10: VERTICAL SCROLLING {2100} 10: VERTICAL SCROLLING {2100}
11: HI RES SCROLLING {2120} 11: HI RES SCROLLING {2120}
12: MOUSE POINTER {2200} 12: MOUSE POINTER {2200}
13: DFUCONTROL {00C0} 13: DFUCONTROL {00C0}
14: unknown:1E80 {1E80} internal, hidden 14: unknown:1E80 {1E80} internal, hidden
15: TOUCHPAD RAW XY {6100} 15: TOUCHPAD RAW XY {6100}
16: unknown:1860 {1860} internal, hidden 16: unknown:1860 {1860} internal, hidden
17: unknown:1E00 {1E00} hidden 17: unknown:1E00 {1E00} hidden
18: REPROG CONTROLS V2 {1B01} 18: REPROG CONTROLS V2 {1B01}
19: unknown:1890 {1890} internal, hidden 19: unknown:1890 {1890} internal, hidden
20: unknown:18E5 {18E5} internal, hidden 20: unknown:18E5 {18E5} internal, hidden
21: unknown:18A0 {18A0} internal, hidden 21: unknown:18A0 {18A0} internal, hidden

View File

@ -121,7 +121,7 @@ lib/logitech_receiver/hidpp20.py
In most cases it should suffice to only implement the settable feature In most cases it should suffice to only implement the settable feature
interface for each setting in the feature. That will add one or more interface for each setting in the feature. That will add one or more
widgets in the Solaar main window to show and change the setting, widgets in the Solaar main window to show and change the setting,
will permit storing and restoring changed settings, and will permit storing and restoring changed settings, and
will output the feature settings in `solaar show`. will output the feature settings in `solaar show`.
@ -183,11 +183,11 @@ the setting name (from the common strings),
the feature ID (if any), the feature ID (if any),
the feature implementation (if any), the feature implementation (if any),
the register implementation (if any). the register implementation (if any).
and and
the identifier for the setting implementation if different from the setting name. the identifier for the setting implementation if different from the setting name.
The identifier is used in descriptors.py to say that a device has the register or feature implementation. The identifier is used in descriptors.py to say that a device has the register or feature implementation.
The identifier can be the same as the setting name if there is only one implementation for the setting. The identifier can be the same as the setting name if there is only one implementation for the setting.
This table is used to generate the data structures for describing devices in descriptors.py This table is used to generate the data structures for describing devices in descriptors.py
and is also used to auto-discover feature implementations. and is also used to auto-discover feature implementations.
``` ```
_S( _POINTER_SPEED[0], _F.POINTER_SPEED, _feature_pointer_speed ), _S( _POINTER_SPEED[0], _F.POINTER_SPEED, _feature_pointer_speed ),

View File

@ -3,8 +3,8 @@ title: Solaar
layout: default layout: default
--- ---
**Solaar** is a Linux manager for Logitech's devices that connect via a USB **Solaar** is a Linux manager for Logitech's devices that connect via a USB
[Unifying][unifying], Lightspeed, or Nano receiver. [Unifying][unifying], Lightspeed, or Nano receiver.
Solaar does not work with Logitech peripherals that Solaar does not work with Logitech peripherals that
use Bluetooth or peripherals from other companies. use Bluetooth or peripherals from other companies.
@ -19,10 +19,10 @@ system tray and also starts with its main window showing.
For more information on Solaar's command-line interface use the help option, For more information on Solaar's command-line interface use the help option,
as in `solaar --help`. as in `solaar --help`.
Solaar is able to pair and unpair devices with Solaar is able to pair and unpair devices with
receivers as supported by the receiver. Solaar can also control receivers as supported by the receiver. Solaar can also control
some of the changeable features of devices, such as smooth scrolling or some of the changeable features of devices, such as smooth scrolling or
function key behavior. function key behavior.
For more information on how to use Solaar see For more information on how to use Solaar see
[docs/usage.md](https://pwr-solaar.github.io/Solaar/usage). [docs/usage.md](https://pwr-solaar.github.io/Solaar/usage).
For more information on the capabilities of Solaar see For more information on the capabilities of Solaar see
@ -39,7 +39,7 @@ Some of the capabilities of Solaar have been developed by observing the behavior
Logitech receivers and devices and generalizing from these observations. Logitech receivers and devices and generalizing from these observations.
If your Logitech receiver or device behaves in a strange way this may be caused by If your Logitech receiver or device behaves in a strange way this may be caused by
an incorrect behavior generalization. an incorrect behavior generalization.
Please report such experiences by creating an issue in Please report such experiences by creating an issue in
[the Solaar repository](https://github.com/pwr-Solaar/Solaar/issues). [the Solaar repository](https://github.com/pwr-Solaar/Solaar/issues).
[unifying]: https://en.wikipedia.org/wiki/Logitech_Unifying_receiver [unifying]: https://en.wikipedia.org/wiki/Logitech_Unifying_receiver

View File

@ -22,7 +22,7 @@ and its daemon running. If you have a recent Linux distribution, you are
most likely good to go. most likely good to go.
Solaar requires Python 3.2+ Solaar requires Python 3.2+
and the `python3-pyudev` package. and the `python3-pyudev` package.
To run the GUI, solaar also requires Gtk3, and its GObject To run the GUI, solaar also requires Gtk3, and its GObject
introspection bindings. introspection bindings.
The Debian/Ubuntu packages that need to be installed are The Debian/Ubuntu packages that need to be installed are
@ -47,7 +47,7 @@ Solaar needs to write to the receiver's HID device.
To be able to do this without running as root requires udev rule To be able to do this without running as root requires udev rule
that gives seated users write access to the HID devices for Logitech receivers. that gives seated users write access to the HID devices for Logitech receivers.
You can install this rule by copying, as root, You can install this rule by copying, as root,
`rules.d/42-logitech-unify-permissions.rules` from Solaar to `rules.d/42-logitech-unify-permissions.rules` from Solaar to
`/etc/udev/rules.d`. `/etc/udev/rules.d`.
The udev daemon will automatically pick up this file using inotify. The udev daemon will automatically pick up this file using inotify.
@ -100,7 +100,7 @@ If you install Solaar yourself you may need to create or modify this file.
## Using PyPI ## Using PyPI
As an alternative to downloading and installing you can install the most recent release As an alternative to downloading and installing you can install the most recent release
(but not the current github version) of Solaar from PyPI. (but not the current github version) of Solaar from PyPI.
Just run `pip install --user solaar` or `sudo pip install solaar`. Just run `pip install --user solaar` or `sudo pip install solaar`.
The `--user` flag will not install the Solaar udev rule or the Solaar autostart file. The `--user` flag will not install the Solaar udev rule or the Solaar autostart file.

View File

@ -275,4 +275,3 @@ Index (same as command)
zz zz
(don't care, recommended to return 0) (don't care, recommended to return 0)

View File

@ -113,4 +113,3 @@ Solaar also has a command line interface that can do most of what can be
done using the Solaar main window. For more information on the Solaar done using the Solaar main window. For more information on the Solaar
command line interface, run `solaar --help` to see the Solaar commands and command line interface, run `solaar --help` to see the Solaar commands and
then `solaar <command> --help` to see the arguments to any of the commands. then `solaar <command> --help` to see the arguments to any of the commands.

View File

@ -108,7 +108,7 @@ def _continuous_read(handle, timeout=2000):
try: try:
reply = _hid.read(handle, 128, timeout) reply = _hid.read(handle, 128, timeout)
except OSError as e: except OSError as e:
_error("Read failed, aborting: " + str(e), True) _error('Read failed, aborting: ' + str(e), True)
break break
assert reply is not None assert reply is not None
if reply: if reply:
@ -119,25 +119,25 @@ def _validate_input(line, hidpp=False):
try: try:
data = unhexlify(line.encode('ascii')) data = unhexlify(line.encode('ascii'))
except Exception as e: except Exception as e:
_error("Invalid input: " + str(e)) _error('Invalid input: ' + str(e))
return None return None
if hidpp: if hidpp:
if len(data) < 4: if len(data) < 4:
_error("Invalid HID++ request: need at least 4 bytes") _error('Invalid HID++ request: need at least 4 bytes')
return None return None
if data[:1] not in b'\x10\x11': if data[:1] not in b'\x10\x11':
_error("Invalid HID++ request: first byte must be 0x10 or 0x11") _error('Invalid HID++ request: first byte must be 0x10 or 0x11')
return None return None
if data[1:2] not in b'\xFF\x01\x02\x03\x04\x05\x06': if data[1:2] not in b'\xFF\x01\x02\x03\x04\x05\x06':
_error( _error(
"Invalid HID++ request: second byte must be 0xFF or one of 0x01..0x06" 'Invalid HID++ request: second byte must be 0xFF or one of 0x01..0x06'
) )
return None return None
if data[:1] == b'\x10': if data[:1] == b'\x10':
if len(data) > 7: if len(data) > 7:
_error( _error(
"Invalid HID++ request: maximum length of a 0x10 request is 7 bytes" 'Invalid HID++ request: maximum length of a 0x10 request is 7 bytes'
) )
return None return None
while len(data) < 7: while len(data) < 7:
@ -145,7 +145,7 @@ def _validate_input(line, hidpp=False):
elif data[:1] == b'\x11': elif data[:1] == b'\x11':
if len(data) > 20: if len(data) > 20:
_error( _error(
"Invalid HID++ request: maximum length of a 0x11 request is 20 bytes" 'Invalid HID++ request: maximum length of a 0x11 request is 20 bytes'
) )
return None return None
while len(data) < 20: while len(data) < 20:
@ -162,27 +162,27 @@ def _open(args):
device = d.path device = d.path
break break
if not device: if not device:
sys.exit("!! No HID++ receiver found.") sys.exit('!! No HID++ receiver found.')
if not device: if not device:
sys.exit("!! Device path required.") sys.exit('!! Device path required.')
print(".. Opening device", device) print('.. Opening device', device)
handle = _hid.open_path(device) handle = _hid.open_path(device)
if not handle: if not handle:
sys.exit("!! Failed to open %s, aborting." % device) sys.exit('!! Failed to open %s, aborting.' % device)
print(".. Opened handle %r, vendor %r product %r serial %r." % print('.. Opened handle %r, vendor %r product %r serial %r.' %
(handle, _hid.get_manufacturer(handle), _hid.get_product(handle), (handle, _hid.get_manufacturer(handle), _hid.get_product(handle),
_hid.get_serial(handle))) _hid.get_serial(handle)))
if args.hidpp: if args.hidpp:
if _hid.get_manufacturer(handle) != b'Logitech': if _hid.get_manufacturer(handle) != b'Logitech':
sys.exit("!! Only Logitech devices support the HID++ protocol.") sys.exit('!! Only Logitech devices support the HID++ protocol.')
print(".. HID++ validation enabled.") print('.. HID++ validation enabled.')
else: else:
if (_hid.get_manufacturer(handle) == b'Logitech' if (_hid.get_manufacturer(handle) == b'Logitech'
and b'Receiver' in _hid.get_product(handle)): and b'Receiver' in _hid.get_product(handle)):
args.hidpp = True args.hidpp = True
print(".. Logitech receiver detected, HID++ validation enabled.") print('.. Logitech receiver detected, HID++ validation enabled.')
return handle return handle
@ -196,15 +196,15 @@ def _parse_arguments():
import argparse import argparse
arg_parser = argparse.ArgumentParser() arg_parser = argparse.ArgumentParser()
arg_parser.add_argument( arg_parser.add_argument(
'--history', help="history file (default ~/.hidconsole-history)") '--history', help='history file (default ~/.hidconsole-history)')
arg_parser.add_argument('--hidpp', arg_parser.add_argument('--hidpp',
action='store_true', action='store_true',
help="ensure input data is a valid HID++ request") help='ensure input data is a valid HID++ request')
arg_parser.add_argument( arg_parser.add_argument(
'device', 'device',
nargs='?', nargs='?',
help="linux device to connect to (/dev/hidrawX); " help='linux device to connect to (/dev/hidrawX); '
"may be omitted if --hidpp is given, in which case it looks for the first Logitech receiver" 'may be omitted if --hidpp is given, in which case it looks for the first Logitech receiver'
) )
return arg_parser.parse_args() return arg_parser.parse_args()
@ -215,7 +215,7 @@ def main():
if interactive: if interactive:
print( print(
".. Press ^C/^D to exit, or type hex bytes to write to the device." '.. Press ^C/^D to exit, or type hex bytes to write to the device.'
) )
import readline import readline
@ -264,12 +264,12 @@ def main():
time.sleep(0.700) time.sleep(0.700)
except EOFError: except EOFError:
if interactive: if interactive:
print("") print('')
else: else:
time.sleep(1) time.sleep(1)
finally: finally:
print(".. Closing handle %r" % handle) print('.. Closing handle %r' % handle)
_hid.close(handle) _hid.close(handle)
if interactive: if interactive:
readline.write_history_file(args.history) readline.write_history_file(args.history)

View File

@ -176,13 +176,13 @@ def write(handle, devnumber, data):
else: else:
wdata = _pack('!BB5s', 0x10, devnumber, data) wdata = _pack('!BB5s', 0x10, devnumber, data)
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("(%s) <= w[%02X %02X %s %s]", handle, ord(wdata[:1]), _log.debug('(%s) <= w[%02X %02X %s %s]', handle, ord(wdata[:1]),
devnumber, _strhex(wdata[2:4]), _strhex(wdata[4:])) devnumber, _strhex(wdata[2:4]), _strhex(wdata[4:]))
try: try:
_hid.write(int(handle), wdata) _hid.write(int(handle), wdata)
except Exception as reason: except Exception as reason:
_log.error("write failed, assuming handle %r no longer available", _log.error('write failed, assuming handle %r no longer available',
handle) handle)
close(handle) close(handle)
raise NoReceiver(reason=reason) raise NoReceiver(reason=reason)
@ -214,7 +214,7 @@ def check_message(data):
if report_lengths.get(report_id) == len(data): if report_lengths.get(report_id) == len(data):
return True return True
else: else:
_log.warn("unexpected message size: report_id %02X message %s" % _log.warn('unexpected message size: report_id %02X message %s' %
(report_id, _strhex(data))) (report_id, _strhex(data)))
return False return False
@ -233,7 +233,7 @@ def _read(handle, timeout):
timeout = int(timeout * 1000) timeout = int(timeout * 1000)
data = _hid.read(int(handle), _MAX_READ_SIZE, timeout) data = _hid.read(int(handle), _MAX_READ_SIZE, timeout)
except Exception as reason: except Exception as reason:
_log.error("read failed, assuming handle %r no longer available", _log.error('read failed, assuming handle %r no longer available',
handle) handle)
close(handle) close(handle)
raise NoReceiver(reason=reason) raise NoReceiver(reason=reason)
@ -243,7 +243,7 @@ def _read(handle, timeout):
devnumber = ord(data[1:2]) devnumber = ord(data[1:2])
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("(%s) => r[%02X %02X %s %s]", handle, report_id, _log.debug('(%s) => r[%02X %02X %s %s]', handle, report_id,
devnumber, _strhex(data[2:4]), _strhex(data[4:])) devnumber, _strhex(data[2:4]), _strhex(data[4:]))
return report_id, devnumber, data[2:] return report_id, devnumber, data[2:]
@ -265,7 +265,7 @@ def _skip_incoming(handle, ihandle, notifications_hook):
# read whatever is already in the buffer, if any # read whatever is already in the buffer, if any
data = _hid.read(ihandle, _MAX_READ_SIZE, 0) data = _hid.read(ihandle, _MAX_READ_SIZE, 0)
except Exception as reason: except Exception as reason:
_log.error("read failed, assuming receiver %s no longer available", _log.error('read failed, assuming receiver %s no longer available',
handle) handle)
close(handle) close(handle)
raise NoReceiver(reason=reason) raise NoReceiver(reason=reason)
@ -389,7 +389,7 @@ def request(handle, devnumber, request_id, *params):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug( _log.debug(
"(%s) device 0x%02X error on request {%04X}: %d = %s", '(%s) device 0x%02X error on request {%04X}: %d = %s',
handle, devnumber, request_id, error, handle, devnumber, request_id, error,
_hidpp10.ERROR[error]) _hidpp10.ERROR[error])
return return
@ -399,7 +399,7 @@ def request(handle, devnumber, request_id, *params):
# a HID++ 2.0 feature call returned with an error # a HID++ 2.0 feature call returned with an error
error = ord(reply_data[3:4]) error = ord(reply_data[3:4])
_log.error( _log.error(
"(%s) device %d error on feature request {%04X}: %d = %s", '(%s) device %d error on feature request {%04X}: %d = %s',
handle, devnumber, request_id, error, handle, devnumber, request_id, error,
_hidpp20.ERROR[error]) _hidpp20.ERROR[error])
raise _hidpp20.FeatureCallError(number=devnumber, raise _hidpp20.FeatureCallError(number=devnumber,
@ -445,7 +445,7 @@ def request(handle, devnumber, request_id, *params):
# if _log.isEnabledFor(_DEBUG): # if _log.isEnabledFor(_DEBUG):
# _log.debug("(%s) still waiting for reply, delta %f", handle, delta) # _log.debug("(%s) still waiting for reply, delta %f", handle, delta)
_log.warn("timeout (%0.2f/%0.2f) on device %d request {%04X} params [%s]", _log.warn('timeout (%0.2f/%0.2f) on device %d request {%04X} params [%s]',
delta, timeout, devnumber, request_id, _strhex(params)) delta, timeout, devnumber, request_id, _strhex(params))
# raise DeviceUnreachable(number=devnumber, request=request_id) # raise DeviceUnreachable(number=devnumber, request=request_id)
@ -456,7 +456,7 @@ def ping(handle, devnumber):
:returns: The HID protocol supported by the device, as a floating point number, if the device is active. :returns: The HID protocol supported by the device, as a floating point number, if the device is active.
""" """
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("(%s) pinging device %d", handle, devnumber) _log.debug('(%s) pinging device %d', handle, devnumber)
# import inspect as _inspect # import inspect as _inspect
# print ('\n '.join(str(s) for s in _inspect.stack())) # print ('\n '.join(str(s) for s in _inspect.stack()))
@ -504,7 +504,7 @@ def ping(handle, devnumber):
if error == _hidpp10.ERROR.unknown_device: # no paired device with that number if error == _hidpp10.ERROR.unknown_device: # no paired device with that number
_log.error( _log.error(
"(%s) device %d error on ping request: unknown device", '(%s) device %d error on ping request: unknown device',
handle, devnumber) handle, devnumber)
raise NoSuchDevice(number=devnumber, raise NoSuchDevice(number=devnumber,
request=request_id) request=request_id)
@ -518,6 +518,6 @@ def ping(handle, devnumber):
delta = _timestamp() - request_started delta = _timestamp() - request_started
_log.warn("(%s) timeout (%0.2f/%0.2f) on device %d ping", handle, delta, _log.warn('(%s) timeout (%0.2f/%0.2f) on device %d ping', handle, delta,
_PING_TIMEOUT, devnumber) _PING_TIMEOUT, devnumber)
# raise DeviceUnreachable(number=devnumber, request=request_id) # raise DeviceUnreachable(number=devnumber, request=request_id)

View File

@ -107,7 +107,7 @@ class NamedInts(object):
def __init__(self, **kwargs): def __init__(self, **kwargs):
def _readable_name(n): def _readable_name(n):
if not is_string(n): if not is_string(n):
raise TypeError("expected (unicode) string, got " + raise TypeError('expected (unicode) string, got ' +
str(type(n))) str(type(n)))
return n.replace('__', '/').replace('_', ' ') return n.replace('__', '/').replace('_', ' ')

View File

@ -202,7 +202,7 @@ def parse_battery_status(register, reply):
elif charging_byte & 0x22 == 0x22: elif charging_byte & 0x22 == 0x22:
status_text = BATTERY_STATUS.full status_text = BATTERY_STATUS.full
else: else:
_log.warn("could not parse 0x07 battery status: %02X (level %02X)", _log.warn('could not parse 0x07 battery status: %02X (level %02X)',
charging_byte, status_byte) charging_byte, status_byte)
status_text = None status_text = None

View File

@ -268,7 +268,7 @@ class FeaturesArray(object):
count = self.device.request(fs_index << 8) count = self.device.request(fs_index << 8)
if count is None: if count is None:
_log.warn( _log.warn(
"FEATURE_SET found, but failed to read features count" 'FEATURE_SET found, but failed to read features count'
) )
# most likely the device is unavailable # most likely the device is unavailable
return False return False
@ -348,7 +348,7 @@ class FeaturesArray(object):
self.features[index] = FEATURE[ivalue] self.features[index] = FEATURE[ivalue]
return index return index
raise ValueError("%r not in list" % featureId) raise ValueError('%r not in list' % featureId)
def __iter__(self): def __iter__(self):
if self._check(): if self._check():
@ -530,7 +530,7 @@ def get_name(device):
name += fragment[:name_length - len(name)] name += fragment[:name_length - len(name)]
else: else:
_log.error( _log.error(
"failed to read whole name of %s (expected %d chars)", 'failed to read whole name of %s (expected %d chars)',
device, name_length) device, name_length)
return None return None
@ -545,7 +545,7 @@ def get_battery(device):
discharge = None if discharge == 0 else discharge discharge = None if discharge == 0 else discharge
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug( _log.debug(
"device %d battery %d%% charged, next level %d%% charge, status %d = %s", 'device %d battery %d%% charged, next level %d%% charge, status %d = %s',
device.number, discharge, dischargeNext, status, device.number, discharge, dischargeNext, status,
BATTERY_STATUS[status]) BATTERY_STATUS[status])
return discharge, BATTERY_STATUS[status], dischargeNext return discharge, BATTERY_STATUS[status], dischargeNext
@ -583,7 +583,7 @@ def decipher_voltage(voltage_report):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug( _log.debug(
"device %d, battery voltage %d mV, charging = %s, charge status %d = %s, charge level %s, charge type %s", 'device %d, battery voltage %d mV, charging = %s, charge status %d = %s, charge level %s, charge type %s',
device.number, voltage, status, (flags & 0x03), charge_sts, device.number, voltage, status, (flags & 0x03), charge_sts,
charge_lvl, charge_type) charge_lvl, charge_type)

View File

@ -35,30 +35,30 @@ except:
_DUMMY = ( _DUMMY = (
# approximative battery levels # approximative battery levels
_("empty"), _('empty'),
_("critical"), _('critical'),
_("low"), _('low'),
_("good"), _('good'),
_("full"), _('full'),
# battery charging statuses # battery charging statuses
_("discharging"), _('discharging'),
_("recharging"), _('recharging'),
_("almost full"), _('almost full'),
_("charged"), _('charged'),
_("slow recharge"), _('slow recharge'),
_("invalid battery"), _('invalid battery'),
_("thermal error"), _('thermal error'),
# pairing errors # pairing errors
_("device timeout"), _('device timeout'),
_("device not supported"), _('device not supported'),
_("too many devices"), _('too many devices'),
_("sequence timeout"), _('sequence timeout'),
# firmware kinds # firmware kinds
_("Firmware"), _('Firmware'),
_("Bootloader"), _('Bootloader'),
_("Hardware"), _('Hardware'),
_("Other"), _('Other'),
) )

View File

@ -67,7 +67,7 @@ class _ThreadedHandle(object):
def _open(self): def _open(self):
handle = _base.open_path(self.path) handle = _base.open_path(self.path)
if handle is None: if handle is None:
_log.error("%r failed to open new handle", self) _log.error('%r failed to open new handle', self)
else: else:
# if _log.isEnabledFor(_DEBUG): # if _log.isEnabledFor(_DEBUG):
# _log.debug("%r opened new handle %d", self, handle) # _log.debug("%r opened new handle %d", self, handle)
@ -80,7 +80,7 @@ class _ThreadedHandle(object):
self._local = None self._local = None
handles, self._handles = self._handles, [] handles, self._handles = self._handles, []
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%r closing %s", self, handles) _log.debug('%r closing %s', self, handles)
for h in handles: for h in handles:
_base.close(h) _base.close(h)
@ -163,7 +163,7 @@ class EventsListener(_threading.Thread):
# get the right low-level handle for this thread # get the right low-level handle for this thread
ihandle = int(self.receiver.handle) ihandle = int(self.receiver.handle)
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("started with %s (%d)", self.receiver, ihandle) _log.info('started with %s (%d)', self.receiver, ihandle)
self.has_started() self.has_started()
@ -178,7 +178,7 @@ class EventsListener(_threading.Thread):
# _log.debug("read next notification") # _log.debug("read next notification")
n = _base.read(ihandle, _EVENT_READ_TIMEOUT) n = _base.read(ihandle, _EVENT_READ_TIMEOUT)
except _base.NoReceiver: except _base.NoReceiver:
_log.warning("receiver disconnected") _log.warning('receiver disconnected')
self.receiver.close() self.receiver.close()
break break
@ -194,7 +194,7 @@ class EventsListener(_threading.Thread):
try: try:
self._notifications_callback(n) self._notifications_callback(n)
except: except:
_log.exception("processing %s", n) _log.exception('processing %s', n)
# elif self.tick_period: # elif self.tick_period:
# idle_reads -= 1 # idle_reads -= 1

View File

@ -72,10 +72,10 @@ def _process_receiver_notification(receiver, status, n):
# pairing lock notification # pairing lock notification
if n.sub_id == 0x4A: if n.sub_id == 0x4A:
status.lock_open = bool(n.address & 0x01) status.lock_open = bool(n.address & 0x01)
reason = (_("pairing lock is open") reason = (_('pairing lock is open')
if status.lock_open else _("pairing lock is closed")) if status.lock_open else _('pairing lock is closed'))
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: %s", receiver, reason) _log.info('%s: %s', receiver, reason)
status[_K.ERROR] = None status[_K.ERROR] = None
if status.lock_open: if status.lock_open:
@ -86,12 +86,12 @@ def _process_receiver_notification(receiver, status, n):
status[ status[
_K.ERROR] = error_string = _hidpp10.PAIRING_ERRORS[pair_error] _K.ERROR] = error_string = _hidpp10.PAIRING_ERRORS[pair_error]
status.new_device = None status.new_device = None
_log.warn("pairing error %d: %s", pair_error, error_string) _log.warn('pairing error %d: %s', pair_error, error_string)
status.changed(reason=reason) status.changed(reason=reason)
return True return True
_log.warn("%s: unhandled notification %s", receiver, n) _log.warn('%s: unhandled notification %s', receiver, n)
# #
@ -124,7 +124,7 @@ def _process_device_notification(device, status, n):
try: try:
feature = device.features[n.sub_id] feature = device.features[n.sub_id]
except IndexError: except IndexError:
_log.warn("%s: notification from invalid feature index %02X: %s", _log.warn('%s: notification from invalid feature index %02X: %s',
device, n.sub_id, n) device, n.sub_id, n)
return False return False
@ -133,31 +133,31 @@ def _process_device_notification(device, status, n):
def _process_dj_notification(device, status, n): def _process_dj_notification(device, status, n):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s (%s) DJ notification %s", device, device.protocol, n) _log.debug('%s (%s) DJ notification %s', device, device.protocol, n)
if n.sub_id == 0x40: if n.sub_id == 0x40:
# do all DJ paired notifications also show up as HID++ 1.0 notifications? # do all DJ paired notifications also show up as HID++ 1.0 notifications?
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: ignoring DJ unpaired: %s", device, n) _log.info('%s: ignoring DJ unpaired: %s', device, n)
return True return True
if n.sub_id == 0x41: if n.sub_id == 0x41:
# do all DJ paired notifications also show up as HID++ 1.0 notifications? # do all DJ paired notifications also show up as HID++ 1.0 notifications?
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: ignoring DJ paired: %s", device, n) _log.info('%s: ignoring DJ paired: %s', device, n)
return True return True
if n.sub_id == 0x42: if n.sub_id == 0x42:
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: ignoring DJ connection: %s", device, n) _log.info('%s: ignoring DJ connection: %s', device, n)
return True return True
_log.warn("%s: unrecognized DJ %s", device, n) _log.warn('%s: unrecognized DJ %s', device, n)
def _process_hidpp10_custom_notification(device, status, n): def _process_hidpp10_custom_notification(device, status, n):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s (%s) custom notification %s", device, device.protocol, _log.debug('%s (%s) custom notification %s', device, device.protocol,
n) n)
if n.sub_id in (_R.battery_status, _R.battery_charge): if n.sub_id in (_R.battery_status, _R.battery_charge):
@ -172,10 +172,10 @@ def _process_hidpp10_custom_notification(device, status, n):
# message layout: 10 ix 17("address") <??> <?> <??> <light level 1=off..5=max> # message layout: 10 ix 17("address") <??> <?> <??> <light level 1=off..5=max>
# TODO anything we can do with this? # TODO anything we can do with this?
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("illumination event: %s", n) _log.info('illumination event: %s', n)
return True return True
_log.warn("%s: unrecognized %s", device, n) _log.warn('%s: unrecognized %s', device, n)
def _process_hidpp10_notification(device, status, n): def _process_hidpp10_notification(device, status, n):
@ -190,9 +190,9 @@ def _process_hidpp10_notification(device, status, n):
del device.receiver[device.number] del device.receiver[device.number]
status.changed(active=False, status.changed(active=False,
alert=_ALERT.ALL, alert=_ALERT.ALL,
reason=_("unpaired")) reason=_('unpaired'))
else: else:
_log.warn("%s: disconnection with unknown type %02X: %s", device, _log.warn('%s: disconnection with unknown type %02X: %s', device,
n.address, n) n.address, n)
return True return True
@ -211,7 +211,7 @@ def _process_hidpp10_notification(device, status, n):
if protocol_name: if protocol_name:
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
wpid = _strhex(n.data[2:3] + n.data[1:2]) wpid = _strhex(n.data[2:3] + n.data[1:2])
assert wpid == device.wpid, "%s wpid mismatch, got %s" % ( assert wpid == device.wpid, '%s wpid mismatch, got %s' % (
device, wpid) device, wpid)
flags = ord(n.data[:1]) & 0xF0 flags = ord(n.data[:1]) & 0xF0
@ -221,14 +221,14 @@ def _process_hidpp10_notification(device, status, n):
sw_present = bool(flags & 0x10) sw_present = bool(flags & 0x10)
has_payload = bool(flags & 0x80) has_payload = bool(flags & 0x80)
_log.debug( _log.debug(
"%s: %s connection notification: software=%s, encrypted=%s, link=%s, payload=%s", '%s: %s connection notification: software=%s, encrypted=%s, link=%s, payload=%s',
device, protocol_name, sw_present, link_encrypted, device, protocol_name, sw_present, link_encrypted,
link_established, has_payload) link_established, has_payload)
status[_K.LINK_ENCRYPTED] = link_encrypted status[_K.LINK_ENCRYPTED] = link_encrypted
status.changed(active=link_established) status.changed(active=link_established)
else: else:
_log.warn( _log.warn(
"%s: connection notification with unknown protocol %02X: %s", '%s: connection notification with unknown protocol %02X: %s',
device.number, n.address, n) device.number, n.address, n)
return True return True
@ -244,16 +244,16 @@ def _process_hidpp10_notification(device, status, n):
if n.sub_id == 0x4B: if n.sub_id == 0x4B:
if n.address == 0x01: if n.address == 0x01:
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: device powered on", device) _log.debug('%s: device powered on', device)
reason = status.to_string() or _("powered on") reason = status.to_string() or _('powered on')
status.changed(active=True, status.changed(active=True,
alert=_ALERT.NOTIFICATION, alert=_ALERT.NOTIFICATION,
reason=reason) reason=reason)
else: else:
_log.warn("%s: unknown %s", device, n) _log.warn('%s: unknown %s', device, n)
return True return True
_log.warn("%s: unrecognized %s", device, n) _log.warn('%s: unrecognized %s', device, n)
def _process_feature_notification(device, status, n, feature): def _process_feature_notification(device, status, n, feature):
@ -267,7 +267,7 @@ def _process_feature_notification(device, status, n, feature):
_hidpp20.BATTERY_STATUS[battery_status], _hidpp20.BATTERY_STATUS[battery_status],
discharge_next_level) discharge_next_level)
else: else:
_log.warn("%s: unknown BATTERY %s", device, n) _log.warn('%s: unknown BATTERY %s', device, n)
return True return True
if feature == _F.BATTERY_VOLTAGE: if feature == _F.BATTERY_VOLTAGE:
@ -276,30 +276,30 @@ def _process_feature_notification(device, status, n, feature):
n.data) n.data)
status.set_battery_info(level, status, None, voltage) status.set_battery_info(level, status, None, voltage)
else: else:
_log.warn("%s: unknown VOLTAGE %s", device, n) _log.warn('%s: unknown VOLTAGE %s', device, n)
return True return True
# TODO: what are REPROG_CONTROLS_V{2,3}? # TODO: what are REPROG_CONTROLS_V{2,3}?
if feature == _F.REPROG_CONTROLS: if feature == _F.REPROG_CONTROLS:
if n.address == 0x00: if n.address == 0x00:
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: reprogrammable key: %s", device, n) _log.info('%s: reprogrammable key: %s', device, n)
else: else:
_log.warn("%s: unknown REPROGRAMMABLE KEYS %s", device, n) _log.warn('%s: unknown REPROGRAMMABLE KEYS %s', device, n)
return True return True
if feature == _F.WIRELESS_DEVICE_STATUS: if feature == _F.WIRELESS_DEVICE_STATUS:
if n.address == 0x00: if n.address == 0x00:
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("wireless status: %s", n) _log.debug('wireless status: %s', n)
if n.data[0:3] == b'\x01\x01\x01': if n.data[0:3] == b'\x01\x01\x01':
status.changed(active=True, status.changed(active=True,
alert=_ALERT.NOTIFICATION, alert=_ALERT.NOTIFICATION,
reason='powered on') reason='powered on')
else: else:
_log.warn("%s: unknown WIRELESS %s", device, n) _log.warn('%s: unknown WIRELESS %s', device, n)
else: else:
_log.warn("%s: unknown WIRELESS %s", device, n) _log.warn('%s: unknown WIRELESS %s', device, n)
return True return True
if feature == _F.SOLAR_DASHBOARD: if feature == _F.SOLAR_DASHBOARD:
@ -319,7 +319,7 @@ def _process_feature_notification(device, status, n, feature):
status.set_battery_info(charge, status_text, None) status.set_battery_info(charge, status_text, None)
elif n.address == 0x20: elif n.address == 0x20:
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: Light Check button pressed", device) _log.debug('%s: Light Check button pressed', device)
status.changed(alert=_ALERT.SHOW_WINDOW) status.changed(alert=_ALERT.SHOW_WINDOW)
# first cancel any reporting # first cancel any reporting
# device.feature_request(_F.SOLAR_DASHBOARD) # device.feature_request(_F.SOLAR_DASHBOARD)
@ -329,25 +329,25 @@ def _process_feature_notification(device, status, n, feature):
device.feature_request(_F.SOLAR_DASHBOARD, 0x00, reports_count, device.feature_request(_F.SOLAR_DASHBOARD, 0x00, reports_count,
reports_period) reports_period)
else: else:
_log.warn("%s: unknown SOLAR CHARGE %s", device, n) _log.warn('%s: unknown SOLAR CHARGE %s', device, n)
else: else:
_log.warn("%s: SOLAR CHARGE not GOOD? %s", device, n) _log.warn('%s: SOLAR CHARGE not GOOD? %s', device, n)
return True return True
if feature == _F.TOUCHMOUSE_RAW_POINTS: if feature == _F.TOUCHMOUSE_RAW_POINTS:
if n.address == 0x00: if n.address == 0x00:
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: TOUCH MOUSE points %s", device, n) _log.info('%s: TOUCH MOUSE points %s', device, n)
elif n.address == 0x10: elif n.address == 0x10:
touch = ord(n.data[:1]) touch = ord(n.data[:1])
button_down = bool(touch & 0x02) button_down = bool(touch & 0x02)
mouse_lifted = bool(touch & 0x01) mouse_lifted = bool(touch & 0x01)
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info( _log.info(
"%s: TOUCH MOUSE status: button_down=%s mouse_lifted=%s", '%s: TOUCH MOUSE status: button_down=%s mouse_lifted=%s',
device, button_down, mouse_lifted) device, button_down, mouse_lifted)
else: else:
_log.warn("%s: unknown TOUCH MOUSE %s", device, n) _log.warn('%s: unknown TOUCH MOUSE %s', device, n)
return True return True
if feature == _F.HIRES_WHEEL: if feature == _F.HIRES_WHEEL:
@ -356,18 +356,18 @@ def _process_feature_notification(device, status, n, feature):
flags, delta_v = _unpack('>bh', n.data[:3]) flags, delta_v = _unpack('>bh', n.data[:3])
high_res = (flags & 0x10) != 0 high_res = (flags & 0x10) != 0
periods = flags & 0x0f periods = flags & 0x0f
_log.info("%s: WHEEL: res: %d periods: %d delta V:%-3d", _log.info('%s: WHEEL: res: %d periods: %d delta V:%-3d',
device, high_res, periods, delta_v) device, high_res, periods, delta_v)
return True return True
elif (n.address == 0x10): elif (n.address == 0x10):
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
flags = ord(n.data[:1]) flags = ord(n.data[:1])
ratchet = flags & 0x01 ratchet = flags & 0x01
_log.info("%s: WHEEL: ratchet: %d", device, ratchet) _log.info('%s: WHEEL: ratchet: %d', device, ratchet)
return True return True
else: else:
_log.warn("%s: unknown WHEEL %s", device, n) _log.warn('%s: unknown WHEEL %s', device, n)
return True return True
_log.warn("%s: unrecognized %s for feature %s (index %02X)", device, n, _log.warn('%s: unrecognized %s for feature %s (index %02X)', device, n,
feature, n.sub_id) feature, n.sub_id)

View File

@ -106,19 +106,19 @@ class PairedDevice(object):
device_info = self.receiver.read_register( device_info = self.receiver.read_register(
_R.receiver_info, 0x04) _R.receiver_info, 0x04)
if device_info is None: if device_info is None:
_log.error("failed to read Nano wpid for device %d of %s", _log.error('failed to read Nano wpid for device %d of %s',
number, receiver) number, receiver)
raise _base.NoSuchDevice(number=number, raise _base.NoSuchDevice(number=number,
receiver=receiver, receiver=receiver,
error="read Nano wpid") error='read Nano wpid')
self.wpid = _strhex(device_info[3:5]) self.wpid = _strhex(device_info[3:5])
self._polling_rate = 0 self._polling_rate = 0
self._power_switch = '(' + _("unknown") + ')' self._power_switch = '(' + _('unknown') + ')'
# the wpid is necessary to properly identify wireless link on/off notifications # the wpid is necessary to properly identify wireless link on/off notifications
# also it gets set to None on this object when the device is unpaired # also it gets set to None on this object when the device is unpaired
assert self.wpid is not None, "failed to read wpid: device %d of %s" % ( assert self.wpid is not None, 'failed to read wpid: device %d of %s' % (
number, receiver) number, receiver)
self.descriptor = _DESCRIPTORS.get(self.wpid) self.descriptor = _DESCRIPTORS.get(self.wpid)
@ -289,14 +289,14 @@ class PairedDevice(object):
set_flag_bits = 0 set_flag_bits = 0
ok = _hidpp10.set_notification_flags(self, set_flag_bits) ok = _hidpp10.set_notification_flags(self, set_flag_bits)
if ok is None: if ok is None:
_log.warn("%s: failed to %s device notifications", self, _log.warn('%s: failed to %s device notifications', self,
'enable' if enable else 'disable') 'enable' if enable else 'disable')
flag_bits = _hidpp10.get_notification_flags(self) flag_bits = _hidpp10.get_notification_flags(self)
flag_names = None if flag_bits is None else tuple( flag_names = None if flag_bits is None else tuple(
_hidpp10.NOTIFICATION_FLAG.flag_names(flag_bits)) _hidpp10.NOTIFICATION_FLAG.flag_names(flag_bits))
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: device notifications %s %s", self, _log.info('%s: device notifications %s %s', self,
'enabled' if enable else 'disabled', flag_names) 'enabled' if enable else 'disabled', flag_names)
return flag_bits if ok else None return flag_bits if ok else None
@ -364,7 +364,7 @@ class Receiver(object):
self.product_id = device_info.product_id self.product_id = device_info.product_id
product_info = _product_information(self.product_id) product_info = _product_information(self.product_id)
if not product_info: if not product_info:
raise Exception("Unknown receiver type", self.product_id) raise Exception('Unknown receiver type', self.product_id)
# read the serial immediately, so we can find out max_devices # read the serial immediately, so we can find out max_devices
serial_reply = self.read_register(_R.receiver_info, 0x03) serial_reply = self.read_register(_R.receiver_info, 0x03)
@ -426,7 +426,7 @@ class Receiver(object):
set_flag_bits = 0 set_flag_bits = 0
ok = _hidpp10.set_notification_flags(self, set_flag_bits) ok = _hidpp10.set_notification_flags(self, set_flag_bits)
if ok is None: if ok is None:
_log.warn("%s: failed to %s receiver notifications", self, _log.warn('%s: failed to %s receiver notifications', self,
'enable' if enable else 'disable') 'enable' if enable else 'disable')
return None return None
@ -434,7 +434,7 @@ class Receiver(object):
flag_names = None if flag_bits is None else tuple( flag_names = None if flag_bits is None else tuple(
_hidpp10.NOTIFICATION_FLAG.flag_names(flag_bits)) _hidpp10.NOTIFICATION_FLAG.flag_names(flag_bits))
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: receiver notifications %s => %s", self, _log.info('%s: receiver notifications %s => %s', self,
'enabled' if enable else 'disabled', flag_names) 'enabled' if enable else 'disabled', flag_names)
return flag_bits return flag_bits
@ -442,12 +442,12 @@ class Receiver(object):
"""Scan all devices.""" """Scan all devices."""
if self.handle: if self.handle:
if not self.write_register(_R.receiver_connection, 0x02): if not self.write_register(_R.receiver_connection, 0x02):
_log.warn("%s: failed to trigger device link notifications", _log.warn('%s: failed to trigger device link notifications',
self) self)
def register_new_device(self, number, notification=None): def register_new_device(self, number, notification=None):
if self._devices.get(number) is not None: if self._devices.get(number) is not None:
raise IndexError("%s: device number %d already registered" % raise IndexError('%s: device number %d already registered' %
(self, number)) (self, number))
assert notification is None or notification.devnumber == number assert notification is None or notification.devnumber == number
@ -457,14 +457,14 @@ class Receiver(object):
dev = PairedDevice(self, number, notification) dev = PairedDevice(self, number, notification)
assert dev.wpid assert dev.wpid
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: found new device %d (%s)", self, number, _log.info('%s: found new device %d (%s)', self, number,
dev.wpid) dev.wpid)
self._devices[number] = dev self._devices[number] = dev
return dev return dev
except _base.NoSuchDevice: except _base.NoSuchDevice:
_log.exception("register_new_device") _log.exception('register_new_device')
_log.warning("%s: looked for device %d, not found", self, number) _log.warning('%s: looked for device %d, not found', self, number)
self._devices[number] = None self._devices[number] = None
def set_lock(self, lock_closed=True, device=0, timeout=0): def set_lock(self, lock_closed=True, device=0, timeout=0):
@ -474,7 +474,7 @@ class Receiver(object):
timeout) timeout)
if reply: if reply:
return True return True
_log.warn("%s: failed to %s the receiver lock", self, _log.warn('%s: failed to %s the receiver lock', self,
'close' if lock_closed else 'open') 'close' if lock_closed else 'open')
def count(self): def count(self):
@ -536,7 +536,7 @@ class Receiver(object):
dev.wpid = None dev.wpid = None
if key in self._devices: if key in self._devices:
del self._devices[key] del self._devices[key]
_log.warn("%s removed device %s", self, dev) _log.warn('%s removed device %s', self, dev)
else: else:
reply = self.write_register(_R.receiver_pairing, 0x03, key) reply = self.write_register(_R.receiver_pairing, 0x03, key)
if reply: if reply:
@ -545,9 +545,9 @@ class Receiver(object):
dev.wpid = None dev.wpid = None
if key in self._devices: if key in self._devices:
del self._devices[key] del self._devices[key]
_log.warn("%s unpaired device %s", self, dev) _log.warn('%s unpaired device %s', self, dev)
else: else:
_log.error("%s failed to unpair device %s", self, dev) _log.error('%s failed to unpair device %s', self, dev)
raise IndexError(key) raise IndexError(key)
def __len__(self): def __len__(self):
@ -586,8 +586,8 @@ class Receiver(object):
if handle: if handle:
return Receiver(handle, device_info) return Receiver(handle, device_info)
except OSError as e: except OSError as e:
_log.exception("open %s", device_info) _log.exception('open %s', device_info)
if e.errno == _errno.EACCES: if e.errno == _errno.EACCES:
raise raise
except: except:
_log.exception("open %s", device_info) _log.exception('open %s', device_info)

View File

@ -110,7 +110,7 @@ class Setting(object):
assert hasattr(self, '_device') assert hasattr(self, '_device')
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings read %r from %s", self.name, self._value, _log.debug('%s: settings read %r from %s', self.name, self._value,
self._device) self._device)
if self._value is None and self._device.persister: if self._value is None and self._device.persister:
@ -141,7 +141,7 @@ class Setting(object):
assert value is not None assert value is not None
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings write %r to %s", self.name, value, _log.debug('%s: settings write %r to %s', self.name, value,
self._device) self._device)
if self._device.online: if self._device.online:
@ -160,7 +160,7 @@ class Setting(object):
data_bytes = self._validator.prepare_write(value, current_value) data_bytes = self._validator.prepare_write(value, current_value)
if data_bytes is not None: if data_bytes is not None:
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings prepare write(%s) => %r", _log.debug('%s: settings prepare write(%s) => %r',
self.name, value, data_bytes) self.name, value, data_bytes)
reply = self._rw.write(self._device, data_bytes) reply = self._rw.write(self._device, data_bytes)
@ -175,7 +175,7 @@ class Setting(object):
assert hasattr(self, '_device') assert hasattr(self, '_device')
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: apply %s (%s)", self.name, self._value, _log.debug('%s: apply %s (%s)', self.name, self._value,
self._device) self._device)
value = self.read() value = self.read()
@ -202,7 +202,7 @@ class Settings(Setting):
assert hasattr(self, '_device') assert hasattr(self, '_device')
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings read %r from %s", self.name, self._value, _log.debug('%s: settings read %r from %s', self.name, self._value,
self._device) self._device)
if self._value is None and getattr(self._device, 'persister', None): if self._value is None and getattr(self._device, 'persister', None):
@ -219,7 +219,7 @@ class Settings(Setting):
return self._value return self._value
if self._device.online: if self._device.online:
reply_map = dict() reply_map = {}
for key, value in self._validator.choices.items(): for key, value in self._validator.choices.items():
reply = self._rw.read(self._device, key) reply = self._rw.read(self._device, key)
if reply: if reply:
@ -241,7 +241,7 @@ class Settings(Setting):
assert key is not None assert key is not None
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings read %r key %r from %s", self.name, _log.debug('%s: settings read %r key %r from %s', self.name,
self._value, key, self._device) self._value, key, self._device)
if self._value is None and getattr(self._device, 'persister', None): if self._value is None and getattr(self._device, 'persister', None):
@ -269,7 +269,7 @@ class Settings(Setting):
assert map is not None assert map is not None
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings write %r to %s", self.name, map, _log.debug('%s: settings write %r to %s', self.name, map,
self._device) self._device)
if self._device.online: if self._device.online:
@ -285,7 +285,7 @@ class Settings(Setting):
if data_bytes is not None: if data_bytes is not None:
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug( _log.debug(
"%s: settings prepare map write(%s,%s) => %r", '%s: settings prepare map write(%s,%s) => %r',
self.name, key, value, data_bytes) self.name, key, value, data_bytes)
reply = self._rw.write(self._device, int(key), data_bytes) reply = self._rw.write(self._device, int(key), data_bytes)
if not reply: if not reply:
@ -300,7 +300,7 @@ class Settings(Setting):
assert value is not None assert value is not None
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings write key %r value %r to %s", self.name, _log.debug('%s: settings write key %r value %r to %s', self.name,
key, value, self._device) key, value, self._device)
if self._device.online: if self._device.online:
@ -315,7 +315,7 @@ class Settings(Setting):
if data_bytes is not None: if data_bytes is not None:
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug( _log.debug(
"%s: settings prepare key value write(%s,%s) => %r", '%s: settings prepare key value write(%s,%s) => %r',
self.name, key, value, data_bytes) self.name, key, value, data_bytes)
reply = self._rw.write(self._device, int(key), data_bytes) reply = self._rw.write(self._device, int(key), data_bytes)
if not reply: if not reply:
@ -333,7 +333,7 @@ class BitFieldSetting(Setting):
assert hasattr(self, '_device') assert hasattr(self, '_device')
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings read %r from %s", self.name, self._value, _log.debug('%s: settings read %r from %s', self.name, self._value,
self._device) self._device)
if self._value is None and getattr(self._device, 'persister', None): if self._value is None and getattr(self._device, 'persister', None):
@ -350,7 +350,7 @@ class BitFieldSetting(Setting):
return self._value return self._value
if self._device.online: if self._device.online:
reply_map = dict() reply_map = {}
reply = self._rw.read(self._device) reply = self._rw.read(self._device)
if reply: if reply:
# keys are ints, because that is what the device uses, # keys are ints, because that is what the device uses,
@ -370,7 +370,7 @@ class BitFieldSetting(Setting):
assert key is not None assert key is not None
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings read %r key %r from %s", self.name, _log.debug('%s: settings read %r key %r from %s', self.name,
self._value, key, self._device) self._value, key, self._device)
if self._value is None and getattr(self._device, 'persister', None): if self._value is None and getattr(self._device, 'persister', None):
@ -397,7 +397,7 @@ class BitFieldSetting(Setting):
assert map is not None assert map is not None
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings write %r to %s", self.name, map, _log.debug('%s: settings write %r to %s', self.name, map,
self._device) self._device)
if self._device.online: if self._device.online:
@ -410,7 +410,7 @@ class BitFieldSetting(Setting):
data_bytes = self._validator.prepare_write(self._value) data_bytes = self._validator.prepare_write(self._value)
if data_bytes is not None: if data_bytes is not None:
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings prepare map write(%s) => %r", _log.debug('%s: settings prepare map write(%s) => %r',
self.name, self._value, data_bytes) self.name, self._value, data_bytes)
reply = self._rw.write(self._device, data_bytes) reply = self._rw.write(self._device, data_bytes)
if not reply: if not reply:
@ -424,7 +424,7 @@ class BitFieldSetting(Setting):
assert value is not None assert value is not None
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: settings write key %r value %r to %s", self.name, _log.debug('%s: settings write key %r value %r to %s', self.name,
key, value, self._device) key, value, self._device)
if self._device.online: if self._device.online:
@ -440,7 +440,7 @@ class BitFieldSetting(Setting):
if data_bytes is not None: if data_bytes is not None:
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug( _log.debug(
"%s: settings prepare key value write(%s,%s) => %r", '%s: settings prepare key value write(%s,%s) => %r',
self.name, key, str(value), data_bytes) self.name, key, str(value), data_bytes)
reply = self._rw.write(self._device, data_bytes) reply = self._rw.write(self._device, data_bytes)
if not reply: if not reply:
@ -583,13 +583,13 @@ class BooleanValidator(object):
if isinstance(self.mask, int): if isinstance(self.mask, int):
reply_value = ord(reply_bytes[:1]) & self.mask reply_value = ord(reply_bytes[:1]) & self.mask
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("BooleanValidator: validate read %r => %02X", _log.debug('BooleanValidator: validate read %r => %02X',
reply_bytes, reply_value) reply_bytes, reply_value)
if reply_value == self.true_value: if reply_value == self.true_value:
return True return True
if reply_value == self.false_value: if reply_value == self.false_value:
return False return False
_log.warn("BooleanValidator: reply %02X mismatched %02X/%02X/%02X", _log.warn('BooleanValidator: reply %02X mismatched %02X/%02X/%02X',
reply_value, self.true_value, self.false_value, reply_value, self.true_value, self.false_value,
self.mask) self.mask)
return False return False
@ -606,7 +606,7 @@ class BooleanValidator(object):
if reply_value == false_value: if reply_value == false_value:
return False return False
_log.warn("BooleanValidator: reply %r mismatched %r/%r/%r", _log.warn('BooleanValidator: reply %r mismatched %r/%r/%r',
reply_bytes, self.true_value, self.false_value, self.mask) reply_bytes, self.true_value, self.false_value, self.mask)
return False return False
@ -642,7 +642,7 @@ class BooleanValidator(object):
return None return None
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("BooleanValidator: prepare_write(%s, %s) => %r", _log.debug('BooleanValidator: prepare_write(%s, %s) => %r',
new_value, current_value, to_write) new_value, current_value, to_write)
return to_write return to_write
@ -706,7 +706,7 @@ class ChoicesValidator(object):
def validate_read(self, reply_bytes): def validate_read(self, reply_bytes):
reply_value = _bytes2int(reply_bytes[:self._bytes_count]) reply_value = _bytes2int(reply_bytes[:self._bytes_count])
valid_value = self.choices[reply_value] valid_value = self.choices[reply_value]
assert valid_value is not None, "%s: failed to validate read value %02X" % ( assert valid_value is not None, '%s: failed to validate read value %02X' % (
self.__class__.__name__, reply_value) self.__class__.__name__, reply_value)
return valid_value return valid_value
@ -724,7 +724,7 @@ class ChoicesValidator(object):
raise ValueError(new_value) raise ValueError(new_value)
if choice is None: if choice is None:
raise ValueError("invalid choice %r" % new_value) raise ValueError('invalid choice %r' % new_value)
assert isinstance(choice, _NamedInt) assert isinstance(choice, _NamedInt)
return choice.bytes(self._bytes_count) return choice.bytes(self._bytes_count)
@ -772,14 +772,14 @@ class ChoicesMapValidator(ChoicesValidator):
if self.extra_default is not None and self.extra_default == reply_value: if self.extra_default is not None and self.extra_default == reply_value:
return int(self.choices[key][0]) return int(self.choices[key][0])
assert reply_value in self.choices[ assert reply_value in self.choices[
key], "%s: failed to validate read value %02X" % ( key], '%s: failed to validate read value %02X' % (
self.__class__.__name__, reply_value) self.__class__.__name__, reply_value)
return reply_value return reply_value
def prepare_write(self, key, new_value): def prepare_write(self, key, new_value):
choices = self.choices[key] choices = self.choices[key]
if new_value not in choices and new_value != self.extra_default: if new_value not in choices and new_value != self.extra_default:
raise ValueError("invalid choice %r" % new_value) raise ValueError('invalid choice %r' % new_value)
return _int2bytes(new_value, return _int2bytes(new_value,
self._skip_bytes_count + self._value_bytes_count) self._skip_bytes_count + self._value_bytes_count)
@ -808,13 +808,13 @@ class RangeValidator(object):
def validate_read(self, reply_bytes): def validate_read(self, reply_bytes):
reply_value = _bytes2int(reply_bytes[:self._bytes_count]) reply_value = _bytes2int(reply_bytes[:self._bytes_count])
assert reply_value >= self.min_value, "%s: failed to validate read value %02X" % ( assert reply_value >= self.min_value, '%s: failed to validate read value %02X' % (
self.__class__.__name__, reply_value) self.__class__.__name__, reply_value)
assert reply_value <= self.max_value, "%s: failed to validate read value %02X" % ( assert reply_value <= self.max_value, '%s: failed to validate read value %02X' % (
self.__class__.__name__, reply_value) self.__class__.__name__, reply_value)
return reply_value return reply_value
def prepare_write(self, new_value, current_value=None): def prepare_write(self, new_value, current_value=None):
if new_value < self.min_value or new_value > self.max_value: if new_value < self.min_value or new_value > self.max_value:
raise ValueError("invalid choice %r" % new_value) raise ValueError('invalid choice %r' % new_value)
return _int2bytes(new_value, self._bytes_count) return _int2bytes(new_value, self._bytes_count)

View File

@ -314,48 +314,48 @@ def feature_range(name,
# #
_HAND_DETECTION = ( _HAND_DETECTION = (
'hand-detection', _("Hand Detection"), 'hand-detection', _('Hand Detection'),
_("Turn on illumination when the hands hover over the keyboard.")) _('Turn on illumination when the hands hover over the keyboard.'))
_SMOOTH_SCROLL = ( _SMOOTH_SCROLL = (
'smooth-scroll', _("Smooth Scrolling"), 'smooth-scroll', _('Smooth Scrolling'),
_("High-sensitivity mode for vertical scroll with the wheel.")) _('High-sensitivity mode for vertical scroll with the wheel.'))
_SIDE_SCROLL = ( _SIDE_SCROLL = (
'side-scroll', _("Side Scrolling"), 'side-scroll', _('Side Scrolling'),
_("When disabled, pushing the wheel sideways sends custom button events\n" _('When disabled, pushing the wheel sideways sends custom button events\n'
"instead of the standard side-scrolling events.")) 'instead of the standard side-scrolling events.'))
_HI_RES_SCROLL = ( _HI_RES_SCROLL = (
'hi-res-scroll', _("High Resolution Scrolling"), 'hi-res-scroll', _('High Resolution Scrolling'),
_("High-sensitivity mode for vertical scroll with the wheel.")) _('High-sensitivity mode for vertical scroll with the wheel.'))
_LOW_RES_SCROLL = ('lowres-smooth-scroll', _("HID++ Scrolling"), _LOW_RES_SCROLL = ('lowres-smooth-scroll', _('HID++ Scrolling'),
_("HID++ mode for vertical scroll with the wheel.") + '\n' + _('HID++ mode for vertical scroll with the wheel.') + '\n' +
_("Effectively turns off wheel scrolling in Linux.")) _('Effectively turns off wheel scrolling in Linux.'))
_HIRES_INV = ('hires-smooth-invert', _("High Resolution Wheel Invert"), _HIRES_INV = ('hires-smooth-invert', _('High Resolution Wheel Invert'),
_("High-sensitivity wheel invert mode for vertical scroll.")) _('High-sensitivity wheel invert mode for vertical scroll.'))
_HIRES_RES = ('hires-smooth-resolution', _("Wheel Resolution"), _HIRES_RES = ('hires-smooth-resolution', _('Wheel Resolution'),
_("High-sensitivity mode for vertical scroll with the wheel.")) _('High-sensitivity mode for vertical scroll with the wheel.'))
_FN_SWAP = ( _FN_SWAP = (
'fn-swap', _("Swap Fx function"), 'fn-swap', _('Swap Fx function'),
_("When set, the F1..F12 keys will activate their special function,\n" _('When set, the F1..F12 keys will activate their special function,\n'
"and you must hold the FN key to activate their standard function.") + 'and you must hold the FN key to activate their standard function.') +
'\n\n' + '\n\n' +
_("When unset, the F1..F12 keys will activate their standard function,\n" _('When unset, the F1..F12 keys will activate their standard function,\n'
"and you must hold the FN key to activate their special function.")) 'and you must hold the FN key to activate their special function.'))
_DPI = ('dpi', _("Sensitivity (DPI)"), None) _DPI = ('dpi', _('Sensitivity (DPI)'), None)
_POINTER_SPEED = ('pointer_speed', _("Sensitivity (Pointer Speed)"), _POINTER_SPEED = ('pointer_speed', _('Sensitivity (Pointer Speed)'),
_("Speed multiplier for mouse (256 is normal multiplier).")) _('Speed multiplier for mouse (256 is normal multiplier).'))
_SMART_SHIFT = ( _SMART_SHIFT = (
'smart-shift', _("Smart Shift"), 'smart-shift', _('Smart Shift'),
_("Automatically switch the mouse wheel between ratchet and freespin mode.\n" _('Automatically switch the mouse wheel between ratchet and freespin mode.\n'
"The mouse wheel is always free at 0, and always locked at 50")) 'The mouse wheel is always free at 0, and always locked at 50'))
_BACKLIGHT = ('backlight', _("Backlight"), _BACKLIGHT = ('backlight', _('Backlight'),
_("Turn illumination on or off on keyboard.")) _('Turn illumination on or off on keyboard.'))
_REPROGRAMMABLE_KEYS = ('reprogrammable-keys', _( _REPROGRAMMABLE_KEYS = ('reprogrammable-keys', _(
"Actions" 'Actions'
), _("Change the action for the key or button.") + "\n" + _( ), _('Change the action for the key or button.') + '\n' + _(
"Changing important actions (such as for the left mouse button) can result in an unusable system." 'Changing important actions (such as for the left mouse button) can result in an unusable system.'
)) ))
_DISABLE_KEYS = ('disable-keyboard-keys', _("Disable keys"), _DISABLE_KEYS = ('disable-keyboard-keys', _('Disable keys'),
_("Disable specific keyboard keys.")) _('Disable specific keyboard keys.'))
# #
# #
@ -741,12 +741,12 @@ def check_feature_settings(device, already_known):
try: try:
detected = featureFn()(device) detected = featureFn()(device)
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("check_feature[%s] detected %s", featureId, _log.debug('check_feature[%s] detected %s', featureId,
detected) detected)
if detected: if detected:
already_known.append(detected) already_known.append(detected)
except Exception as reason: except Exception as reason:
_log.error("check_feature[%s] inconsistent feature %s", featureId, _log.error('check_feature[%s] inconsistent feature %s', featureId,
reason) reason)
for name, featureId, featureFn, _, _ in _SETTINGS_TABLE: for name, featureId, featureFn, _, _ in _SETTINGS_TABLE:

View File

@ -271,7 +271,7 @@ CONTROL = _NamedInts(
MultiPlatform_App_Switch_2=0x0100, # MultiPlatform_App_Switch MultiPlatform_App_Switch_2=0x0100, # MultiPlatform_App_Switch
Fn_Inversion__Hot_Key=0x0101, Fn_Inversion__Hot_Key=0x0101,
LeftAndRightClick=0x0102, LeftAndRightClick=0x0102,
LED_TOGGLE=0x013B, # LED_TOGGLE=0x013B, #
) )
CONTROL._fallback = lambda x: 'unknown:%04X' % x CONTROL._fallback = lambda x: 'unknown:%04X' % x
@ -486,7 +486,7 @@ TASK = _NamedInts(
App_Switch=0x00D5, App_Switch=0x00D5,
Fn_Inversion=0x00D6, Fn_Inversion=0x00D6,
LeftAndRightClick=0x00D7, LeftAndRightClick=0x00D7,
LedToggle=0x00DD, # LedToggle=0x00DD, #
) )
TASK._fallback = lambda x: 'unknown:%04X' % x TASK._fallback = lambda x: 'unknown:%04X' % x
# hidpp 4.5 info from https://lekensteyn.nl/files/logitech/x1b04_specialkeysmsebuttons.html # hidpp 4.5 info from https://lekensteyn.nl/files/logitech/x1b04_specialkeysmsebuttons.html

View File

@ -106,8 +106,8 @@ class ReceiverStatus(dict):
def __str__(self): def __str__(self):
count = len(self._receiver) count = len(self._receiver)
return (_("No paired devices.") if count == 0 else ngettext( return (_('No paired devices.') if count == 0 else ngettext(
"%(count)s paired device.", "%(count)s paired devices.", count) % { '%(count)s paired device.', '%(count)s paired devices.', count) % {
'count': count 'count': count
}) })
@ -161,11 +161,11 @@ class DeviceStatus(dict):
battery_level = self.get(KEYS.BATTERY_LEVEL) battery_level = self.get(KEYS.BATTERY_LEVEL)
if battery_level is not None: if battery_level is not None:
if isinstance(battery_level, _NamedInt): if isinstance(battery_level, _NamedInt):
yield _("Battery: %(level)s") % { yield _('Battery: %(level)s') % {
'level': _(str(battery_level)) 'level': _(str(battery_level))
} }
else: else:
yield _("Battery: %(percent)d%%") % { yield _('Battery: %(percent)d%%') % {
'percent': battery_level 'percent': battery_level
} }
@ -178,7 +178,7 @@ class DeviceStatus(dict):
light_level = self.get(KEYS.LIGHT_LEVEL) light_level = self.get(KEYS.LIGHT_LEVEL)
if light_level is not None: if light_level is not None:
if comma: yield ', ' if comma: yield ', '
yield _("Lighting: %(level)s lux") % {'level': light_level} yield _('Lighting: %(level)s lux') % {'level': light_level}
return ''.join(i for i in _items()) return ''.join(i for i in _items())
@ -198,7 +198,7 @@ class DeviceStatus(dict):
voltage=None, voltage=None,
timestamp=None): timestamp=None):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s: battery %s, %s", self._device, level, status) _log.debug('%s: battery %s, %s', self._device, level, status)
if level is None: if level is None:
# Some notifications may come with no battery level info, just # Some notifications may come with no battery level info, just
@ -239,19 +239,19 @@ class DeviceStatus(dict):
level > _BATTERY_ATTENTION_LEVEL): level > _BATTERY_ATTENTION_LEVEL):
self[KEYS.ERROR] = None self[KEYS.ERROR] = None
else: else:
_log.warn("%s: battery %d%%, ALERT %s", self._device, level, _log.warn('%s: battery %d%%, ALERT %s', self._device, level,
status) status)
if self.get(KEYS.ERROR) != status: if self.get(KEYS.ERROR) != status:
self[KEYS.ERROR] = status self[KEYS.ERROR] = status
# only show the notification once # only show the notification once
alert = ALERT.NOTIFICATION | ALERT.ATTENTION alert = ALERT.NOTIFICATION | ALERT.ATTENTION
if isinstance(level, _NamedInt): if isinstance(level, _NamedInt):
reason = _("Battery: %(level)s (%(status)s)") % { reason = _('Battery: %(level)s (%(status)s)') % {
'level': _(level), 'level': _(level),
'status': _(status) 'status': _(status)
} }
else: else:
reason = _("Battery: %(percent)d%% (%(status)s)") % { reason = _('Battery: %(percent)d%% (%(status)s)') % {
'percent': level, 'percent': level,
'status': status.name 'status': status.name
} }
@ -336,7 +336,7 @@ class DeviceStatus(dict):
# Devices lose configuration when they are turned off, # Devices lose configuration when they are turned off,
# make sure they're up-to-date. # make sure they're up-to-date.
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s pushing device settings %s", d, _log.debug('%s pushing device settings %s', d,
d.settings) d.settings)
for s in d.settings: for s in d.settings:
s.apply() s.apply()

View File

@ -113,12 +113,12 @@ def _receivers(dev_path=None):
try: try:
r = Receiver.open(dev_info) r = Receiver.open(dev_info)
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("[%s] => %s", dev_info.path, r) _log.debug('[%s] => %s', dev_info.path, r)
if r: if r:
yield r yield r
except Exception as e: except Exception as e:
_log.exception('opening ' + str(dev_info)) _log.exception('opening ' + str(dev_info))
_sys.exit("%s: error: %s" % (NAME, str(e))) _sys.exit('%s: error: %s' % (NAME, str(e)))
def _find_receiver(receivers, name): def _find_receiver(receivers, name):

View File

@ -127,7 +127,7 @@ def run(receivers, args, find_receiver, find_device):
raise Exception("can't interpret '%s' as integer" % args.value) raise Exception("can't interpret '%s' as integer" % args.value)
else: else:
raise Exception("NotImplemented") raise Exception('NotImplemented')
result = setting.write(value) result = setting.write(value)
if result is None: if result is None:

View File

@ -96,6 +96,6 @@ def run(receivers, args, find_receiver, _ignore):
else: else:
error = receiver.status.get(_status.KEYS.ERROR) error = receiver.status.get(_status.KEYS.ERROR)
if error: if error:
raise Exception("pairing failed: %s" % error) raise Exception('pairing failed: %s' % error)
else: else:
print('Paired a device') # this is better than an error print('Paired a device') # this is better than an error

View File

@ -48,32 +48,32 @@ def run(receivers, args, find_receiver, _ignore):
print(' Register Dump') print(' Register Dump')
register = receiver.read_register(_R.notifications) register = receiver.read_register(_R.notifications)
print(" Notification Register %#04x: %s" % print(' Notification Register %#04x: %s' %
(_R.notifications % 0x100, (_R.notifications % 0x100,
'0x' + _strhex(register) if register else "None")) '0x' + _strhex(register) if register else 'None'))
register = receiver.read_register(_R.receiver_connection) register = receiver.read_register(_R.receiver_connection)
print(" Connection State %#04x: %s" % print(' Connection State %#04x: %s' %
(_R.receiver_connection % 0x100, (_R.receiver_connection % 0x100,
'0x' + _strhex(register) if register else "None")) '0x' + _strhex(register) if register else 'None'))
register = receiver.read_register(_R.devices_activity) register = receiver.read_register(_R.devices_activity)
print(" Device Activity %#04x: %s" % print(' Device Activity %#04x: %s' %
(_R.devices_activity % 0x100, (_R.devices_activity % 0x100,
'0x' + _strhex(register) if register else "None")) '0x' + _strhex(register) if register else 'None'))
for device in range(0, 6): for device in range(0, 6):
for sub_reg in [0x0, 0x10, 0x20, 0x30]: for sub_reg in [0x0, 0x10, 0x20, 0x30]:
register = receiver.read_register(_R.receiver_info, register = receiver.read_register(_R.receiver_info,
sub_reg + device) sub_reg + device)
print(" Pairing Register %#04x %#04x: %s" % print(' Pairing Register %#04x %#04x: %s' %
(_R.receiver_info % 0x100, sub_reg + device, (_R.receiver_info % 0x100, sub_reg + device,
'0x' + _strhex(register) if register else "None")) '0x' + _strhex(register) if register else 'None'))
register = receiver.read_register(_R.receiver_info, 0x40 + device) register = receiver.read_register(_R.receiver_info, 0x40 + device)
print(" Pairing Name %#04x %#02x: %s" % print(' Pairing Name %#04x %#02x: %s' %
(_R.receiver_info % 0x100, 0x40 + device, (_R.receiver_info % 0x100, 0x40 + device,
register[2:2 + ord(register[1:2])] if register else "None")) register[2:2 + ord(register[1:2])] if register else 'None'))
for sub_reg in range(0, 5): for sub_reg in range(0, 5):
register = receiver.read_register(_R.firmware, sub_reg) register = receiver.read_register(_R.firmware, sub_reg)
print(" Firmware %#04x %#04x: %s" % print(' Firmware %#04x %#04x: %s' %
(_R.firmware % 0x100, sub_reg, (_R.firmware % 0x100, sub_reg,
'0x' + _strhex(register) if register else "None")) '0x' + _strhex(register) if register else 'None'))

View File

@ -124,79 +124,79 @@ def _print_device(dev):
wheel = _hidpp20.get_hires_wheel(dev) wheel = _hidpp20.get_hires_wheel(dev)
if wheel: if wheel:
multi, has_invert, has_switch, inv, res, target, ratchet = wheel multi, has_invert, has_switch, inv, res, target, ratchet = wheel
print(" Multiplier: %s" % multi) print(' Multiplier: %s' % multi)
if has_invert: if has_invert:
print(" Has invert") print(' Has invert')
if inv: if inv:
print(" Inverse wheel motion") print(' Inverse wheel motion')
else: else:
print(" Normal wheel motion") print(' Normal wheel motion')
if has_switch: if has_switch:
print(" Has ratchet switch") print(' Has ratchet switch')
if ratchet: if ratchet:
print(" Normal wheel mode") print(' Normal wheel mode')
else: else:
print(" Free wheel mode") print(' Free wheel mode')
if res: if res:
print(" High resolution mode") print(' High resolution mode')
else: else:
print(" Low resolution mode") print(' Low resolution mode')
if target: if target:
print(" HID++ notification") print(' HID++ notification')
else: else:
print(" HID notification") print(' HID notification')
elif feature == _hidpp20.FEATURE.MOUSE_POINTER: elif feature == _hidpp20.FEATURE.MOUSE_POINTER:
mouse_pointer = _hidpp20.get_mouse_pointer_info(dev) mouse_pointer = _hidpp20.get_mouse_pointer_info(dev)
if mouse_pointer: if mouse_pointer:
print(" DPI: %s" % mouse_pointer['dpi']) print(' DPI: %s' % mouse_pointer['dpi'])
print(" Acceleration: %s" % print(' Acceleration: %s' %
mouse_pointer['acceleration']) mouse_pointer['acceleration'])
if mouse_pointer['suggest_os_ballistics']: if mouse_pointer['suggest_os_ballistics']:
print(" Use OS ballistics") print(' Use OS ballistics')
else: else:
print(" Override OS ballistics") print(' Override OS ballistics')
if mouse_pointer['suggest_vertical_orientation']: if mouse_pointer['suggest_vertical_orientation']:
print(" Provide vertical tuning, trackball") print(' Provide vertical tuning, trackball')
else: else:
print(" No vertical tuning, standard mice") print(' No vertical tuning, standard mice')
if feature == _hidpp20.FEATURE.VERTICAL_SCROLLING: if feature == _hidpp20.FEATURE.VERTICAL_SCROLLING:
vertical_scrolling_info = _hidpp20.get_vertical_scrolling_info( vertical_scrolling_info = _hidpp20.get_vertical_scrolling_info(
dev) dev)
if vertical_scrolling_info: if vertical_scrolling_info:
print(" Roller type: %s" % print(' Roller type: %s' %
vertical_scrolling_info['roller']) vertical_scrolling_info['roller'])
print(" Ratchet per turn: %s" % print(' Ratchet per turn: %s' %
vertical_scrolling_info['ratchet']) vertical_scrolling_info['ratchet'])
print(" Scroll lines: %s" % print(' Scroll lines: %s' %
vertical_scrolling_info['lines']) vertical_scrolling_info['lines'])
elif feature == _hidpp20.FEATURE.HI_RES_SCROLLING: elif feature == _hidpp20.FEATURE.HI_RES_SCROLLING:
scrolling_mode, scrolling_resolution = _hidpp20.get_hi_res_scrolling_info( scrolling_mode, scrolling_resolution = _hidpp20.get_hi_res_scrolling_info(
dev) dev)
if scrolling_mode: if scrolling_mode:
print(" Hi-res scrolling enabled") print(' Hi-res scrolling enabled')
else: else:
print(" Hi-res scrolling disabled") print(' Hi-res scrolling disabled')
if scrolling_resolution: if scrolling_resolution:
print(" Hi-res scrolling multiplier: %s" % print(' Hi-res scrolling multiplier: %s' %
scrolling_resolution) scrolling_resolution)
elif feature == _hidpp20.FEATURE.POINTER_SPEED: elif feature == _hidpp20.FEATURE.POINTER_SPEED:
pointer_speed = _hidpp20.get_pointer_speed_info(dev) pointer_speed = _hidpp20.get_pointer_speed_info(dev)
if pointer_speed: if pointer_speed:
print(" Pointer Speed: %s" % pointer_speed) print(' Pointer Speed: %s' % pointer_speed)
elif feature == _hidpp20.FEATURE.LOWRES_WHEEL: elif feature == _hidpp20.FEATURE.LOWRES_WHEEL:
wheel_status = _hidpp20.get_lowres_wheel_status(dev) wheel_status = _hidpp20.get_lowres_wheel_status(dev)
if wheel_status: if wheel_status:
print(" Wheel Reports: %s" % wheel_status) print(' Wheel Reports: %s' % wheel_status)
elif feature == _hidpp20.FEATURE.NEW_FN_INVERSION: elif feature == _hidpp20.FEATURE.NEW_FN_INVERSION:
inverted, default_inverted = _hidpp20.get_new_fn_inversion(dev) inverted, default_inverted = _hidpp20.get_new_fn_inversion(dev)
print(" Fn-swap:", print(' Fn-swap:',
"enabled" if inverted else "disabled") 'enabled' if inverted else 'disabled')
print(" Fn-swap default:", print(' Fn-swap default:',
"enabled" if default_inverted else "disabled") 'enabled' if default_inverted else 'disabled')
for setting in dev_settings: for setting in dev_settings:
if setting.feature == feature: if setting.feature == feature:
v = setting.read(False) v = setting.read(False)
print(" %s: %s" % (setting.label, v)) print(' %s: %s' % (setting.label, v))
if dev.online and dev.keys: if dev.online and dev.keys:
print(' Has %d reprogrammable keys:' % len(dev.keys)) print(' Has %d reprogrammable keys:' % len(dev.keys))

View File

@ -47,14 +47,14 @@ def _load():
with open(_file_path, 'r') as config_file: with open(_file_path, 'r') as config_file:
loaded_configuration = _json_load(config_file) loaded_configuration = _json_load(config_file)
except: except:
_log.error("failed to load from %s", _file_path) _log.error('failed to load from %s', _file_path)
# loaded_configuration.update(_configuration) # loaded_configuration.update(_configuration)
_configuration.clear() _configuration.clear()
_configuration.update(loaded_configuration) _configuration.update(loaded_configuration)
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("load => %s", _configuration) _log.debug('load => %s', _configuration)
_cleanup(_configuration) _cleanup(_configuration)
_configuration[_KEY_VERSION] = __version__ _configuration[_KEY_VERSION] = __version__
@ -71,7 +71,7 @@ def save():
try: try:
_os.makedirs(dirname) _os.makedirs(dirname)
except: except:
_log.error("failed to create %s", dirname) _log.error('failed to create %s', dirname)
return False return False
_cleanup(_configuration) _cleanup(_configuration)
@ -85,10 +85,10 @@ def save():
sort_keys=True) sort_keys=True)
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("saved %s to %s", _configuration, _file_path) _log.info('saved %s to %s', _configuration, _file_path)
return True return True
except: except:
_log.error("failed to save to %s", _file_path) _log.error('failed to save to %s', _file_path)
def _cleanup(d): def _cleanup(d):

View File

@ -39,7 +39,7 @@ def _require(module, os_package, gi=None, gi_package=None, gi_version=None):
return importlib.import_module(module) return importlib.import_module(module)
except (ImportError, ValueError): except (ImportError, ValueError):
import sys import sys
sys.exit("%s: missing required system package %s" % (NAME, os_package)) sys.exit('%s: missing required system package %s' % (NAME, os_package))
prefer_symbolic_battery_icons = False prefer_symbolic_battery_icons = False
@ -115,7 +115,7 @@ def _parse_arguments():
if not args.action: if not args.action:
if logging.root.isEnabledFor(logging.INFO): if logging.root.isEnabledFor(logging.INFO):
logging.info("language %s (%s), translations path %s", logging.info('language %s (%s), translations path %s',
_i18n.language, _i18n.encoding, _i18n.path) _i18n.language, _i18n.encoding, _i18n.path)
return args return args

View File

@ -84,7 +84,7 @@ class ReceiverListener(_listener.EventsListener):
def has_started(self): def has_started(self):
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: notifications listener has started (%s)", _log.info('%s: notifications listener has started (%s)',
self.receiver, self.receiver.handle) self.receiver, self.receiver.handle)
notification_flags = self.receiver.enable_notifications() notification_flags = self.receiver.enable_notifications()
self.receiver.status[ self.receiver.status[
@ -96,18 +96,18 @@ class ReceiverListener(_listener.EventsListener):
r, self.receiver = self.receiver, None r, self.receiver = self.receiver, None
assert r is not None assert r is not None
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: notifications listener has stopped", r) _log.info('%s: notifications listener has stopped', r)
# because udev is not notifying us about device removal, # because udev is not notifying us about device removal,
# make sure to clean up in _all_listeners # make sure to clean up in _all_listeners
_all_listeners.pop(r.path, None) _all_listeners.pop(r.path, None)
r.status = _("The receiver was unplugged.") r.status = _('The receiver was unplugged.')
if r: if r:
try: try:
r.close() r.close()
except: except:
_log.exception("closing receiver %s" % r.path) _log.exception('closing receiver %s' % r.path)
self.status_changed_callback(r) #, _status.ALERT.NOTIFICATION) self.status_changed_callback(r) #, _status.ALERT.NOTIFICATION)
# def tick(self, timestamp): # def tick(self, timestamp):
@ -151,11 +151,11 @@ class ReceiverListener(_listener.EventsListener):
assert device is not None assert device is not None
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
if device.kind is None: if device.kind is None:
_log.info("status_changed %s: %s, %s (%X) %s", device, _log.info('status_changed %s: %s, %s (%X) %s', device,
'present' if bool(device) else 'removed', 'present' if bool(device) else 'removed',
device.status, alert, reason or '') device.status, alert, reason or '')
else: else:
_log.info("status_changed %s: %s %s, %s (%X) %s", device, _log.info('status_changed %s: %s %s, %s (%X) %s', device,
'paired' if bool(device) else 'unpaired', 'paired' if bool(device) else 'unpaired',
'online' if device.online else 'offline', 'online' if device.online else 'offline',
device.status, alert, reason or '') device.status, alert, reason or '')
@ -171,7 +171,7 @@ class ReceiverListener(_listener.EventsListener):
# Device was unpaired, and isn't valid anymore. # Device was unpaired, and isn't valid anymore.
# We replace it with a ghost so that the UI has something to work # We replace it with a ghost so that the UI has something to work
# with while cleaning up. # with while cleaning up.
_log.warn("device %s was unpaired, ghosting", device) _log.warn('device %s was unpaired, ghosting', device)
device = _ghost(device) device = _ghost(device)
self.status_changed_callback(device, alert, reason) self.status_changed_callback(device, alert, reason)
@ -194,7 +194,7 @@ class ReceiverListener(_listener.EventsListener):
if not (0 < n.devnumber <= self.receiver.max_devices): if not (0 < n.devnumber <= self.receiver.max_devices):
if _log.isEnabledFor(_WARNING): if _log.isEnabledFor(_WARNING):
_log.warning( _log.warning(
_("Unexpected device number (%s) in notification %s." % _('Unexpected device number (%s) in notification %s.' %
(n.devnumber, n))) (n.devnumber, n)))
return return
already_known = n.devnumber in self.receiver already_known = n.devnumber in self.receiver
@ -231,14 +231,14 @@ class ReceiverListener(_listener.EventsListener):
dev = self.receiver[n.devnumber] dev = self.receiver[n.devnumber]
if not dev: if not dev:
_log.warn("%s: received %s for invalid device %d: %r", _log.warn('%s: received %s for invalid device %d: %r',
self.receiver, n, n.devnumber, dev) self.receiver, n, n.devnumber, dev)
return return
# Apply settings every time the device connects # Apply settings every time the device connects
if n.sub_id == 0x41: if n.sub_id == 0x41:
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s triggered new device %s (%s)", n, dev, dev.kind) _log.info('%s triggered new device %s (%s)', n, dev, dev.kind)
# If there are saved configs, bring the device's settings up-to-date. # If there are saved configs, bring the device's settings up-to-date.
# They will be applied when the device is marked as online. # They will be applied when the device is marked as online.
configuration.attach_to(dev) configuration.attach_to(dev)
@ -253,7 +253,7 @@ class ReceiverListener(_listener.EventsListener):
# this should be the first notification after a device was paired # this should be the first notification after a device was paired
assert n.sub_id == 0x41 and n.address == 0x04 assert n.sub_id == 0x41 and n.address == 0x04
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("%s: pairing detected new device", self.receiver) _log.info('%s: pairing detected new device', self.receiver)
self.receiver.status.new_device = dev self.receiver.status.new_device = dev
elif dev.online is None: elif dev.online is None:
dev.ping() dev.ping()
@ -283,7 +283,7 @@ def _start(device_info):
_all_listeners[device_info.path] = rl _all_listeners[device_info.path] = rl
return rl return rl
_log.warn("failed to open %s", device_info) _log.warn('failed to open %s', device_info)
def start_all(): def start_all():
@ -291,7 +291,7 @@ def start_all():
stop_all() stop_all()
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("starting receiver listening threads") _log.info('starting receiver listening threads')
for device_info in _base.receivers(): for device_info in _base.receivers():
_process_receiver_event('add', device_info) _process_receiver_event('add', device_info)
@ -302,7 +302,7 @@ def stop_all():
if listeners: if listeners:
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("stopping receiver listening threads %s", listeners) _log.info('stopping receiver listening threads %s', listeners)
for l in listeners: for l in listeners:
l.stop() l.stop()
@ -352,7 +352,7 @@ def _process_receiver_event(action, device_info):
assert _error_callback assert _error_callback
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("receiver event %s %s", action, device_info) _log.info('receiver event %s %s', action, device_info)
# whatever the action, stop any previous receivers at this path # whatever the action, stop any previous receivers at this path
l = _all_listeners.pop(device_info.path, None) l = _all_listeners.pop(device_info.path, None)

View File

@ -56,7 +56,7 @@ class TaskRunner(_Thread):
self.alive = True self.alive = True
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("started") _log.debug('started')
while self.alive: while self.alive:
task = self.queue.get() task = self.queue.get()
@ -66,7 +66,7 @@ class TaskRunner(_Thread):
try: try:
function(*args, **kwargs) function(*args, **kwargs)
except: except:
_log.exception("calling %s", function) _log.exception('calling %s', function)
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("stopped") _log.debug('stopped')

View File

@ -43,18 +43,18 @@ GLib.threads_init()
def _error_dialog(reason, object): def _error_dialog(reason, object):
_log.error("error: %s %s", reason, object) _log.error('error: %s %s', reason, object)
if reason == 'permissions': if reason == 'permissions':
title = _("Permissions error") title = _('Permissions error')
text = _("Found a Logitech Receiver (%s), but did not have permission to open it.") % object + \ text = _('Found a Logitech Receiver (%s), but did not have permission to open it.') % object + \
'\n\n' + \ '\n\n' + \
_("If you've just installed Solaar, try removing the receiver and plugging it back in.") _("If you've just installed Solaar, try removing the receiver and plugging it back in.")
elif reason == 'unpair': elif reason == 'unpair':
title = _("Unpairing failed") title = _('Unpairing failed')
text = _("Failed to unpair %{device} from %{receiver}.").format(device=object.name, receiver=object.receiver.name) + \ text = _('Failed to unpair %{device} from %{receiver}.').format(device=object.name, receiver=object.receiver.name) + \
'\n\n' + \ '\n\n' + \
_("The receiver returned an error, with no further details.") _('The receiver returned an error, with no further details.')
else: else:
raise Exception("ui.error_dialog: don't know how to handle (%s, %s)", raise Exception("ui.error_dialog: don't know how to handle (%s, %s)",
reason, object) reason, object)
@ -95,7 +95,7 @@ from . import notify, tray, window # isort:skip # noqa: E402
def _startup(app, startup_hook, use_tray, show_window): def _startup(app, startup_hook, use_tray, show_window):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("startup registered=%s, remote=%s", app.get_is_registered(), _log.debug('startup registered=%s, remote=%s', app.get_is_registered(),
app.get_is_remote()) app.get_is_remote())
from solaar.tasks import TaskRunner as _TaskRunner from solaar.tasks import TaskRunner as _TaskRunner
@ -113,7 +113,7 @@ def _startup(app, startup_hook, use_tray, show_window):
def _activate(app): def _activate(app):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("activate") _log.debug('activate')
if app.get_windows(): if app.get_windows():
window.popup() window.popup()
else: else:
@ -122,14 +122,14 @@ def _activate(app):
def _command_line(app, command_line): def _command_line(app, command_line):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("command_line %s", command_line.get_arguments()) _log.debug('command_line %s', command_line.get_arguments())
return 0 return 0
def _shutdown(app, shutdown_hook): def _shutdown(app, shutdown_hook):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("shutdown") _log.debug('shutdown')
shutdown_hook() shutdown_hook()
@ -167,7 +167,7 @@ def run_loop(startup_hook, shutdown_hook, use_tray, show_window, args=None):
def _status_changed(device, alert, reason): def _status_changed(device, alert, reason):
assert device is not None assert device is not None
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("status changed: %s (%s) %s", device, alert, reason) _log.debug('status changed: %s (%s) %s', device, alert, reason)
tray.update(device) tray.update(device)
if alert & ALERT.ATTENTION: if alert & ALERT.ATTENTION:

View File

@ -36,7 +36,7 @@ def _create():
about.set_program_name(NAME) about.set_program_name(NAME)
about.set_version(__version__) about.set_version(__version__)
about.set_comments( about.set_comments(
_("Shows status of devices connected\nthrough wireless Logitech receivers." _('Shows status of devices connected\nthrough wireless Logitech receivers.'
)) ))
about.set_logo_icon_name(NAME.lower()) about.set_logo_icon_name(NAME.lower())
@ -46,25 +46,25 @@ def _create():
about.set_authors(('Daniel Pavel http://github.com/pwr', )) about.set_authors(('Daniel Pavel http://github.com/pwr', ))
try: try:
about.add_credit_section(_("GUI design"), about.add_credit_section(_('GUI design'),
('Julien Gascard', 'Daniel Pavel')) ('Julien Gascard', 'Daniel Pavel'))
about.add_credit_section(_("Testing"), ( about.add_credit_section(_('Testing'), (
'Douglas Wagner', 'Douglas Wagner',
'Julien Gascard', 'Julien Gascard',
'Peter Wu http://www.lekensteyn.nl/logitech-unifying.html', 'Peter Wu http://www.lekensteyn.nl/logitech-unifying.html',
)) ))
about.add_credit_section(_("Logitech documentation"), ( about.add_credit_section(_('Logitech documentation'), (
'Julien Danjou http://julien.danjou.info/blog/2012/logitech-unifying-upower', 'Julien Danjou http://julien.danjou.info/blog/2012/logitech-unifying-upower',
'Nestor Lopez Casado http://drive.google.com/folderview?id=0BxbRzx7vEV7eWmgwazJ3NUFfQ28', 'Nestor Lopez Casado http://drive.google.com/folderview?id=0BxbRzx7vEV7eWmgwazJ3NUFfQ28',
)) ))
except TypeError: except TypeError:
# gtk3 < ~3.6.4 has incorrect gi bindings # gtk3 < ~3.6.4 has incorrect gi bindings
import logging import logging
logging.exception("failed to fully create the about dialog") logging.exception('failed to fully create the about dialog')
except: except:
# the Gtk3 version may be too old, and the function does not exist # the Gtk3 version may be too old, and the function does not exist
import logging import logging
logging.exception("failed to fully create the about dialog") logging.exception('failed to fully create the about dialog')
about.set_translator_credits('\n'.join(( about.set_translator_credits('\n'.join((
'gogo (croatian)', 'gogo (croatian)',

View File

@ -68,7 +68,7 @@ def make_toggle(name, label, function, stock_id=None, *args):
# toggle_notifications = make_toggle('notifications', 'Notifications', _toggle_notifications) # toggle_notifications = make_toggle('notifications', 'Notifications', _toggle_notifications)
about = make('help-about', about = make('help-about',
_("About") + ' ' + NAME, _('About') + ' ' + NAME,
_show_about_window, _show_about_window,
stock_id=Gtk.STOCK_ABOUT) stock_id=Gtk.STOCK_ABOUT)
@ -96,10 +96,10 @@ def unpair(window, device):
qdialog = Gtk.MessageDialog(window, 0, Gtk.MessageType.QUESTION, qdialog = Gtk.MessageDialog(window, 0, Gtk.MessageType.QUESTION,
Gtk.ButtonsType.NONE, Gtk.ButtonsType.NONE,
_("Unpair") + ' ' + device.name + ' ?') _('Unpair') + ' ' + device.name + ' ?')
qdialog.set_icon_name('remove') qdialog.set_icon_name('remove')
qdialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL) qdialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
qdialog.add_button(_("Unpair"), Gtk.ResponseType.ACCEPT) qdialog.add_button(_('Unpair'), Gtk.ResponseType.ACCEPT)
choice = qdialog.run() choice = qdialog.run()
qdialog.destroy() qdialog.destroy()
if choice == Gtk.ResponseType.ACCEPT: if choice == Gtk.ResponseType.ACCEPT:

View File

@ -184,11 +184,11 @@ def _create_sbox(s):
sbox.pack_start(Gtk.Label(s.label), False, False, 0) sbox.pack_start(Gtk.Label(s.label), False, False, 0)
spinner = Gtk.Spinner() spinner = Gtk.Spinner()
spinner.set_tooltip_text(_("Working") + '...') spinner.set_tooltip_text(_('Working') + '...')
failed = Gtk.Image.new_from_icon_name('dialog-warning', failed = Gtk.Image.new_from_icon_name('dialog-warning',
Gtk.IconSize.SMALL_TOOLBAR) Gtk.IconSize.SMALL_TOOLBAR)
failed.set_tooltip_text(_("Read/write operation failed.")) failed.set_tooltip_text(_('Read/write operation failed.'))
if s.kind == _SETTING_KIND.toggle: if s.kind == _SETTING_KIND.toggle:
control = _create_toggle_control(s) control = _create_toggle_control(s)
@ -220,7 +220,7 @@ def _create_sbox(s):
control = _create_map_choice_control(X(s, {'choices': choices})) control = _create_map_choice_control(X(s, {'choices': choices}))
sbox.pack_end(control, True, True, 0) sbox.pack_end(control, True, True, 0)
else: else:
raise Exception("NotImplemented") raise Exception('NotImplemented')
control.set_sensitive(False) # the first read will enable it control.set_sensitive(False) # the first read will enable it
sbox.pack_end(spinner, False, False, 0) sbox.pack_end(spinner, False, False, 0)
@ -259,7 +259,7 @@ def _update_setting_item(sbox, value, is_online=True):
if value.get(kbox.get_active_id()): if value.get(kbox.get_active_id()):
vbox.set_active_id(str(value.get(kbox.get_active_id()))) vbox.set_active_id(str(value.get(kbox.get_active_id())))
else: else:
raise Exception("NotImplemented") raise Exception('NotImplemented')
control.set_sensitive(True) control.set_sensitive(True)

View File

@ -54,7 +54,7 @@ def _look_for_application_icons():
import sys as _sys import sys as _sys
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("sys.path[0] = %s", _sys.path[0]) _log.debug('sys.path[0] = %s', _sys.path[0])
prefix_share = _path.normpath( prefix_share = _path.normpath(
_path.join(_path.realpath(_sys.path[0]), '..')) _path.join(_path.realpath(_sys.path[0]), '..'))
src_share = _path.normpath( src_share = _path.normpath(
@ -75,7 +75,7 @@ def _look_for_application_icons():
for location in share_solaar: for location in share_solaar:
location = _path.join(location, 'icons') location = _path.join(location, 'icons')
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("looking for icons in %s", location) _log.debug('looking for icons in %s', location)
if _path.exists(_path.join(location, TRAY_ATTENTION + '.svg')): if _path.exists(_path.join(location, TRAY_ATTENTION + '.svg')):
yield location yield location
@ -97,7 +97,7 @@ def _init_icon_paths():
for p in _look_for_application_icons(): for p in _look_for_application_icons():
_default_theme.prepend_search_path(p) _default_theme.prepend_search_path(p)
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("icon theme paths: %s", _default_theme.get_search_path()) _log.debug('icon theme paths: %s', _default_theme.get_search_path())
if gtk.prefer_symbolic_battery_icons: if gtk.prefer_symbolic_battery_icons:
if _default_theme.has_icon('battery-good-symbolic'): if _default_theme.has_icon('battery-good-symbolic'):
@ -105,9 +105,9 @@ def _init_icon_paths():
_use_symbolic_icons = True _use_symbolic_icons = True
return return
else: else:
_log.warning("failed to detect symbolic icons") _log.warning('failed to detect symbolic icons')
if not _default_theme.has_icon('battery-good'): if not _default_theme.has_icon('battery-good'):
_log.warning("failed to detect icons") _log.warning('failed to detect icons')
# #
@ -118,10 +118,10 @@ def _init_icon_paths():
def battery(level=None, charging=False): def battery(level=None, charging=False):
icon_name = _battery_icon_name(level, charging) icon_name = _battery_icon_name(level, charging)
if not _default_theme.has_icon(icon_name): if not _default_theme.has_icon(icon_name):
_log.warning("icon %s not found in current theme", icon_name) _log.warning('icon %s not found in current theme', icon_name)
return TRAY_OKAY # use Solaar icon if battery icon not available return TRAY_OKAY # use Solaar icon if battery icon not available
elif _log.isEnabledFor(_DEBUG): elif _log.isEnabledFor(_DEBUG):
_log.debug("battery icon for %s:%s = %s", level, charging, icon_name) _log.debug('battery icon for %s:%s = %s', level, charging, icon_name)
return icon_name return icon_name
@ -222,4 +222,4 @@ def icon_file(name, size=_LARGE_SIZE):
# _log.debug("icon %s(%d) => %s", name, size, file_name) # _log.debug("icon %s(%d) => %s", name, size, file_name)
return file_name return file_name
_log.warn("icon %s(%d) not found in current theme", name, size) _log.warn('icon %s(%d) not found in current theme', name, size)

View File

@ -57,18 +57,18 @@ if available:
if available: if available:
if not Notify.is_initted(): if not Notify.is_initted():
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("starting desktop notifications") _log.info('starting desktop notifications')
try: try:
return Notify.init(NAME) return Notify.init(NAME)
except: except:
_log.exception("initializing desktop notifications") _log.exception('initializing desktop notifications')
available = False available = False
return available and Notify.is_initted() return available and Notify.is_initted()
def uninit(): def uninit():
if available and Notify.is_initted(): if available and Notify.is_initted():
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("stopping desktop notifications") _log.info('stopping desktop notifications')
_notifications.clear() _notifications.clear()
Notify.uninit() Notify.uninit()
@ -95,14 +95,14 @@ if available:
n.update(NAME, reason, icon_file) n.update(NAME, reason, icon_file)
n.set_urgency(Notify.Urgency.NORMAL) n.set_urgency(Notify.Urgency.NORMAL)
n.set_hint("desktop-entry", GLib.Variant('s', NAME.lower())) n.set_hint('desktop-entry', GLib.Variant('s', NAME.lower()))
try: try:
# if _log.isEnabledFor(_DEBUG): # if _log.isEnabledFor(_DEBUG):
# _log.debug("showing %s", n) # _log.debug("showing %s", n)
n.show() n.show()
except Exception: except Exception:
_log.exception("showing %s", n) _log.exception('showing %s', n)
def show(dev, reason=None, icon=None): def show(dev, reason=None, icon=None):
"""Show a notification with title and text.""" """Show a notification with title and text."""
@ -117,11 +117,11 @@ if available:
if reason: if reason:
message = reason message = reason
elif dev.status is None: elif dev.status is None:
message = _("unpaired") message = _('unpaired')
elif bool(dev.status): elif bool(dev.status):
message = dev.status.to_string() or _("connected") message = dev.status.to_string() or _('connected')
else: else:
message = _("offline") message = _('offline')
# we need to use the filename here because the notifications daemon # we need to use the filename here because the notifications daemon
# is an external application that does not know about our icon sets # is an external application that does not know about our icon sets
@ -131,14 +131,14 @@ if available:
n.update(summary, message, icon_file) n.update(summary, message, icon_file)
urgency = Notify.Urgency.LOW if dev.status else Notify.Urgency.NORMAL urgency = Notify.Urgency.LOW if dev.status else Notify.Urgency.NORMAL
n.set_urgency(urgency) n.set_urgency(urgency)
n.set_hint("desktop-entry", GLib.Variant('s', NAME.lower())) n.set_hint('desktop-entry', GLib.Variant('s', NAME.lower()))
try: try:
# if _log.isEnabledFor(_DEBUG): # if _log.isEnabledFor(_DEBUG):
# _log.debug("showing %s", n) # _log.debug("showing %s", n)
n.show() n.show()
except Exception: except Exception:
_log.exception("showing %s", n) _log.exception('showing %s', n)
else: else:
init = lambda: False init = lambda: False

View File

@ -70,7 +70,7 @@ def _create_page(assistant, kind, header=None, icon_name=None, text=None):
def _check_lock_state(assistant, receiver, count=2): def _check_lock_state(assistant, receiver, count=2):
if not assistant.is_drawable(): if not assistant.is_drawable():
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("assistant %s destroyed, bailing out", assistant) _log.debug('assistant %s destroyed, bailing out', assistant)
return False return False
if receiver.status.get(_K.ERROR): if receiver.status.get(_K.ERROR):
@ -99,7 +99,7 @@ def _check_lock_state(assistant, receiver, count=2):
def _prepare(assistant, page, receiver): def _prepare(assistant, page, receiver):
index = assistant.get_current_page() index = assistant.get_current_page()
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("prepare %s %d %s", assistant, index, page) _log.debug('prepare %s %d %s', assistant, index, page)
if index == 0: if index == 0:
if receiver.set_lock(False, timeout=_PAIRING_TIMEOUT): if receiver.set_lock(False, timeout=_PAIRING_TIMEOUT):
@ -119,7 +119,7 @@ def _prepare(assistant, page, receiver):
def _finish(assistant, receiver): def _finish(assistant, receiver):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("finish %s", assistant) _log.debug('finish %s', assistant)
assistant.destroy() assistant.destroy()
receiver.status.new_device = None receiver.status.new_device = None
if receiver.status.lock_open: if receiver.status.lock_open:
@ -130,23 +130,23 @@ def _finish(assistant, receiver):
def _pairing_failed(assistant, receiver, error): def _pairing_failed(assistant, receiver, error):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s fail: %s", receiver, error) _log.debug('%s fail: %s', receiver, error)
assistant.commit() assistant.commit()
header = _("Pairing failed") + ': ' + _(str(error)) + '.' header = _('Pairing failed') + ': ' + _(str(error)) + '.'
if 'timeout' in str(error): if 'timeout' in str(error):
text = _( text = _(
"Make sure your device is within range, and has a decent battery charge." 'Make sure your device is within range, and has a decent battery charge.'
) )
elif str(error) == 'device not supported': elif str(error) == 'device not supported':
text = _( text = _(
"A new device was detected, but it is not compatible with this receiver." 'A new device was detected, but it is not compatible with this receiver.'
) )
elif 'many' in str(error): elif 'many' in str(error):
text = _("The receiver only supports %d paired device(s).") text = _('The receiver only supports %d paired device(s).')
else: else:
text = _("No further details are available about the error.") text = _('No further details are available about the error.')
_create_page(assistant, Gtk.AssistantPageType.SUMMARY, header, _create_page(assistant, Gtk.AssistantPageType.SUMMARY, header,
'dialog-error', text) 'dialog-error', text)
@ -157,11 +157,11 @@ def _pairing_failed(assistant, receiver, error):
def _pairing_succeeded(assistant, receiver, device): def _pairing_succeeded(assistant, receiver, device):
assert device assert device
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s success: %s", receiver, device) _log.debug('%s success: %s', receiver, device)
page = _create_page(assistant, Gtk.AssistantPageType.SUMMARY) page = _create_page(assistant, Gtk.AssistantPageType.SUMMARY)
header = Gtk.Label(_("Found a new device:")) header = Gtk.Label(_('Found a new device:'))
header.set_alignment(0.5, 0) header.set_alignment(0.5, 0)
page.pack_start(header, False, False, 0) page.pack_start(header, False, False, 0)
@ -190,7 +190,7 @@ def _pairing_succeeded(assistant, receiver, device):
Gtk.IconSize.MENU), False, Gtk.IconSize.MENU), False,
False, 0) False, 0)
hbox.pack_start( hbox.pack_start(
Gtk.Label(_("The wireless link is not encrypted") + '!'), Gtk.Label(_('The wireless link is not encrypted') + '!'),
False, False, 0) False, False, 0)
hbox.show_all() hbox.show_all()
else: else:
@ -219,14 +219,14 @@ def create(receiver):
assistant.set_role('pair-device') assistant.set_role('pair-device')
page_text = _( page_text = _(
"If the device is already turned on, turn if off and on again.") 'If the device is already turned on, turn if off and on again.')
if receiver.remaining_pairings() and receiver.remaining_pairings() >= 0: if receiver.remaining_pairings() and receiver.remaining_pairings() >= 0:
page_text += _("\n\nThis receiver has %d pairing(s) remaining." page_text += _('\n\nThis receiver has %d pairing(s) remaining.'
) % receiver.remaining_pairings() ) % receiver.remaining_pairings()
page_text += _("\nCancelling at this point will not use up a pairing.") page_text += _('\nCancelling at this point will not use up a pairing.')
page_intro = _create_page(assistant, Gtk.AssistantPageType.PROGRESS, page_intro = _create_page(assistant, Gtk.AssistantPageType.PROGRESS,
_("Turn on the device you want to pair."), _('Turn on the device you want to pair.'),
'preferences-desktop-peripherals', page_text) 'preferences-desktop-peripherals', page_text)
spinner = Gtk.Spinner() spinner = Gtk.Spinner()
spinner.set_visible(True) spinner.set_visible(True)

View File

@ -56,7 +56,7 @@ def _create_menu(quit_handler):
# per-device menu entries will be generated as-needed # per-device menu entries will be generated as-needed
no_receiver = Gtk.MenuItem.new_with_label(_("No Logitech receiver found")) no_receiver = Gtk.MenuItem.new_with_label(_('No Logitech receiver found'))
no_receiver.set_sensitive(False) no_receiver.set_sensitive(False)
menu.append(no_receiver) menu.append(no_receiver)
menu.append(Gtk.SeparatorMenuItem.new()) menu.append(Gtk.SeparatorMenuItem.new())
@ -65,7 +65,7 @@ def _create_menu(quit_handler):
menu.append(about.create_menu_item()) menu.append(about.create_menu_item())
menu.append( menu.append(
make('application-exit', make('application-exit',
_("Quit"), _('Quit'),
quit_handler, quit_handler,
stock_id=Gtk.STOCK_QUIT).create_menu_item()) stock_id=Gtk.STOCK_QUIT).create_menu_item())
del about, make del about, make
@ -149,7 +149,7 @@ def _scroll(tray_icon, event, direction=None):
_picked_device = candidate or _picked_device _picked_device = candidate or _picked_device
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("scroll: picked %s", _picked_device) _log.debug('scroll: picked %s', _picked_device)
_update_tray_icon() _update_tray_icon()
@ -172,7 +172,7 @@ try:
from gi.repository import AppIndicator3 from gi.repository import AppIndicator3
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("using %sAppIndicator3" % _log.debug('using %sAppIndicator3' %
('Ayatana ' if ayatana_appindicator_found else '')) ('Ayatana ' if ayatana_appindicator_found else ''))
# Defense against AppIndicator3 bug that treats files in current directory as icon files # Defense against AppIndicator3 bug that treats files in current directory as icon files
@ -238,7 +238,7 @@ try:
except ImportError: except ImportError:
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("using StatusIcon") _log.debug('using StatusIcon')
def _create(menu): def _create(menu):
icon = Gtk.StatusIcon.new_from_icon_name(_icons.TRAY_INIT) icon = Gtk.StatusIcon.new_from_icon_name(_icons.TRAY_INIT)
@ -302,7 +302,7 @@ except ImportError:
def _generate_tooltip_lines(): def _generate_tooltip_lines():
if not _devices_info: if not _devices_info:
yield '<b>%s</b>: ' % NAME + _("no receiver") yield '<b>%s</b>: ' % NAME + _('no receiver')
return return
yield from _generate_description_lines() yield from _generate_description_lines()
@ -310,7 +310,7 @@ def _generate_tooltip_lines():
def _generate_description_lines(): def _generate_description_lines():
if not _devices_info: if not _devices_info:
yield _("no receiver") yield _('no receiver')
return return
for _ignore, number, name, status in _devices_info: for _ignore, number, name, status in _devices_info:
@ -323,13 +323,13 @@ def _generate_description_lines():
if status: if status:
yield '\t%s' % p yield '\t%s' % p
else: else:
yield '\t%s <small>(' % p + _("offline") + ')</small>' yield '\t%s <small>(' % p + _('offline') + ')</small>'
else: else:
if status: if status:
yield '<b>%s</b> <small>(' % name + _( yield '<b>%s</b> <small>(' % name + _(
"no status") + ')</small>' 'no status') + ')</small>'
else: else:
yield '<b>%s</b> <small>(' % name + _("offline") + ')</small>' yield '<b>%s</b> <small>(' % name + _('offline') + ')</small>'
yield '' yield ''
@ -350,7 +350,7 @@ def _pick_device_with_lowest_battery():
picked_level = level or 0 picked_level = level or 0
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("picked device with lowest battery: %s", picked) _log.debug('picked device with lowest battery: %s', picked)
return picked return picked

View File

@ -52,7 +52,7 @@ _INFO_ICON_SIZE = Gtk.IconSize.LARGE_TOOLBAR
_DEVICE_ICON_SIZE = Gtk.IconSize.DND _DEVICE_ICON_SIZE = Gtk.IconSize.DND
try: try:
import gi import gi
gi.check_version("3.7.4") gi.check_version('3.7.4')
_CAN_SET_ROW_NONE = None _CAN_SET_ROW_NONE = None
except (ValueError, AttributeError): except (ValueError, AttributeError):
_CAN_SET_ROW_NONE = '' _CAN_SET_ROW_NONE = ''
@ -112,7 +112,7 @@ def _create_receiver_panel():
p._count.set_alignment(0, 0.5) p._count.set_alignment(0, 0.5)
p.pack_start(p._count, True, True, 0) p.pack_start(p._count, True, True, 0)
p._scanning = Gtk.Label(_("Scanning") + '...') p._scanning = Gtk.Label(_('Scanning') + '...')
p._spinner = Gtk.Spinner() p._spinner = Gtk.Spinner()
bp = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 8) bp = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 8)
@ -145,14 +145,14 @@ def _create_device_panel():
return b return b
p._battery = _status_line(_("Battery")) p._battery = _status_line(_('Battery'))
p.pack_start(p._battery, False, False, 0) p.pack_start(p._battery, False, False, 0)
p._secure = _status_line(_("Wireless Link")) p._secure = _status_line(_('Wireless Link'))
p._secure._icon.set_from_icon_name('dialog-warning', _INFO_ICON_SIZE) p._secure._icon.set_from_icon_name('dialog-warning', _INFO_ICON_SIZE)
p.pack_start(p._secure, False, False, 0) p.pack_start(p._secure, False, False, 0)
p._lux = _status_line(_("Lighting")) p._lux = _status_line(_('Lighting'))
p.pack_start(p._lux, False, False, 0) p.pack_start(p._lux, False, False, 0)
p._config = _config_panel.create() p._config = _config_panel.create()
@ -183,7 +183,7 @@ def _create_buttons_box():
bb._details = _new_button(None, bb._details = _new_button(None,
'dialog-information', 'dialog-information',
_SMALL_BUTTON_ICON_SIZE, _SMALL_BUTTON_ICON_SIZE,
tooltip=_("Show Technical Details"), tooltip=_('Show Technical Details'),
toggle=True, toggle=True,
clicked=_update_details) clicked=_update_details)
bb.add(bb._details) bb.add(bb._details)
@ -198,7 +198,7 @@ def _create_buttons_box():
assert receiver.kind is None assert receiver.kind is None
_action.pair(_window, receiver) _action.pair(_window, receiver)
bb._pair = _new_button(_("Pair new device"), bb._pair = _new_button(_('Pair new device'),
'list-add', 'list-add',
clicked=_pair_new_device) clicked=_pair_new_device)
bb.add(bb._pair) bb.add(bb._pair)
@ -211,7 +211,7 @@ def _create_buttons_box():
assert device.kind is not None assert device.kind is not None
_action.unpair(_window, device) _action.unpair(_window, device)
bb._unpair = _new_button(_("Unpair"), bb._unpair = _new_button(_('Unpair'),
'edit-delete', 'edit-delete',
clicked=_unpair_current_device) clicked=_unpair_current_device)
bb.add(bb._unpair) bb.add(bb._unpair)
@ -221,7 +221,7 @@ def _create_buttons_box():
def _create_empty_panel(): def _create_empty_panel():
p = Gtk.Label() p = Gtk.Label()
p.set_markup('<small>' + _("Select a device") + '</small>') p.set_markup('<small>' + _('Select a device') + '</small>')
p.set_sensitive(False) p.set_sensitive(False)
return p return p
@ -339,12 +339,12 @@ def _create_window_layout():
bottom_buttons_box = Gtk.ButtonBox(Gtk.Orientation.HORIZONTAL) bottom_buttons_box = Gtk.ButtonBox(Gtk.Orientation.HORIZONTAL)
bottom_buttons_box.set_layout(Gtk.ButtonBoxStyle.START) bottom_buttons_box.set_layout(Gtk.ButtonBoxStyle.START)
bottom_buttons_box.set_spacing(20) bottom_buttons_box.set_spacing(20)
quit_button = _new_button(_("Quit") + ' ' + NAME, quit_button = _new_button(_('Quit') + ' ' + NAME,
'application-exit', 'application-exit',
icon_size=_SMALL_BUTTON_ICON_SIZE, icon_size=_SMALL_BUTTON_ICON_SIZE,
clicked=destroy) clicked=destroy)
bottom_buttons_box.add(quit_button) bottom_buttons_box.add(quit_button)
about_button = _new_button(_("About") + ' ' + NAME, about_button = _new_button(_('About') + ' ' + NAME,
'help-about', 'help-about',
icon_size=_SMALL_BUTTON_ICON_SIZE, icon_size=_SMALL_BUTTON_ICON_SIZE,
clicked=_show_about_window) clicked=_show_about_window)
@ -444,7 +444,7 @@ def _receiver_row(receiver_path, receiver=None):
status_text, status_icon, receiver) status_text, status_icon, receiver)
assert len(row_data) == len(_TREE_SEPATATOR) assert len(row_data) == len(_TREE_SEPATATOR)
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("new receiver row %s", row_data) _log.debug('new receiver row %s', row_data)
item = _model.append(None, row_data) item = _model.append(None, row_data)
if _TREE_SEPATATOR: if _TREE_SEPATATOR:
_model.append(None, _TREE_SEPATATOR) _model.append(None, _TREE_SEPATATOR)
@ -480,7 +480,7 @@ def _device_row(receiver_path, device_number, device=None):
device) device)
assert len(row_data) == len(_TREE_SEPATATOR) assert len(row_data) == len(_TREE_SEPATATOR)
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("new device row %s at index %d", row_data, _log.debug('new device row %s at index %d', row_data,
new_child_index) new_child_index)
item = _model.insert(receiver_row, new_child_index, row_data) item = _model.insert(receiver_row, new_child_index, row_data)
@ -503,7 +503,7 @@ def select(receiver_path, device_number=None):
selection = _tree.get_selection() selection = _tree.get_selection()
selection.select_iter(item) selection.select_iter(item)
else: else:
_log.warn("select(%s, %s) failed to find an item", receiver_path, _log.warn('select(%s, %s) failed to find an item', receiver_path,
device_number) device_number)
@ -548,33 +548,33 @@ def _update_details(button):
# cached, and involves no HID++ calls. # cached, and involves no HID++ calls.
if device.kind is None: if device.kind is None:
yield (_("Path"), device.path) yield (_('Path'), device.path)
# 046d is the Logitech vendor id # 046d is the Logitech vendor id
yield (_("USB id"), '046d:' + device.product_id) yield (_('USB id'), '046d:' + device.product_id)
if read_all: if read_all:
yield (_("Serial"), device.serial) yield (_('Serial'), device.serial)
else: else:
yield (_("Serial"), '...') yield (_('Serial'), '...')
else: else:
# yield ('Codename', device.codename) # yield ('Codename', device.codename)
yield (_("Index"), device.number) yield (_('Index'), device.number)
yield (_("Wireless PID"), device.wpid) yield (_('Wireless PID'), device.wpid)
hid_version = device.protocol hid_version = device.protocol
yield (_("Protocol"), 'HID++ %1.1f' % yield (_('Protocol'), 'HID++ %1.1f' %
hid_version if hid_version else _('Unknown')) hid_version if hid_version else _('Unknown'))
if read_all and device.polling_rate: if read_all and device.polling_rate:
yield (_("Polling rate"), yield (_('Polling rate'),
_('%(rate)d ms (%(rate_hz)dHz)') % { _('%(rate)d ms (%(rate_hz)dHz)') % {
'rate': device.polling_rate, 'rate': device.polling_rate,
'rate_hz': 1000 // device.polling_rate 'rate_hz': 1000 // device.polling_rate
}) })
if read_all or not device.online: if read_all or not device.online:
yield (_("Serial"), device.serial) yield (_('Serial'), device.serial)
else: else:
yield (_("Serial"), '...') yield (_('Serial'), '...')
if read_all: if read_all:
if device.firmware: if device.firmware:
@ -582,15 +582,15 @@ def _update_details(button):
yield (' ' + _(str(fw.kind)), yield (' ' + _(str(fw.kind)),
(fw.name + ' ' + fw.version).strip()) (fw.name + ' ' + fw.version).strip())
elif device.kind is None or device.online: elif device.kind is None or device.online:
yield (' %s' % _("Firmware"), '...') yield (' %s' % _('Firmware'), '...')
flag_bits = device.status.get(_K.NOTIFICATION_FLAGS) flag_bits = device.status.get(_K.NOTIFICATION_FLAGS)
if flag_bits is not None: if flag_bits is not None:
flag_names = ( flag_names = (
'(%s)' % _("none"), '(%s)' % _('none'),
) if flag_bits == 0 else _hidpp10.NOTIFICATION_FLAG.flag_names( ) if flag_bits == 0 else _hidpp10.NOTIFICATION_FLAG.flag_names(
flag_bits) flag_bits)
yield (_("Notifications"), ('\n%15s' % ' ').join(flag_names)) yield (_('Notifications'), ('\n%15s' % ' ').join(flag_names))
def _set_details(text): def _set_details(text):
_details._text.set_markup(text) _details._text.set_markup(text)
@ -696,7 +696,7 @@ def _update_device_panel(device, panel, buttons, full=False):
panel._battery._icon.set_sensitive(False) panel._battery._icon.set_sensitive(False)
panel._battery._icon.set_from_icon_name(icon_name, _INFO_ICON_SIZE) panel._battery._icon.set_from_icon_name(icon_name, _INFO_ICON_SIZE)
panel._battery._text.set_sensitive(True) panel._battery._text.set_sensitive(True)
panel._battery._text.set_markup('<small>%s</small>' % _("unknown")) panel._battery._text.set_markup('<small>%s</small>' % _('unknown'))
else: else:
charging = device.status.get(_K.BATTERY_CHARGING) charging = device.status.get(_K.BATTERY_CHARGING)
icon_name = _icons.battery(battery_level, charging) icon_name = _icons.battery(battery_level, charging)
@ -704,52 +704,52 @@ def _update_device_panel(device, panel, buttons, full=False):
panel._battery._icon.set_sensitive(True) panel._battery._icon.set_sensitive(True)
if battery_voltage is not None: if battery_voltage is not None:
text = "%(battery_voltage)dmV" % { text = '%(battery_voltage)dmV' % {
'battery_voltage': battery_voltage 'battery_voltage': battery_voltage
} }
elif isinstance(battery_level, _NamedInt): elif isinstance(battery_level, _NamedInt):
text = _(str(battery_level)) text = _(str(battery_level))
else: else:
text = "%(battery_percent)d%%" % {'battery_percent': battery_level} text = '%(battery_percent)d%%' % {'battery_percent': battery_level}
if battery_next_level is not None: if battery_next_level is not None:
if isinstance(battery_next_level, _NamedInt): if isinstance(battery_next_level, _NamedInt):
text += "<small> (" + _("next ") + _( text += '<small> (' + _('next ') + _(
str(battery_next_level)) + ")</small>" str(battery_next_level)) + ')</small>'
else: else:
text += "<small> (" + _("next ") + ( text += '<small> (' + _('next ') + (
"%d%%" % battery_next_level) + ")</small>" '%d%%' % battery_next_level) + ')</small>'
if is_online: if is_online:
if charging: if charging:
text += ' <small>(%s)</small>' % _("charging") text += ' <small>(%s)</small>' % _('charging')
else: else:
text += ' <small>(%s)</small>' % _("last known") text += ' <small>(%s)</small>' % _('last known')
panel._battery._text.set_sensitive(is_online) panel._battery._text.set_sensitive(is_online)
panel._battery._text.set_markup(text) panel._battery._text.set_markup(text)
if is_online: if is_online:
not_secure = device.status.get(_K.LINK_ENCRYPTED) == False not_secure = device.status.get(_K.LINK_ENCRYPTED) == False
if not_secure: if not_secure:
panel._secure._text.set_text(_("not encrypted")) panel._secure._text.set_text(_('not encrypted'))
panel._secure._icon.set_from_icon_name('security-low', panel._secure._icon.set_from_icon_name('security-low',
_INFO_ICON_SIZE) _INFO_ICON_SIZE)
panel._secure.set_tooltip_text( panel._secure.set_tooltip_text(
_("The wireless link between this device and its receiver is not encrypted.\n" _('The wireless link between this device and its receiver is not encrypted.\n'
"\n" '\n'
"For pointing devices (mice, trackballs, trackpads), this is a minor security issue.\n" 'For pointing devices (mice, trackballs, trackpads), this is a minor security issue.\n'
"\n" '\n'
"It is, however, a major security issue for text-input devices (keyboards, numpads),\n" 'It is, however, a major security issue for text-input devices (keyboards, numpads),\n'
"because typed text can be sniffed inconspicuously by 3rd parties within range." 'because typed text can be sniffed inconspicuously by 3rd parties within range.'
)) ))
else: else:
panel._secure._text.set_text(_("encrypted")) panel._secure._text.set_text(_('encrypted'))
panel._secure._icon.set_from_icon_name('security-high', panel._secure._icon.set_from_icon_name('security-high',
_INFO_ICON_SIZE) _INFO_ICON_SIZE)
panel._secure.set_tooltip_text( panel._secure.set_tooltip_text(
_("The wireless link between this device and its receiver is encrypted." _('The wireless link between this device and its receiver is encrypted.'
)) ))
panel._secure._icon.set_visible(True) panel._secure._icon.set_visible(True)
else: else:
panel._secure._text.set_markup('<small>%s</small>' % _("offline")) panel._secure._text.set_markup('<small>%s</small>' % _('offline'))
panel._secure._icon.set_visible(False) panel._secure._icon.set_visible(False)
panel._secure.set_tooltip_text('') panel._secure.set_tooltip_text('')
@ -761,7 +761,7 @@ def _update_device_panel(device, panel, buttons, full=False):
panel._lux._icon.set_from_icon_name(_icons.lux(light_level), panel._lux._icon.set_from_icon_name(_icons.lux(light_level),
_INFO_ICON_SIZE) _INFO_ICON_SIZE)
panel._lux._text.set_text( panel._lux._text.set_text(
_("%(light_level)d lux") % {'light_level': light_level}) _('%(light_level)d lux') % {'light_level': light_level})
panel._lux.set_visible(True) panel._lux.set_visible(True)
else: else:
panel._lux.set_visible(False) panel._lux.set_visible(False)
@ -898,7 +898,7 @@ def update(device, need_popup=False):
# peripheral # peripheral
is_paired = bool(device) is_paired = bool(device)
assert device.receiver assert device.receiver
assert device.number is not None and device.number > 0, "invalid device number" + str( assert device.number is not None and device.number > 0, 'invalid device number' + str(
device.number) device.number)
item = _device_row(device.receiver.path, device.number, item = _device_row(device.receiver.path, device.number,
device if is_paired else None) device if is_paired else None)
@ -915,13 +915,13 @@ def update(device, need_popup=False):
_model.set_value(item, _COLUMN.STATUS_ICON, _CAN_SET_ROW_NONE) _model.set_value(item, _COLUMN.STATUS_ICON, _CAN_SET_ROW_NONE)
else: else:
if battery_voltage is not None: if battery_voltage is not None:
status_text = "%(battery_voltage)dmV" % { status_text = '%(battery_voltage)dmV' % {
'battery_voltage': battery_voltage 'battery_voltage': battery_voltage
} }
elif isinstance(battery_level, _NamedInt): elif isinstance(battery_level, _NamedInt):
status_text = _(str(battery_level)) status_text = _(str(battery_level))
else: else:
status_text = "%(battery_percent)d%%" % { status_text = '%(battery_percent)d%%' % {
'battery_percent': battery_level 'battery_percent': battery_level
} }
_model.set_value(item, _COLUMN.STATUS_TEXT, status_text) _model.set_value(item, _COLUMN.STATUS_TEXT, status_text)

View File

@ -35,7 +35,7 @@ _suspend_callback = None
def _suspend(): def _suspend():
if _suspend_callback: if _suspend_callback:
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("received suspend event") _log.info('received suspend event')
_suspend_callback() _suspend_callback()
@ -45,7 +45,7 @@ _resume_callback = None
def _resume(): def _resume():
if _resume_callback: if _resume_callback:
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info("received resume event") _log.info('received resume event')
_resume_callback() _resume_callback()
@ -93,11 +93,11 @@ try:
if _log.isEnabledFor(_INFO): if _log.isEnabledFor(_INFO):
_log.info( _log.info(
"connected to system dbus, watching for suspend/resume events") 'connected to system dbus, watching for suspend/resume events')
except: except:
# Either: # Either:
# - the dbus library is not available # - the dbus library is not available
# - the system dbus is not running # - the system dbus is not running
_log.warn("failed to register suspend/resume callbacks") _log.warn('failed to register suspend/resume callbacks')
pass pass

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from glob import glob as _glob from glob import glob as _glob
try: try:
from setuptools import setup from setuptools import setup
except ImportError: except ImportError:

View File

@ -13,7 +13,7 @@ sys.path += (sys.path[0] + '/../lib', )
def print_event(action, device): def print_event(action, device):
print("~~~~ device [%s] %s" % (action, device)) print('~~~~ device [%s] %s' % (action, device))
hidapi.monitor(print_event, DEVICE_UNIFYING_RECEIVER, hidapi.monitor(print_event, DEVICE_UNIFYING_RECEIVER,