I come from the __future__, come with me if you want to live.

This commit is contained in:
Daniel Pavel 2012-12-07 17:10:22 +02:00
parent c4be58f074
commit b86dcce381
25 changed files with 151 additions and 49 deletions

View File

@ -2,6 +2,8 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
from logging import getLogger, DEBUG as _DEBUG from logging import getLogger, DEBUG as _DEBUG
_log = getLogger('listener') _log = getLogger('listener')
del getLogger del getLogger
@ -23,7 +25,7 @@ class _DUMMY_RECEIVER(object):
max_devices = Receiver.max_devices max_devices = Receiver.max_devices
status = 'Receiver not found.' status = 'Receiver not found.'
__bool__ = __nonzero__ = lambda self: False __bool__ = __nonzero__ = lambda self: False
__str__ = lambda self: 'DUMMY' __unicode__ = __str__ = __repr__ = lambda self: 'DUMMY'
DUMMY = _DUMMY_RECEIVER() DUMMY = _DUMMY_RECEIVER()
from collections import namedtuple from collections import namedtuple
@ -137,6 +139,7 @@ class ReceiverListener(_listener.EventsListener):
def __str__(self): def __str__(self):
return '<ReceiverListener(%s,%s)>' % (self.receiver.path, self.receiver.handle) return '<ReceiverListener(%s,%s)>' % (self.receiver.path, self.receiver.handle)
__unicode__ = __str__
@classmethod @classmethod
def open(self, status_changed_callback=None): def open(self, status_changed_callback=None):

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python -u #!/usr/bin/env python -u
from __future__ import absolute_import, division, print_function, unicode_literals
NAME = 'Solaar' NAME = 'Solaar'
VERSION = '0.8.2' VERSION = '0.8.2'
__author__ = "Daniel Pavel <daniel.pavel@gmail.com>" __author__ = "Daniel Pavel <daniel.pavel@gmail.com>"

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python -u #!/usr/bin/env python -u
from __future__ import absolute_import, division, print_function, unicode_literals
import sys import sys
import solaar import solaar
@ -179,14 +181,13 @@ def pair_device(receiver, args):
from logitech.unifying_receiver import status from logitech.unifying_receiver import status
r_status = status.ReceiverStatus(receiver, lambda *args, **kwargs: None) r_status = status.ReceiverStatus(receiver, lambda *args, **kwargs: None)
done = False done = [False]
def _events_handler(event): def _events_handler(event):
global done
if event.devnumber == 0xFF: if event.devnumber == 0xFF:
r_status.process_event(event) r_status.process_event(event)
if not r_status.lock_open: if not r_status.lock_open:
done = True done[0] = True
elif event.sub_id == 0x41 and event.address == 0x04: elif event.sub_id == 0x41 and event.address == 0x04:
if event.devnumber not in known_devices: if event.devnumber not in known_devices:
r_status.new_device = receiver[event.devnumber] r_status.new_device = receiver[event.devnumber]
@ -203,7 +204,7 @@ def pair_device(receiver, args):
receiver.set_lock(False, timeout=20) receiver.set_lock(False, timeout=20)
print ("Pairing: turn your new device on (timing out in 20 seconds).") 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) event = base.read(receiver.handle, 2000)
if event: if event:
event = base.make_event(*event) event = base.make_event(*event)
@ -319,15 +320,15 @@ def _parse_arguments():
help='print all available information about the inspected device(s)') help='print all available information about the inspected device(s)')
sp.set_defaults(cmd=show_devices) 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.') epilog='Please note that configuration only works on active devices.')
sp.add_argument('device', sp.add_argument('device',
help='device to configure; may be a device number (1..6), a device serial, ' help='device to configure; may be a device number (1..6), a device serial, '
'or at least 3 characters of a device\'s name') 'or at least 3 characters of a device\'s name')
sp.add_argument('option', nargs='?', sp.add_argument('setting', nargs='?',
help='device-specific option; leave empty to show available options') help='device-specific setting; leave empty to list available settings')
sp.add_argument('value', nargs='?', sp.add_argument('value', nargs='?',
help='new value for the option') help='new value for the setting')
sp.set_defaults(cmd=config_device) sp.set_defaults(cmd=config_device)
sp = subparsers.add_parser('pair', help='pair a new device', sp = subparsers.add_parser('pair', help='pair a new device',

View File

@ -2,6 +2,8 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
from gi.repository import GObject, Gtk from gi.repository import GObject, Gtk
GObject.threads_init() GObject.threads_init()

View File

@ -2,6 +2,8 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
# from sys import version as PYTHON_VERSION # from sys import version as PYTHON_VERSION
from gi.repository import Gtk, Gdk from gi.repository import Gtk, Gdk

View File

@ -2,6 +2,8 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
from gi.repository import Gtk, GObject from gi.repository import Gtk, GObject
import ui import ui

View File

@ -2,6 +2,8 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
from gi.repository import Gtk, Gdk, GObject from gi.repository import Gtk, Gdk, GObject
import ui import ui

View File

@ -2,11 +2,13 @@
# Optional desktop notifications. # Optional desktop notifications.
# #
import logging from __future__ import absolute_import, division, print_function, unicode_literals
try: try:
# this import is allowed to fail, in which case the entire feature is unavailable
from gi.repository import Notify from gi.repository import Notify
import logging
import ui import ui

View File

@ -2,16 +2,20 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
from gi.repository import Gtk, GObject from gi.repository import Gtk, GObject
from logging import getLogger, DEBUG as _DEBUG from logging import getLogger, DEBUG as _DEBUG
_log = getLogger('pair-window') _log = getLogger('pair-window')
del getLogger del getLogger
import ui import ui
from logitech.unifying_receiver import status as _status from logitech.unifying_receiver import status as _status
#
#
#
_PAIRING_TIMEOUT = 30 _PAIRING_TIMEOUT = 30

View File

@ -2,11 +2,16 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
from gi.repository import Gtk, GdkPixbuf from gi.repository import Gtk, GdkPixbuf
import ui import ui
from logitech.unifying_receiver import status as _status from logitech.unifying_receiver import status as _status
#
#
#
def create(window, menu_actions=None): def create(window, menu_actions=None):
name = window.get_title() name = window.get_title()

View File

@ -1,7 +1,9 @@
"""Generic Human Interface Device API.""" """Generic Human Interface Device API."""
from __future__ import absolute_import, division, print_function, unicode_literals
__author__ = "Daniel Pavel" __author__ = "Daniel Pavel"
__license__ = "GPL" __license__ = "GPL"
__version__ = "0.4" __version__ = "0.5"
from hidapi.udev import * from hidapi.udev import *

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python -u #!/usr/bin/env python -u
from __future__ import absolute_import, division, print_function, unicode_literals
import os import os
import sys import sys
from select import select as _select from select import select as _select
@ -62,7 +64,7 @@ if __name__ == '__main__':
import hidapi import hidapi
print (".. Opening device %s" % args.device) print (".. Opening device %s" % args.device)
handle = hidapi.open_path(args.device.encode('utf-8')) handle = hidapi.open_path(args.device)
if handle: if handle:
print (".. Opened handle %s, vendor %s product %s serial %s" % ( print (".. Opened handle %s, vendor %s product %s serial %s" % (
repr(handle), repr(handle),

View File

@ -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. :returns: ``True`` if the report was successfully written to the device.
""" """
if report_number is not None: 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)) bytes_written = _native.hid_send_feature_report(device_handle, _C.c_char_p(data), len(data))
return bytes_written > -1 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)) out_buffer = _C.create_string_buffer('\x00' * (bytes_count + 2))
if report_number is not None: 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) bytes_read = _native.hid_get_feature_report(device_handle, out_buffer, bytes_count)
if bytes_read > -1: if bytes_read > -1:
return out_buffer[:bytes_read] return out_buffer[:bytes_read]

View File

@ -7,6 +7,8 @@ The docstrings are mostly copied from the hidapi API header, with changes where
necessary. necessary.
""" """
from __future__ import absolute_import, division, print_function, unicode_literals
import os as _os import os as _os
import errno as _errno import errno as _errno
from select import select as _select from select import select as _select
@ -126,7 +128,7 @@ def open_path(device_path):
:returns: an opaque device handle, or ``None``. :returns: an opaque device handle, or ``None``.
""" """
assert device_path 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) return _os.open(device_path, _os.O_RDWR | _os.O_SYNC)

View File

@ -1,5 +1,9 @@
# #
#
#
from __future__ import absolute_import, division, print_function, unicode_literals
__author__ = "Daniel Pavel" __author__ = "Daniel Pavel"
__license__ = "GPL" __license__ = "GPL"
__version__ = "0.5" __version__ = "0.8"

View File

@ -11,6 +11,8 @@ http://julien.danjou.info/blog/2012/logitech-k750-linux-support
http://6xq.net/git/lars/lshidpp.git/plain/doc/ http://6xq.net/git/lars/lshidpp.git/plain/doc/
""" """
from __future__ import absolute_import, division, print_function, unicode_literals
import logging import logging
_DEBUG = logging.DEBUG _DEBUG = logging.DEBUG

View File

@ -3,6 +3,8 @@
# Unlikely to be used directly unless you're expanding the API. # 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 time import time as _timestamp
from struct import pack as _pack from struct import pack as _pack
from random import getrandbits as _random_bits 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 # the data is padded to either 5 or 18 bytes
if len(data) > _SHORT_MESSAGE_SIZE - 2 or data[:1] == b'\x82': 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: else:
wdata = _pack('!BB5s', 0x10, devnumber, data) wdata = _pack(b'!BB5s', 0x10, devnumber, data)
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("(%s) <= w[%02X %02X %s %s]", handle, ord(wdata[:1]), devnumber, _strhex(wdata[2:4]), _strhex(wdata[4:])) _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 from collections import namedtuple
_Event = namedtuple('_Event', ['devnumber', 'sub_id', 'address', 'data']) _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.__str__ = lambda self: 'Event(%d,%02X,%02X,%s)' % (self.devnumber, self.sub_id, self.address, _strhex(self.data))
_Event.__unicode__ = _Event.__str__
del namedtuple del namedtuple
def make_event(devnumber, data): 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 request_id = (request_id & 0xFFF0) | _random_bits(4) | 0x01
else: else:
timeout = _RECEIVER_REQUEST_TIMEOUT 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): # if _log.isEnabledFor(_DEBUG):
# _log.debug("(%s) device %d request_id {%04X} params [%s]", handle, devnumber, request_id, _strhex(params)) # _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 # and set the last (0) bit in swid to make it easier to distinguish requests
# from events # from events
request_id = 0x0010 | _random_bits(4) | 0x01 request_id = 0x0010 | _random_bits(4) | 0x01
request_str = _pack('!H', request_id) request_str = _pack(b'!H', request_id)
ping_mark = _pack('B', _random_bits(8)) ping_mark = _pack(b'B', _random_bits(8))
write(ihandle, devnumber, request_str + b'\x00\x00' + ping_mark) write(ihandle, devnumber, request_str + b'\x00\x00' + ping_mark)
while True: while True:

