# Buggy code
def _notifications_handler(self, n):
    assert self.receiver
    # if _log.isEnabledFor(_DEBUG):
    #     _log.debug("%s: handling %s", self.receiver, n)
    if n.devnumber == 0xFF:
        # a receiver notification
        _notifications.process(self.receiver, n)
        return

    # a device notification
    if not (0 < n.devnumber <= self.receiver.max_devices):
        if _log.isEnabledFor(_WARNING):
            _log.warning(
                _(
                    "Unexpected device number (%s) in notification %s."
                    % (n.devnumber, n)
                )
            )
        return
    already_known = n.devnumber in self.receiver

    # FIXME: hacky fix for kernel/hardware race condition
    # If the device was just turned on or woken up from sleep, it may not
    # be ready to receive commands. The "payload" bit of the wireless
    # status notification seems to tell us this. If this is the case, we
    # must wait a short amount of time to avoid causing a broken pipe
    # error.
    device_ready = not bool(ord(n.data[0:1]) & 0x80) or n.sub_id != 0x41
    if not device_ready:
        time.sleep(0.01)

    if n.sub_id == 0x40 and not already_known:
        return  # disconnecting something that is not known - nothing to do

    if n.sub_id == 0x41:
        if not already_known:
            dev = self.receiver.register_new_device(n.devnumber, n)
        elif (
            self.receiver.status.lock_open
            and self.receiver.re_pairs
            and not ord(n.data[0:1]) & 0x40
        ):
            dev = self.receiver[n.devnumber]
            del self.receiver[
                n.devnumber
            ]  # get rid of information on device re-paired away
            self._status_changed(dev)  # signal that this device has changed
            dev = self.receiver.register_new_device(n.devnumber, n)
            self.receiver.status.new_device = self.receiver[n.devnumber]
        else:
            dev = self.receiver[n.devnumber]
    else:
        dev = self.receiver[n.devnumber]

    if not dev:
        _log.warn(
            "%s: received %s for invalid device %d: %r",
            self.receiver,
            n,
            n.devnumber,
            dev,
        )
        return

    # Apply settings every time the device connects
    if n.sub_id == 0x41:
        if _log.isEnabledFor(_INFO):
            _log.info("%s triggered new device %s (%s)", n, dev, dev.kind)
        # If there are saved configs, bring the device's settings up-to-date.
        # They will be applied when the device is marked as online.
        configuration.attach_to(dev)
        _status.attach_to(dev, self._status_changed)
        # the receiver changed status as well
        self._status_changed(self.receiver)

    assert dev
    assert dev.status is not None
    _notifications.process(dev, n)
    if self.receiver.status.lock_open and not already_known:
        # this should be the first notification after a device was paired
        assert n.sub_id == 0x41 and n.address == 0x04
        if _log.isEnabledFor(_INFO):
            _log.info("%s: pairing detected new device", self.receiver)
        self.receiver.status.new_device = dev
    elif dev.online is None:
        dev.ping()


