From b86dcce381865cd844e35d5b97fab067ae418d4c Mon Sep 17 00:00:00 2001 From: Daniel Pavel Date: Fri, 7 Dec 2012 17:10:22 +0200 Subject: [PATCH] I come from the __future__, come with me if you want to live. --- app/listener.py | 5 +- app/solaar.py | 2 + app/solaar_cli.py | 17 +++--- app/ui/__init__.py | 2 + app/ui/action.py | 2 + app/ui/config_panel.py | 2 + app/ui/main_window.py | 2 + app/ui/notify.py | 4 +- app/ui/pair_window.py | 6 ++- app/ui/status_icon.py | 5 ++ lib/hidapi/__init__.py | 4 +- lib/hidapi/hidconsole.py | 4 +- lib/hidapi/native.py | 4 +- lib/hidapi/udev.py | 4 +- lib/logitech/__init__.py | 6 ++- lib/logitech/unifying_receiver/__init__.py | 2 + lib/logitech/unifying_receiver/base.py | 15 +++--- lib/logitech/unifying_receiver/common.py | 54 +++++++++++++++---- lib/logitech/unifying_receiver/descriptors.py | 2 + lib/logitech/unifying_receiver/hidpp10.py | 2 + lib/logitech/unifying_receiver/hidpp20.py | 18 ++++--- lib/logitech/unifying_receiver/listener.py | 3 ++ lib/logitech/unifying_receiver/receiver.py | 26 ++++++--- lib/logitech/unifying_receiver/settings.py | 3 ++ lib/logitech/unifying_receiver/status.py | 6 ++- 25 files changed, 151 insertions(+), 49 deletions(-) diff --git a/app/listener.py b/app/listener.py index fd57e522..cee2e1b2 100644 --- a/app/listener.py +++ b/app/listener.py @@ -2,6 +2,8 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + from logging import getLogger, DEBUG as _DEBUG _log = getLogger('listener') del getLogger @@ -23,7 +25,7 @@ class _DUMMY_RECEIVER(object): max_devices = Receiver.max_devices status = 'Receiver not found.' __bool__ = __nonzero__ = lambda self: False - __str__ = lambda self: 'DUMMY' + __unicode__ = __str__ = __repr__ = lambda self: 'DUMMY' DUMMY = _DUMMY_RECEIVER() from collections import namedtuple @@ -137,6 +139,7 @@ class ReceiverListener(_listener.EventsListener): def __str__(self): return '' % (self.receiver.path, self.receiver.handle) + __unicode__ = __str__ @classmethod def open(self, status_changed_callback=None): diff --git a/app/solaar.py b/app/solaar.py index d11718dd..e8e9d085 100644 --- a/app/solaar.py +++ b/app/solaar.py @@ -1,5 +1,7 @@ #!/usr/bin/env python -u +from __future__ import absolute_import, division, print_function, unicode_literals + NAME = 'Solaar' VERSION = '0.8.2' __author__ = "Daniel Pavel " diff --git a/app/solaar_cli.py b/app/solaar_cli.py index 9cdd847f..f58e6bd7 100644 --- a/app/solaar_cli.py +++ b/app/solaar_cli.py @@ -1,5 +1,7 @@ #!/usr/bin/env python -u +from __future__ import absolute_import, division, print_function, unicode_literals + import sys import solaar @@ -179,14 +181,13 @@ def pair_device(receiver, args): from logitech.unifying_receiver import status r_status = status.ReceiverStatus(receiver, lambda *args, **kwargs: None) - done = False + done = [False] def _events_handler(event): - global done if event.devnumber == 0xFF: r_status.process_event(event) if not r_status.lock_open: - done = True + done[0] = True elif event.sub_id == 0x41 and event.address == 0x04: if event.devnumber not in known_devices: r_status.new_device = receiver[event.devnumber] @@ -203,7 +204,7 @@ def pair_device(receiver, args): receiver.set_lock(False, timeout=20) print ("Pairing: turn your new device on (timing out in 20 seconds).") - while not done: + while not done[0]: event = base.read(receiver.handle, 2000) if event: event = base.make_event(*event) @@ -319,15 +320,15 @@ def _parse_arguments(): help='print all available information about the inspected device(s)') sp.set_defaults(cmd=show_devices) - sp = subparsers.add_parser('config', help='read/write device-specific options', + sp = subparsers.add_parser('config', help='read/write device-specific settings', epilog='Please note that configuration only works on active devices.') sp.add_argument('device', help='device to configure; may be a device number (1..6), a device serial, ' 'or at least 3 characters of a device\'s name') - sp.add_argument('option', nargs='?', - help='device-specific option; leave empty to show available options') + sp.add_argument('setting', nargs='?', + help='device-specific setting; leave empty to list available settings') sp.add_argument('value', nargs='?', - help='new value for the option') + help='new value for the setting') sp.set_defaults(cmd=config_device) sp = subparsers.add_parser('pair', help='pair a new device', diff --git a/app/ui/__init__.py b/app/ui/__init__.py index fb09b31f..e64af19a 100644 --- a/app/ui/__init__.py +++ b/app/ui/__init__.py @@ -2,6 +2,8 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + from gi.repository import GObject, Gtk GObject.threads_init() diff --git a/app/ui/action.py b/app/ui/action.py index 2786eb46..79ae460b 100644 --- a/app/ui/action.py +++ b/app/ui/action.py @@ -2,6 +2,8 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + # from sys import version as PYTHON_VERSION from gi.repository import Gtk, Gdk diff --git a/app/ui/config_panel.py b/app/ui/config_panel.py index ccc6b41c..3961a904 100644 --- a/app/ui/config_panel.py +++ b/app/ui/config_panel.py @@ -2,6 +2,8 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + from gi.repository import Gtk, GObject import ui diff --git a/app/ui/main_window.py b/app/ui/main_window.py index e34c35e5..a9a36b20 100644 --- a/app/ui/main_window.py +++ b/app/ui/main_window.py @@ -2,6 +2,8 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + from gi.repository import Gtk, Gdk, GObject import ui diff --git a/app/ui/notify.py b/app/ui/notify.py index b6ca790e..17fe1112 100644 --- a/app/ui/notify.py +++ b/app/ui/notify.py @@ -2,11 +2,13 @@ # Optional desktop notifications. # -import logging +from __future__ import absolute_import, division, print_function, unicode_literals try: + # this import is allowed to fail, in which case the entire feature is unavailable from gi.repository import Notify + import logging import ui diff --git a/app/ui/pair_window.py b/app/ui/pair_window.py index 3a8b9d3a..d267196d 100644 --- a/app/ui/pair_window.py +++ b/app/ui/pair_window.py @@ -2,16 +2,20 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + from gi.repository import Gtk, GObject from logging import getLogger, DEBUG as _DEBUG _log = getLogger('pair-window') del getLogger - import ui from logitech.unifying_receiver import status as _status +# +# +# _PAIRING_TIMEOUT = 30 diff --git a/app/ui/status_icon.py b/app/ui/status_icon.py index a1c7ae38..562bc913 100644 --- a/app/ui/status_icon.py +++ b/app/ui/status_icon.py @@ -2,11 +2,16 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + from gi.repository import Gtk, GdkPixbuf import ui from logitech.unifying_receiver import status as _status +# +# +# def create(window, menu_actions=None): name = window.get_title() diff --git a/lib/hidapi/__init__.py b/lib/hidapi/__init__.py index 2b0e7cec..e57e28ed 100644 --- a/lib/hidapi/__init__.py +++ b/lib/hidapi/__init__.py @@ -1,7 +1,9 @@ """Generic Human Interface Device API.""" +from __future__ import absolute_import, division, print_function, unicode_literals + __author__ = "Daniel Pavel" __license__ = "GPL" -__version__ = "0.4" +__version__ = "0.5" from hidapi.udev import * diff --git a/lib/hidapi/hidconsole.py b/lib/hidapi/hidconsole.py index 6560d44e..7266a0ca 100644 --- a/lib/hidapi/hidconsole.py +++ b/lib/hidapi/hidconsole.py @@ -1,5 +1,7 @@ #!/usr/bin/env python -u +from __future__ import absolute_import, division, print_function, unicode_literals + import os import sys from select import select as _select @@ -62,7 +64,7 @@ if __name__ == '__main__': import hidapi print (".. Opening device %s" % args.device) - handle = hidapi.open_path(args.device.encode('utf-8')) + handle = hidapi.open_path(args.device) if handle: print (".. Opened handle %s, vendor %s product %s serial %s" % ( repr(handle), diff --git a/lib/hidapi/native.py b/lib/hidapi/native.py index baa23756..8c807f74 100644 --- a/lib/hidapi/native.py +++ b/lib/hidapi/native.py @@ -314,7 +314,7 @@ def send_feature_report(device_handle, data, report_number=None): :returns: ``True`` if the report was successfully written to the device. """ if report_number is not None: - data = _pack('!B', report_number) + data + data = _pack(b'!B', report_number) + data bytes_written = _native.hid_send_feature_report(device_handle, _C.c_char_p(data), len(data)) return bytes_written > -1 @@ -330,7 +330,7 @@ def get_feature_report(device_handle, bytes_count, report_number=None): """ out_buffer = _C.create_string_buffer('\x00' * (bytes_count + 2)) if report_number is not None: - out_buffer[0] = _pack('!B', report_number) + out_buffer[0] = _pack(b'!B', report_number) bytes_read = _native.hid_get_feature_report(device_handle, out_buffer, bytes_count) if bytes_read > -1: return out_buffer[:bytes_read] diff --git a/lib/hidapi/udev.py b/lib/hidapi/udev.py index 7a931ae7..98ee6558 100644 --- a/lib/hidapi/udev.py +++ b/lib/hidapi/udev.py @@ -7,6 +7,8 @@ The docstrings are mostly copied from the hidapi API header, with changes where necessary. """ +from __future__ import absolute_import, division, print_function, unicode_literals + import os as _os import errno as _errno from select import select as _select @@ -126,7 +128,7 @@ def open_path(device_path): :returns: an opaque device handle, or ``None``. """ assert device_path - assert '/dev/hidraw' in device_path + assert device_path.startswith('/dev/hidraw') return _os.open(device_path, _os.O_RDWR | _os.O_SYNC) diff --git a/lib/logitech/__init__.py b/lib/logitech/__init__.py index f1e61944..af308ea8 100644 --- a/lib/logitech/__init__.py +++ b/lib/logitech/__init__.py @@ -1,5 +1,9 @@ # +# +# + +from __future__ import absolute_import, division, print_function, unicode_literals __author__ = "Daniel Pavel" __license__ = "GPL" -__version__ = "0.5" +__version__ = "0.8" diff --git a/lib/logitech/unifying_receiver/__init__.py b/lib/logitech/unifying_receiver/__init__.py index 40224229..4ca40a42 100644 --- a/lib/logitech/unifying_receiver/__init__.py +++ b/lib/logitech/unifying_receiver/__init__.py @@ -11,6 +11,8 @@ http://julien.danjou.info/blog/2012/logitech-k750-linux-support http://6xq.net/git/lars/lshidpp.git/plain/doc/ """ +from __future__ import absolute_import, division, print_function, unicode_literals + import logging _DEBUG = logging.DEBUG diff --git a/lib/logitech/unifying_receiver/base.py b/lib/logitech/unifying_receiver/base.py index 78515c04..ff05de3d 100644 --- a/lib/logitech/unifying_receiver/base.py +++ b/lib/logitech/unifying_receiver/base.py @@ -3,6 +3,8 @@ # Unlikely to be used directly unless you're expanding the API. # +from __future__ import absolute_import, division, print_function, unicode_literals + from time import time as _timestamp from struct import pack as _pack from random import getrandbits as _random_bits @@ -131,9 +133,9 @@ def write(handle, devnumber, data): """ # the data is padded to either 5 or 18 bytes if len(data) > _SHORT_MESSAGE_SIZE - 2 or data[:1] == b'\x82': - wdata = _pack('!BB18s', 0x11, devnumber, data) + wdata = _pack(b'!BB18s', 0x11, devnumber, data) else: - wdata = _pack('!BB5s', 0x10, devnumber, data) + wdata = _pack(b'!BB5s', 0x10, devnumber, data) if _log.isEnabledFor(_DEBUG): _log.debug("(%s) <= w[%02X %02X %s %s]", handle, ord(wdata[:1]), devnumber, _strhex(wdata[2:4]), _strhex(wdata[4:])) @@ -230,6 +232,7 @@ def _unhandled(report_id, devnumber, data): from collections import namedtuple _Event = namedtuple('_Event', ['devnumber', 'sub_id', 'address', 'data']) _Event.__str__ = lambda self: 'Event(%d,%02X,%02X,%s)' % (self.devnumber, self.sub_id, self.address, _strhex(self.data)) +_Event.__unicode__ = _Event.__str__ del namedtuple def make_event(devnumber, data): @@ -265,9 +268,9 @@ def request(handle, devnumber, request_id, *params): request_id = (request_id & 0xFFF0) | _random_bits(4) | 0x01 else: timeout = _RECEIVER_REQUEST_TIMEOUT - request_str = _pack('!H', request_id) + request_str = _pack(b'!H', request_id) - params = b''.join(_pack('B', p) if type(p) == int else p for p in params) + params = b''.join(_pack(b'B', p) if type(p) == int else p for p in params) # if _log.isEnabledFor(_DEBUG): # _log.debug("(%s) device %d request_id {%04X} params [%s]", handle, devnumber, request_id, _strhex(params)) @@ -349,8 +352,8 @@ def ping(handle, devnumber): # and set the last (0) bit in swid to make it easier to distinguish requests # from events request_id = 0x0010 | _random_bits(4) | 0x01 - request_str = _pack('!H', request_id) - ping_mark = _pack('B', _random_bits(8)) + request_str = _pack(b'!H', request_id) + ping_mark = _pack(b'B', _random_bits(8)) write(ihandle, devnumber, request_str + b'\x00\x00' + ping_mark) while True: diff --git a/lib/logitech/unifying_receiver/common.py b/lib/logitech/unifying_receiver/common.py index df729e6a..0b81f1a2 100644 --- a/lib/logitech/unifying_receiver/common.py +++ b/lib/logitech/unifying_receiver/common.py @@ -2,12 +2,17 @@ # Some common functions and types. # +from __future__ import absolute_import, division, print_function, unicode_literals + from binascii import hexlify as _hexlify from struct import pack as _pack class NamedInt(int): - """An integer with an attached name.""" + """An reqular Python integer with an attached name. + + Careful when using this, because + """ def __new__(cls, value, name): obj = int.__new__(cls, value) @@ -17,23 +22,50 @@ class NamedInt(int): def bytes(self, count=2): value = int(self) if value.bit_length() > count * 8: - raise ValueError("cannot fit %X into %d bytes" % (value, count)) + raise ValueError('cannot fit %X into %d bytes' % (value, count)) - return _pack('!L', value)[-count:] + return _pack(b'!L', value)[-count:] + + def __hash__(self): + return int(self) def __eq__(self, other): - try: - if int(self) == int(other): - return True - except: - pass - return self.name.lower() == str(other).lower() + if isinstance(other, int): + return int(self) == int(other) - def __cmp__(self, other): - return int(self) - int(other) + if isinstance(other, str): + return self.name.lower() == other.lower() + + def __ne__(self, other): + if isinstance(other, int): + return int(self) != int(other) + + if isinstance(other, str): + return self.name.lower() != other.lower() + + def __lt__(self, other): + if not isinstance(other, int): + raise TypeError('unorderable types: %s < %s' % (type(self), type(other))) + return int(self) < int(other) + + def __le__(self, other): + if not isinstance(other, int): + raise TypeError('unorderable types: %s <= %s' % (type(self), type(other))) + return int(self) <= int(other) + + def __gt__(self, other): + if not isinstance(other, int): + raise TypeError('unorderable types: %s > %s' % (type(self), type(other))) + return int(self) > int(other) + + def __ge__(self, other): + if not isinstance(other, int): + raise TypeError('unorderable types: %s >= %s' % (type(self), type(other))) + return int(self) >= int(other) def __str__(self): return self.name + __unicode__ = __str__ def __repr__(self): return 'NamedInt(%d, %s)' % (int(self), repr(self.name)) diff --git a/lib/logitech/unifying_receiver/descriptors.py b/lib/logitech/unifying_receiver/descriptors.py index 90da1a69..de1cbb20 100644 --- a/lib/logitech/unifying_receiver/descriptors.py +++ b/lib/logitech/unifying_receiver/descriptors.py @@ -2,6 +2,8 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + from collections import namedtuple from .common import NamedInts as _NamedInts diff --git a/lib/logitech/unifying_receiver/hidpp10.py b/lib/logitech/unifying_receiver/hidpp10.py index b0fc93b0..d49a642a 100644 --- a/lib/logitech/unifying_receiver/hidpp10.py +++ b/lib/logitech/unifying_receiver/hidpp10.py @@ -2,6 +2,8 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + from .common import (strhex as _strhex, NamedInts as _NamedInts, FirmwareInfo as _FirmwareInfo) diff --git a/lib/logitech/unifying_receiver/hidpp20.py b/lib/logitech/unifying_receiver/hidpp20.py index 1cce2981..5dc92347 100644 --- a/lib/logitech/unifying_receiver/hidpp20.py +++ b/lib/logitech/unifying_receiver/hidpp20.py @@ -2,6 +2,8 @@ # Logitech Unifying Receiver API. # +from __future__ import absolute_import, division, print_function, unicode_literals + from struct import pack as _pack, unpack as _unpack from weakref import proxy as _proxy @@ -152,7 +154,7 @@ class FeaturesArray(object): self.device = None return False - reply = self.device.request(int(FEATURE.ROOT), _pack('!H', FEATURE.FEATURE_SET)) + reply = self.device.request(int(FEATURE.ROOT), _pack(b'!H', FEATURE.FEATURE_SET)) if reply is None: self.supported = False else: @@ -186,7 +188,7 @@ class FeaturesArray(object): if self.features[index] is None: feature = self.device.feature_request(FEATURE.FEATURE_SET, 0x10, index) if feature: - feature, = _unpack('!H', feature[:2]) + feature, = _unpack(b'!H', feature[:2]) self.features[index] = FEATURE[feature] return self.features[index] @@ -203,7 +205,7 @@ class FeaturesArray(object): break if may_have: - reply = self.device.request(int(FEATURE.ROOT), _pack('!H', value)) + reply = self.device.request(int(FEATURE.ROOT), _pack(b'!H', value)) if reply: index = ord(reply[0:1]) if index: @@ -222,7 +224,7 @@ class FeaturesArray(object): raise ValueError("%s not in list" % repr(value)) if may_have: - reply = self.device.request(int(FEATURE.ROOT), _pack('!H', value)) + reply = self.device.request(int(FEATURE.ROOT), _pack(b'!H', value)) if reply: index = ord(reply[0:1]) self.features[index] = FEATURE[int(value)] @@ -263,7 +265,7 @@ class KeysArray(object): if self.keys[index] is None: keydata = feature_request(self.device, FEATURE.REPROGRAMMABLE_KEYS, 0x10, index) if keydata: - key, key_task, flags = _unpack('!HHB', keydata[:5]) + key, key_task, flags = _unpack(b'!HHB', keydata[:5]) self.keys[index] = _ReprogrammableKeyInfo(index, KEY[key], KEY[key_task], flags) return self.keys[index] @@ -293,7 +295,7 @@ class KeysArray(object): class ToggleFN_Setting(_settings.Setting): def __init__(self): - super(ToggleFN_Setting, self).__init__('fn-toggle', _settings.KIND.toggle, 'Swap Fx function', + super(ToggleFN_Setting, self).__init__('fn-swap', _settings.KIND.toggle, 'Swap Fx function', 'When set, the F1..F12 keys will activate their special function,\n' 'and you must hold the FN key to activate their standard function.\n' '\n' @@ -339,7 +341,7 @@ def get_firmware(device): if fw_info: level = ord(fw_info[:1]) & 0x0F if level == 0 or level == 1: - name, version_major, version_minor, build = _unpack('!3sBBH', fw_info[1:8]) + name, version_major, version_minor, build = _unpack(b'!3sBBH', fw_info[1:8]) version = '%02X.%02X' % (version_major, version_minor) if build: version += '.B%04X' % build @@ -398,7 +400,7 @@ def get_battery(device): """ battery = feature_request(device, FEATURE.BATTERY) if battery: - discharge, dischargeNext, status = _unpack('!BBB', battery[:3]) + discharge, dischargeNext, status = _unpack(b'!BBB', battery[:3]) if _log.isEnabledFor(_DEBUG): _log.debug("device %d battery %d%% charged, next level %d%% charge, status %d = %s", device.number, discharge, dischargeNext, status, BATTERY_STATUS[status]) diff --git a/lib/logitech/unifying_receiver/listener.py b/lib/logitech/unifying_receiver/listener.py index 6000f0b3..4df2cff7 100644 --- a/lib/logitech/unifying_receiver/listener.py +++ b/lib/logitech/unifying_receiver/listener.py @@ -2,6 +2,8 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + import threading as _threading from time import time as _timestamp @@ -70,6 +72,7 @@ class ThreadedHandle(object): def __str__(self): if self._local: return str(int(self)) + __unicode__ = __str__ def __repr__(self): return '' % self.path diff --git a/lib/logitech/unifying_receiver/receiver.py b/lib/logitech/unifying_receiver/receiver.py index 0a257db5..54ad45bf 100644 --- a/lib/logitech/unifying_receiver/receiver.py +++ b/lib/logitech/unifying_receiver/receiver.py @@ -2,6 +2,8 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + import errno as _errno from weakref import proxy as _proxy from collections import defaultdict as _defaultdict @@ -175,18 +177,30 @@ class PairedDevice(object): return self.number __int__ = __index__ - def __hash__(self): - return self.number + def __lt__(self, other): + return self.number < other.number - def __cmp__(self, other): - return self.number - other.number + def __le__(self, other): + return self.number <= other.number + + def __gt__(self, other): + return self.number > other.number + + def __ge__(self, other): + return self.number >= other.number def __eq__(self, other): return self.receiver == other.receiver and self.number == other.number + def __ne__(self, other): + return self.receiver != other.receiver or self.number != other.number + + def __hash__(self): + return self.number + def __str__(self): return '' % (self.number, self.codename or '?') - __repr__ = __str__ + __unicode__ = __repr__ = __str__ # # @@ -330,7 +344,7 @@ class Receiver(object): def __str__(self): return '' % (self.path, '' if type(self.handle) == int else 'T', self.handle) - __repr__ = __str__ + __unicode__ = __repr__ = __str__ __bool__ = __nonzero__ = lambda self: self.handle is not None diff --git a/lib/logitech/unifying_receiver/settings.py b/lib/logitech/unifying_receiver/settings.py index cc4ede20..4441c5f4 100644 --- a/lib/logitech/unifying_receiver/settings.py +++ b/lib/logitech/unifying_receiver/settings.py @@ -2,6 +2,8 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + from weakref import proxy as _proxy from copy import copy as _copy @@ -44,3 +46,4 @@ class Setting(object): def __str__(self): return '<%s(%s=%s)>' % (self.__class__.__name__, self.name, self._value) + __unicode__ = __repr__ = __str__ diff --git a/lib/logitech/unifying_receiver/status.py b/lib/logitech/unifying_receiver/status.py index 901ad637..1cea1cb8 100644 --- a/lib/logitech/unifying_receiver/status.py +++ b/lib/logitech/unifying_receiver/status.py @@ -2,6 +2,8 @@ # # +from __future__ import absolute_import, division, print_function, unicode_literals + from time import time as _timestamp from struct import unpack as _unpack from weakref import proxy as _proxy @@ -54,6 +56,7 @@ class ReceiverStatus(dict): return ('No devices found.' if count == 0 else '1 device found.' if count == 1 else '%d devices found.' % count) + __unicode__ = __str__ def _changed(self, alert=ALERT.LOW, reason=None): # self.updated = _timestamp() @@ -104,6 +107,7 @@ class DeviceStatus(dict): if self.get(LIGHT_LEVEL) is not None: t.append('Light: %d lux' % self[LIGHT_LEVEL]) return ', '.join(t) + __unicode__ = __str__ def __bool__(self): return bool(self._active) @@ -247,7 +251,7 @@ class DeviceStatus(dict): if feature == _hidpp20.FEATURE.SOLAR_CHARGE: if event.data[5:9] == b'GOOD': - charge, lux, adc = _unpack('!BHH', event.data[:5]) + charge, lux, adc = _unpack(b'!BHH', event.data[:5]) self[BATTERY_LEVEL] = charge # guesstimate the battery voltage, emphasis on 'guess' self[BATTERY_STATUS] = '%1.2fV' % (adc * 2.67793237653 / 0x0672)