I come from the __future__, come with me if you want to live.
This commit is contained in:
parent
c4be58f074
commit
b86dcce381
|
@ -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):
|
||||||
|
|
|
@ -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>"
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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 *
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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])
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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__
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue