code clean-ups, the app starts faster now

This commit is contained in:
Daniel Pavel 2012-12-01 15:49:52 +02:00
parent 89c6904d69
commit 8f5fa0cf9a
12 changed files with 134 additions and 125 deletions

View File

@ -6,8 +6,9 @@ from logging import getLogger, DEBUG as _DEBUG
_log = getLogger('listener') _log = getLogger('listener')
del getLogger del getLogger
from logitech.unifying_receiver import ( from types import MethodType as _MethodType
Receiver, PairedDevice,
from logitech.unifying_receiver import (Receiver,
listener as _listener, listener as _listener,
hidpp10 as _hidpp10, hidpp10 as _hidpp10,
hidpp20 as _hidpp20, hidpp20 as _hidpp20,
@ -35,16 +36,6 @@ DUMMY = _DUMMY_RECEIVER()
_DEVICE_STATUS_POLL = 30 # seconds _DEVICE_STATUS_POLL = 30 # seconds
_DEVICE_TIMEOUT = 2 * _DEVICE_STATUS_POLL # seconds _DEVICE_TIMEOUT = 2 * _DEVICE_STATUS_POLL # seconds
# def _fake_device(listener):
# dev = _lur.PairedDevice(listener.receiver, 6)
# dev._wpid = '1234'
# dev._kind = 'touchpad'
# dev._codename = 'T650'
# dev._name = 'Wireless Rechargeable Touchpad T650'
# dev._serial = '0123456789'
# dev._protocol = 2.0
# dev.status = _lur.status.DeviceStatus(dev, listener._status_changed)
# return dev
class ReceiverListener(_listener.EventsListener): class ReceiverListener(_listener.EventsListener):
"""Keeps the status of a Unifying Receiver. """Keeps the status of a Unifying Receiver.
@ -57,29 +48,23 @@ class ReceiverListener(_listener.EventsListener):
self.status_changed_callback = status_changed_callback self.status_changed_callback = status_changed_callback
receiver.status = _status.ReceiverStatus(receiver, self._status_changed) receiver.status = _status.ReceiverStatus(receiver, self._status_changed)
Receiver.create_device = self.create_device
def create_device(self, receiver, number): # enhance the original register_new_device
def _register_with_status(r, number):
if bool(self): if bool(self):
dev = PairedDevice(receiver, number) dev = r.__register_new_device(number)
if dev.wpid: if dev is not None:
# read these as soon as possible, they will be used everywhere
dev.protocol, dev.codename
dev.status = _status.DeviceStatus(dev, self._status_changed) dev.status = _status.DeviceStatus(dev, self._status_changed)
_log.info("new device %s", dev)
return dev return dev
receiver.__register_new_device = receiver.register_new_device
receiver.register_new_device = _MethodType(_register_with_status, receiver)
def has_started(self): def has_started(self):
_log.info("events listener has started") _log.info("events listener has started")
# self._status_changed(self.receiver) self._status_changed(self.receiver)
self.receiver.enable_notifications() self.receiver.enable_notifications()
for dev in self.receiver:
dev.codename, dev.kind, dev.name
# dev.status._changed(dev.protocol > 0)
# fake = _fake_device(self)
# self.receiver._devices[fake.number] = fake
# self._status_changed(fake, _status.ALERT.LOW)
self.receiver.notify_devices() self.receiver.notify_devices()
self._status_changed(self.receiver, _status.ALERT.LOW) self._status_changed(self.receiver, _status.ALERT.LOW)
@ -88,13 +73,12 @@ class ReceiverListener(_listener.EventsListener):
if self.receiver: if self.receiver:
self.receiver.enable_notifications(False) self.receiver.enable_notifications(False)
self.receiver.close() self.receiver.close()
self.receiver = None self.receiver = None
self._status_changed(None, alert=_status.ALERT.LOW) self._status_changed(None, alert=_status.ALERT.LOW)
def tick(self, timestamp): def tick(self, timestamp):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("tick: polling status: %s %s", self.receiver, self.receiver._devices) _log.debug("tick: polling status: %s %s", self.receiver, list(iter(self.receiver)))
if self._last_tick > 0 and timestamp - self._last_tick > _DEVICE_STATUS_POLL * 2: if self._last_tick > 0 and timestamp - self._last_tick > _DEVICE_STATUS_POLL * 2:
# if we missed a couple of polls, most likely the computer went into # if we missed a couple of polls, most likely the computer went into
@ -114,7 +98,7 @@ class ReceiverListener(_listener.EventsListener):
for dev in self.receiver: for dev in self.receiver:
if dev.status: if dev.status:
# read these in case they haven't been read already # read these in case they haven't been read already
dev.wpid, dev.serial, dev.protocol, dev.firmware dev.protocol, dev.serial, dev.firmware
if _status.BATTERY_LEVEL not in dev.status: if _status.BATTERY_LEVEL not in dev.status:
battery = _hidpp20.get_battery(dev) or _hidpp10.get_battery(dev) battery = _hidpp20.get_battery(dev) or _hidpp10.get_battery(dev)
@ -130,12 +114,12 @@ class ReceiverListener(_listener.EventsListener):
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("status_changed %s: %s (%X) %s", device, None if device is None else device.status, alert, reason or '') _log.debug("status_changed %s: %s (%X) %s", device, None if device is None else device.status, alert, reason or '')
if self.status_changed_callback: if self.status_changed_callback:
if device is None or device is self.receiver: if device is None or device.kind is None:
self.status_changed_callback(self.receiver or DUMMY, None, alert, reason) self.status_changed_callback(self.receiver or DUMMY, None, alert, reason)
else: else:
self.status_changed_callback(self.receiver or DUMMY, device, alert, reason) self.status_changed_callback(self.receiver or DUMMY, device, alert, reason)
if device.status is None: # if device.status is None:
self.status_changed_callback(self.receiver, None) # self.status_changed_callback(self.receiver, None)
def _events_handler(self, event): def _events_handler(self, event):
assert self.receiver assert self.receiver

View File

@ -2,6 +2,8 @@
# #
# #
# from gi import pygtkcompat
# pygtkcompat.enable_gtk()
from gi.repository import GObject, Gtk from gi.repository import GObject, Gtk
GObject.threads_init() GObject.threads_init()

View File

@ -2,7 +2,7 @@
# #
# #
# from sys import version as PYTTHON_VERSION # from sys import version as PYTHON_VERSION
from gi.repository import Gtk, Gdk from gi.repository import Gtk, Gdk
import ui import ui
@ -46,13 +46,19 @@ def _show_about_window(action):
about.set_version(_VERSION) about.set_version(_VERSION)
about.set_comments('Shows status of devices connected\nto a Logitech Unifying Receiver.') about.set_comments('Shows status of devices connected\nto a Logitech Unifying Receiver.')
about.set_license_type(Gtk.License.GPL_2_0)
about.set_copyright(b'\xC2\xA9'.decode('utf-8') + ' 2012 Daniel Pavel') about.set_copyright(b'\xC2\xA9'.decode('utf-8') + ' 2012 Daniel Pavel')
about.set_license_type(Gtk.License.GPL_2_0)
about.set_authors(('Daniel Pavel http://github.com/pwr',)) about.set_authors(('Daniel Pavel http://github.com/pwr',))
try: try:
about.add_credit_section('Testing', ('Douglas Wagner',)) about.add_credit_section('Testing', ('Douglas Wagner',))
except Exception: about.add_credit_section('Technical specifications\nprovided by',
('Julien Danjou http://julien.danjou.info/blog/2012/logitech-unifying-upower',))
except TypeError:
# gtk3 < 3.6 has incorrect gi bindings
pass
except:
# is the Gtk3 version too old?
pass pass
about.set_website('http://github.com/pwr/Solaar/wiki') about.set_website('http://github.com/pwr/Solaar/wiki')
@ -73,6 +79,7 @@ def _pair_device(action, frame):
pair_dialog = ui.pair_window.create(action, frame._device) pair_dialog = ui.pair_window.create(action, frame._device)
pair_dialog.set_transient_for(window) pair_dialog.set_transient_for(window)
pair_dialog.set_destroy_with_parent(True)
pair_dialog.set_modal(True) pair_dialog.set_modal(True)
pair_dialog.set_type_hint(Gdk.WindowTypeHint.DIALOG) pair_dialog.set_type_hint(Gdk.WindowTypeHint.DIALOG)
pair_dialog.set_position(Gtk.WindowPosition.CENTER) pair_dialog.set_position(Gtk.WindowPosition.CENTER)

View File

@ -268,7 +268,7 @@ def _update_receiver_info_label(label, dev):
def _toggle_info_box(action, label_widget, box_widget, frame, update_function): def _toggle_info_box(action, label_widget, box_widget, frame, update_function):
if action.get_active(): if action.get_active():
box_widget.set_visible(True) box_widget.set_visible(True)
GObject.timeout_add(60, update_function, label_widget, frame._device) GObject.timeout_add(50, update_function, label_widget, frame._device)
else: else:
box_widget.set_visible(False) box_widget.set_visible(False)
@ -375,8 +375,8 @@ def _update_device_box(frame, dev):
def update(window, receiver, device=None): def update(window, receiver, device=None):
# print ("update", receiver, receiver.status, device)
assert receiver is not None assert receiver is not None
# print ("update", receiver, receiver.status, device, None if device is None else device.number)
window.set_icon_name(ui.appicon(receiver.status)) window.set_icon_name(ui.appicon(receiver.status))
vbox = window._vbox vbox = window._vbox

View File

@ -64,15 +64,13 @@ def _check_lock_state(assistant, receiver):
return False return False
if receiver.status.get(_status.ERROR): if receiver.status.get(_status.ERROR):
# fake = _fake_device(receiver) # receiver.status.new_device = _fake_device(receiver)
# receiver._devices[fake.number] = fake
# receiver.status.new_device = fake
# fake.status._changed()
_pairing_failed(assistant, receiver, receiver.status.pop(_status.ERROR)) _pairing_failed(assistant, receiver, receiver.status.pop(_status.ERROR))
return False return False
if receiver.status.new_device: if receiver.status.new_device:
_pairing_succeeded(assistant, receiver) device, receiver.status.new_device = receiver.status.new_device, None
_pairing_succeeded(assistant, receiver, device)
return False return False
if not receiver.status.lock_open: if not receiver.status.lock_open:
@ -129,8 +127,7 @@ def _pairing_failed(assistant, receiver, error):
assistant.commit() assistant.commit()
def _pairing_succeeded(assistant, receiver): def _pairing_succeeded(assistant, receiver, device):
device, receiver.status.new_device = receiver.status.new_device, None
assert device assert device
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("%s success: %s", receiver, device) _log.debug("%s success: %s", receiver, device)
@ -173,7 +170,7 @@ def create(action, receiver):
assistant.set_title(action.get_label()) assistant.set_title(action.get_label())
assistant.set_icon_name(action.get_icon_name()) assistant.set_icon_name(action.get_icon_name())
assistant.set_size_request(420, 240) assistant.set_size_request(400, 240)
assistant.set_resizable(False) assistant.set_resizable(False)
assistant.set_role('pair-device') assistant.set_role('pair-device')

View File

@ -14,6 +14,7 @@ def create(window, menu_actions=None):
icon.set_title(name) icon.set_title(name)
icon.set_name(name) icon.set_name(name)
icon.set_from_icon_name(ui.appicon(False)) icon.set_from_icon_name(ui.appicon(False))
icon._devices = {}
icon.set_tooltip_text(name) icon.set_tooltip_text(name)
icon.connect('activate', window.toggle_visible) icon.connect('activate', window.toggle_visible)
@ -44,6 +45,7 @@ def _icon_with_battery(s):
assert mask assert mask
mask = GdkPixbuf.Pixbuf.new_from_file(mask) mask = GdkPixbuf.Pixbuf.new_from_file(mask)
assert mask.get_width() == 128 and mask.get_height() == 128 assert mask.get_width() == 128 and mask.get_height() == 128
mask.saturate_and_pixelate(mask, 0.8, False)
battery = ui.icon_file(battery_icon, 128) battery = ui.icon_file(battery_icon, 128)
assert battery assert battery
@ -59,15 +61,22 @@ def _icon_with_battery(s):
return _PIXMAPS[name] return _PIXMAPS[name]
def update(icon, receiver, device=None): def update(icon, receiver, device=None):
# print "icon update", receiver, receiver._devices, device # print ("icon update", receiver, receiver.status, len(receiver._devices), device)
battery_status = None battery_status = None
if device is not None:
icon._devices[device.number] = device
lines = [ui.NAME + ': ' + str(receiver.status), ''] lines = [ui.NAME + ': ' + str(receiver.status), '']
if receiver and receiver._devices: if receiver:
for dev in receiver: for k in range(1, 1+ receiver.max_devices):
dev = icon._devices.get(k)
if dev is None:
continue
lines.append('<b>' + dev.name + '</b>') lines.append('<b>' + dev.name + '</b>')
assert dev.status is not None assert hasattr(dev, 'status') and dev.status is not None
p = str(dev.status) p = str(dev.status)
if p: if p:
if not dev.status: if not dev.status:
@ -86,6 +95,8 @@ def update(icon, receiver, device=None):
if battery_status is None and dev.status.get(_status.BATTERY_LEVEL): if battery_status is None and dev.status.get(_status.BATTERY_LEVEL):
battery_status = dev.status battery_status = dev.status
else:
icon._devices.clear()
icon.set_tooltip_markup('\n'.join(lines).rstrip('\n')) icon.set_tooltip_markup('\n'.join(lines).rstrip('\n'))

View File

@ -130,7 +130,7 @@ def write(handle, devnumber, data):
unloaded. The handle will be closed automatically. unloaded. The handle will be closed automatically.
""" """
# the data is padded to either 5 or 18 bytes # the data is padded to either 5 or 18 bytes
if len(data) > _SHORT_MESSAGE_SIZE - 2: if len(data) > _SHORT_MESSAGE_SIZE - 2 or data[:1] == b'\x82':
wdata = _pack('!BB18s', 0x11, devnumber, data) wdata = _pack('!BB18s', 0x11, devnumber, data)
else: else:
wdata = _pack('!BB5s', 0x10, devnumber, data) wdata = _pack('!BB5s', 0x10, devnumber, data)
@ -306,6 +306,13 @@ def request(handle, devnumber, request_id, *params):
raise _hidpp20.FeatureCallError(number=devnumber, request=request_id, error=error, params=params) raise _hidpp20.FeatureCallError(number=devnumber, request=request_id, error=error, params=params)
if reply_data[:2] == request_str: if reply_data[:2] == request_str:
if request_id & 0xFF00 == 0x8300:
# long registry r/w should return a long reply
assert report_id == 0x11
elif request_id & 0xF000 == 0x8000:
# short registry r/w should return a short reply
assert report_id == 0x10
if devnumber == 0xFF: if devnumber == 0xFF:
if request_id == 0x83B5 or request_id == 0x81F1: if request_id == 0x83B5 or request_id == 0x81F1:
# these replies have to match the first parameter as well # these replies have to match the first parameter as well

View File

@ -2,7 +2,10 @@
# #
# #
from .common import NamedInts as _NamedInts from .common import (strhex as _strhex,
NamedInts as _NamedInts,
FirmwareInfo as _FirmwareInfo)
from .hidpp20 import FIRMWARE_KIND
# #
# constants # constants
@ -64,3 +67,29 @@ def get_battery(device):
if reply: if reply:
charge = ord(reply[:1]) charge = ord(reply[:1])
return charge, None return charge, None
def get_receiver_serial(receiver):
serial = receiver.request(0x83B5, 0x03)
if serial:
return _strhex(serial[1:5])
def get_receiver_firmware(receiver):
firmware = []
reply = receiver.request(0x83B5, 0x02)
if reply:
fw_version = _strhex(reply[1:5])
fw_version = '%s.%s.B%s' % (fw_version[0:2], fw_version[2:4], fw_version[4:8])
fw = _FirmwareInfo(FIRMWARE_KIND.Firmware, '', fw_version, None)
firmware.append(fw)
reply = receiver.request(0x81F1, 0x04)
if reply:
bl_version = _strhex(reply[1:3])
bl_version = '%s.%s' % (bl_version[0:2], bl_version[2:4])
bl = _FirmwareInfo(FIRMWARE_KIND.Bootloader, '', bl_version, None)
firmware.append(bl)
return tuple(firmware)

View File

@ -3,6 +3,7 @@
# #
from struct import pack as _pack, unpack as _unpack from struct import pack as _pack, unpack as _unpack
from weakref import proxy as _proxy
from logging import getLogger, DEBUG as _DEBUG from logging import getLogger, DEBUG as _DEBUG
_log = getLogger('LUR').getChild('hidpp20') _log = getLogger('LUR').getChild('hidpp20')
@ -123,14 +124,12 @@ class FeaturesArray(object):
def __init__(self, device): def __init__(self, device):
assert device is not None assert device is not None
self.device = device self.device = _proxy(device)
self.supported = True self.supported = True
self.features = None self.features = None
def __del__(self): def __del__(self):
self.supported = False self.supported = False
self.features = None
self.device = None
def _check(self): def _check(self):
# print ("%s check" % self.device) # print ("%s check" % self.device)
@ -251,13 +250,9 @@ class KeysArray(object):
def __init__(self, device, count): def __init__(self, device, count):
assert device is not None assert device is not None
self.device = device self.device = _proxy(device)
self.keys = [None] * count self.keys = [None] * count
def __del__(self):
self.keys = None
self.device = None
def __getitem__(self, index): def __getitem__(self, index):
assert type(index) == int assert type(index) == int
if index < 0 or index >= len(self.keys): if index < 0 or index >= len(self.keys):

View File

@ -83,6 +83,7 @@ class ThreadedHandle(object):
# #
_EVENT_READ_TIMEOUT = 500 _EVENT_READ_TIMEOUT = 500
_IDLE_READS = 5
class EventsListener(_threading.Thread): class EventsListener(_threading.Thread):
@ -111,6 +112,7 @@ class EventsListener(_threading.Thread):
self.has_started() self.has_started()
last_tick = 0 last_tick = 0
idle_reads = 0
while self._active: while self._active:
if self._queued_events.empty(): if self._queued_events.empty():
@ -136,6 +138,9 @@ class EventsListener(_threading.Thread):
except: except:
_log.exception("processing event %s", event) _log.exception("processing event %s", event)
elif self.tick_period: elif self.tick_period:
idle_reads += 1
if idle_reads % _IDLE_READS == 0:
idle_reads = 0
now = _timestamp() now = _timestamp()
if now - last_tick >= self.tick_period: if now - last_tick >= self.tick_period:
last_tick = now last_tick = now

View File

@ -3,6 +3,7 @@
# #
import errno as _errno import errno as _errno
from weakref import proxy as _proxy
from logging import getLogger from logging import getLogger
_log = getLogger('LUR').getChild('receiver') _log = getLogger('LUR').getChild('receiver')
@ -25,7 +26,7 @@ MAX_PAIRED_DEVICES = 6
class PairedDevice(object): class PairedDevice(object):
def __init__(self, receiver, number): def __init__(self, receiver, number):
assert receiver assert receiver
self.receiver = receiver self.receiver = _proxy(receiver)
assert number > 0 and number <= MAX_PAIRED_DEVICES assert number > 0 and number <= MAX_PAIRED_DEVICES
self.number = number self.number = number
@ -41,11 +42,6 @@ class PairedDevice(object):
self.features = _hidpp20.FeaturesArray(self) self.features = _hidpp20.FeaturesArray(self)
def __del__(self):
del self.receiver
del self.features
del self._keys
@property @property
def protocol(self): def protocol(self):
if self._protocol is None: if self._protocol is None:
@ -82,10 +78,9 @@ class PairedDevice(object):
@property @property
def name(self): def name(self):
if self._name is None: if self._name is None:
if self.protocol < 2.0:
if self.codename in _DEVICES: if self.codename in _DEVICES:
_, self._name, self._kind = _DEVICES[self._codename] _, self._name, self._kind = _DEVICES[self._codename]
else: elif self.protocol >= 2.0:
self._name = _hidpp20.get_name(self) self._name = _hidpp20.get_name(self)
return self._name or self.codename or '?' return self._name or self.codename or '?'
@ -99,10 +94,9 @@ class PairedDevice(object):
if self._wpid is None: if self._wpid is None:
self._wpid = _strhex(pair_info[3:5]) self._wpid = _strhex(pair_info[3:5])
if self._kind is None: if self._kind is None:
if self.protocol < 2.0:
if self.codename in _DEVICES: if self.codename in _DEVICES:
_, self._name, self._kind = _DEVICES[self._codename] _, self._name, self._kind = _DEVICES[self._codename]
else: elif self.protocol >= 2.0:
self._kind = _hidpp20.get_kind(self) self._kind = _hidpp20.get_kind(self)
return self._kind or '?' return self._kind or '?'
@ -168,7 +162,6 @@ class Receiver(object):
name = 'Unifying Receiver' name = 'Unifying Receiver'
kind = None kind = None
max_devices = MAX_PAIRED_DEVICES max_devices = MAX_PAIRED_DEVICES
create_device = PairedDevice
def __init__(self, handle, path=None): def __init__(self, handle, path=None):
assert handle assert handle
@ -192,30 +185,13 @@ class Receiver(object):
@property @property
def serial(self): def serial(self):
if self._serial is None and self.handle: if self._serial is None and self.handle:
serial = self.request(0x83B5, 0x03) self._serial = _hidpp10.get_receiver_serial(self)
if serial:
self._serial = _strhex(serial[1:5])
return self._serial return self._serial
@property @property
def firmware(self): def firmware(self):
if self._firmware is None and self.handle: if self._firmware is None and self.handle:
firmware = [] self._firmware = _hidpp10.get_receiver_firmware(self)
reply = self.request(0x83B5, 0x02)
if reply:
fw_version = _strhex(reply[1:5])
fw_version = '%s.%s.B%s' % (fw_version[0:2], fw_version[2:4], fw_version[4:8])
firmware.append(_FirmwareInfo(_hidpp20.FIRMWARE_KIND.Firmware, '', fw_version, None))
reply = self.request(0x81F1, 0x04)
if reply:
bl_version = _strhex(reply[1:3])
bl_version = '%s.%s' % (bl_version[0:2], bl_version[2:4])
firmware.append(_FirmwareInfo(_hidpp20.FIRMWARE_KIND.Bootloader, '', bl_version, None))
self._firmware = tuple(firmware)
return self._firmware return self._firmware
def enable_notifications(self, enable=True): def enable_notifications(self, enable=True):
@ -241,6 +217,16 @@ class Receiver(object):
if not self.request(0x8002, 0x02): if not self.request(0x8002, 0x02):
_log.warn("failed to trigger device events") _log.warn("failed to trigger device events")
def register_new_device(self, number):
if self._devices.get(number) is not None:
raise IndexError("device number %d already registered" % number)
dev = PairedDevice(self, number)
if dev.wpid:
_log.info("registered new device %d (%s)", number, dev.wpid)
self._devices[number] = dev
return dev
self._devices[number] = None
def set_lock(self, lock_closed=True, device=0, timeout=0): def set_lock(self, lock_closed=True, device=0, timeout=0):
if self.handle: if self.handle:
lock = 0x02 if lock_closed else 0x01 lock = 0x02 if lock_closed else 0x01
@ -271,13 +257,7 @@ class Receiver(object):
if key < 1 or key > MAX_PAIRED_DEVICES: if key < 1 or key > MAX_PAIRED_DEVICES:
raise IndexError(key) raise IndexError(key)
dev = Receiver.create_device(self, key) return self.register_new_device(key)
if dev is not None and dev.wpid:
self._devices[key] = dev
return dev
# no paired device at this index
self._devices[key] = None
def __delitem__(self, key): def __delitem__(self, key):
if self._devices.get(key) is None: if self._devices.get(key) is None:

View File

@ -4,6 +4,7 @@
from time import time as _timestamp from time import time as _timestamp
from struct import unpack as _unpack from struct import unpack as _unpack
from weakref import proxy as _proxy
from logging import getLogger, DEBUG as _DEBUG from logging import getLogger, DEBUG as _DEBUG
_log = getLogger('LUR.status') _log = getLogger('LUR.status')
@ -33,7 +34,7 @@ ERROR='error'
class ReceiverStatus(dict): class ReceiverStatus(dict):
def __init__(self, receiver, changed_callback): def __init__(self, receiver, changed_callback):
assert receiver assert receiver
self._receiver = receiver self._receiver = _proxy(receiver)
assert changed_callback assert changed_callback
self._changed_callback = changed_callback self._changed_callback = changed_callback
@ -52,9 +53,7 @@ class ReceiverStatus(dict):
def device_paired(self, number): def device_paired(self, number):
_log.info("new device paired") _log.info("new device paired")
dev = self._receiver.create_device(self._receiver, number) dev = self.new_device = self._receiver.register_new_device(number)
self._receiver._devices[number] = dev
self.new_device = dev
return dev return dev
def _changed(self, alert=ALERT.LOW, reason=None): def _changed(self, alert=ALERT.LOW, reason=None):
@ -88,7 +87,7 @@ class ReceiverStatus(dict):
class DeviceStatus(dict): class DeviceStatus(dict):
def __init__(self, device, changed_callback): def __init__(self, device, changed_callback):
assert device assert device
self._device = device self._device = _proxy(device)
assert changed_callback assert changed_callback
self._changed_callback = changed_callback self._changed_callback = changed_callback
@ -126,13 +125,6 @@ class DeviceStatus(dict):
# _log.debug("device %d changed: active=%s %s", self._device.number, self._active, dict(self)) # _log.debug("device %d changed: active=%s %s", self._device.number, self._active, dict(self))
self._changed_callback(self._device, alert, reason) self._changed_callback(self._device, alert, reason)
# @property
# def battery(self):
# battery = _hidpp10.get_battery_level(self)
# if battery is None:
# battery = _hidpp20.get_battery_level(self)
# return battery
def process_event(self, event): def process_event(self, event):
if event.sub_id == 0x40: if event.sub_id == 0x40:
if event.address == 0x02: if event.address == 0x02:
@ -241,7 +233,7 @@ class DeviceStatus(dict):
else: else:
self._changed() self._changed()
else: else:
_log.warn("SOLAR_CHARGE event not GOOD? %s", event) _log.warn("SOLAR CHARGE event not GOOD? %s", event)
return True return True
if feature == _hidpp20.FEATURE.TOUCH_MOUSE: if feature == _hidpp20.FEATURE.TOUCH_MOUSE: