Example #1
0
def _print_receiver(receiver):
    paired_count = receiver.count()

    print(receiver.name)
    print('  Device path  :', receiver.path)
    print('  USB id       : 046d:%s' % receiver.product_id)
    print('  Serial       :', receiver.serial)
    if receiver.firmware:
        for f in receiver.firmware:
            print('    %-11s: %s' % (f.kind, f.version))

    print('  Has', paired_count,
          'paired device(s) out of a maximum of %d.' % receiver.max_devices)
    if receiver.remaining_pairings() and receiver.remaining_pairings() >= 0:
        print('  Has %d successful pairing(s) remaining.' %
              receiver.remaining_pairings())

    notification_flags = _hidpp10.get_notification_flags(receiver)
    if notification_flags is not None:
        if notification_flags:
            notification_names = _hidpp10.NOTIFICATION_FLAG.flag_names(
                notification_flags)
            print('  Notifications: %s (0x%06X)' %
                  (', '.join(notification_names), notification_flags))
        else:
            print('  Notifications: (none)')

    activity = receiver.read_register(_hidpp10.REGISTERS.devices_activity)
    if activity:
        activity = [(d, ord(activity[d - 1:d]))
                    for d in range(1, receiver.max_devices)]
        activity_text = ', '.join(
            ('%d=%d' % (d, a)) for d, a in activity if a > 0)
        print('  Device activity counters:', activity_text or '(empty)')
Example #2
0
def _print_receiver(receiver):
	paired_count = receiver.count()

	print ('Unifying Receiver')
	print ('  Device path  :', receiver.path)
	print ('  USB id       : 046d:%s' % receiver.product_id)
	print ('  Serial       :', receiver.serial)
	for f in receiver.firmware:
		print ('    %-11s: %s' % (f.kind, f.version))

	print ('  Has', paired_count, 'paired device(s) out of a maximum of %d.' % receiver.max_devices)

	notification_flags = _hidpp10.get_notification_flags(receiver)
	if notification_flags is not None:
		if notification_flags:
			notification_names = _hidpp10.NOTIFICATION_FLAG.flag_names(notification_flags)
			print ('  Notifications: %s (0x%06X)' % (', '.join(notification_names), notification_flags))
		else:
			print ('  Notifications: (none)')

	activity = receiver.read_register(_hidpp10.REGISTERS.devices_activity)
	if activity:
		activity = [(d, ord(activity[d - 1:d])) for d in range(1, receiver.max_devices)]
		activity_text = ', '.join(('%d=%d' % (d, a)) for d, a in activity if a > 0)
		print ('  Device activity counters:', activity_text or '(empty)')
Example #3
0
def _print_receiver(receiver, verbose=False):
	paired_count = receiver.count()
	if not verbose:
		print ("Unifying Receiver [%s:%s] with %d devices" % (receiver.path, receiver.serial, paired_count))
		return

	print ("Unifying Receiver")
	print ("   Device path  :", receiver.path)
	print ("   USB id       : 046d:%s" % receiver.product_id)
	print ("   Serial       :", receiver.serial)
	for f in receiver.firmware:
		print ("     %-11s: %s" % (f.kind, f.version))

	print ("   Has", paired_count, "paired device(s) out of a maximum of", receiver.max_devices, ".")

	from logitech_receiver import hidpp10
	notification_flags = hidpp10.get_notification_flags(receiver)
	if notification_flags is not None:
		if notification_flags:
			notification_names = hidpp10.NOTIFICATION_FLAG.flag_names(notification_flags)
			print ("   Notifications: 0x%06X = %s" % (notification_flags, ', '.join(notification_names)))
		else:
			print ("   Notifications: (none)")

	activity = receiver.read_register(hidpp10.REGISTERS.devices_activity)
	if activity:
		activity = [(d, ord(activity[d - 1:d])) for d in range(1, receiver.max_devices)]
		activity_text = ', '.join(('%d=%d' % (d, a)) for d, a in activity if a > 0)
		print ("   Device activity counters:", activity_text or '(empty)')
Example #4
0
def run(receivers, args, find_receiver, _ignore):
	assert receivers

	if args.receiver:
		receiver_name = args.receiver.lower()
		receiver = find_receiver(receiver_name)
		if not receiver:
			raise Exception("no receiver found matching '%s'" % receiver_name)
	else:
		receiver = receivers[0]

	assert receiver
	receiver.status = _status.ReceiverStatus(receiver, lambda *args, **kwargs: None)

	# check if it's necessary to set the notification flags
	old_notification_flags = _hidpp10.get_notification_flags(receiver) or 0
	if not (old_notification_flags & _hidpp10.NOTIFICATION_FLAG.wireless):
		_hidpp10.set_notification_flags(receiver, old_notification_flags | _hidpp10.NOTIFICATION_FLAG.wireless)

	# get all current devices
	known_devices = [dev.number for dev in receiver]

	class _HandleWithNotificationHook(int):
		def notifications_hook(self, n):
			assert n
			if n.devnumber == 0xFF:
				_notifications.process(receiver, n)
			elif n.sub_id == 0x41 and n.address == 0x04:
				if n.devnumber not in known_devices:
					receiver.status.new_device = receiver[n.devnumber]

	timeout = 20  # seconds
	receiver.handle = _HandleWithNotificationHook(receiver.handle)

	receiver.set_lock(False, timeout=timeout)
	print ('Pairing: turn your new device on (timing out in', timeout, 'seconds).')

	# the lock-open notification may come slightly later, wait for it a bit
	pairing_start = _timestamp()
	patience = 5  # seconds

	while receiver.status.lock_open or _timestamp() - pairing_start < patience:
		n = _base.read(receiver.handle)
		if n:
			n = _base.make_notification(*n)
			if n:
				receiver.handle.notifications_hook(n)

	if not (old_notification_flags & _hidpp10.NOTIFICATION_FLAG.wireless):
		# only clear the flags if they weren't set before, otherwise a
		# concurrently running Solaar app might stop working properly
		_hidpp10.set_notification_flags(receiver, old_notification_flags)

	if receiver.status.new_device:
		dev = receiver.status.new_device
		print ('Paired device %d: %s (%s) [%s:%s]' % (dev.number, dev.name, dev.codename, dev.wpid, dev.serial))
	else:
		error = receiver.status.get(_status.KEYS.ERROR) or 'no device detected?'
		raise Exception("pairing failed: %s" % error)
