cleanups in api

This commit is contained in:
Daniel Pavel 2012-10-07 20:19:57 +03:00
parent 3fdec81cf2
commit 8ee2940106
8 changed files with 60 additions and 80 deletions

View File

@ -49,11 +49,13 @@ _REQUEST_STATUS_FUNCTIONS = _FDict()
_REQUEST_STATUS_FUNCTIONS[k750.NAME] = k750.request_status
def request_status(devinfo, listener):
return _REQUEST_STATUS_FUNCTIONS[devinfo.name](devinfo, listener) or default_request_status(devinfo, listener) or ping(devinfo, listener)
if listener:
return _REQUEST_STATUS_FUNCTIONS[devinfo.name](devinfo, listener) or default_request_status(devinfo, listener) or ping(devinfo, listener)
_PROCESS_EVENT_FUNCTIONS = _FDict()
_PROCESS_EVENT_FUNCTIONS[k750.NAME] = k750.process_event
def process_event(devinfo, listener, data):
return default_process_event(devinfo, listener, data) or _PROCESS_EVENT_FUNCTIONS[devinfo.name](devinfo, listener, data)
if listener:
return default_process_event(devinfo, listener, data) or _PROCESS_EVENT_FUNCTIONS[devinfo.name](devinfo, listener, data)

View File

@ -10,7 +10,7 @@ STATUS = type('STATUS', (),
))
STATUS_NAME = {
STATUS.UNAVAILABLE: 'disconnected?',
STATUS.UNAVAILABLE: 'inactive',
STATUS.CONNECTED: 'connected',
}

View File

@ -48,9 +48,10 @@ def _charge_status(data, hasLux=False):
def request_status(devinfo, listener):
reply = listener.request(_trigger_solar_charge_events, devinfo)
if reply is None:
return C.STATUS.UNAVAILABLE
if listener:
reply = listener.request(_trigger_solar_charge_events, devinfo)
if reply is None:
return C.STATUS.UNAVAILABLE
def process_event(devinfo, listener, data):
@ -64,7 +65,7 @@ def process_event(devinfo, listener, data):
if data[:2] == b'\x09\x20' and data[7:11] == b'GOOD':
logging.debug("Solar key pressed")
if _trigger_solar_charge_events(listener.receiver, devinfo) is None:
if listener and _trigger_solar_charge_events(listener.receiver, devinfo) is None:
return C.STATUS.UNAVAILABLE
return _charge_status(data)

View File

