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
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):

View File

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

View File

@ -152,7 +152,7 @@ def _process_hidpp10_custom_notification(device, status, n):
assert n.data[-1:] == b'\x00'
data = chr(n.address).encode() + n.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
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_next_level = ord(n.data[1:2])
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:
_log.warn("%s: unknown BATTERY %s", device, n)
return True
@ -277,12 +277,12 @@ def _process_feature_notification(device, status, n, feature):
if n.address == 0x00:
status[_K.LIGHT_LEVEL] = None
status.set_battery_info(charge, status_text)
status.set_battery_info(charge, status_text, None)
elif n.address == 0x10:
status[_K.LIGHT_LEVEL] = lux
if lux > 200:
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:
if _log.isEnabledFor(_DEBUG):
_log.debug("%s: Light Check button pressed", device)

View File

@ -47,6 +47,7 @@ KEYS = _NamedInts(
LINK_ENCRYPTED=5,
NOTIFICATION_FLAGS=6,
ERROR=7,
BATTERY_NEXT_LEVEL=8,
)
# If the battery charge is under this percentage, trigger an attention event
@ -170,7 +171,7 @@ class DeviceStatus(dict):
return bool(self._active)
__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):
_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.
old_level, self[KEYS.BATTERY_LEVEL] = self.get(KEYS.BATTERY_LEVEL), level
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,
_hidpp20.BATTERY_STATUS.full, _hidpp20.BATTERY_STATUS.slow_recharge)
@ -237,8 +239,8 @@ class DeviceStatus(dict):
return
if battery is not None:
level, status = battery
self.set_battery_info(level, status)
level, status, nextLevel = battery
self.set_battery_info(level, status, nextLevel)
elif KEYS.BATTERY_STATUS in self:
self[KEYS.BATTERY_STATUS] = None
self[KEYS.BATTERY_CHARGING] = None

View File

@ -25,6 +25,7 @@ from logitech_receiver import (
hidpp20 as _hidpp20,
special_keys as _special_keys,
)
from logitech_receiver.common import NamedInt as _NamedInt
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)
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):
assert dev
@ -173,16 +181,10 @@ def _print_device(dev):
if battery is None:
battery = _hidpp10.get_battery(dev)
if battery is not None:
from logitech_receiver.common import NamedInt as _NamedInt
level, status = battery
if level is not None:
if isinstance(level, _NamedInt):
text = str(level)
else:
text = '%d%%' % level
else:
text = 'N/A'
print (' Battery: %s, %s.' % (text, status))
level, status, nextLevel = battery
text = _battery_text(level)
nextText = '' if nextLevel is None else ', next level ' +_battery_text(nextLevel)
print (' Battery: %s, %s%s.' % (text, status, nextText))
else:
battery_voltage = _hidpp20.get_voltage(dev)
if battery_voltage :

View File

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