Example #5
0
def pair_device(receiver, args):
	# get all current devices
	known_devices = [dev.number for dev in receiver]

	from logitech_receiver import base, hidpp10, status, notifications
	receiver.status = status.ReceiverStatus(receiver, lambda *args, **kwargs: None)

	# check if it's necessary to set the notification flags
	old_notification_flags = hidpp10.get_notification_flags(receiver) or 0
	if not (old_notification_flags & hidpp10.NOTIFICATION_FLAG.wireless):
		hidpp10.set_notification_flags(receiver, old_notification_flags | hidpp10.NOTIFICATION_FLAG.wireless)

	class HandleWithNotificationHook(int):
		def notifications_hook(self, n):
			assert n
			if n.devnumber == 0xFF:
				notifications.process(receiver, n)
			elif n.sub_id == 0x41 and n.address == 0x04:
				if n.devnumber not in known_devices:
					receiver.status.new_device = receiver[n.devnumber]

	timeout = 20  # seconds
	receiver.handle = HandleWithNotificationHook(receiver.handle)
	receiver.set_lock(False, timeout=timeout)
	print ("Pairing: turn your new device on (timing out in", timeout, "seconds).")

	# the lock-open notification may come slightly later, wait for it a bit
	from time import time as timestamp
	pairing_start = timestamp()
	patience = 5  # seconds

	while receiver.status.lock_open or timestamp() - pairing_start < patience:
		n = base.read(receiver.handle)
		if n:
			n = base.make_notification(*n)
			if n:
				receiver.handle.notifications_hook(n)

	if not (old_notification_flags & hidpp10.NOTIFICATION_FLAG.wireless):
		# only clear the flags if they weren't set before, otherwise a
		# concurrently running Solaar app might stop working properly
		hidpp10.set_notification_flags(receiver, old_notification_flags)

	if receiver.status.new_device:
		dev = receiver.status.new_device
		print ("Paired device %d: %s [%s:%s:%s]" % (dev.number, dev.name, dev.wpid, dev.codename, dev.serial))
	else:
		error = receiver.status[status.KEYS.ERROR] or 'no device detected?'
		_fail(error)
