attach configuration to device settings objects

This commit is contained in:
Daniel Pavel 2013-06-17 08:51:55 +02:00
parent 9d6402a4f7
commit 57c759773a
4 changed files with 28 additions and 74 deletions

View File

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

View File

@ -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

View File

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

View File

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