attach configuration to device settings objects
This commit is contained in:
parent
9d6402a4f7
commit
57c759773a
|
@ -16,9 +16,8 @@ from .common import NamedInt as _NamedInt, NamedInts as _NamedInts
|
|||
KIND = _NamedInts(toggle=0x1, choice=0x02, range=0x12)
|
||||
|
||||
class _Setting(object):
|
||||
__slots__ = ['name', 'label', 'description',
|
||||
'kind', '_rw', '_validator',
|
||||
'_device', '_value']
|
||||
__slots__ = ['name', 'label', 'description', 'kind', 'persister',
|
||||
'_rw', '_validator', '_device', '_value']
|
||||
|
||||
def __init__(self, name, rw, validator, kind=None, label=None, description=None):
|
||||
assert name
|
||||
|
@ -31,6 +30,7 @@ class _Setting(object):
|
|||
|
||||
assert kind is None or kind & validator.kind != 0
|
||||
self.kind = kind or validator.kind
|
||||
self.persister = None
|
||||
|
||||
def __call__(self, device):
|
||||
o = _copy(self)
|
||||
|
@ -43,14 +43,17 @@ class _Setting(object):
|
|||
return self._validator.choices if self._validator.kind & KIND.choice else None
|
||||
|
||||
def read(self, cached=True):
|
||||
if cached and self._value is not None:
|
||||
if self.persister and self.name not in self.persister:
|
||||
self.persister[self.name] = self._value
|
||||
return self._value
|
||||
|
||||
if self._device:
|
||||
if self._value is None or not cached:
|
||||
reply = self._rw.read(self._device)
|
||||
# print ("read reply", repr(reply))
|
||||
if reply:
|
||||
# print ("pre-read", self._value)
|
||||
self._value = self._validator.validate_read(reply)
|
||||
# print ("post-read", self._value)
|
||||
reply = self._rw.read(self._device)
|
||||
if reply:
|
||||
self._value = self._validator.validate_read(reply)
|
||||
if self.persister and self.name not in self.persister:
|
||||
self.persister[self.name] = self._value
|
||||
return self._value
|
||||
|
||||
def write(self, value):
|
||||
|
@ -59,6 +62,8 @@ class _Setting(object):
|
|||
reply = self._rw.write(self._device, data_bytes)
|
||||
if reply:
|
||||
self._value = self._validator.validate_write(value, reply)
|
||||
if self.persister and self._value is not None:
|
||||
self.persister[self.name] = self._value
|
||||
return self._value
|
||||
|
||||
def __str__(self):
|
||||
|
|
|
@ -218,9 +218,8 @@ class DeviceStatus(dict):
|
|||
# get cleared when the device is turned off (but not when the device
|
||||
# goes idle, and we can't tell the difference right now).
|
||||
d.enable_notifications()
|
||||
d.settings, None
|
||||
if self.configuration:
|
||||
self.configuration.apply_to(d)
|
||||
self.configuration.attach_to(d)
|
||||
else:
|
||||
if was_active:
|
||||
battery = self.get(BATTERY_LEVEL)
|
||||
|
@ -229,8 +228,6 @@ class DeviceStatus(dict):
|
|||
# to change much while the device is offline.
|
||||
if battery is not None:
|
||||
self[BATTERY_LEVEL] = battery
|
||||
if self.configuration:
|
||||
self.configuration.acquire_from(d)
|
||||
|
||||
if self.updated == 0 and active:
|
||||
# if the device is active on the very first status notification,
|
||||
|
@ -360,7 +357,7 @@ class DeviceStatus(dict):
|
|||
_log.warn("%s: connection notification with unknown protocol %02X: %s", self._device.number, n.address, n)
|
||||
|
||||
# if the device just came online, read the battery charge
|
||||
if self._active: # and BATTERY_LEVEL not in self:
|
||||
if self._active and BATTERY_LEVEL not in self:
|
||||
self.read_battery()
|
||||
|
||||
return True
|
||||
|
|
|
@ -67,6 +67,7 @@ def all():
|
|||
def _device_key(device):
|
||||
return '%s:%s' % (device.serial, device.kind)
|
||||
|
||||
|
||||
def _device_entry(device):
|
||||
if not _configuration:
|
||||
_load()
|
||||
|
@ -81,66 +82,17 @@ def _device_entry(device):
|
|||
return c
|
||||
|
||||
|
||||
def set(key, value):
|
||||
set(None, key, value)
|
||||
|
||||
|
||||
def get(key, default_value=None):
|
||||
return
|
||||
|
||||
|
||||
def set_device(device, key, value):
|
||||
_device_entry(device)[key] = value
|
||||
|
||||
|
||||
def get_device(device, key, default_value=None):
|
||||
return _device_entry(device).get(key, default_value)
|
||||
|
||||
|
||||
def apply_to(device):
|
||||
def attach_to(device):
|
||||
"""Apply the last saved configuration to a device."""
|
||||
if not _configuration:
|
||||
_load()
|
||||
|
||||
entry = _device_entry(device)
|
||||
if _log.isEnabledFor(_DEBUG):
|
||||
_log.debug("applying %s to %s", entry, device)
|
||||
|
||||
persister = _device_entry(device)
|
||||
for s in device.settings:
|
||||
value = s.read()
|
||||
if s.name in entry:
|
||||
if value is None:
|
||||
del entry[s.name]
|
||||
elif value != entry[s.name]:
|
||||
s.write(entry[s.name])
|
||||
if s.persister is None:
|
||||
s.persister = persister
|
||||
assert s.persister == persister
|
||||
if s.name in persister:
|
||||
s.write(persister[s.name])
|
||||
else:
|
||||
entry[s.name] = value
|
||||
|
||||
|
||||
def acquire_from(device):
|
||||
"""Read the values of all the settings a device has, and save them."""
|
||||
if not _configuration:
|
||||
_load()
|
||||
|
||||
entry = _device_entry(device)
|
||||
for s in device.settings:
|
||||
value = s.read()
|
||||
if value is not None:
|
||||
entry[s.name] = value
|
||||
|
||||
if _log.isEnabledFor(_DEBUG):
|
||||
_log.debug("acquired %s from %s", entry, device)
|
||||
|
||||
save()
|
||||
|
||||
|
||||
def forget(device):
|
||||
if not _configuration:
|
||||
_load()
|
||||
|
||||
if _log.isEnabledFor(_DEBUG):
|
||||
_log.debug("forgetting %s", device)
|
||||
|
||||
device_key = _device_key(device)
|
||||
if device_key in _configuration:
|
||||
del _configuration[device_key]
|
||||
persister[s.name] = s.read(cached=False)
|
||||
|
|
|
@ -186,11 +186,11 @@ def update(frame):
|
|||
if device.status:
|
||||
items = list(_add_settings(box, device))
|
||||
assert len(device.settings) == len(items)
|
||||
force_read = True
|
||||
# force_read = True
|
||||
|
||||
device_active = bool(device.status)
|
||||
# if the device just became active, re-read the settings
|
||||
force_read |= device_active and not box.get_sensitive()
|
||||
# force_read |= device_active and not box.get_sensitive()
|
||||
box.set_sensitive(device_active)
|
||||
if device_active:
|
||||
for sbox, s in zip(items, device.settings):
|
||||
|
|
Loading…
Reference in New Issue