device: move battery information from status to Device
This commit is contained in:
parent
0805ecb511
commit
15d425c365
|
@ -605,3 +605,6 @@ class Battery:
|
|||
return _("Battery: %(percent)d%% (%(status)s)") % {"percent": self.level, "status": _(self.status)}
|
||||
else:
|
||||
return ""
|
||||
|
||||
|
||||
ALERT = NamedInts(NONE=0x00, NOTIFICATION=0x01, SHOW_WINDOW=0x02, ATTENTION=0x04, ALL=0xFF)
|
||||
|
|
|
@ -26,6 +26,7 @@ import hidapi as _hid
|
|||
import solaar.configuration as _configuration
|
||||
|
||||
from . import base, descriptors, exceptions, hidpp10, hidpp10_constants, hidpp20
|
||||
from .common import ALERT, Battery
|
||||
from .settings_templates import check_feature_settings as _check_feature_settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -92,6 +93,7 @@ class Device:
|
|||
self._led_effects = self._firmware = self._keys = self._remap_keys = self._gestures = None
|
||||
self._profiles = self._backlight = self._registers = self._settings = None
|
||||
self.notification_flags = None
|
||||
self.battery_info = None
|
||||
|
||||
self._feature_settings_checked = False
|
||||
self._gestures_lock = _threading.Lock()
|
||||
|
@ -351,6 +353,36 @@ class Device:
|
|||
if self.persister and battery_feature is None:
|
||||
self.persister["_battery"] = result
|
||||
|
||||
def set_battery_info(self, info):
|
||||
"""Update battery information for device, calling changed callback if necessary"""
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("%s: battery %s, %s", self, info.level, info.status)
|
||||
if info.level is None and self.battery_info: # use previous level if missing from new information
|
||||
info.level = self.battery_info.level
|
||||
|
||||
changed = self.battery_info != info
|
||||
print("SBI", changed, info, self.battery_info)
|
||||
self.battery_info, old_info = info, self.battery_info
|
||||
|
||||
alert, reason = ALERT.NONE, None
|
||||
if not info.ok():
|
||||
logger.warning("%s: battery %d%%, ALERT %s", self, info.level, info.status)
|
||||
if old_info.status != info.status:
|
||||
alert = ALERT.NOTIFICATION | ALERT.ATTENTION
|
||||
reason = info.to_str()
|
||||
|
||||
if changed or reason:
|
||||
# update the leds on the device, if any
|
||||
_hidpp10.set_3leds(self, info.level, charging=info.charging(), warning=bool(alert))
|
||||
if hasattr(self, "status"):
|
||||
self.status.changed(active=True, alert=alert, reason=reason)
|
||||
|
||||
# Retrieve and regularize battery status
|
||||
def read_battery(self):
|
||||
if self.online:
|
||||
battery = self.battery()
|
||||
self.set_battery_info(battery if battery is not None else Battery(None, None, None, None))
|
||||
|
||||
def enable_connection_notifications(self, enable=True):
|
||||
"""Enable or disable device (dis)connection notifications on this
|
||||
receiver."""
|
||||
|
@ -464,7 +496,7 @@ class Device:
|
|||
__nonzero__ = __bool__
|
||||
|
||||
def status_string(self):
|
||||
return self.status.battery.to_str() if hasattr(self, "status") and self.status.battery is not None else ""
|
||||
return self.battery_info.to_str() if hasattr(self, "status") and self.battery_info is not None else ""
|
||||
|
||||
def __str__(self):
|
||||
try:
|
||||
|
|
|
@ -222,7 +222,7 @@ def _process_hidpp10_custom_notification(device, status, n):
|
|||
if n.sub_id in (_R.battery_status, _R.battery_charge):
|
||||
assert n.data[-1:] == b"\x00"
|
||||
data = chr(n.address).encode() + n.data
|
||||
status.set_battery_info(hidpp10.parse_battery_status(n.sub_id, data))
|
||||
device.set_battery_info(hidpp10.parse_battery_status(n.sub_id, data))
|
||||
return True
|
||||
|
||||
logger.warning("%s: unrecognized %s", device, n)
|
||||
|
@ -295,7 +295,7 @@ def _process_feature_notification(device, status, n, feature):
|
|||
|
||||
if feature == _F.BATTERY_STATUS:
|
||||
if n.address == 0x00:
|
||||
status.set_battery_info(hidpp20.decipher_battery_status(n.data)[1])
|
||||
device.set_battery_info(hidpp20.decipher_battery_status(n.data)[1])
|
||||
elif n.address == 0x10:
|
||||
if logger.isEnabledFor(logging.INFO):
|
||||
logger.info("%s: spurious BATTERY status %s", device, n)
|
||||
|
@ -304,13 +304,13 @@ def _process_feature_notification(device, status, n, feature):
|
|||
|
||||
elif feature == _F.BATTERY_VOLTAGE:
|
||||
if n.address == 0x00:
|
||||
status.set_battery_info(hidpp20.decipher_battery_voltage(n.data)[1])
|
||||
device.set_battery_info(hidpp20.decipher_battery_voltage(n.data)[1])
|
||||
else:
|
||||
logger.warning("%s: unknown VOLTAGE %s", device, n)
|
||||
|
||||
elif feature == _F.UNIFIED_BATTERY:
|
||||
if n.address == 0x00:
|
||||
status.set_battery_info(hidpp20.decipher_battery_unified(n.data)[1])
|
||||
device.set_battery_info(hidpp20.decipher_battery_unified(n.data)[1])
|
||||
else:
|
||||
logger.warning("%s: unknown UNIFIED BATTERY %s", device, n)
|
||||
|
||||
|
@ -318,7 +318,7 @@ def _process_feature_notification(device, status, n, feature):
|
|||
if n.address == 0x00:
|
||||
result = hidpp20.decipher_adc_measurement(n.data)
|
||||
if result:
|
||||
status.set_battery_info(result[1])
|
||||
device.set_battery_info(result[1])
|
||||
else: # this feature is used to signal device becoming inactive
|
||||
status.changed(active=False)
|
||||
else:
|
||||
|
@ -331,11 +331,11 @@ def _process_feature_notification(device, status, n, feature):
|
|||
# status_text = '%1.2fV' % (adc * 2.67793237653 / 0x0672)
|
||||
status_text = _Battery.STATUS.discharging
|
||||
if n.address == 0x00:
|
||||
status.set_battery_info(_Battery(charge, None, status_text, None))
|
||||
device.set_battery_info(_Battery(charge, None, status_text, None))
|
||||
elif n.address == 0x10:
|
||||
if lux > 200:
|
||||
status_text = _Battery.STATUS.recharging
|
||||
status.set_battery_info(_Battery(charge, None, status_text, None, lux))
|
||||
device.set_battery_info(_Battery(charge, None, status_text, None, lux))
|
||||
elif n.address == 0x20:
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("%s: Light Check button pressed", device)
|
||||
|
|
|
@ -21,7 +21,7 @@ from . import hidpp10
|
|||
from . import hidpp10_constants as _hidpp10_constants
|
||||
from . import hidpp20_constants as _hidpp20_constants
|
||||
from . import settings as _settings
|
||||
from .common import Battery, NamedInts
|
||||
from .common import NamedInts
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -52,19 +52,6 @@ class ReceiverStatus:
|
|||
assert changed_callback
|
||||
self._changed_callback = changed_callback
|
||||
|
||||
# self.notification_flags = None
|
||||
# self.error = None
|
||||
|
||||
# self.lock_open = False
|
||||
# self.discovering = False
|
||||
# self.counter = None
|
||||
# self.device_address = None
|
||||
# self.device_authentication = None
|
||||
# self.device_kind = None
|
||||
# self.device_name = None
|
||||
# self.device_passkey = None
|
||||
# self.new_device = None
|
||||
|
||||
def changed(self, alert=ALERT.NOTIFICATION, reason=None):
|
||||
self._changed_callback(self._receiver, alert=alert, reason=reason)
|
||||
|
||||
|
@ -81,46 +68,13 @@ class DeviceStatus:
|
|||
assert changed_callback
|
||||
self._changed_callback = changed_callback
|
||||
self._active = None # is the device active?
|
||||
self.battery = None
|
||||
self.link_encrypted = None
|
||||
# self.notification_flags = None
|
||||
self.battery_error = None
|
||||
|
||||
def __bool__(self):
|
||||
return bool(self._active)
|
||||
|
||||
__nonzero__ = __bool__
|
||||
|
||||
def set_battery_info(self, info):
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug("%s: battery %s, %s", self._device, info.level, info.status)
|
||||
if info.level is None and self.battery: # use previous level if missing from new information
|
||||
info.level = self.battery.level
|
||||
|
||||
changed = self.battery != info
|
||||
self.battery = info
|
||||
|
||||
alert, reason = ALERT.NONE, None
|
||||
if info.ok():
|
||||
self.battery_error = None
|
||||
else:
|
||||
logger.warning("%s: battery %d%%, ALERT %s", self._device, info.level, info.status)
|
||||
if self.battery_error != info.status:
|
||||
self.battery_error = info.status
|
||||
alert = ALERT.NOTIFICATION | ALERT.ATTENTION
|
||||
reason = info.to_str()
|
||||
|
||||
if changed or reason or not self._active: # a battery response means device is active
|
||||
# update the leds on the device, if any
|
||||
_hidpp10.set_3leds(self._device, info.level, charging=info.charging(), warning=bool(alert))
|
||||
self.changed(active=True, alert=alert, reason=reason)
|
||||
|
||||
# Retrieve and regularize battery status
|
||||
def read_battery(self):
|
||||
if self._active:
|
||||
battery = self._device.battery()
|
||||
self.set_battery_info(battery if battery is not None else Battery(None, None, None, None))
|
||||
|
||||
def changed(self, active=None, alert=ALERT.NONE, reason=None, push=False):
|
||||
d = self._device
|
||||
|
||||
|
@ -135,7 +89,7 @@ class DeviceStatus:
|
|||
if d.protocol < 2.0:
|
||||
self._device.notification_flags = d.enable_connection_notifications()
|
||||
# battery information may have changed so try to read it now
|
||||
self.read_battery()
|
||||
self._device.read_battery()
|
||||
|
||||
# Push settings for new devices when devices request software reconfiguration
|
||||
# and when devices become active if they don't have wireless device status feature,
|
||||
|
|
|
@ -197,9 +197,8 @@ try:
|
|||
def _update_tray_icon():
|
||||
if _picked_device and gtk.battery_icons_style != "solaar":
|
||||
_ignore, _ignore, name, device = _picked_device
|
||||
device_status = device.status
|
||||
battery_level = device_status.battery.level if device_status.battery is not None else None
|
||||
battery_charging = device_status.battery.charging() if device_status.battery is not None else None
|
||||
battery_level = device.battery_info.level if device.battery_info is not None else None
|
||||
battery_charging = device.battery_info.charging() if device.battery_info is not None else None
|
||||
tray_icon_name = _icons.battery(battery_level, battery_charging)
|
||||
|
||||
description = "%s: %s" % (name, device.status_string())
|
||||
|
@ -252,9 +251,9 @@ except ImportError:
|
|||
_icon.set_tooltip_markup(tooltip)
|
||||
|
||||
if _picked_device and gtk.battery_icons_style != "solaar":
|
||||
_ignore, _ignore, name, device_status = _picked_device
|
||||
battery_level = device_status.battery.level if device_status.battery is not None else None
|
||||
battery_charging = device_status.battery.charging() if device_status.battery is not None else None
|
||||
_ignore, _ignore, name, device = _picked_device
|
||||
battery_level = device.battery_info.level if device.battery_info is not None else None
|
||||
battery_charging = device.battery_info.charging() if device.battery_info is not None else None
|
||||
tray_icon_name = _icons.battery(battery_level, battery_charging)
|
||||
else:
|
||||
# there may be a receiver, but no peripherals
|
||||
|
@ -331,7 +330,7 @@ def _pick_device_with_lowest_battery():
|
|||
for info in _devices_info:
|
||||
if info[1] is None: # is receiver
|
||||
continue
|
||||
level = info[-1].status.battery.level if hasattr(info[-1], "status") and info[-1].status.battery is not None else None
|
||||
level = info[-1].battery_info.level if hasattr(info[-1], "status") and info[-1].battery_info is not None else None
|
||||
# print ("checking %s -> %s", info, level)
|
||||
if level is not None and picked_level > level:
|
||||
picked = info
|
||||
|
@ -428,8 +427,8 @@ def _update_menu_item(index, device):
|
|||
menu_items = _menu.get_children()
|
||||
menu_item = menu_items[index]
|
||||
|
||||
level = device.status.battery.level if device.status.battery is not None else None
|
||||
charging = device.status.battery.charging() if device.status.battery is not None else None
|
||||
level = device.battery_info.level if device.battery_info is not None else None
|
||||
charging = device.battery_info.charging() if device.battery_info is not None else None
|
||||
icon_name = _icons.battery(level, charging)
|
||||
|
||||
menu_item.set_label((" " if 0 < device.number <= 6 else "") + device.name + ": " + device.status_string())
|
||||
|
|
|
@ -682,17 +682,17 @@ def _update_device_panel(device, panel, buttons, full=False):
|
|||
is_online = bool(device.online)
|
||||
panel.set_sensitive(is_online)
|
||||
|
||||
if device.status.battery is None or device.status.battery.level is None:
|
||||
device.status.read_battery()
|
||||
if device.battery_info is None or device.battery_info.level is None:
|
||||
device.read_battery()
|
||||
|
||||
battery_level = device.status.battery.level if device.status.battery is not None else None
|
||||
battery_voltage = device.status.battery.voltage if device.status.battery is not None else None
|
||||
battery_level = device.battery_info.level if device.battery_info is not None else None
|
||||
battery_voltage = device.battery_info.voltage if device.battery_info is not None else None
|
||||
if battery_level is None and battery_voltage is None:
|
||||
panel._battery.set_visible(False)
|
||||
else:
|
||||
panel._battery.set_visible(True)
|
||||
battery_next_level = device.status.battery.next_level
|
||||
charging = device.status.battery.charging() if device.status.battery is not None else None
|
||||
battery_next_level = device.battery_info.next_level
|
||||
charging = device.battery_info.charging() if device.battery_info is not None else None
|
||||
icon_name = _icons.battery(battery_level, charging)
|
||||
panel._battery._icon.set_from_icon_name(icon_name, _INFO_ICON_SIZE)
|
||||
panel._battery._icon.set_sensitive(True)
|
||||
|
@ -750,7 +750,7 @@ def _update_device_panel(device, panel, buttons, full=False):
|
|||
panel._secure.set_tooltip_text("")
|
||||
|
||||
if is_online:
|
||||
light_level = device.status.battery.light_level if device.status.battery is not None else None
|
||||
light_level = device.battery_info.light_level if device.battery_info is not None else None
|
||||
if light_level is None:
|
||||
panel._lux.set_visible(False)
|
||||
else:
|
||||
|
@ -906,8 +906,8 @@ def update_device(device, item, selected_device_id, need_popup, full=False):
|
|||
is_online = bool(device.online)
|
||||
_model.set_value(item, _COLUMN.ACTIVE, is_online)
|
||||
|
||||
battery_level = device.status.battery.level if device.status.battery is not None else None
|
||||
battery_voltage = device.status.battery.voltage if device.status.battery is not None else None
|
||||
battery_level = device.battery_info.level if device.battery_info is not None else None
|
||||
battery_voltage = device.battery_info.voltage if device.battery_info is not None else None
|
||||
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)
|
||||
|
@ -920,7 +920,7 @@ def update_device(device, item, selected_device_id, need_popup, full=False):
|
|||
status_text = "%(battery_percent)d%%" % {"battery_percent": battery_level}
|
||||
_model.set_value(item, _COLUMN.STATUS_TEXT, status_text)
|
||||
|
||||
charging = device.status.battery.charging() if device.status.battery is not None else None
|
||||
charging = device.battery_info.charging() if device.battery_info is not None else None
|
||||
icon_name = _icons.battery(battery_level, charging)
|
||||
_model.set_value(item, _COLUMN.STATUS_ICON, icon_name)
|
||||
|
||||
|
|
Loading…
Reference in New Issue