Example #6
0
def _print_device(dev):
	assert dev

	print ('  %d: %s' % (dev.number, dev.name))
	print ('     Codename     :', dev.codename)
	print ('     Kind         :', dev.kind)
	print ('     Wireless PID :', dev.wpid)
	if dev.protocol:
		print ('     Protocol     : HID++ %1.1f' % dev.protocol)
	else:
		print ('     Protocol     : unknown (device is offline)')
	if dev.polling_rate:
		print ('     Polling rate :', dev.polling_rate, 'ms (%dHz)' % (1000 // dev.polling_rate))
	print ('     Serial number:', dev.serial)
	for fw in dev.firmware:
		print ('       %11s:' % fw.kind, (fw.name + ' ' + fw.version).strip())

	if dev.power_switch_location:
		print ('     The power switch is located on the %s.' % dev.power_switch_location)

	if dev.online:
		notification_flags = _hidpp10.get_notification_flags(dev)
		if notification_flags is not None:
			if notification_flags:
				notification_names = _hidpp10.NOTIFICATION_FLAG.flag_names(notification_flags)
				print ('     Notifications: %s (0x%06X).' % (', '.join(notification_names), notification_flags))
			else:
				print ('     Notifications: (none).')

	if dev.online and dev.features:
		print ('     Supports %d HID++ 2.0 features:' % len(dev.features))
		for index, feature in enumerate(dev.features):
			feature = dev.features[index]
			flags = dev.request(0x0000, feature.bytes(2))
			flags = 0 if flags is None else ord(flags[1:2])
			flags = _hidpp20.FEATURE_FLAG.flag_names(flags)
			print ('        %2d: %-22s {%04X}   %s' % (index, feature, feature, ', '.join(flags)))

	if dev.online and dev.keys:
		print ('     Has %d reprogrammable keys:' % len(dev.keys))
		for k in dev.keys:
			flags = _special_keys.KEY_FLAG.flag_names(k.flags)
			print ('        %2d: %-26s => %-27s   %s' % (k.index, k.key, k.task, ', '.join(flags)))
	_print_battery_status(dev)
Example #7
0
def _print_device(dev):
    assert dev
    # check if the device is online
    dev.ping()

    print('  %d: %s' % (dev.number, dev.name))
    print('     Codename     :', dev.codename)
    print('     Kind         :', dev.kind)
    print('     Wireless PID :', dev.wpid)
    if dev.protocol:
        print('     Protocol     : HID++ %1.1f' % dev.protocol)
    else:
        print('     Protocol     : unknown (device is offline)')
    if dev.polling_rate:
        print('     Polling rate :', dev.polling_rate,
              'ms (%dHz)' % (1000 // dev.polling_rate))
    print('     Serial number:', dev.serial)
    if dev.firmware:
        for fw in dev.firmware:
            print('       %11s:' % fw.kind,
                  (fw.name + ' ' + fw.version).strip())

    if dev.power_switch_location:
        print('     The power switch is located on the %s.' %
              dev.power_switch_location)

    if dev.online:
        notification_flags = _hidpp10.get_notification_flags(dev)
        if notification_flags is not None:
            if notification_flags:
                notification_names = _hidpp10.NOTIFICATION_FLAG.flag_names(
                    notification_flags)
                print('     Notifications: %s (0x%06X).' %
                      (', '.join(notification_names), notification_flags))
            else:
                print('     Notifications: (none).')
        device_features = _hidpp10.get_device_features(dev)
        if device_features is not None:
            if device_features:
                device_features_names = _hidpp10.DEVICE_FEATURES.flag_names(
                    device_features)
                print('     Features: %s (0x%06X)' %
                      (', '.join(device_features_names), device_features))
            else:
                print('     Features: (none)')

    if dev.online and dev.features:
        print('     Supports %d HID++ 2.0 features:' % len(dev.features))
        dev.persister = None  # Give the device a fake persister
        dev_settings = []
        _settings_templates.check_feature_settings(dev, dev_settings)
        for index, feature in enumerate(dev.features):
            feature = dev.features[index]
            flags = dev.request(0x0000, feature.bytes(2))
            flags = 0 if flags is None else ord(flags[1:2])
            flags = _hidpp20.FEATURE_FLAG.flag_names(flags)
            print('        %2d: %-22s {%04X}   %s' %
                  (index, feature, feature, ', '.join(flags)))
            if feature == _hidpp20.FEATURE.HIRES_WHEEL:
                wheel = _hidpp20.get_hires_wheel(dev)
                if wheel:
                    multi, has_invert, has_switch, inv, res, target, ratchet = wheel
                    print('            Multiplier: %s' % multi)
                    if has_invert:
                        print('            Has invert')
                        if inv:
                            print('              Inverse wheel motion')
                        else:
                            print('              Normal wheel motion')
                    if has_switch:
                        print('            Has ratchet switch')
                        if ratchet:
                            print('              Normal wheel mode')
                        else:
                            print('              Free wheel mode')
                    if res:
                        print('            High resolution mode')
                    else:
                        print('            Low resolution mode')
                    if target:
                        print('            HID++ notification')
                    else:
                        print('            HID notification')
            elif feature == _hidpp20.FEATURE.MOUSE_POINTER:
                mouse_pointer = _hidpp20.get_mouse_pointer_info(dev)
                if mouse_pointer:
                    print('            DPI: %s' % mouse_pointer['dpi'])
                    print('            Acceleration: %s' %
                          mouse_pointer['acceleration'])
                    if mouse_pointer['suggest_os_ballistics']:
                        print('            Use OS ballistics')
                    else:
                        print('            Override OS ballistics')
                    if mouse_pointer['suggest_vertical_orientation']:
                        print('            Provide vertical tuning, trackball')
                    else:
                        print('            No vertical tuning, standard mice')
            if feature == _hidpp20.FEATURE.VERTICAL_SCROLLING:
                vertical_scrolling_info = _hidpp20.get_vertical_scrolling_info(
                    dev)
                if vertical_scrolling_info:
                    print('            Roller type: %s' %
                          vertical_scrolling_info['roller'])
                    print('            Ratchet per turn: %s' %
                          vertical_scrolling_info['ratchet'])
                    print('            Scroll lines: %s' %
                          vertical_scrolling_info['lines'])
            elif feature == _hidpp20.FEATURE.HI_RES_SCROLLING:
                scrolling_mode, scrolling_resolution = _hidpp20.get_hi_res_scrolling_info(
                    dev)
                if scrolling_mode:
                    print('            Hi-res scrolling enabled')
                else:
                    print('            Hi-res scrolling disabled')
                if scrolling_resolution:
                    print('            Hi-res scrolling multiplier: %s' %
                          scrolling_resolution)
            elif feature == _hidpp20.FEATURE.POINTER_SPEED:
                pointer_speed = _hidpp20.get_pointer_speed_info(dev)
                if pointer_speed:
                    print('            Pointer Speed: %s' % pointer_speed)
            elif feature == _hidpp20.FEATURE.LOWRES_WHEEL:
                wheel_status = _hidpp20.get_lowres_wheel_status(dev)
                if wheel_status:
                    print('            Wheel Reports: %s' % wheel_status)
            elif feature == _hidpp20.FEATURE.NEW_FN_INVERSION:
                inverted, default_inverted = _hidpp20.get_new_fn_inversion(dev)
                print('            Fn-swap:',
                      'enabled' if inverted else 'disabled')
                print('            Fn-swap default:',
                      'enabled' if default_inverted else 'disabled')
            elif feature == _hidpp20.FEATURE.HOSTS_INFO:
                host_names = _hidpp20.get_host_names(dev)
                for host, (paired, name) in host_names.items():
                    print('            Host %s (%s): %s' %
                          (host, 'paired' if paired else 'unpaired', name))
            for setting in dev_settings:
                if setting.feature == feature:
                    v = setting.read(False)
                    print('            %s: %s' % (setting.label, v))

    if dev.online and dev.keys:
        print('     Has %d reprogrammable keys:' % len(dev.keys))
        for k in dev.keys:
            flags = _special_keys.KEY_FLAG.flag_names(k.flags)
            # TODO: add here additional variants for other REPROG_CONTROLS
            if dev.keys.keyversion == 1:
                print('        %2d: %-26s => %-27s   %s' %
                      (k.index, k.key, k.task, ', '.join(flags)))
            if dev.keys.keyversion == 4:
                print('        %2d: %-26s, default: %-27s => %-26s' %
                      (k.index, k.key, k.task, k.remapped))
                print('             %s, pos:%d, group:%1d, gmask:%d' %
                      (', '.join(flags), k.pos, k.group, k.group_mask))
    if dev.online:
        battery = _hidpp20.get_battery(dev)
        if battery is None:
            battery = _hidpp10.get_battery(dev)
        if battery is not None:
            level, status, nextLevel = battery
            text = _battery_text(level)
            nextText = '' if nextLevel is None else ', next level ' + _battery_text(
                nextLevel)
            print('     Battery: %s, %s%s.' % (text, status, nextText))
        else:
            battery_voltage = _hidpp20.get_voltage(dev)
            if battery_voltage:
                (level, status, voltage, charge_sts,
                 charge_type) = battery_voltage
                print('     Battery: %smV, %s, %s.' % (voltage, status, level))
            else:
                print('     Battery status unavailable.')
    else:
        print('     Battery: unknown (device is offline).')
Example #8
0
def _print_device(dev):
    assert dev
    # check if the device is online
    dev.ping()

    print('  %d: %s' % (dev.number, dev.name))
    print('     Codename     :', dev.codename)
    print('     Kind         :', dev.kind)
    print('     Wireless PID :', dev.wpid)
    if dev.protocol:
        print('     Protocol     : HID++ %1.1f' % dev.protocol)
    else:
        print('     Protocol     : unknown (device is offline)')
    if dev.polling_rate:
        print('     Polling rate :', dev.polling_rate,
              'ms (%dHz)' % (1000 // dev.polling_rate))
    print('     Serial number:', dev.serial)
    for fw in dev.firmware:
        print('       %11s:' % fw.kind, (fw.name + ' ' + fw.version).strip())

    if dev.power_switch_location:
        print('     The power switch is located on the %s.' %
              dev.power_switch_location)

    if dev.online:
        notification_flags = _hidpp10.get_notification_flags(dev)
        if notification_flags is not None:
            if notification_flags:
                notification_names = _hidpp10.NOTIFICATION_FLAG.flag_names(
                    notification_flags)
                print('     Notifications: %s (0x%06X).' %
                      (', '.join(notification_names), notification_flags))
            else:
                print('     Notifications: (none).')

    if dev.online and dev.features:
        print('     Supports %d HID++ 2.0 features:' % len(dev.features))
        for index, feature in enumerate(dev.features):
            feature = dev.features[index]
            flags = dev.request(0x0000, feature.bytes(2))
            flags = 0 if flags is None else ord(flags[1:2])
            flags = _hidpp20.FEATURE_FLAG.flag_names(flags)
            print('        %2d: %-22s {%04X}   %s' %
                  (index, feature, feature, ', '.join(flags)))
            if feature == _hidpp20.FEATURE.HIRES_WHEEL:
                wheel = _hidpp20.get_hires_wheel(dev)
                if wheel:
                    multi, has_invert, has_switch, inv, res, target, ratchet = wheel
                    print("            Multiplier: %s" % multi)
                    if has_invert:
                        print("            Has invert")
                        if inv:
                            print("              Inverse wheel motion")
                        else:
                            print("              Normal wheel motion")
                    if has_switch:
                        print("            Has ratchet switch")
                        if ratchet:
                            print("              Normal wheel mode")
                        else:
                            print("              Free wheel mode")
                    if res:
                        print("            High resolution mode")
                    else:
                        print("            Low resolution mode")
                    if target:
                        print("            HID++ notification")
                    else:
                        print("            HID notification")
            if feature == _hidpp20.FEATURE.MOUSE_POINTER:
                mouse_pointer = _hidpp20.get_mouse_pointer_info(dev)
                if mouse_pointer:
                    print("            DPI: %s" % mouse_pointer['dpi'])
                    print("            Acceleration: %s" %
                          mouse_pointer['acceleration'])
                    if mouse_pointer['suggest_os_ballistics']:
                        print("            Use OS ballistics")
                    else:
                        print("            Override OS ballistics")
                    if mouse_pointer['suggest_vertical_orientation']:
                        print("            Provide vertical tuning, trackball")
                    else:
                        print("            No vertical tuning, standard mice")
            if feature == _hidpp20.FEATURE.VERTICAL_SCROLLING:
                vertical_scrolling_info = _hidpp20.get_vertical_scrolling_info(
                    dev)
                if vertical_scrolling_info:
                    print("            Roller type: %s" %
                          vertical_scrolling_info['roller'])
                    print("            Ratchet per turn: %s" %
                          vertical_scrolling_info['ratchet'])
                    print("            Scroll lines: %s" %
                          vertical_scrolling_info['lines'])
            if feature == _hidpp20.FEATURE.HI_RES_SCROLLING:
                scrolling_mode, scrolling_resolution = _hidpp20.get_hi_res_scrolling_info(
                    dev)
                if scrolling_mode:
                    print("            Hi-res scrolling enabled")
                else:
                    print("            Hi-res scrolling disabled")
                if scrolling_resolution:
                    print("            Hi-res scrolling multiplier: %s" %
                          scrolling_resolution)
            if feature == _hidpp20.FEATURE.POINTER_SPEED:
                pointer_speed = _hidpp20.get_pointer_speed_info(dev)
                if pointer_speed:
                    print("            Pointer Speed: %s" % pointer_speed)
            if feature == _hidpp20.FEATURE.LOWRES_WHEEL:
                wheel_status = _hidpp20.get_lowres_wheel_status(dev)
                if wheel_status:
                    print("            Wheel Reports: %s" % wheel_status)

    if dev.online and dev.keys:
        print('     Has %d reprogrammable keys:' % len(dev.keys))
        for k in dev.keys:
            flags = _special_keys.KEY_FLAG.flag_names(k.flags)
            # TODO: add here additional variants for other REPROG_CONTROLS
            if dev.keys.keyversion == 1:
                print('        %2d: %-26s => %-27s   %s' %
                      (k.index, k.key, k.task, ', '.join(flags)))
            if dev.keys.keyversion == 4:
                print('        %2d: %-26s, default: %-27s => %-26s' %
                      (k.index, k.key, k.task, k.remapped))
                print('             %s, pos:%d, group:%1d, gmask:%d' %
                      (', '.join(flags), k.pos, k.group, k.group_mask))
    if dev.online:
        battery = _hidpp20.get_battery(dev)
        if battery is None:
            battery = _hidpp10.get_battery(dev)
        if battery is not None:
            from logitech_receiver.common import NamedInt as _NamedInt
            level, status = battery
            if level is not None:
                if isinstance(level, _NamedInt):
                    text = str(level)
                else:
                    text = '%d%%' % level
            else:
                text = 'N/A'
            print('     Battery: %s, %s.' % (text, status))
        else:
            battery_voltage = _hidpp20.get_voltage(dev)
            if battery_voltage:
                (voltage, charging, charge_sts, charge_lvl,
                 charge_type) = battery_voltage
                print('     Battery: %smV, %s.' %
                      (voltage, 'Charging' if charging else 'Discharging'))
            else:
                print('     Battery status unavailable.')
    else:
        print('     Battery: unknown (device is offline).')
Example #9
0
def _print_device(dev, num=None):
    assert dev is not None
    # check if the device is online
    dev.ping()

    print('  %d: %s' % (num or dev.number, dev.name))
    print('     Device path  :', dev.path)
    if dev.wpid:
        print('     WPID         : %s' % dev.wpid)
    if dev.product_id:
        print('     USB id       : 046d:%s' % dev.product_id)
    print('     Codename     :', dev.codename)
    print('     Kind         :', dev.kind)
    if dev.protocol:
        print('     Protocol     : HID++ %1.1f' % dev.protocol)
    else:
        print('     Protocol     : unknown (device is offline)')
    if dev.polling_rate:
        print('     Polling rate :', dev.polling_rate,
              'ms (%dHz)' % (1000 // dev.polling_rate))
    print('     Serial number:', dev.serial)
    if dev.modelId:
        print('     Model ID:     ', dev.modelId)
    if dev.unitId:
        print('     Unit ID:      ', dev.unitId)
    if dev.firmware:
        for fw in dev.firmware:
            print('       %11s:' % fw.kind,
                  (fw.name + ' ' + fw.version).strip())

    if dev.power_switch_location:
        print('     The power switch is located on the %s.' %
              dev.power_switch_location)

    if dev.online:
        notification_flags = _hidpp10.get_notification_flags(dev)
        if notification_flags is not None:
            if notification_flags:
                notification_names = _hidpp10.NOTIFICATION_FLAG.flag_names(
                    notification_flags)
                print('     Notifications: %s (0x%06X).' %
                      (', '.join(notification_names), notification_flags))
            else:
                print('     Notifications: (none).')
        device_features = _hidpp10.get_device_features(dev)
        if device_features is not None:
            if device_features:
                device_features_names = _hidpp10.DEVICE_FEATURES.flag_names(
                    device_features)
                print('     Features: %s (0x%06X)' %
                      (', '.join(device_features_names), device_features))
            else:
                print('     Features: (none)')

    if dev.online and dev.features:
        print('     Supports %d HID++ 2.0 features:' % len(dev.features))
        dev_settings = []
        _settings_templates.check_feature_settings(dev, dev_settings)
        for index, feature in enumerate(dev.features):
            feature = dev.features[index]
            flags = dev.request(0x0000, feature.bytes(2))
            flags = 0 if flags is None else ord(flags[1:2])
            flags = _hidpp20.FEATURE_FLAG.flag_names(flags)
            print('        %2d: %-22s {%04X}   %s' %
                  (index, feature, feature, ', '.join(flags)))
            if feature == _hidpp20.FEATURE.HIRES_WHEEL:
                wheel = _hidpp20.get_hires_wheel(dev)
                if wheel:
                    multi, has_invert, has_switch, inv, res, target, ratchet = wheel
                    print('            Multiplier: %s' % multi)
                    if has_invert:
                        print(
                            '            Has invert:', 'Inverse wheel motion'
                            if inv else 'Normal wheel motion')
                    if has_switch:
                        print(
                            '            Has ratchet switch:',
                            'Normal wheel mode'
                            if ratchet else 'Free wheel mode')
                    if res:
                        print('            High resolution mode')
                    else:
                        print('            Low resolution mode')
                    if target:
                        print('            HID++ notification')
                    else:
                        print('            HID notification')
            elif feature == _hidpp20.FEATURE.MOUSE_POINTER:
                mouse_pointer = _hidpp20.get_mouse_pointer_info(dev)
                if mouse_pointer:
                    print('            DPI: %s' % mouse_pointer['dpi'])
                    print('            Acceleration: %s' %
                          mouse_pointer['acceleration'])
                    if mouse_pointer['suggest_os_ballistics']:
                        print('            Use OS ballistics')
                    else:
                        print('            Override OS ballistics')
                    if mouse_pointer['suggest_vertical_orientation']:
                        print('            Provide vertical tuning, trackball')
                    else:
                        print('            No vertical tuning, standard mice')
            if feature == _hidpp20.FEATURE.VERTICAL_SCROLLING:
                vertical_scrolling_info = _hidpp20.get_vertical_scrolling_info(
                    dev)
                if vertical_scrolling_info:
                    print('            Roller type: %s' %
                          vertical_scrolling_info['roller'])
                    print('            Ratchet per turn: %s' %
                          vertical_scrolling_info['ratchet'])
                    print('            Scroll lines: %s' %
                          vertical_scrolling_info['lines'])
            elif feature == _hidpp20.FEATURE.HI_RES_SCROLLING:
                scrolling_mode, scrolling_resolution = _hidpp20.get_hi_res_scrolling_info(
                    dev)
                if scrolling_mode:
                    print('            Hi-res scrolling enabled')
                else:
                    print('            Hi-res scrolling disabled')
                if scrolling_resolution:
                    print('            Hi-res scrolling multiplier: %s' %
                          scrolling_resolution)
            elif feature == _hidpp20.FEATURE.POINTER_SPEED:
                pointer_speed = _hidpp20.get_pointer_speed_info(dev)
                if pointer_speed:
                    print('            Pointer Speed: %s' % pointer_speed)
            elif feature == _hidpp20.FEATURE.LOWRES_WHEEL:
                wheel_status = _hidpp20.get_lowres_wheel_status(dev)
                if wheel_status:
                    print('            Wheel Reports: %s' % wheel_status)
            elif feature == _hidpp20.FEATURE.NEW_FN_INVERSION:
                inversion = _hidpp20.get_new_fn_inversion(dev)
                if inversion:
                    inverted, default_inverted = inversion
                    print('            Fn-swap:',
                          'enabled' if inverted else 'disabled')
                    print('            Fn-swap default:',
                          'enabled' if default_inverted else 'disabled')
            elif feature == _hidpp20.FEATURE.HOSTS_INFO:
                host_names = _hidpp20.get_host_names(dev)
                for host, (paired, name) in host_names.items():
                    print('            Host %s (%s): %s' %
                          (host, 'paired' if paired else 'unpaired', name))
            elif feature == _hidpp20.FEATURE.DEVICE_NAME:
                print('            Name: %s' % _hidpp20.get_name(dev))
                print('            Kind: %s' % _hidpp20.get_kind(dev))
            elif feature == _hidpp20.FEATURE.DEVICE_FRIENDLY_NAME:
                print('            Friendly Name: %s' %
                      _hidpp20.get_friendly_name(dev))
            elif feature == _hidpp20.FEATURE.DEVICE_FW_VERSION:
                for fw in _hidpp20.get_firmware(dev):
                    extras = _strhex(fw.extras) if fw.extras else ''
                    print('            Firmware: %s %s %s %s' %
                          (fw.kind, fw.name, fw.version, extras))
                ids = _hidpp20.get_ids(dev)
                if ids:
                    unitId, modelId, tid_map = ids
                    print(
                        '            Unit ID: %s  Model ID: %s  Transport IDs: %s'
                        % (unitId, modelId, tid_map))
            elif feature == _hidpp20.FEATURE.REPORT_RATE:
                print('            Polling Rate (ms): %d' %
                      _hidpp20.get_polling_rate(dev))
            elif feature == _hidpp20.FEATURE.REMAINING_PAIRING:
                print('            Remaining Pairings: %d' %
                      _hidpp20.get_remaining_pairing(dev))
            elif feature == _hidpp20.FEATURE.ONBOARD_PROFILES:
                if _hidpp20.get_onboard_mode(
                        dev) == _hidpp20.ONBOARD_MODES.MODE_HOST:
                    mode = 'Host'
                else:
                    mode = 'On-Board'
                print('            Device Mode: %s' % mode)
            elif feature in (_F.BATTERY_STATUS, _F.BATTERY_VOLTAGE,
                             _F.BATTERY_VOLTAGE):
                print('', end='       ')
                _battery_line(dev)
            for setting in dev_settings:
                if setting.feature == feature:
                    if setting._device and getattr(
                            setting._device, 'persister',
                            None) and setting._device.persister.get(
                                setting.name) is not None:
                        print('            %s (saved): %s' %
                              (setting.label,
                               setting._device.persister.get(setting.name)))
                    v = setting.read(False)
                    print('            %s        : %s' % (setting.label, v))

    if dev.online and dev.keys:
        print('     Has %d reprogrammable keys:' % len(dev.keys))
        for k in dev.keys:
            # TODO: add here additional variants for other REPROG_CONTROLS
            if dev.keys.keyversion == _hidpp20.FEATURE.REPROG_CONTROLS_V2:
                print('        %2d: %-26s => %-27s   %s' %
                      (k.index, k.key, k.default_task, ', '.join(k.flags)))
            if dev.keys.keyversion == _hidpp20.FEATURE.REPROG_CONTROLS_V4:
                print('        %2d: %-26s, default: %-27s => %-26s' %
                      (k.index, k.key, k.default_task, k.mapped_to))
                gmask_fmt = ','.join(k.group_mask)
                gmask_fmt = gmask_fmt if gmask_fmt else 'empty'
                print('             %s, pos:%d, group:%1d, group mask:%s' %
                      (', '.join(k.flags), k.pos, k.group, gmask_fmt))
                report_fmt = ', '.join(k.mapping_flags)
                report_fmt = report_fmt if report_fmt else 'default'
                print('             reporting: %s' % (report_fmt))
    if dev.online and dev.gestures:
        print('     Has %d gesture(s), %d param(s) and %d spec(s):' %
              (len(dev.gestures.gestures), len(
                  dev.gestures.params), len(dev.gestures.specs)))
        for k in dev.gestures.gestures.values():
            print('        %-26s Enabled (%4s): %s' %
                  (k.gesture, k.index, k.enabled()))
        for k in dev.gestures.params.values():
            print('        %-26s Value   (%4s): %s [Default: %s]' %
                  (k.param, k.index, k.value, k.default_value))
        for k in dev.gestures.specs.values():
            print('        %-26s Spec    (%4s): %s' % (k.spec, k.id, k.value))
    if dev.online:
        _battery_line(dev)
    else:
        print('     Battery: unknown (device is offline).')
Example #10
0
def _print_device(dev, verbose=False):
	assert dev
	state = '' if dev.ping() else 'offline'

	if not verbose:
		print ("%d: %s [%s:%s]" % (dev.number, dev.name, dev.codename, dev.serial), state)
		return

	print ("%d: %s" % (dev.number, dev.name))
	print ("   Codename     :", dev.codename)
	print ("   Kind         :", dev.kind)
	print ("   Wireless PID :", dev.wpid)
	if dev.protocol:
		print ("   Protocol     : HID++ %1.1f" % dev.protocol)
	else:
		print ("   Protocol     : unknown (device is offline)")
	print ("   Polling rate :", dev.polling_rate, "ms")
	print ("   Serial number:", dev.serial)
	for fw in dev.firmware:
		print ("     %11s:" % fw.kind, (fw.name + ' ' + fw.version).strip())

	if dev.power_switch_location:
		print ("   The power switch is located on the %s." % dev.power_switch_location)

	from logitech_receiver import hidpp10, hidpp20, special_keys

	if dev.online:
		notification_flags = hidpp10.get_notification_flags(dev)
		if notification_flags is not None:
			if notification_flags:
				notification_names = hidpp10.NOTIFICATION_FLAG.flag_names(notification_flags)
				print ("   Notifications: 0x%06X = %s." % (notification_flags, ', '.join(notification_names)))
			else:
				print ("   Notifications: (none).")

	if dev.online:
		if dev.features:
			print ("   Supports %d HID++ 2.0 features:" % len(dev.features))
			for index, feature in enumerate(dev.features):
				feature = dev.features[index]
				flags = dev.request(0x0000, feature.bytes(2))
				flags = 0 if flags is None else ord(flags[1:2])
				flags = hidpp20.FEATURE_FLAG.flag_names(flags)
				print ("      %2d: %-22s {%04X}   %s" % (index, feature, feature, ', '.join(flags)))

	if dev.online:
		if dev.keys:
			print ("   Has %d reprogrammable keys:" % len(dev.keys))
			for k in dev.keys:
				flags = special_keys.KEY_FLAG.flag_names(k.flags)
				print ("      %2d: %-26s => %-27s   %s" % (k.index, k.key, k.task, ', '.join(flags)))

	if dev.online:
		battery = hidpp20.get_battery(dev)
		if battery is None:
			battery = hidpp10.get_battery(dev)
		if battery is not None:
			from logitech_receiver.common import NamedInt as _NamedInt
			level, status = battery
			if isinstance(level, _NamedInt):
				text = str(level)
			else:
				text = '%d%%' % level
			print ("   Battery: %s, %s," % (text, status))
		else:
			print ("   Battery status unavailable.")
	else:
		print ("   Battery status is unknown (device is offline).")
Example #11
0
def _print_device(dev):
    assert dev
    # check if the device is online
    dev.ping()

    print('  %d: %s' % (dev.number, dev.name))
    print('     Codename     :', dev.codename)
    print('     Kind         :', dev.kind)
    print('     Wireless PID :', dev.wpid)
    if dev.protocol:
        print('     Protocol     : HID++ %1.1f' % dev.protocol)
    else:
        print('     Protocol     : unknown (device is offline)')
    if dev.polling_rate:
        print('     Polling rate :', dev.polling_rate,
              'ms (%dHz)' % (1000 // dev.polling_rate))
    print('     Serial number:', dev.serial)
    for fw in dev.firmware:
        print('       %11s:' % fw.kind, (fw.name + ' ' + fw.version).strip())

    if dev.power_switch_location:
        print('     The power switch is located on the %s.' %
              dev.power_switch_location)

    if dev.online:
        notification_flags = _hidpp10.get_notification_flags(dev)
        if notification_flags is not None:
            if notification_flags:
                notification_names = _hidpp10.NOTIFICATION_FLAG.flag_names(
                    notification_flags)
                print('     Notifications: %s (0x%06X).' %
                      (', '.join(notification_names), notification_flags))
            else:
                print('     Notifications: (none).')

    if dev.online and dev.features:
        print('     Supports %d HID++ 2.0 features:' % len(dev.features))
        for index, feature in enumerate(dev.features):
            feature = dev.features[index]
            flags = dev.request(0x0000, feature.bytes(2))
            flags = 0 if flags is None else ord(flags[1:2])
            flags = _hidpp20.FEATURE_FLAG.flag_names(flags)
            print('        %2d: %-22s {%04X}   %s' %
                  (index, feature, feature, ', '.join(flags)))

    if dev.online and dev.keys:
        print('     Has %d reprogrammable keys:' % len(dev.keys))
        for k in dev.keys:
            flags = _special_keys.KEY_FLAG.flag_names(k.flags)
            # TODO: add here additional variants for other REPROG_CONTROLS
            if dev.keys.keyversion == 1:
                print('        %2d: %-26s => %-27s   %s' %
                      (k.index, k.key, k.task, ', '.join(flags)))
            if dev.keys.keyversion == 4:
                print('        %2d: %-26s, default: %-27s => %-26s' %
                      (k.index, k.key, k.task, k.remapped))
                print('             %s, pos:%d, group:%1d, gmask:%d' %
                      (', '.join(flags), k.pos, k.group, k.group_mask))
    if dev.online:
        battery = _hidpp20.get_battery(dev)
        if battery is None:
            battery = _hidpp10.get_battery(dev)
        if battery is not None:
            from logitech_receiver.common import NamedInt as _NamedInt
            level, status = battery
            if level is not None:
                if isinstance(level, _NamedInt):
                    text = str(level)
                else:
                    text = '%d%%' % level
            else:
                text = 'N/A'
            print('     Battery: %s, %s.' % (text, status))
        else:
            print('     Battery status unavailable.')
    else:
        print('     Battery: unknown (device is offline).')
Example #12
0
def run(receivers, args, find_receiver, _ignore):
    assert receivers

    if args.receiver:
        receiver_name = args.receiver.lower()
        receiver = find_receiver(receivers, receiver_name)
        if not receiver:
            raise Exception("no receiver found matching '%s'" % receiver_name)
    else:
        receiver = receivers[0]

    assert receiver
    receiver.status = _status.ReceiverStatus(receiver,
                                             lambda *args, **kwargs: None)

    # check if it's necessary to set the notification flags
    old_notification_flags = _hidpp10.get_notification_flags(receiver) or 0
    if not (old_notification_flags & _hidpp10.NOTIFICATION_FLAG.wireless):
        _hidpp10.set_notification_flags(
            receiver,
            old_notification_flags | _hidpp10.NOTIFICATION_FLAG.wireless)

    # get all current devices
    known_devices = [dev.number for dev in receiver]

    class _HandleWithNotificationHook(int):
        def notifications_hook(self, n):
            nonlocal known_devices
            assert n
            if n.devnumber == 0xFF:
                _notifications.process(receiver, n)
            elif n.sub_id == 0x41 and len(
                    n.data) == _base._SHORT_MESSAGE_SIZE - 4:
                kd, known_devices = known_devices, None  # only process one connection notification
                if kd is not None:
                    if n.devnumber not in kd:
                        receiver.status.new_device = receiver.register_new_device(
                            n.devnumber, n)
                    elif receiver.re_pairs:
                        del receiver[
                            n.
                            devnumber]  # get rid of information on device re-paired away
                        receiver.status.new_device = receiver.register_new_device(
                            n.devnumber, n)

    timeout = 30  # seconds
    receiver.handle = _HandleWithNotificationHook(receiver.handle)

    if receiver.receiver_kind == 'bolt':  # Bolt receivers require authentication to pair a device
        receiver.discover(timeout=timeout)
        print(
            'Bolt Pairing: long-press the pairing key or button on your device (timing out in',
            timeout, 'seconds).')
        pairing_start = _timestamp()
        patience = 5  # the discovering notification may come slightly later, so be patient
        while receiver.status.discovering or _timestamp(
        ) - pairing_start < patience:
            if receiver.status.device_address and receiver.status.device_authentication and receiver.status.device_name:
                break
            n = _base.read(receiver.handle)
            n = _base.make_notification(*n) if n else None
            if n:
                receiver.handle.notifications_hook(n)
        address = receiver.status.device_address
        name = receiver.status.device_name
        authentication = receiver.status.device_authentication
        kind = receiver.status.device_kind
        print(f'Bolt Pairing: discovered {name}')
        receiver.pair_device(
            address=address,
            authentication=authentication,
            entropy=20 if kind == _hidpp10.DEVICE_KIND.keyboard else 10)
        pairing_start = _timestamp()
        patience = 5  # the discovering notification may come slightly later, so be patient
        while receiver.status.lock_open or _timestamp(
        ) - pairing_start < patience:
            if receiver.status.device_passkey:
                break
            n = _base.read(receiver.handle)
            n = _base.make_notification(*n) if n else None
            if n:
                receiver.handle.notifications_hook(n)
        if authentication & 0x01:
            print(
                f'Bolt Pairing: type passkey {receiver.status.device_passkey} and then press the enter key'
            )
        else:
            passkey = f'{int(receiver.status.device_passkey):010b}'
            passkey = ', '.join(
                ['right' if bit == '1' else 'left' for bit in passkey])
            print(f'Bolt Pairing: press {passkey}')
            print('and then press left and right buttons simultaneously')
        while receiver.status.lock_open:
            n = _base.read(receiver.handle)
            n = _base.make_notification(*n) if n else None
            if n:
                receiver.handle.notifications_hook(n)

    else:
        receiver.set_lock(False, timeout=timeout)
        print('Pairing: turn your new device on (timing out in', timeout,
              'seconds).')
        pairing_start = _timestamp()
        patience = 5  # the lock-open notification may come slightly later, wait for it a bit
        while receiver.status.lock_open or _timestamp(
        ) - pairing_start < patience:
            n = _base.read(receiver.handle)
            if n:
                n = _base.make_notification(*n)
                if n:
                    receiver.handle.notifications_hook(n)

    if not (old_notification_flags & _hidpp10.NOTIFICATION_FLAG.wireless):
        # only clear the flags if they weren't set before, otherwise a
        # concurrently running Solaar app might stop working properly
        _hidpp10.set_notification_flags(receiver, old_notification_flags)

    if receiver.status.new_device:
        dev = receiver.status.new_device
        print('Paired device %d: %s (%s) [%s:%s]' %
              (dev.number, dev.name, dev.codename, dev.wpid, dev.serial))
    else:
        error = receiver.status.get(_status.KEYS.ERROR)
        if error:
            raise Exception('pairing failed: %s' % error)
        else:
            print('Paired device')  # this is better than an error
Example #13
0
def _print_device(dev):
	assert dev
	# check if the device is online
	dev.ping()

	print ('  %d: %s' % (dev.number, dev.name))
	print ('     Codename     :', dev.codename)
	print ('     Kind         :', dev.kind)
	print ('     Wireless PID :', dev.wpid)
	if dev.protocol:
		print ('     Protocol     : HID++ %1.1f' % dev.protocol)
	else:
		print ('     Protocol     : unknown (device is offline)')
	if dev.polling_rate:
		print ('     Polling rate :', dev.polling_rate, 'ms (%dHz)' % (1000 // dev.polling_rate))
	print ('     Serial number:', dev.serial)
	for fw in dev.firmware:
		print ('       %11s:' % fw.kind, (fw.name + ' ' + fw.version).strip())

	if dev.power_switch_location:
		print ('     The power switch is located on the %s.' % dev.power_switch_location)

	if dev.online:
		notification_flags = _hidpp10.get_notification_flags(dev)
		if notification_flags is not None:
			if notification_flags:
				notification_names = _hidpp10.NOTIFICATION_FLAG.flag_names(notification_flags)
				print ('     Notifications: %s (0x%06X).' % (', '.join(notification_names), notification_flags))
			else:
				print ('     Notifications: (none).')

	if dev.online and dev.features:
		print ('     Supports %d HID++ 2.0 features:' % len(dev.features))
		for index, feature in enumerate(dev.features):
			feature = dev.features[index]
			flags = dev.request(0x0000, feature.bytes(2))
			flags = 0 if flags is None else ord(flags[1:2])
			flags = _hidpp20.FEATURE_FLAG.flag_names(flags)
			print ('        %2d: %-22s {%04X}   %s' % (index, feature, feature, ', '.join(flags)))
			if feature == _hidpp20.FEATURE.HIRES_WHEEL:
				wheel = _hidpp20.get_hires_wheel(dev)
				if wheel:
					multi, has_invert, has_switch, inv, res, target, ratchet = wheel
					print("            Multiplier: %s" % multi)
					if has_invert:
						print("            Has invert")
						if inv:
							print("              Inverse wheel motion")
						else:
							print("              Normal wheel motion")
					if has_switch:
						print("            Has ratchet switch")
						if ratchet:
							print("              Normal wheel mode")
						else:
							print("              Free wheel mode")
					if res:
						print("            High resolution mode")
					else:
						print("            Low resolution mode")
					if target:
						print("            HID++ notification")
					else:
						print("            HID notification")

	if dev.online and dev.keys:
		print ('     Has %d reprogrammable keys:' % len(dev.keys))
		for k in dev.keys:
			flags = _special_keys.KEY_FLAG.flag_names(k.flags)
			# TODO: add here additional variants for other REPROG_CONTROLS
			if dev.keys.keyversion == 1:
				print ('        %2d: %-26s => %-27s   %s' % (k.index, k.key, k.task, ', '.join(flags)))
			if dev.keys.keyversion == 4:
				print ('        %2d: %-26s, default: %-27s => %-26s' % (k.index, k.key, k.task, k.remapped))
				print ('             %s, pos:%d, group:%1d, gmask:%d' % ( ', '.join(flags), k.pos, k.group, k.group_mask))
	if dev.online:
		battery = _hidpp20.get_battery(dev)
		if battery is None:
			battery = _hidpp10.get_battery(dev)
		if battery is not None:
			from logitech_receiver.common import NamedInt as _NamedInt
			level, status = battery
			if level is not None:
				if isinstance(level, _NamedInt):
					text = str(level)
				else:
					text = '%d%%' % level
			else:
				text = 'N/A'
			print ('     Battery: %s, %s.' % (text, status))
		else:
			print ('     Battery status unavailable.')
	else:
		print ('     Battery: unknown (device is offline).')