receiver: gather and show battery next level where available

This commit is contained in:
Peter F. Patel-Schneider 2020-05-17 19:22:40 -04:00
parent d41c35b1c6
commit 79947dca6c
6 changed files with 31 additions and 19 deletions

View File

@ -215,7 +215,8 @@ def parse_battery_status(register, reply):
# some 'charging' notifications may come with no battery level information # some 'charging' notifications may come with no battery level information
charge = None charge = None
return charge, status_text # Return None for next charge level as this is not in HID++ 1.0 spec
return charge, status_text, None
def get_firmware(device): def get_firmware(device):

View File

@ -524,7 +524,7 @@ def get_battery(device):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("device %d battery %d%% charged, next level %d%% charge, status %d = %s", _log.debug("device %d battery %d%% charged, next level %d%% charge, status %d = %s",
device.number, discharge, dischargeNext, status, BATTERY_STATUS[status]) device.number, discharge, dischargeNext, status, BATTERY_STATUS[status])
return discharge, BATTERY_STATUS[status] return discharge, BATTERY_STATUS[status], dischargeNext
def get_voltage(device): def get_voltage(device):

View File

@ -152,7 +152,7 @@ def _process_hidpp10_custom_notification(device, status, n):
assert n.data[-1:] == b'\x00' assert n.data[-1:] == b'\x00'
data = chr(n.address).encode() + n.data data = chr(n.address).encode() + n.data
charge, status_text = _hidpp10.parse_battery_status(n.sub_id, data) charge, status_text = _hidpp10.parse_battery_status(n.sub_id, data)
status.set_battery_info(charge, status_text) status.set_battery_info(charge, status_text, None)
return True return True
if n.sub_id == _R.keyboard_illumination: if n.sub_id == _R.keyboard_illumination:
@ -242,7 +242,7 @@ def _process_feature_notification(device, status, n, feature):
discharge_level = None if discharge_level == 0 else discharge_level discharge_level = None if discharge_level == 0 else discharge_level
discharge_next_level = ord(n.data[1:2]) discharge_next_level = ord(n.data[1:2])
battery_status = ord(n.data[2:3]) battery_status = ord(n.data[2:3])
status.set_battery_info(discharge_level, _hidpp20.BATTERY_STATUS[battery_status]) status.set_battery_info(discharge_level, _hidpp20.BATTERY_STATUS[battery_status], 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
@ -277,12 +277,12 @@ def _process_feature_notification(device, status, n, feature):
if n.address == 0x00: if n.address == 0x00:
status[_K.LIGHT_LEVEL] = None status[_K.LIGHT_LEVEL] = None
status.set_battery_info(charge, status_text) status.set_battery_info(charge, status_text, None)
elif n.address == 0x10: elif n.address == 0x10:
status[_K.LIGHT_LEVEL] = lux status[_K.LIGHT_LEVEL] = lux
if lux > 200: if lux > 200:
status_text = _hidpp20.BATTERY_STATUS.recharging status_text = _hidpp20.BATTERY_STATUS.recharging
status.set_battery_info(charge, status_text) 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)

View File

