logitech_receiver: Move hidpp10 constants into new module
Related #1097
This commit is contained in:
parent
e8fdbeee8e
commit
2fcab65486
|
@ -24,8 +24,8 @@
|
|||
# - the device uses a USB interface other than 2
|
||||
# - the name or codename should be different from what the device reports
|
||||
|
||||
from .hidpp10 import DEVICE_KIND as _DK
|
||||
from .hidpp10 import REGISTERS as _R
|
||||
from .hidpp10_constants import DEVICE_KIND as _DK
|
||||
from .hidpp10_constants import REGISTERS as _R
|
||||
|
||||
#
|
||||
#
|
||||
|
|
|
@ -30,16 +30,18 @@ from . import base as _base
|
|||
from . import descriptors as _descriptors
|
||||
from . import exceptions
|
||||
from . import hidpp10 as _hidpp10
|
||||
from . import hidpp10_constants as _hidpp10_constants
|
||||
from . import hidpp20 as _hidpp20
|
||||
from . import hidpp20_constants as _hidpp20_constants
|
||||
from .common import strhex as _strhex
|
||||
from .settings_templates import check_feature_settings as _check_feature_settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_R = _hidpp10.REGISTERS
|
||||
_IR = _hidpp10.INFO_SUBREGISTERS
|
||||
_R = _hidpp10_constants.REGISTERS
|
||||
_IR = _hidpp10_constants.INFO_SUBREGISTERS
|
||||
|
||||
KIND_MAP = {kind: _hidpp10.DEVICE_KIND[str(kind)] for kind in _hidpp20.DEVICE_KIND}
|
||||
KIND_MAP = {kind: _hidpp10_constants.DEVICE_KIND[str(kind)] for kind in _hidpp20_constants.DEVICE_KIND}
|
||||
|
||||
#
|
||||
#
|
||||
|
@ -124,14 +126,14 @@ class Device:
|
|||
if receiver.receiver_kind == '27Mhz': # 27 Mhz receiver
|
||||
self.wpid = '00' + _strhex(link_notification.data[2:3])
|
||||
kind = receiver.get_kind_from_index(number)
|
||||
self._kind = _hidpp10.DEVICE_KIND[kind]
|
||||
self._kind = _hidpp10_constants.DEVICE_KIND[kind]
|
||||
elif receiver.receiver_kind == '27Mhz': # 27 Mhz receiver doesn't have pairing registers
|
||||
self.wpid = _hid.find_paired_node_wpid(receiver.path, number)
|
||||
if not self.wpid:
|
||||
logger.error('Unable to get wpid from udev for device %d of %s', number, receiver)
|
||||
raise exceptions.NoSuchDevice(number=number, receiver=receiver, error='Not present 27Mhz device')
|
||||
kind = receiver.get_kind_from_index(number)
|
||||
self._kind = _hidpp10.DEVICE_KIND[kind]
|
||||
self._kind = _hidpp10_constants.DEVICE_KIND[kind]
|
||||
else: # get information from pairing registers
|
||||
self.online = True
|
||||
self.update_pairing_information()
|
||||
|
@ -415,10 +417,10 @@ class Device:
|
|||
|
||||
if enable:
|
||||
set_flag_bits = (
|
||||
_hidpp10.NOTIFICATION_FLAG.battery_status
|
||||
| _hidpp10.NOTIFICATION_FLAG.keyboard_illumination
|
||||
| _hidpp10.NOTIFICATION_FLAG.wireless
|
||||
| _hidpp10.NOTIFICATION_FLAG.software_present
|
||||
_hidpp10_constants.NOTIFICATION_FLAG.battery_status
|
||||
| _hidpp10_constants.NOTIFICATION_FLAG.keyboard_illumination
|
||||
| _hidpp10_constants.NOTIFICATION_FLAG.wireless
|
||||
| _hidpp10_constants.NOTIFICATION_FLAG.software_present
|
||||
)
|
||||
else:
|
||||
set_flag_bits = 0
|
||||
|
@ -427,7 +429,7 @@ class Device:
|
|||
logger.warning('%s: failed to %s device notifications', self, 'enable' if enable else 'disable')
|
||||
|
||||
flag_bits = _hidpp10.get_notification_flags(self)
|
||||
flag_names = None if flag_bits is None else tuple(_hidpp10.NOTIFICATION_FLAG.flag_names(flag_bits))
|
||||
flag_names = None if flag_bits is None else tuple(_hidpp10_constants.NOTIFICATION_FLAG.flag_names(flag_bits))
|
||||
if logger.isEnabledFor(logging.INFO):
|
||||
logger.info('%s: device notifications %s %s', self, 'enabled' if enable else 'disabled', flag_names)
|
||||
return flag_bits if ok else None
|
||||
|
|
|
@ -20,164 +20,14 @@ import logging
|
|||
|
||||
from .common import BATTERY_APPROX as _BATTERY_APPROX
|
||||
from .common import FirmwareInfo as _FirmwareInfo
|
||||
from .common import NamedInts as _NamedInts
|
||||
from .common import bytes2int as _bytes2int
|
||||
from .common import int2bytes as _int2bytes
|
||||
from .common import strhex as _strhex
|
||||
from .hidpp20 import BATTERY_STATUS, FIRMWARE_KIND
|
||||
from .hidpp10_constants import REGISTERS
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
#
|
||||
# Constants - most of them as defined by the official Logitech HID++ 1.0
|
||||
# documentation, some of them guessed.
|
||||
#
|
||||
|
||||
DEVICE_KIND = _NamedInts(
|
||||
unknown=0x00,
|
||||
keyboard=0x01,
|
||||
mouse=0x02,
|
||||
numpad=0x03,
|
||||
presenter=0x04,
|
||||
remote=0x07,
|
||||
trackball=0x08,
|
||||
touchpad=0x09,
|
||||
headset=0x0D, # not from Logitech documentation
|
||||
remote_control=0x0E, # for compatibility with HID++ 2.0
|
||||
receiver=0x0F # for compatibility with HID++ 2.0
|
||||
)
|
||||
|
||||
POWER_SWITCH_LOCATION = _NamedInts(
|
||||
base=0x01,
|
||||
top_case=0x02,
|
||||
edge_of_top_right_corner=0x03,
|
||||
top_left_corner=0x05,
|
||||
bottom_left_corner=0x06,
|
||||
top_right_corner=0x07,
|
||||
bottom_right_corner=0x08,
|
||||
top_edge=0x09,
|
||||
right_edge=0x0A,
|
||||
left_edge=0x0B,
|
||||
bottom_edge=0x0C
|
||||
)
|
||||
|
||||
# Some flags are used both by devices and receivers. The Logitech documentation
|
||||
# mentions that the first and last (third) byte are used for devices while the
|
||||
# second is used for the receiver. In practise, the second byte is also used for
|
||||
# some device-specific notifications (keyboard illumination level). Do not
|
||||
# simply set all notification bits if the software does not support it. For
|
||||
# example, enabling keyboard_sleep_raw makes the Sleep key a no-operation unless
|
||||
# the software is updated to handle that event.
|
||||
# Observations:
|
||||
# - wireless and software present were seen on receivers, reserved_r1b4 as well
|
||||
# - the rest work only on devices as far as we can tell right now
|
||||
# In the future would be useful to have separate enums for receiver and device notification flags,
|
||||
# but right now we don't know enough.
|
||||
# additional flags taken from https://drive.google.com/file/d/0BxbRzx7vEV7eNDBheWY0UHM5dEU/view?usp=sharing
|
||||
NOTIFICATION_FLAG = _NamedInts(
|
||||
numpad_numerical_keys=0x800000,
|
||||
f_lock_status=0x400000,
|
||||
roller_H=0x200000,
|
||||
battery_status=0x100000, # send battery charge notifications (0x07 or 0x0D)
|
||||
mouse_extra_buttons=0x080000,
|
||||
roller_V=0x040000,
|
||||
keyboard_sleep_raw=0x020000, # system control keys such as Sleep
|
||||
keyboard_multimedia_raw=0x010000, # consumer controls such as Mute and Calculator
|
||||
# reserved_r1b4= 0x001000, # unknown, seen on a unifying receiver
|
||||
reserved5=0x008000,
|
||||
reserved4=0x004000,
|
||||
reserved3=0x002000,
|
||||
reserved2=0x001000,
|
||||
software_present=0x000800, # .. no idea
|
||||
reserved1=0x000400,
|
||||
keyboard_illumination=0x000200, # illumination brightness level changes (by pressing keys)
|
||||
wireless=0x000100, # notify when the device wireless goes on/off-line
|
||||
mx_air_3d_gesture=0x000001,
|
||||
)
|
||||
|
||||
ERROR = _NamedInts(
|
||||
invalid_SubID__command=0x01,
|
||||
invalid_address=0x02,
|
||||
invalid_value=0x03,
|
||||
connection_request_failed=0x04,
|
||||
too_many_devices=0x05,
|
||||
already_exists=0x06,
|
||||
busy=0x07,
|
||||
unknown_device=0x08,
|
||||
resource_error=0x09,
|
||||
request_unavailable=0x0A,
|
||||
unsupported_parameter_value=0x0B,
|
||||
wrong_pin_code=0x0C
|
||||
)
|
||||
|
||||
PAIRING_ERRORS = _NamedInts(device_timeout=0x01, device_not_supported=0x02, too_many_devices=0x03, sequence_timeout=0x06)
|
||||
BOLT_PAIRING_ERRORS = _NamedInts(device_timeout=0x01, failed=0x02)
|
||||
"""Known registers.
|
||||
Devices usually have a (small) sub-set of these. Some registers are only
|
||||
applicable to certain device kinds (e.g. smooth_scroll only applies to mice."""
|
||||
REGISTERS = _NamedInts(
|
||||
# only apply to receivers
|
||||
receiver_connection=0x02,
|
||||
receiver_pairing=0xB2,
|
||||
devices_activity=0x2B3,
|
||||
receiver_info=0x2B5,
|
||||
bolt_device_discovery=0xC0,
|
||||
bolt_pairing=0x2C1,
|
||||
bolt_uniqueId=0x02FB,
|
||||
|
||||
# only apply to devices
|
||||
mouse_button_flags=0x01,
|
||||
keyboard_hand_detection=0x01,
|
||||
battery_status=0x07,
|
||||
keyboard_fn_swap=0x09,
|
||||
battery_charge=0x0D,
|
||||
keyboard_illumination=0x17,
|
||||
three_leds=0x51,
|
||||
mouse_dpi=0x63,
|
||||
|
||||
# apply to both
|
||||
notifications=0x00,
|
||||
firmware=0xF1,
|
||||
|
||||
# notifications
|
||||
passkey_request_notification=0x4D,
|
||||
passkey_pressed_notification=0x4E,
|
||||
device_discovery_notification=0x4F,
|
||||
discovery_status_notification=0x53,
|
||||
pairing_status_notification=0x54,
|
||||
)
|
||||
# Subregisters for receiver_info register
|
||||
INFO_SUBREGISTERS = _NamedInts(
|
||||
serial_number=0x01, # not found on many receivers
|
||||
fw_version=0x02,
|
||||
receiver_information=0x03,
|
||||
pairing_information=0x20, # 0x2N, by connected device
|
||||
extended_pairing_information=0x30, # 0x3N, by connected device
|
||||
device_name=0x40, # 0x4N, by connected device
|
||||
bolt_pairing_information=0x50, # 0x5N, by connected device
|
||||
bolt_device_name=0x60, # 0x6N01, by connected device,
|
||||
)
|
||||
|
||||
# Flags taken from https://drive.google.com/file/d/0BxbRzx7vEV7eNDBheWY0UHM5dEU/view?usp=sharing
|
||||
DEVICE_FEATURES = _NamedInts(
|
||||
reserved1=0x010000,
|
||||
special_buttons=0x020000,
|
||||
enhanced_key_usage=0x040000,
|
||||
fast_fw_rev=0x080000,
|
||||
reserved2=0x100000,
|
||||
reserved3=0x200000,
|
||||
scroll_accel=0x400000,
|
||||
buttons_control_resolution=0x800000,
|
||||
inhibit_lock_key_sound=0x000001,
|
||||
reserved4=0x000002,
|
||||
mx_air_3d_engine=0x000004,
|
||||
host_control_leds=0x000008,
|
||||
reserved5=0x000010,
|
||||
reserved6=0x000020,
|
||||
reserved7=0x000040,
|
||||
reserved8=0x000080,
|
||||
)
|
||||
|
||||
#
|
||||
# functions
|
||||
#
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
from .common import NamedInts
|
||||
|
||||
#
|
||||
# Constants - most of them as defined by the official Logitech HID++ 1.0
|
||||
# documentation, some of them guessed.
|
||||
#
|
||||
|
||||
DEVICE_KIND = NamedInts(
|
||||
unknown=0x00,
|
||||
keyboard=0x01,
|
||||
mouse=0x02,
|
||||
numpad=0x03,
|
||||
presenter=0x04,
|
||||
remote=0x07,
|
||||
trackball=0x08,
|
||||
touchpad=0x09,
|
||||
headset=0x0D, # not from Logitech documentation
|
||||
remote_control=0x0E, # for compatibility with HID++ 2.0
|
||||
receiver=0x0F # for compatibility with HID++ 2.0
|
||||
)
|
||||
|
||||
POWER_SWITCH_LOCATION = NamedInts(
|
||||
base=0x01,
|
||||
top_case=0x02,
|
||||
edge_of_top_right_corner=0x03,
|
||||
top_left_corner=0x05,
|
||||
bottom_left_corner=0x06,
|
||||
top_right_corner=0x07,
|
||||
bottom_right_corner=0x08,
|
||||
top_edge=0x09,
|
||||
right_edge=0x0A,
|
||||
left_edge=0x0B,
|
||||
bottom_edge=0x0C
|
||||
)
|
||||
|
||||
# Some flags are used both by devices and receivers. The Logitech documentation
|
||||
# mentions that the first and last (third) byte are used for devices while the
|
||||
# second is used for the receiver. In practise, the second byte is also used for
|
||||
# some device-specific notifications (keyboard illumination level). Do not
|
||||
# simply set all notification bits if the software does not support it. For
|
||||
# example, enabling keyboard_sleep_raw makes the Sleep key a no-operation unless
|
||||
# the software is updated to handle that event.
|
||||
# Observations:
|
||||
# - wireless and software present were seen on receivers, reserved_r1b4 as well
|
||||
# - the rest work only on devices as far as we can tell right now
|
||||
# In the future would be useful to have separate enums for receiver and device notification flags,
|
||||
# but right now we don't know enough.
|
||||
# additional flags taken from https://drive.google.com/file/d/0BxbRzx7vEV7eNDBheWY0UHM5dEU/view?usp=sharing
|
||||
NOTIFICATION_FLAG = NamedInts(
|
||||
numpad_numerical_keys=0x800000,
|
||||
f_lock_status=0x400000,
|
||||
roller_H=0x200000,
|
||||
battery_status=0x100000, # send battery charge notifications (0x07 or 0x0D)
|
||||
mouse_extra_buttons=0x080000,
|
||||
roller_V=0x040000,
|
||||
keyboard_sleep_raw=0x020000, # system control keys such as Sleep
|
||||
keyboard_multimedia_raw=0x010000, # consumer controls such as Mute and Calculator
|
||||
# reserved_r1b4= 0x001000, # unknown, seen on a unifying receiver
|
||||
reserved5=0x008000,
|
||||
reserved4=0x004000,
|
||||
reserved3=0x002000,
|
||||
reserved2=0x001000,
|
||||
software_present=0x000800, # .. no idea
|
||||
reserved1=0x000400,
|
||||
keyboard_illumination=0x000200, # illumination brightness level changes (by pressing keys)
|
||||
wireless=0x000100, # notify when the device wireless goes on/off-line
|
||||
mx_air_3d_gesture=0x000001,
|
||||
)
|
||||
|
||||
ERROR = NamedInts(
|
||||
invalid_SubID__command=0x01,
|
||||
invalid_address=0x02,
|
||||
invalid_value=0x03,
|
||||
connection_request_failed=0x04,
|
||||
too_many_devices=0x05,
|
||||
already_exists=0x06,
|
||||
busy=0x07,
|
||||
unknown_device=0x08,
|
||||
resource_error=0x09,
|
||||
request_unavailable=0x0A,
|
||||
unsupported_parameter_value=0x0B,
|
||||
wrong_pin_code=0x0C
|
||||
)
|
||||
|
||||
PAIRING_ERRORS = NamedInts(device_timeout=0x01, device_not_supported=0x02, too_many_devices=0x03, sequence_timeout=0x06)
|
||||
BOLT_PAIRING_ERRORS = NamedInts(device_timeout=0x01, failed=0x02)
|
||||
"""Known registers.
|
||||
Devices usually have a (small) sub-set of these. Some registers are only
|
||||
applicable to certain device kinds (e.g. smooth_scroll only applies to mice."""
|
||||
REGISTERS = NamedInts(
|
||||
# only apply to receivers
|
||||
receiver_connection=0x02,
|
||||
receiver_pairing=0xB2,
|
||||
devices_activity=0x2B3,
|
||||
receiver_info=0x2B5,
|
||||
bolt_device_discovery=0xC0,
|
||||
bolt_pairing=0x2C1,
|
||||
bolt_uniqueId=0x02FB,
|
||||
|
||||
# only apply to devices
|
||||
mouse_button_flags=0x01,
|
||||
keyboard_hand_detection=0x01,
|
||||
battery_status=0x07,
|
||||
keyboard_fn_swap=0x09,
|
||||
battery_charge=0x0D,
|
||||
keyboard_illumination=0x17,
|
||||
three_leds=0x51,
|
||||
mouse_dpi=0x63,
|
||||
|
||||
# apply to both
|
||||
notifications=0x00,
|
||||
firmware=0xF1,
|
||||
|
||||
# notifications
|
||||
passkey_request_notification=0x4D,
|
||||
passkey_pressed_notification=0x4E,
|
||||
device_discovery_notification=0x4F,
|
||||
discovery_status_notification=0x53,
|
||||
pairing_status_notification=0x54,
|
||||
)
|
||||
# Subregisters for receiver_info register
|
||||
INFO_SUBREGISTERS = NamedInts(
|
||||
serial_number=0x01, # not found on many receivers
|
||||
fw_version=0x02,
|
||||
receiver_information=0x03,
|
||||
pairing_information=0x20, # 0x2N, by connected device
|
||||
extended_pairing_information=0x30, # 0x3N, by connected device
|
||||
device_name=0x40, # 0x4N, by connected device
|
||||
bolt_pairing_information=0x50, # 0x5N, by connected device
|
||||
bolt_device_name=0x60, # 0x6N01, by connected device,
|
||||
)
|
||||
|
||||
# Flags taken from https://drive.google.com/file/d/0BxbRzx7vEV7eNDBheWY0UHM5dEU/view?usp=sharing
|
||||
DEVICE_FEATURES = NamedInts(
|
||||
reserved1=0x010000,
|
||||
special_buttons=0x020000,
|
||||
enhanced_key_usage=0x040000,
|
||||
fast_fw_rev=0x080000,
|
||||
reserved2=0x100000,
|
||||
reserved3=0x200000,
|
||||
scroll_accel=0x400000,
|
||||
buttons_control_resolution=0x800000,
|
||||
inhibit_lock_key_sound=0x000001,
|
||||
reserved4=0x000002,
|
||||
mx_air_3d_engine=0x000004,
|
||||
host_control_leds=0x000008,
|
||||
reserved5=0x000010,
|
||||
reserved6=0x000020,
|
||||
reserved7=0x000040,
|
||||
reserved8=0x000080,
|
||||
)
|
|
@ -173,7 +173,8 @@ class Receiver:
|
|||
if not wpid:
|
||||
logger.error('Unable to get wpid from udev for device %d of %s', n, self)
|
||||
raise exceptions.NoSuchDevice(number=n, receiver=self, error='Not present 27Mhz device')
|
||||
kind = _hidpp10.DEVICE_KIND[self.get_kind_from_index(n)]
|
||||
kind = _hidpp10_constants.DEVICE_KIND[self.get_kind_from_index(n)]
|
||||
|
||||
elif not self.receiver_kind == 'unifying': # unifying protocol not supported, may be an old Nano receiver
|
||||
device_info = self.read_register(_R.receiver_info, 0x04)
|
||||
if device_info:
|
||||
|
@ -197,7 +198,7 @@ class Receiver:
|
|||
return '?', power_switch
|
||||
pair_info = self.read_register(_R.receiver_info, _IR.extended_pairing_information + n - 1)
|
||||
if pair_info:
|
||||
power_switch = _hidpp10.POWER_SWITCH_LOCATION[ord(pair_info[9:10]) & 0x0F]
|
||||
power_switch = _hidpp10_constants.POWER_SWITCH_LOCATION[ord(pair_info[9:10]) & 0x0F]
|
||||
else: # some Nano receivers?
|
||||
pair_info = self.read_register(0x2D5)
|
||||
if pair_info:
|
||||
|
|
|
@ -26,7 +26,7 @@ from time import time as _time
|
|||
from traceback import format_exc as _format_exc
|
||||
|
||||
from . import descriptors as _descriptors
|
||||
from . import hidpp10 as _hidpp10
|
||||
from . import hidpp10_constants as _hidpp10_constants
|
||||
from . import hidpp20 as _hidpp20
|
||||
from . import special_keys as _special_keys
|
||||
from .base import _HIDPP_Notification as _HIDPP_Notification
|
||||
|
@ -58,8 +58,8 @@ from .special_keys import DISABLE as _DKEY
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_DK = _hidpp10.DEVICE_KIND
|
||||
_R = _hidpp10.REGISTERS
|
||||
_DK = _hidpp10_constants.DEVICE_KIND
|
||||
_R = _hidpp10_constants.REGISTERS
|
||||
_F = _hidpp20.FEATURE
|
||||
|
||||
_GG = _hidpp20.GESTURE
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
import logging
|
||||
|
||||
from . import hidpp10 as _hidpp10
|
||||
from . import hidpp20 as _hidpp20
|
||||
from . import hidpp10_constants as _hidpp10_constants
|
||||
from . import hidpp20_constants as _hidpp20_constants
|
||||
from . import settings as _settings
|
||||
from .common import BATTERY_APPROX as _BATTERY_APPROX
|
||||
from .common import NamedInt as _NamedInt
|
||||
|
@ -28,7 +29,7 @@ from .i18n import _, ngettext
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_R = _hidpp10.REGISTERS
|
||||
_R = _hidpp10_constants.REGISTERS
|
||||
|
||||
#
|
||||
#
|
||||
|
@ -154,11 +155,11 @@ class DeviceStatus(dict):
|
|||
# Some notifications may come with no battery level info, just
|
||||
# charging state info, so do our best to infer a level (even if it is just the last level)
|
||||
# It is not always possible to do this well
|
||||
if status == _hidpp20.BATTERY_STATUS.full:
|
||||
if status == _hidpp20_constants.BATTERY_STATUS.full:
|
||||
level = _BATTERY_APPROX.full
|
||||
elif status in (_hidpp20.BATTERY_STATUS.almost_full, _hidpp20.BATTERY_STATUS.recharging):
|
||||
elif status in (_hidpp20_constants.BATTERY_STATUS.almost_full, _hidpp20_constants.BATTERY_STATUS.recharging):
|
||||
level = _BATTERY_APPROX.good
|
||||
elif status == _hidpp20.BATTERY_STATUS.slow_recharge:
|
||||
elif status == _hidpp20_constants.BATTERY_STATUS.slow_recharge:
|
||||
level = _BATTERY_APPROX.low
|
||||
else:
|
||||
level = self.get(KEYS.BATTERY_LEVEL)
|
||||
|
@ -172,15 +173,15 @@ class DeviceStatus(dict):
|
|||
old_voltage, self[KEYS.BATTERY_VOLTAGE] = self.get(KEYS.BATTERY_VOLTAGE), voltage
|
||||
|
||||
charging = status in (
|
||||
_hidpp20.BATTERY_STATUS.recharging, _hidpp20.BATTERY_STATUS.almost_full, _hidpp20.BATTERY_STATUS.full,
|
||||
_hidpp20.BATTERY_STATUS.slow_recharge
|
||||
_hidpp20_constants.BATTERY_STATUS.recharging, _hidpp20_constants.BATTERY_STATUS.almost_full, _hidpp20_constants.BATTERY_STATUS.full,
|
||||
_hidpp20_constants.BATTERY_STATUS.slow_recharge
|
||||
)
|
||||
old_charging, self[KEYS.BATTERY_CHARGING] = self.get(KEYS.BATTERY_CHARGING), charging
|
||||
|
||||
changed = old_level != level or old_status != status or old_charging != charging or old_voltage != voltage
|
||||
alert, reason = ALERT.NONE, None
|
||||
|
||||
if _hidpp20.BATTERY_OK(status) and (level is None or level > _BATTERY_ATTENTION_LEVEL):
|
||||
if _hidpp20_constants.BATTERY_OK(status) and (level is None or level > _BATTERY_ATTENTION_LEVEL):
|
||||
self[KEYS.ERROR] = None
|
||||
else:
|
||||
logger.warning('%s: battery %d%%, ALERT %s', self._device, level, status)
|
||||
|
@ -238,7 +239,7 @@ class DeviceStatus(dict):
|
|||
# when devices request software reconfiguration
|
||||
# and when devices become active if they don't have wireless device status feature,
|
||||
if was_active is None or push or not was_active and (
|
||||
not d.features or _hidpp20.FEATURE.WIRELESS_DEVICE_STATUS not in d.features
|
||||
not d.features or _hidpp20_constants.FEATURE.WIRELESS_DEVICE_STATUS not in d.features
|
||||
):
|
||||
if logger.isEnabledFor(logging.INFO):
|
||||
logger.info('%s pushing device settings %s', d, d.settings)
|
||||
|
|
|
@ -20,10 +20,11 @@ from time import time as _timestamp
|
|||
|
||||
from logitech_receiver import base as _base
|
||||
from logitech_receiver import hidpp10 as _hidpp10
|
||||
from logitech_receiver import hidpp10_constants as _hidpp10_constants
|
||||
from logitech_receiver import notifications as _notifications
|
||||
from logitech_receiver import status as _status
|
||||
|
||||
_R = _hidpp10.REGISTERS
|
||||
_R = _hidpp10_constants.REGISTERS
|
||||
|
||||
|
||||
def run(receivers, args, find_receiver, _ignore):
|
||||
|
@ -42,8 +43,8 @@ def run(receivers, args, find_receiver, _ignore):
|
|||
|
||||
# check if it's necessary to set the notification flags
|
||||
old_notification_flags = _hidpp10.get_notification_flags(receiver) or 0
|
||||
if not (old_notification_flags & _hidpp10.NOTIFICATION_FLAG.wireless):
|
||||
_hidpp10.set_notification_flags(receiver, old_notification_flags | _hidpp10.NOTIFICATION_FLAG.wireless)
|
||||
if not (old_notification_flags & _hidpp10_constants.NOTIFICATION_FLAG.wireless):
|
||||
_hidpp10.set_notification_flags(receiver, old_notification_flags | _hidpp10_constants.NOTIFICATION_FLAG.wireless)
|
||||
|
||||
# get all current devices
|
||||
known_devices = [dev.number for dev in receiver]
|
||||
|
@ -85,7 +86,9 @@ def run(receivers, args, find_receiver, _ignore):
|
|||
kind = receiver.status.device_kind
|
||||
print(f'Bolt Pairing: discovered {name}')
|
||||
receiver.pair_device(
|
||||
address=address, authentication=authentication, entropy=20 if kind == _hidpp10.DEVICE_KIND.keyboard else 10
|
||||
address=address,
|
||||
authentication=authentication,
|
||||
entropy=20 if kind == _hidpp10_constants.DEVICE_KIND.keyboard else 10
|
||||
)
|
||||
pairing_start = _timestamp()
|
||||
patience = 5 # the discovering notification may come slightly later, so be patient
|
||||
|
@ -121,7 +124,7 @@ def run(receivers, args, find_receiver, _ignore):
|
|||
if n:
|
||||
receiver.handle.notifications_hook(n)
|
||||
|
||||
if not (old_notification_flags & _hidpp10.NOTIFICATION_FLAG.wireless):
|
||||
if not (old_notification_flags & _hidpp10_constants.NOTIFICATION_FLAG.wireless):
|
||||
# only clear the flags if they weren't set before, otherwise a
|
||||
# concurrently running Solaar app might stop working properly
|
||||
_hidpp10.set_notification_flags(receiver, old_notification_flags)
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from logitech_receiver import base as _base
|
||||
from logitech_receiver import hidpp10 as _hidpp10
|
||||
from logitech_receiver import hidpp10_constants as _hidpp10_constants
|
||||
from logitech_receiver.common import strhex as _strhex
|
||||
from solaar.cli.show import _print_device, _print_receiver
|
||||
|
||||
_R = _hidpp10.REGISTERS
|
||||
_R = _hidpp10_constants.REGISTERS
|
||||
|
||||
|
||||
def run(receivers, args, find_receiver, _ignore):
|
||||
|
@ -90,9 +90,9 @@ def run(receivers, args, find_receiver, _ignore):
|
|||
last = None
|
||||
for sub in range(0, 0xFF):
|
||||
rgst = _base.request(receiver.handle, 0xFF, 0x8100 | reg, sub, return_error=True)
|
||||
if isinstance(rgst, int) and rgst == _hidpp10.ERROR.invalid_address:
|
||||
if isinstance(rgst, int) and rgst == _hidpp10_constants.ERROR.invalid_address:
|
||||
break
|
||||
elif isinstance(rgst, int) and rgst == _hidpp10.ERROR.invalid_value:
|
||||
elif isinstance(rgst, int) and rgst == _hidpp10_constants.ERROR.invalid_value:
|
||||
continue
|
||||
else:
|
||||
if not isinstance(last, bytes) or not isinstance(rgst, bytes) or last != rgst:
|
||||
|
@ -104,9 +104,9 @@ def run(receivers, args, find_receiver, _ignore):
|
|||
last = None
|
||||
for sub in range(0, 0xFF):
|
||||
rgst = _base.request(receiver.handle, 0xFF, 0x8100 | (0x200 + reg), sub, return_error=True)
|
||||
if isinstance(rgst, int) and rgst == _hidpp10.ERROR.invalid_address:
|
||||
if isinstance(rgst, int) and rgst == _hidpp10_constants.ERROR.invalid_address:
|
||||
break
|
||||
elif isinstance(rgst, int) and rgst == _hidpp10.ERROR.invalid_value:
|
||||
elif isinstance(rgst, int) and rgst == _hidpp10_constants.ERROR.invalid_value:
|
||||
continue
|
||||
else:
|
||||
if not isinstance(last, bytes) or not isinstance(rgst, bytes) or last != rgst:
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
from logitech_receiver import exceptions
|
||||
from logitech_receiver import hidpp10 as _hidpp10
|
||||
from logitech_receiver import hidpp10_constants as _hidpp10_constants
|
||||
from logitech_receiver import hidpp20 as _hidpp20
|
||||
from logitech_receiver import receiver as _receiver
|
||||
from logitech_receiver import settings_templates as _settings_templates
|
||||
|
@ -46,12 +47,12 @@ def _print_receiver(receiver):
|
|||
notification_flags = _hidpp10.get_notification_flags(receiver)
|
||||
if notification_flags is not None:
|
||||
if notification_flags:
|
||||
notification_names = _hidpp10.NOTIFICATION_FLAG.flag_names(notification_flags)
|
||||
notification_names = _hidpp10_constants.NOTIFICATION_FLAG.flag_names(notification_flags)
|
||||
print(' Notifications: %s (0x%06X)' % (', '.join(notification_names), notification_flags))
|
||||
else:
|
||||
print(' Notifications: (none)')
|
||||
|
||||
activity = receiver.read_register(_hidpp10.REGISTERS.devices_activity)
|
||||
activity = receiver.read_register(_hidpp10_constants.REGISTERS.devices_activity)
|
||||
if activity:
|
||||
activity = [(d, ord(activity[d - 1:d])) for d in range(1, receiver.max_devices)]
|
||||
activity_text = ', '.join(('%d=%d' % (d, a)) for d, a in activity if a > 0)
|
||||
|
@ -122,14 +123,14 @@ def _print_device(dev, num=None):
|
|||
notification_flags = _hidpp10.get_notification_flags(dev)
|
||||
if notification_flags is not None:
|
||||
if notification_flags:
|
||||
notification_names = _hidpp10.NOTIFICATION_FLAG.flag_names(notification_flags)
|
||||
notification_names = _hidpp10_constants.NOTIFICATION_FLAG.flag_names(notification_flags)
|
||||
print(' Notifications: %s (0x%06X).' % (', '.join(notification_names), notification_flags))
|
||||
else:
|
||||
print(' Notifications: (none).')
|
||||
device_features = _hidpp10.get_device_features(dev)
|
||||
if device_features is not None:
|
||||
if device_features:
|
||||
device_features_names = _hidpp10.DEVICE_FEATURES.flag_names(device_features)
|
||||
device_features_names = _hidpp10_constants.DEVICE_FEATURES.flag_names(device_features)
|
||||
print(' Features: %s (0x%06X)' % (', '.join(device_features_names), device_features))
|
||||
else:
|
||||
print(' Features: (none)')
|
||||
|
|
Loading…
Reference in New Issue