View File

@ -2,12 +2,17 @@
# Some common functions and types. # Some common functions and types.
# #
from __future__ import absolute_import, division, print_function, unicode_literals
from binascii import hexlify as _hexlify from binascii import hexlify as _hexlify
from struct import pack as _pack from struct import pack as _pack
class NamedInt(int): 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): def __new__(cls, value, name):
obj = int.__new__(cls, value) obj = int.__new__(cls, value)
@ -17,23 +22,50 @@ class NamedInt(int):
def bytes(self, count=2): def bytes(self, count=2):
value = int(self) value = int(self)
if value.bit_length() > count * 8: 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): def __eq__(self, other):
try: if isinstance(other, int):
if int(self) == int(other): return int(self) == int(other)
return True
except:
pass
return self.name.lower() == str(other).lower()
def __cmp__(self, other): if isinstance(other, str):
return int(self) - int(other) 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): def __str__(self):
return self.name return self.name
__unicode__ = __str__
def __repr__(self): def __repr__(self):
return 'NamedInt(%d, %s)' % (int(self), repr(self.name)) return 'NamedInt(%d, %s)' % (int(self), repr(self.name))

View File

@ -2,6 +2,8 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
from collections import namedtuple from collections import namedtuple
from .common import NamedInts as _NamedInts from .common import NamedInts as _NamedInts