@ -47,6 +47,7 @@ KEYS = _NamedInts(
LINK_ENCRYPTED=5, LINK_ENCRYPTED=5,
NOTIFICATION_FLAGS=6, NOTIFICATION_FLAGS=6,
ERROR=7, ERROR=7,
BATTERY_NEXT_LEVEL=8,
) )
# If the battery charge is under this percentage, trigger an attention event # If the battery charge is under this percentage, trigger an attention event
@ -170,7 +171,7 @@ class DeviceStatus(dict):
return bool(self._active) return bool(self._active)
__nonzero__ = __bool__ __nonzero__ = __bool__
def set_battery_info(self, level, status, timestamp=None): def set_battery_info(self, level, status, nextLevel=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)
@ -192,6 +193,7 @@ class DeviceStatus(dict):
# TODO: this is also executed when pressing Fn+F7 on K800. # TODO: this is also executed when pressing Fn+F7 on K800.
old_level, self[KEYS.BATTERY_LEVEL] = self.get(KEYS.BATTERY_LEVEL), level old_level, self[KEYS.BATTERY_LEVEL] = self.get(KEYS.BATTERY_LEVEL), level
old_status, self[KEYS.BATTERY_STATUS] = self.get(KEYS.BATTERY_STATUS), status old_status, self[KEYS.BATTERY_STATUS] = self.get(KEYS.BATTERY_STATUS), status
self[KEYS.BATTERY_NEXT_LEVEL] = nextLevel
charging = status in (_hidpp20.BATTERY_STATUS.recharging, _hidpp20.BATTERY_STATUS.almost_full, charging = status in (_hidpp20.BATTERY_STATUS.recharging, _hidpp20.BATTERY_STATUS.almost_full,
_hidpp20.BATTERY_STATUS.full, _hidpp20.BATTERY_STATUS.slow_recharge) _hidpp20.BATTERY_STATUS.full, _hidpp20.BATTERY_STATUS.slow_recharge)
@ -237,8 +239,8 @@ class DeviceStatus(dict):
return return
if battery is not None: if battery is not None:
level, status = battery level, status, nextLevel = battery
self.set_battery_info(level, status) self.set_battery_info(level, status, nextLevel)
elif KEYS.BATTERY_STATUS in self: elif KEYS.BATTERY_STATUS in self:
self[KEYS.BATTERY_STATUS] = None self[KEYS.BATTERY_STATUS] = None
self[KEYS.BATTERY_CHARGING] = None self[KEYS.BATTERY_CHARGING] = None

View File

@ -25,6 +25,7 @@ from logitech_receiver import (
hidpp20 as _hidpp20, hidpp20 as _hidpp20,
special_keys as _special_keys, special_keys as _special_keys,
) )
from logitech_receiver.common import NamedInt as _NamedInt
def _print_receiver(receiver): def _print_receiver(receiver):
@ -56,6 +57,13 @@ def _print_receiver(receiver):
activity_text = ', '.join(('%d=%d' % (d, a)) for d, a in activity if a > 0) activity_text = ', '.join(('%d=%d' % (d, a)) for d, a in activity if a > 0)
print (' Device activity counters:', activity_text or '(empty)') print (' Device activity counters:', activity_text or '(empty)')
def _battery_text(level) :
if level is None:
return 'N/A'
elif isinstance(level, _NamedInt):
return str(level)
else:
return '%d%%' % level
def _print_device(dev): def _print_device(dev):
assert dev assert dev
@ -173,16 +181,10 @@ def _print_device(dev):
if battery is None: if battery is None:
battery = _hidpp10.get_battery(dev) battery = _hidpp10.get_battery(dev)
if battery is not None: if battery is not None:
from logitech_receiver.common import NamedInt as _NamedInt level, status, nextLevel = battery
level, status = battery text = _battery_text(level)
if level is not None: nextText = '' if nextLevel is None else ', next level ' +_battery_text(nextLevel)
if isinstance(level, _NamedInt): print (' Battery: %s, %s%s.' % (text, status, nextText))
text = str(level)
else:
text = '%d%%' % level
else:
text = 'N/A'
print (' Battery: %s, %s.' % (text, status))
else: else:
battery_voltage = _hidpp20.get_voltage(dev) battery_voltage = _hidpp20.get_voltage(dev)
if battery_voltage : if battery_voltage :

View File

@ -618,6 +618,8 @@ def _update_device_panel(device, panel, buttons, full=False):
panel.set_sensitive(is_online) panel.set_sensitive(is_online)
battery_level = device.status.get(_K.BATTERY_LEVEL) battery_level = device.status.get(_K.BATTERY_LEVEL)
battery_next_level = device.status.get(_K.BATTERY_NEXT_LEVEL)
if battery_level is None: if battery_level is None:
icon_name = _icons.battery() icon_name = _icons.battery()
panel._battery._icon.set_sensitive(False) panel._battery._icon.set_sensitive(False)
@ -634,6 +636,11 @@ def _update_device_panel(device, panel, buttons, full=False):
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 isinstance(battery_next_level, _NamedInt):
text += "<small> (" +_("next ") + _(str(battery_next_level)) + ")</small>"
else:
text += "<small> (" + _("next ") + ( "%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")