initial support for performance mx leds

The leds light up when we get updates about the battery level.
Right now they are not (programatically) turned off.
This commit is contained in:
Daniel Pavel 2013-06-23 19:19:32 +02:00
parent 70c341e268
commit 20dfc063ff
3 changed files with 60 additions and 6 deletions

View File

@ -75,6 +75,10 @@ def _D(name, codename=None, kind=None, product_id=None, protocol=None, registers
codename = name.split(' ')[-1]
assert codename is not None, "descriptor for %s does not have codename set" % name
if protocol is not None:
# ? 2.0 devices should not have any registers
assert protocol < 2.0 or registers is None
DEVICES[codename] = _DeviceDescriptor(
name=name,
kind=kind,
@ -183,7 +187,7 @@ _D('Anywhere Mouse MX', codename='Anywhere MX',
# ],
)
_D('Performance Mouse MX', codename='Performance MX', protocol=1.0,
registers={'battery_charge': -0x0D, 'battery_status': 0x07},
registers={'battery_charge': -0x0D, 'battery_status': 0x07, 'leds': 0x51},
settings=[
_register_dpi(0x63, _NamedInts.range(0x81, 0x8F, lambda x: str((x - 0x80) * 100))),
],

View File

@ -81,6 +81,13 @@ PAIRING_ERRORS = _NamedInts(
too_many_devices=0x03,
sequence_timeout=0x06)
BATTERY_APPOX = _NamedInts(
empty = 0,
critical = 5,
low = 20,
good = 50,
full = 90)
#
# functions
#
@ -151,11 +158,11 @@ def parse_battery_reply_0D(level, battery_status):
return charge, status
def parse_battery_reply_07(level, battery_status):
charge = (90 if level == 7 # full
else 50 if level == 5 # good
else 20 if level == 3 # low
else 5 if level == 1 # critical
else 0 ) # wtf?
charge = (BATTERY_APPOX.full if level == 7 # full
else BATTERY_APPOX.good if level == 5 # good
else BATTERY_APPOX.low if level == 3 # low
else BATTERY_APPOX.critical if level == 1 # critical
else BATTERY_APPOX.empty ) # wtf?
status = ('charging' if battery_status == 0x21 or battery_status == 0x25
else 'fully charged' if battery_status == 0x22
else 'discharging' if battery_status == 0x00
@ -208,6 +215,47 @@ def get_firmware(device):
return tuple(f for f in firmware if f)
def set_3leds(device, battery_level=None, charging=None, warning=None):
assert device
assert device.kind is not None
if not device.online:
return
leds_register = device.registers.get('leds')
if leds_register is None or leds_register < 0:
return
if battery_level is not None:
if battery_level < BATTERY_APPOX.critical:
# 1 orange, and force blink
v1, v2 = 0x22, 0x00
warning = True
elif battery_level < BATTERY_APPOX.low:
# 1 orange
v1, v2 = 0x22, 0x00
elif battery_level < BATTERY_APPOX.good:
# 1 green
v1, v2 = 0x20, 0x00
elif battery_level < BATTERY_APPOX.full:
# 2 greens
v1, v2 = 0x20, 0x02
else:
# all 3 green
v1, v2 = 0x20, 0x22
if warning:
# set the blinking flag for the leds already set
v1 |= (v1 >> 1)
v2 |= (v2 >> 1)
elif warning:
# 1 red
v1, v2 = 0x02, 0x00
else:
# turn off all leds
v1, v2 = 0x11, 0x11
write_register(device, leds_register, v1, v2)
def get_notification_flags(device):
assert device

View File

@ -187,6 +187,8 @@ class DeviceStatus(dict):
reason = 'Battery: %d%% (%s)' % (level, status)
if changed or reason:
# update the leds on the device, if any
_hidpp10.set_3leds(self._device, level, charging=charging, warning=bool(alert))
self._changed(alert=alert, reason=reason, timestamp=timestamp)
def read_battery(self, timestamp=None):