View File

@ -2,6 +2,8 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
from .common import (strhex as _strhex, from .common import (strhex as _strhex,
NamedInts as _NamedInts, NamedInts as _NamedInts,
FirmwareInfo as _FirmwareInfo) FirmwareInfo as _FirmwareInfo)

View File

@ -2,6 +2,8 @@
# Logitech Unifying Receiver API. # Logitech Unifying Receiver API.
# #
from __future__ import absolute_import, division, print_function, unicode_literals
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 weakref import proxy as _proxy
@ -152,7 +154,7 @@ class FeaturesArray(object):
self.device = None self.device = None
return False 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: if reply is None:
self.supported = False self.supported = False
else: else:
@ -186,7 +188,7 @@ class FeaturesArray(object):
if self.features[index] is None: if self.features[index] is None:
feature = self.device.feature_request(FEATURE.FEATURE_SET, 0x10, index) feature = self.device.feature_request(FEATURE.FEATURE_SET, 0x10, index)
if feature: if feature:
feature, = _unpack('!H', feature[:2]) feature, = _unpack(b'!H', feature[:2])
self.features[index] = FEATURE[feature] self.features[index] = FEATURE[feature]
return self.features[index] return self.features[index]
@ -203,7 +205,7 @@ class FeaturesArray(object):
break break
if may_have: 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: if reply:
index = ord(reply[0:1]) index = ord(reply[0:1])
if index: if index:
@ -222,7 +224,7 @@ class FeaturesArray(object):
raise ValueError("%s not in list" % repr(value)) raise ValueError("%s not in list" % repr(value))
if may_have: 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: if reply:
index = ord(reply[0:1]) index = ord(reply[0:1])
self.features[index] = FEATURE[int(value)] self.features[index] = FEATURE[int(value)]
@ -263,7 +265,7 @@ class KeysArray(object):
if self.keys[index] is None: if self.keys[index] is None:
keydata = feature_request(self.device, FEATURE.REPROGRAMMABLE_KEYS, 0x10, index) keydata = feature_request(self.device, FEATURE.REPROGRAMMABLE_KEYS, 0x10, index)
if keydata: 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) self.keys[index] = _ReprogrammableKeyInfo(index, KEY[key], KEY[key_task], flags)
return self.keys[index] return self.keys[index]
@ -293,7 +295,7 @@ class KeysArray(object):
class ToggleFN_Setting(_settings.Setting): class ToggleFN_Setting(_settings.Setting):
def __init__(self): 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' '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' 'and you must hold the FN key to activate their standard function.\n'
'\n' '\n'
@ -339,7 +341,7 @@ def get_firmware(device):
if fw_info: if fw_info:
level = ord(fw_info[:1]) & 0x0F level = ord(fw_info[:1]) & 0x0F
if level == 0 or level == 1: 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) version = '%02X.%02X' % (version_major, version_minor)
if build: if build:
version += '.B%04X' % build version += '.B%04X' % build
@ -398,7 +400,7 @@ def get_battery(device):
""" """
battery = feature_request(device, FEATURE.BATTERY) battery = feature_request(device, FEATURE.BATTERY)
if battery: if battery:
discharge, dischargeNext, status = _unpack('!BBB', battery[:3]) discharge, dischargeNext, status = _unpack(b'!BBB', battery[:3])
if _log.isEnabledFor(_DEBUG): if _log.isEnabledFor(_DEBUG):
_log.debug("device %d battery %d%% charged, next level %d%% charge, status %d = %s", _log.debug("device %d battery %d%% charged, next level %d%% charge, status %d = %s",
device.number, discharge, dischargeNext, status, BATTERY_STATUS[status]) device.number, discharge, dischargeNext, status, BATTERY_STATUS[status])

View File

@ -2,6 +2,8 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
import threading as _threading import threading as _threading
from time import time as _timestamp from time import time as _timestamp
@ -70,6 +72,7 @@ class ThreadedHandle(object):
def __str__(self): def __str__(self):
if self._local: if self._local:
return str(int(self)) return str(int(self))
__unicode__ = __str__
def __repr__(self): def __repr__(self):
return '<ThreadedHandle(%s)>' % self.path return '<ThreadedHandle(%s)>' % self.path

View File

@ -2,6 +2,8 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
import errno as _errno import errno as _errno
from weakref import proxy as _proxy from weakref import proxy as _proxy
from collections import defaultdict as _defaultdict from collections import defaultdict as _defaultdict
@ -175,18 +177,30 @@ class PairedDevice(object):
return self.number return self.number
__int__ = __index__ __int__ = __index__
def __hash__(self): def __lt__(self, other):
return self.number return self.number < other.number
def __cmp__(self, other): def __le__(self, other):
return self.number - other.number 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): def __eq__(self, other):
return self.receiver == other.receiver and self.number == other.number 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): def __str__(self):
return '<PairedDevice(%d,%s)>' % (self.number, self.codename or '?') return '<PairedDevice(%d,%s)>' % (self.number, self.codename or '?')
__repr__ = __str__ __unicode__ = __repr__ = __str__
# #
# #
@ -330,7 +344,7 @@ class Receiver(object):
def __str__(self): def __str__(self):
return '<Receiver(%s,%s%s)>' % (self.path, '' if type(self.handle) == int else 'T', self.handle) return '<Receiver(%s,%s%s)>' % (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 __bool__ = __nonzero__ = lambda self: self.handle is not None

View File

@ -2,6 +2,8 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
from weakref import proxy as _proxy from weakref import proxy as _proxy
from copy import copy as _copy from copy import copy as _copy
@ -44,3 +46,4 @@ class Setting(object):
def __str__(self): def __str__(self):
return '<%s(%s=%s)>' % (self.__class__.__name__, self.name, self._value) return '<%s(%s=%s)>' % (self.__class__.__name__, self.name, self._value)
__unicode__ = __repr__ = __str__

View File

@ -2,6 +2,8 @@
# #
# #
from __future__ import absolute_import, division, print_function, unicode_literals
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 weakref import proxy as _proxy
@ -54,6 +56,7 @@ class ReceiverStatus(dict):
return ('No devices found.' if count == 0 else return ('No devices found.' if count == 0 else
'1 device found.' if count == 1 else '1 device found.' if count == 1 else
'%d devices found.' % count) '%d devices found.' % count)
__unicode__ = __str__
def _changed(self, alert=ALERT.LOW, reason=None): def _changed(self, alert=ALERT.LOW, reason=None):
# self.updated = _timestamp() # self.updated = _timestamp()
@ -104,6 +107,7 @@ class DeviceStatus(dict):
if self.get(LIGHT_LEVEL) is not None: if self.get(LIGHT_LEVEL) is not None:
t.append('Light: %d lux' % self[LIGHT_LEVEL]) t.append('Light: %d lux' % self[LIGHT_LEVEL])
return ', '.join(t) return ', '.join(t)
__unicode__ = __str__
def __bool__(self): def __bool__(self):
return bool(self._active) return bool(self._active)
@ -247,7 +251,7 @@ class DeviceStatus(dict):
if feature == _hidpp20.FEATURE.SOLAR_CHARGE: if feature == _hidpp20.FEATURE.SOLAR_CHARGE:
if event.data[5:9] == b'GOOD': 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 self[BATTERY_LEVEL] = charge
# guesstimate the battery voltage, emphasis on 'guess' # guesstimate the battery voltage, emphasis on 'guess'
self[BATTERY_STATUS] = '%1.2fV' % (adc * 2.67793237653 / 0x0672) self[BATTERY_STATUS] = '%1.2fV' % (adc * 2.67793237653 / 0x0672)