@ -17,7 +17,7 @@ from . import base as _base
_LOG_LEVEL = 5
_l = logging.getLogger('logitech.unifying_receiver.api')
_l = logging.getLogger('lur.api')
#
#
@ -86,47 +86,8 @@ def ping(handle, devnumber):
not attached, None if no conclusive reply is received.
"""
ping_marker = b'\xAA'
def _status(reply):
if not reply:
return None
reply_code, reply_devnumber, reply_data = reply
if reply_devnumber != devnumber:
# oops
_l.log(_LOG_LEVEL, "(%d,%d) ping: reply for another device %d: %s", handle, devnumber, reply_devnumber, _hexlify(reply_data))
_unhandled._publish(reply_code, reply_devnumber, reply_data)
return _status(_base.read(handle))
if (reply_code == 0x11 and reply_data[:2] == b'\x00\x10' and reply_data[4:5] == ping_marker):
# ping ok
_l.log(_LOG_LEVEL, "(%d,%d) ping: ok [%s]", handle, devnumber, _hexlify(reply_data))
return True
if (reply_code == 0x10 and reply_data[:2] == b'\x8F\x00'):
# ping failed
_l.log(_LOG_LEVEL, "(%d,%d) ping: device not present", handle, devnumber)
return False
if (reply_code == 0x11 and reply_data[:2] == b'\x09\x00' and len(reply_data) == 18 and reply_data[7:11] == b'GOOD'):
# some devices may reply with a SOLAR_CHARGE event before the
# ping_ok reply, especially right after the device connected to the
# receiver
_l.log(_LOG_LEVEL, "(%d,%d) ping: solar status [%s]", handle, devnumber, _hexlify(reply_data))
_unhandled._publish(reply_code, reply_devnumber, reply_data)
return _status(_base.read(handle))
# ugh
_l.log(_LOG_LEVEL, "(%d,%d) ping: unknown reply for this device: %d=[%s]", handle, devnumber, reply_code, _hexlify(reply_data))
_unhandled._publish(reply_code, reply_devnumber, reply_data)
return None
_l.log(_LOG_LEVEL, "(%d,%d) pinging", handle, devnumber)
_base.write(handle, devnumber, b'\x00\x10\x00\x00' + ping_marker)
# pings may take a while to reply success
return _status(_base.read(handle, _base.DEFAULT_TIMEOUT * 3))
reply = _base.request(handle, devnumber, b'\x00\x10', b'\x00\x00\xAA')
return reply is not None and reply[2:3] == b'\xAA'
def find_device_by_name(handle, device_name):
@ -195,20 +156,21 @@ def get_feature_index(handle, devnumber, feature):
feature_index = ord(reply[0:1])
if feature_index:
feature_flags = ord(reply[1:2]) & 0xE0
_l.log(_LOG_LEVEL, "(%d,%d) feature <%s:%s> has index %d flags %02x", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature], feature_index, feature_flags)
if feature_flags == 0:
return feature_index
if _l.isEnabledFor(_LOG_LEVEL):
if feature_flags:
_l.log(_LOG_LEVEL, "(%d,%d) feature <%s:%s> has index %d: %s",
handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature], feature_index,
','.join([C.FEATURE_FLAGS[k] for k in C.FEATURE_FLAGS if feature_flags & k]))
else:
_l.log(_LOG_LEVEL, "(%d,%d) feature <%s:%s> has index %d", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature], feature_index)
if feature_flags & 0x80:
_l.warn("(%d,%d) feature <%s:%s> not supported: obsolete", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature])
if feature_flags & 0x40:
_l.warn("(%d,%d) feature <%s:%s> not supported: hidden", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature])
if feature_flags & 0x20:
_l.warn("(%d,%d) feature <%s:%s> not supported: Logitech internal", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature])
raise E.FeatureNotSupported(devnumber, feature)
else:
_l.warn("(%d,%d) feature <%s:%s> not supported by the device", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature])
raise E.FeatureNotSupported(devnumber, feature)
# if feature_flags:
# raise E.FeatureNotSupported(devnumber, feature)
return feature_index
_l.warn("(%d,%d) feature <%s:%s> not supported by the device", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature])
raise E.FeatureNotSupported(devnumber, feature)
def get_device_features(handle, devnumber):
@ -246,9 +208,17 @@ def get_device_features(handle, devnumber):
# for each index, get the feature residing at that index
feature = _base.request(handle, devnumber, fs_index + b'\x10', _pack('!B', index))
if feature:
feature_flags = ord(feature[2:3]) & 0xE0
feature = feature[0:2].upper()
features[index] = feature
_l.log(_LOG_LEVEL, "(%d,%d) feature <%s:%s> at index %d", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature], index)
if _l.isEnabledFor(_LOG_LEVEL):
if feature_flags:
_l.log(_LOG_LEVEL, "(%d,%d) feature <%s:%s> at index %d: %s",
handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature], index,
','.join([C.FEATURE_FLAGS[k] for k in C.FEATURE_FLAGS if feature_flags & k]))
else:
_l.log(_LOG_LEVEL, "(%d,%d) feature <%s:%s> at index %d", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature], index)
features[0] = C.FEATURE.ROOT
while features[-1] is None:
@ -278,11 +248,8 @@ def get_device_firmware(handle, devnumber, features_array=None):
fw_type = C.FIRMWARE_TYPE[fw_level]
name, = _unpack('!3s', fw_info[1:4])
name = name.decode('ascii')
version = ( chr(0x30 + (ord(fw_info[4:5]) >> 4)) +
chr(0x30 + (ord(fw_info[4:5]) & 0x0F)) +
'.' +
chr(0x30 + (ord(fw_info[5:6]) >> 4)) +
chr(0x30 + (ord(fw_info[5:6]) & 0x0F)))
version = _hexlify(fw_info[4:6])
version = '%s.%s' % (version[0:2], version[2:4])
build, = _unpack('!H', fw_info[6:8])
extras = fw_info[9:].rstrip(b'\x00')
if extras:
@ -327,8 +294,11 @@ def get_device_name(handle, devnumber, features_array=None):
while len(d_name) < name_length:
name_index = _pack('!B', len(d_name))
name_fragment = request(handle, devnumber, C.FEATURE.NAME, function=b'\x10', params=name_index, features_array=features_array)
name_fragment = name_fragment[:name_length - len(d_name)]
d_name += name_fragment
if name_fragment:
name_fragment = name_fragment[:name_length - len(d_name)]
d_name += name_fragment
else:
break
d_name = d_name.decode('ascii')
_l.log(_LOG_LEVEL, "(%d,%d) device name %s", handle, devnumber, d_name)

View File

@ -45,6 +45,9 @@ FEATURE_NAME[FEATURE.WIRELESS] = 'WIRELESS'
FEATURE_NAME[FEATURE.SOLAR_CHARGE] = 'SOLAR_CHARGE'
FEATURE_FLAGS = { 0x20: 'internal', 0x40: 'hidden', 0x80: 'obsolete' }
_DEVICE_TYPES = ('Keyboard', 'Remote Control', 'NUMPAD', 'Mouse',
'Touchpad', 'Trackball', 'Presenter', 'Receiver')

View File

@ -5,7 +5,7 @@
import logging
import threading
from time import sleep as _sleep
# from binascii import hexlify as _hexlify
from binascii import hexlify as _hexlify
from . import base as _base
from . import exceptions as E
@ -13,11 +13,11 @@ from . import exceptions as E
_LOG_LEVEL = 6
_l = logging.getLogger('logitech.unifying_receiver.listener')
_l = logging.getLogger('lur.listener')
_READ_EVENT_TIMEOUT = 90 # ms
_IDLE_SLEEP = 950 # ms
_READ_EVENT_TIMEOUT = int(_base.DEFAULT_TIMEOUT * 0.1) # ms
_IDLE_SLEEP = int(_base.DEFAULT_TIMEOUT * 0.9) # ms
class EventsListener(threading.Thread):
@ -64,7 +64,8 @@ class EventsListener(threading.Thread):
if self.active:
if event:
_l.log(_LOG_LEVEL, "(%d) got event %s", self.receiver, event)
if _l.isEnabledFor(_LOG_LEVEL):
_l.log(_LOG_LEVEL, "(%d) got event (%02x %02x [%s])", self.receiver, event[0], event[1], _hexlify(event[2]))
self.callback.__call__(*event)
elif self.task is None:
# _l.log(_LOG_LEVEL, "(%d) idle sleep", self.receiver)
@ -86,7 +87,8 @@ class EventsListener(threading.Thread):
The api_function will get the receiver handle as a first agument, all
other args and kwargs will follow.
"""
# _l.log(_LOG_LEVEL, "(%d) request '%s.%s' with %s, %s", self.receiver, api_function.__module__, api_function.__name__, args, kwargs)
# if _l.isEnabledFor(_LOG_LEVEL):
# _l.log(_LOG_LEVEL, "(%d) request '%s.%s' with %s, %s", self.receiver, api_function.__module__, api_function.__name__, args, kwargs)
self.task_processing.acquire()
self.task_done.clear()
self.task = (api_function, args, kwargs)
@ -96,13 +98,15 @@ class EventsListener(threading.Thread):
self.task = self.task_reply = None
self.task_processing.release()
# _l.log(_LOG_LEVEL, "(%d) request '%s.%s' => [%s]", self.receiver, api_function.__module__, api_function.__name__, _hexlify(reply))
# if _l.isEnabledFor(_LOG_LEVEL):
# _l.log(_LOG_LEVEL, "(%d) request '%s.%s' => [%s]", self.receiver, api_function.__module__, api_function.__name__, _hexlify(reply))
if isinstance(reply, Exception):
raise reply
return reply
def _make_request(self, api_function, args, kwargs):
_l.log(_LOG_LEVEL, "(%d) calling '%s.%s' with %s, %s", self.receiver, api_function.__module__, api_function.__name__, args, kwargs)
if _l.isEnabledFor(_LOG_LEVEL):
_l.log(_LOG_LEVEL, "(%d) calling '%s.%s' with %s, %s", self.receiver, api_function.__module__, api_function.__name__, args, kwargs)
try:
return api_function.__call__(self.receiver, *args, **kwargs)
except E.NoReceiver as nr:

View File

@ -9,7 +9,7 @@ from binascii import hexlify as _hexlify
def _logdebug_hook(reply_code, devnumber, data):
"""Default unhandled hook, logs the reply as DEBUG."""
_l = logging.getLogger('logitech.unifying_receiver.unhandled')
_l = logging.getLogger('lur.unhandled')
_l.debug("UNHANDLED (,%d) code 0x%02x data [%s]", devnumber, reply_code, _hexlify(data))

View File

@ -16,7 +16,7 @@ if __name__ == '__main__':
arg_parser.add_argument('-H', '--start-hidden', action='store_true', dest='start_hidden',
help='hide the application window on start')
arg_parser.add_argument('-t', '--close-to-tray', action='store_true',
help='closing the application window hides it')
help='closing the application window hides it instead of terminating the application')
arg_parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__)
args = arg_parser.parse_args()