# Traceback (AssertionError)
idefix Solaar> bin/solaar -dd
17:57:28,196     INFO [MainThread] root: language en_US (UTF-8), translations path /home/local/SoftwareDownloads/Solaar/share/locale
17:57:28,251    DEBUG [MainThread] solaar.ui.tray: using AppIndicator3
17:57:28,263     INFO [MainThread] solaar.upower: connected to system dbus, watching for suspend/resume events
17:57:28,285    DEBUG [MainThread] solaar.ui: startup registered=True, remote=False
17:57:28,286    DEBUG [AsyncUI] solaar.tasks: started
17:57:28,286     INFO [MainThread] solaar.ui.notify: starting desktop notifications
17:57:28,290    DEBUG [MainThread] solaar.ui.icons: sys.path[0] = /home/local/SoftwareDownloads/Solaar/lib
17:57:28,291    DEBUG [MainThread] solaar.ui.icons: looking for icons in /home/local/SoftwareDownloads/Solaar/icons
17:57:28,291    DEBUG [MainThread] solaar.ui.icons: looking for icons in /home/local/SoftwareDownloads/Solaar/share/solaar/icons
17:57:28,291    DEBUG [MainThread] solaar.ui.icons: looking for icons in /home/pfps/.local/share/solaar/icons
17:57:28,291    DEBUG [MainThread] solaar.ui.icons: looking for icons in /home/local/SoftwareDownloads/Solaar/lib/share/solaar/icons
17:57:28,291    DEBUG [MainThread] solaar.ui.icons: looking for icons in /home/local/SoftwareDownloads/Solaar/share/solaar/icons
17:57:28,291    DEBUG [MainThread] solaar.ui.icons: looking for icons in /usr/local/share/solaar/icons
17:57:28,291    DEBUG [MainThread] solaar.ui.icons: looking for icons in /usr/share/solaar/icons
17:57:28,291    DEBUG [MainThread] solaar.ui.icons: icon theme paths: ['/home/local/SoftwareDownloads/Solaar/share/solaar/icons', '/home/local/SoftwareDownloads/Solaar/share/solaar/icons', '/home/pfps/.local/share/icons', '/home/pfps/.icons', '/usr/local/share/icons', '/usr/share/icons', '/usr/local/share/pixmaps', '/usr/share/pixmaps']
17:57:28,343     INFO [MainThread] solaar.listener: starting receiver listening threads
17:57:28,347     INFO [MainThread] solaar.listener: receiver event add DeviceInfo(path='/dev/hidraw0', vendor_id='046d', product_id='c52b', serial='', release=b'1210', manufacturer=b'Logitech', product=b'USB Receiver', interface=2, driver='logitech-djreceiver')
17:57:28,348    DEBUG [MainThread] logitech_receiver.base: (16) <= w[10 FF 83B5 030000]
17:57:28,349    DEBUG [MainThread] logitech_receiver.base: (16) => r[11 FF 83B5 031EB692A30106510000000000000000]
17:57:28,349    DEBUG [MainThread] logitech_receiver.base: (16) <= w[10 FF 80B2 000000]
17:57:28,351    DEBUG [MainThread] logitech_receiver.base: (16) => r[10 FF 8F80 B20300]
17:57:28,351    DEBUG [MainThread] logitech_receiver.base: (16) device 0xFF error on request {80B2}: 3 = invalid value
17:57:28,352     INFO [ReceiverListener:hidraw0] logitech_receiver.listener: started with <UnifyingReceiver(/dev/hidraw0,16)> (16)
17:57:28,352     INFO [ReceiverListener:hidraw0] solaar.listener: <UnifyingReceiver(/dev/hidraw0,16)>: notifications listener has started (16)
17:57:28,352    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) <= w[10 FF 8000 100900]
17:57:28,354    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) => r[10 FF 8000 000000]
17:57:28,354    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) <= w[10 FF 8100 000000]
17:57:28,357    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) => r[20 01 4101 5140040000000000000000]
17:57:28,359    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) => r[20 00 4102 0000000000000000000000]
17:57:28,361    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) => r[10 FF 8100 000900]
17:57:28,361     INFO [ReceiverListener:hidraw0] logitech_receiver.receiver: <UnifyingReceiver(/dev/hidraw0,16)>: receiver notifications enabled => ('wireless', 'software present')
17:57:28,361    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) <= w[10 FF 8002 020000]
17:57:28,363    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) => r[10 01 4104 125140]
17:57:28,365    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) => r[10 FF 8002 000000]
17:57:28,365     INFO [ReceiverListener:hidraw0] solaar.listener: status_changed <UnifyingReceiver(/dev/hidraw0,16)>: present, No paired devices. (0)
17:57:28,367    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) <= w[10 FF 83B5 400000]
17:57:28,369    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) => r[11 FF 83B5 40044D35313000000000000000000000]
17:57:28,370     INFO [ReceiverListener:hidraw0] logitech_receiver.receiver: <UnifyingReceiver(/dev/hidraw0,16)>: found new device 1 (0440)
17:57:28,370    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) <= w[10 FF 83B5 300000]
17:57:28,372    DEBUG [ReceiverListener:hidraw0] logitech_receiver.base: (16) => r[11 FF 83B5 3060E4B97D0400000001000000000000]
17:57:28,370     INFO [ReceiverListener:hidraw0] solaar.listener: Notification(1,41,01,5140040000000000000000) triggered new device <PairedDevice(1,0440,M510,60E4B97D)> (keyboard)
17:57:28,372    DEBUG [ReceiverListener:hidraw0] solaar.configuration: load => {'0410:93E8527F': {'_name': 'Wireless Mouse M510', 'side-scroll': True}, '1025:93E8527F': {'_name': 'Wireless Mouse M510', 'side-scroll': True}, '4051:60E4B97D': {'_name': 'Wireless Mouse M510', 'lowres-smooth-scroll': False, 'pointer_speed': 302, 'reprogrammable-keys': {'80': 80, '81': 81, '82': 93, '83': 93, '86': 93, '91': 83, '93': 83}}, '_version': '1.0.3rc1'}
17:57:28,373     INFO [ReceiverListener:hidraw0] solaar.listener: status_changed <UnifyingReceiver(/dev/hidraw0,16)>: present, 1 paired device. (0)
17:57:28,373    DEBUG [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(1,0440,M510,60E4B97D)> (1.0) DJ notification Notification(1,41,01,5140040000000000000000)
17:57:28,373     INFO [ReceiverListener:hidraw0] logitech_receiver.notifications: <PairedDevice(1,0440,M510,60E4B97D)>: ignoring DJ paired: Notification(1,41,01,5140040000000000000000)
17:57:28,373  WARNING [ReceiverListener:hidraw0] solaar.listener: Unexpected device number (0) in notification Notification(0,41,02,0000000000000000000000).
17:57:28,373     INFO [ReceiverListener:hidraw0] solaar.listener: Notification(1,41,04,125140) triggered new device <PairedDevice(1,0440,M510,60E4B97D)> (keyboard)
17:57:28,373     INFO [ReceiverListener:hidraw0] solaar.listener: status_changed <UnifyingReceiver(/dev/hidraw0,16)>: present, 1 paired device. (0)
17:57:28,374    ERROR [ReceiverListener:hidraw0] logitech_receiver.listener: processing Notification(1,41,04,125140)
Traceback (most recent call last):
File "/home/local/SoftwareDownloads/Solaar/lib/logitech_receiver/listener.py", line 193, in run
self._notifications_callback(n)
File "/home/local/SoftwareDownloads/Solaar/lib/solaar/listener.py", line 237, in _notifications_handler
_notifications.process(dev, n)
File "/home/local/SoftwareDownloads/Solaar/lib/logitech_receiver/notifications.py", line 60, in process
return _process_device_notification(device, status, notification)
File "/home/local/SoftwareDownloads/Solaar/lib/logitech_receiver/notifications.py", line 110, in _process_device_notification
return _process_hidpp10_notification(device, status, n)
File "/home/local/SoftwareDownloads/Solaar/lib/logitech_receiver/notifications.py", line 207, in _process_hidpp10_notification
assert wpid == device.wpid, '%s wpid mismatch, got %s' % (device, wpid)
AssertionError: <PairedDevice(1,0440,M510,60E4B97D)> wpid mismatch, got 4051

# Fixed code
def _notifications_handler(self, n):
    assert self.receiver
    # if _log.isEnabledFor(_DEBUG):
    #     _log.debug("%s: handling %s", self.receiver, n)
    if n.devnumber == 0xFF:
        # a receiver notification
        _notifications.process(self.receiver, n)
        return

    # a device notification
    if not (0 < n.devnumber <= self.receiver.max_devices):
        if _log.isEnabledFor(_WARNING):
            _log.warning(
                _(
                    "Unexpected device number (%s) in notification %s."
                    % (n.devnumber, n)
                )
            )
        return
    already_known = n.devnumber in self.receiver

    # FIXME: hacky fix for kernel/hardware race condition
    # If the device was just turned on or woken up from sleep, it may not
    # be ready to receive commands. The "payload" bit of the wireless
    # status notification seems to tell us this. If this is the case, we
    # must wait a short amount of time to avoid causing a broken pipe
    # error.
    device_ready = not bool(ord(n.data[0:1]) & 0x80) or n.sub_id != 0x41
    if not device_ready:
        time.sleep(0.01)

    if n.sub_id == 0x40 and not already_known:
        return  # disconnecting something that is not known - nothing to do

    if n.sub_id == 0x41 and len(n.data) > _base._SHORT_MESSAGE_SIZE - 4:
        # DJ pairing notification - ignore - hid++ 1.0 pairing notification is all that is needed
        if _log.isEnabledFor(_INFO):
            _log.info("ignoring DJ pairing notification", n)
        return
    elif n.sub_id == 0x41:
        if not already_known:
            dev = self.receiver.register_new_device(n.devnumber, n)
        elif (
            self.receiver.status.lock_open
            and self.receiver.re_pairs
            and not ord(n.data[0:1]) & 0x40
        ):
            dev = self.receiver[n.devnumber]
            del self.receiver[
                n.devnumber
            ]  # get rid of information on device re-paired away
            self._status_changed(dev)  # signal that this device has changed
            dev = self.receiver.register_new_device(n.devnumber, n)
            self.receiver.status.new_device = self.receiver[n.devnumber]
        else:
            dev = self.receiver[n.devnumber]
    else:
        dev = self.receiver[n.devnumber]

    if not dev:
        _log.warn(
            "%s: received %s for invalid device %d: %r",
            self.receiver,
            n,
            n.devnumber,
            dev,
        )
        return

    # Apply settings every time the device connects
    if n.sub_id == 0x41:
        if _log.isEnabledFor(_INFO):
            _log.info("%s triggered new device %s (%s)", n, dev, dev.kind)
        # If there are saved configs, bring the device's settings up-to-date.
        # They will be applied when the device is marked as online.
        configuration.attach_to(dev)
        _status.attach_to(dev, self._status_changed)
        # the receiver changed status as well
        self._status_changed(self.receiver)

    assert dev
    assert dev.status is not None
    _notifications.process(dev, n)
    if self.receiver.status.lock_open and not already_known:
        # this should be the first notification after a device was paired
        assert n.sub_id == 0x41 and n.address == 0x04
        if _log.isEnabledFor(_INFO):
            _log.info("%s: pairing detected new device", self.receiver)
        self.receiver.status.new_device = dev
    elif dev.online is None:
        dev.ping()