From 013f383bc87d267d4ca7e8132fc4aa40c6d4efb8 Mon Sep 17 00:00:00 2001 From: "Peter F. Patel-Schneider" Date: Fri, 5 Jun 2020 06:16:15 -0400 Subject: [PATCH] ui: display battery voltage in ui if available --- lib/logitech_receiver/status.py | 41 ++++++++++++++++++++------------- lib/solaar/ui/window.py | 10 ++++++-- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/lib/logitech_receiver/status.py b/lib/logitech_receiver/status.py index ded08c6e..9bf21612 100644 --- a/lib/logitech_receiver/status.py +++ b/lib/logitech_receiver/status.py @@ -48,6 +48,7 @@ KEYS = _NamedInts( NOTIFICATION_FLAGS=6, ERROR=7, BATTERY_NEXT_LEVEL=8, + BATTERY_VOLTAGE=9, ) # If the battery charge is under this percentage, trigger an attention event @@ -171,7 +172,7 @@ class DeviceStatus(dict): return bool(self._active) __nonzero__ = __bool__ - def set_battery_info(self, level, status, nextLevel=None, timestamp=None): + def set_battery_info(self, level, status, nextLevel=None, voltage=None, timestamp=None): if _log.isEnabledFor(_DEBUG): _log.debug("%s: battery %s, %s", self._device, level, status) @@ -194,6 +195,8 @@ class DeviceStatus(dict): 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 + if voltage is not None: + self[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) @@ -220,6 +223,7 @@ class DeviceStatus(dict): _hidpp10.set_3leds(self._device, level, charging=charging, warning=bool(alert)) self.changed(active=True, alert=alert, reason=reason, timestamp=timestamp) + # Retrieve and regularize battery status def read_battery(self, timestamp=None): if self._active: d = self._device @@ -227,14 +231,17 @@ class DeviceStatus(dict): if d.protocol < 2.0: battery = _hidpp10.get_battery(d) - else: - battery = _hidpp20.get_battery(d) - if battery is None: - v = _hidpp20.get_voltage(d) - if v is not None: - _, charging, status, level, _ = v - status = _hidpp20.BATTERY_STATUS.recharging if status == _hidpp20.BATTERY_STATUS.recharging else _hidpp20.BATTERY_STATUS.discharging - battery = ( level, status, None ) + self.set_battery_keys(battery) + return + + battery = _hidpp20.get_battery(d) + if battery is None: + v = _hidpp20.get_voltage(d) + if v is not None: + voltage, charging, _ignore, level, _ignore = v + status = _hidpp20.BATTERY_STATUS.recharging if charging else _hidpp20.BATTERY_STATUS.discharging + self.set_battery_keys( (level, status, None), voltage) + return # Really unnecessary, if the device has SOLAR_DASHBOARD it should be # broadcasting it's battery status anyway, it will just take a little while. @@ -243,14 +250,16 @@ class DeviceStatus(dict): if battery is None and d.features and _hidpp20.FEATURE.SOLAR_DASHBOARD in d.features: d.feature_request(_hidpp20.FEATURE.SOLAR_DASHBOARD, 0x00, 1, 1) return + self.set_battery_keys(battery) - if battery is not None: - 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 - self.changed() + def set_battery_keys(self, battery, voltage=None) : + if battery is not None: + level, status, nextLevel = battery + self.set_battery_info(level, status, nextLevel, voltage) + elif KEYS.BATTERY_STATUS in self: + self[KEYS.BATTERY_STATUS] = None + self[KEYS.BATTERY_CHARGING] = None + self.changed() def changed(self, active=None, alert=ALERT.NONE, reason=None, timestamp=None): assert self._changed_callback diff --git a/lib/solaar/ui/window.py b/lib/solaar/ui/window.py index ef389f94..d3e3e0c4 100644 --- a/lib/solaar/ui/window.py +++ b/lib/solaar/ui/window.py @@ -619,6 +619,7 @@ def _update_device_panel(device, panel, buttons, full=False): battery_level = device.status.get(_K.BATTERY_LEVEL) battery_next_level = device.status.get(_K.BATTERY_NEXT_LEVEL) + battery_voltage = device.status.get(_K.BATTERY_VOLTAGE) if battery_level is None: icon_name = _icons.battery() @@ -632,7 +633,9 @@ def _update_device_panel(device, panel, buttons, full=False): panel._battery._icon.set_from_icon_name(icon_name, _INFO_ICON_SIZE) panel._battery._icon.set_sensitive(True) - if isinstance(battery_level, _NamedInt): + if battery_voltage is not None: + text = "%(battery_voltage)dmV" % { 'battery_voltage' : battery_voltage } + elif isinstance(battery_level, _NamedInt): text = _(str(battery_level)) else: text = "%(battery_percent)d%%" % { 'battery_percent': battery_level } @@ -819,11 +822,14 @@ def update(device, need_popup=False): _model.set_value(item, _COLUMN.ACTIVE, is_online) battery_level = device.status.get(_K.BATTERY_LEVEL) + battery_voltage = device.status.get(_K.BATTERY_VOLTAGE) if battery_level is None: _model.set_value(item, _COLUMN.STATUS_TEXT, _CAN_SET_ROW_NONE) _model.set_value(item, _COLUMN.STATUS_ICON, _CAN_SET_ROW_NONE) else: - if isinstance(battery_level, _NamedInt): + if battery_voltage is not None: + status_text = "%(battery_voltage)dmV" % { 'battery_voltage' : battery_voltage } + elif isinstance(battery_level, _NamedInt): status_text = _(str(battery_level)) else: status_text = "%(battery_percent)d%%" % { 'battery_percent': battery_level }