+
     vif\  c                   sx   R t ^ RIt^ RIt^ RIt^ RIHt  ^ RIt ^ RI	t	^ RI
HtHtHt ^ RIHt ^ RIHt ^ RIHt Rt]P*                  ! ]4      t ! R R	]4      t ! R
 R]4      t ! R R]4      t ! R R4      t ! R R4      t ! R R]4      t ! R R]4      tR#   ] d    ^ RIt Li ; i  ] d    Rt	 Li ; i)uw  Base USB bus, driver and device APIs.

This modules provides abstractions over several platform and implementation
differences.  As such, there is a lot of boilerplate here, but callers should
be able to disregard almost everything and simply work on the UsbDriver/
UsbHidDriver level.

BaseUsbDriver
└── device: PyUsbDevice
    ├── uses PyUSB
    └── backed by (in order of priority)
        ├── libusb-1.0
        ├── libusb-0.1
        └── OpenUSB

UsbHidDriver
├── extends: BaseUsbDriver
└── device: HidapiDevice
    ├── uses hidapi
    └── backed by
        ├── hid.dll on Windows
        ├── hidraw on Linux if it was enabled during the build of hidapi
        ├── IOHidManager on MacOS
        └── libusb-1.0 on all other cases

UsbDriver
├── extends: BaseUsbDriver
└── allows to differentiate between UsbHidDriver and (non HID) UsbDriver

UsbDriver and UsbHidDriver are meant to be used as base classes to the actual
device drivers.  The users of those drivers generally do not care about read,
write or other low level operations; thus, these low level operations are
placed in <driver>.device.

However, there still are legitimate reasons as to why someone would want to
directly access the lower layers (device wrapper level, device implementation
level, or lower).  We do not hide or mark those references as private, but good
judgement should be exercised when calling anything within <driver>.device.

The USB drivers are organized into two buses.  The recommended way to
initialize and bind drivers is through their respective buses, though
<driver>.find_supported_devices can also be useful in certain scenarios.

HidapiBus
└── drivers: all (recursive) subclasses of UsbHidDriver

PyUsbBus
└── drivers: all (recursive) subclasses of UsbDriver

The subclass constructor can generally be kept unaware of the implementation
details of the device parameter, and find_supported_devices already accepts
keyword arguments and forwards them to the driver constructor.

Copyright Jonas Malaco and contributors
SPDX-License-Identifier: GPL-3.0-or-later
N)USBTimeoutError)
BaseDriverBaseBusfind_all_subclasses)HwmonDevice)Timeout)LazyHexRepri  c                   s   a  ] tR t^Xt o Rt. t]RR l4       tR tR t	R t
]R 4       t]R 4       t]R	 4       t]R
 4       t]R 4       t]R 4       t]R 4       t]R 4       tRtV tR# )BaseUsbDrivera~  Base driver class for generic USB devices.

Each driver should provide its own list of _MATCHES, as well as
implementations for all methods applicable to the devices is supports.

_MATCHES should consist of a list of (vendor id, product id, description,
and extra kwargs) tuples.

find_supported_devices will pass these extra kwargs, as well as any it
receives, to the constructor.
Nc              +  s"  "   V P                    F  w  rrV'       d   W(8w  g   VP                  V8w  d   K'  V'       d   W98w  g   VP                  V	8w  d   KH  V'       d   VP                  V8w  d   Kc  V'       d   VP                  V8w  d   K~  V'       d&   VP                  4       V
P                  4       9  d   K  VP                  4       pVP                  V4       V ! W3/ VB p\        P                  RV P                  V
4       Vx  K  	  R# 5i)z8Probe `handle` and yield corresponding driver instances.z%s identified: %sN)_MATCHES	vendor_id
product_idrelease_numberserial_numberZlowerZcopyZupdate_LOGGERdebug__name__)clshandlevendorproductreleaseZserialZmatchkwargsvidpidZdescZdevargsZconsargsdevs   &&&&&&&,      9/usr/lib/python3.14/site-packages/liquidctl/driver/usb.pyprobeZBaseUsbDriver.probeg   s      (+||#Cd6=V-=-=-DGNv/@/@C/G600G;&..&8djjl:||~HOOF#f/h/CMM-s||TBI (4s   ;D DD:DA:Dc                s    Wn         W n        R # N)device_description)selfr   descriptionr   s   &&&,r   __init__ZBaseUsbDriver.__init__|   s    '    c                s:    V P                   P                  4        V # )Connect to the device.)r   openr   r      &,r   connectZBaseUsbDriver.connect   s    r!   c                :    V P                   P                  4        R# )zDisconnect from the device.N)r   closer$   r%   r   
disconnectZBaseUsbDriver.disconnect       r!   c                    V P                   # )z7Human readable description of the corresponding device.)r   r      &r   r   ZBaseUsbDriver.description   s        r!   c                .    V P                   P                  # )z!16-bit numeric vendor identifier.)r   r	   r,   r-   r   r	   ZBaseUsbDriver.vendor_id   s     {{$$$r!   c                r.   )z!16-bit umeric product identifier.)r   r
   r,   r-   r   r
   ZBaseUsbDriver.product_id   s     {{%%%r!   c                r.   )z$16-bit BCD device versioning number.)r   r   r,   r-   r   r   ZBaseUsbDriver.release_number   s     {{)))r!   c                r.   )z5Serial number reported by the device, or None if N/A.)r   r   r,   r-   r   r   ZBaseUsbDriver.serial_number   s     {{(((r!   c                r.   )z/Bus the device is connected to, or None if N/A.)r   busr,   r-   r   r/   ZBaseUsbDriver.bus   s     {{r!   c                r.   )zhAddress of the device on the corresponding bus, or None if N/A.

Dependendent on bus enumeration order.
)r   addressr,   r-   r   r0   ZBaseUsbDriver.address   s     {{"""r!   c                r.   )zPhysical location of the device, or None if N/A.

Tuple of USB port numbers, from the root hub to this device.

Only available for PyUSB-backed devices, and only when using LibUSB 1.0.
But has the advantage of not depending on the bus enumeration order.
)r   portr,   r-   r   r1   ZBaseUsbDriver.port   s     {{r!   )r   r   NNNNN)r   
__module____qualname____firstlineno____doc__r   classmethodr   r    r&   r)   propertyr   r	   r
   r   r   r/   r0   r1   __static_attributes____classdictcell____classdict__   @r   r   r   X   s     
 H ((
 ! ! % % & & * * ) )   # #    r!   r   c                   sF   a a ] tR t^t oRt]R 4       tV 3R ltRtVt	V ;t
# )UsbHidDriverz9Base driver class for USB Human Interface Devices (HIDs).c                    . pV P                    FO  w  r4 p\        4       P                  ! RRVRV/VB  F&  p\        V4      V 8X  g   K  VP	                  V4       K(  	  KQ  	  V# z6Find devices specifically compatible with this driver.r   r    )r   	HidapiBusfind_devicestypeappendr   r   Zdevsr   r   Z_r      &,     r   find_supported_devicesZ#UsbHidDriver.find_supported_devices   sa     !llNCa {//RsRCR6R9#KK$ S + r!   c                s  <a \        V\        P                  P                  4      '       d   V P                  P
                  p\        P                  R WD4       Vo\        V3R l\        P                  ! SP                  SP                  4       4       4      pV'       g   Q R4       h\        \        V4      p\        SV `<  ! W3/ VB  \         P"                  ! VP$                  4      V n        V P&                  '       dB   \        P)                  RV P&                  P*                  V P&                  P$                  4       R# R# )zconstructing a %s instance from a usb.core.Device has been deprecated, use %s.find_supported_devices() or pass a HidapiDevice handlec              3   s\   <"   T F!  pVR ,          SP                   8X  g   K  Vx  K#  	  R# 5i)r   Nr   )Z.0infousbdevs   & r   Z	<genexpr>Z(UsbHidDriver.__init__.<locals>.<genexpr>   s.      M,\D"?3v7K7KK  4,\s   ,
,z Could not find device in HID buszhas kernel driver: %s (%s)N)Z
isinstanceusbcoreZDevice	__class__r   r   ZwarningZnexthid	enumerateidVendor	idProductHidapiDeviceZsuperr    r   Zfrom_hidrawpath_hwmonr   Zdriver)r   r   r   r   ZclnamehidinforK   rN   s   &&&,  @r   r    ZUsbHidDriver.__init__   s     fchhoo..^^,,FOO \]cmF MCMM&//6K[K[,\ M MG>>>7!#w/F77!--fkk:;;;MM68J8JDKKL\L\] r!   )rU   )r   r3   r4   r5   r6   r7   rH   r    r9   r:   Z__classcell__)rN   r<   s   @@r   r>   r>      s&     C ^ ^r!   r>   c                   s4   a  ] tR t^t o Rt]R 4       tRtV tR# )	UsbDriverzxBase driver class for regular USB devices.

Specifically, regular USB devices are *not* Human Interface Devices (HIDs).
c                r?   r@   )r   PyUsbBusrC   rD   rE   rF   rG   r   rH   Z UsbDriver.find_supported_devices   sa     !llNCaz..QcQ3Q&Q9#KK$ R + r!   rA   N)	r   r3   r4   r5   r6   r7   rH   r9   r:   r;   r=   r   rW   rW      s     
  r!   rW   c                   s  a  ] tR t^t o RtRR ltR tRR ltR tR t	R t
R	]/R
 ltR	]/R ltR	]/R lt]RR l4       t]R 4       t]R 4       t]R 4       t]R 4       t]R 4       t]R 4       t]R 4       tR tRtV tR# )PyUsbDevicez"A PyUSB backed device.

PyUSB will automatically pick the first available backend (at runtime).
The supported backends are:

 - libusb-1.0
 - libusb-0.1
 - OpenUSB
Nc                sB    \         V n        Wn        W n        R V n        R# )FN)rL   apirK   bInterfaceNumber	_attached)r   rK   r[      &&&r   r    ZPyUsbDevice.__init__   s     0r!   c                s.    V P                   ;'       g    ^ #     )r[   )r   cfg   &&r   _select_interfaceZPyUsbDevice._select_interface   s    $$)))r!   c                s    V P                   P                  4       pT P                  T4      T n
        \        P                  RT P                  4       \        P                  P                  R4      '       dq   T P                   P                  T P                  4      '       dD   \        P                  R4       T P                   P                  T P                  4       RT n        R# R# R#   \        P                  P                   dn   pTP
                  ^ ,          R8X  dP   \        P                  R4       T P                   P                  4        T P                   P                  4       p Rp?ELSh Rp?ii ; i)zConnect to the device.

Ensure the device is configured and replace the kernel kernel on the
selected interface, if necessary.
zConfiguration not setz!setting the (first) configurationNzselected interface: %dZlinuxz)replacing stock kernel driver with libusbT)rK   Zget_active_configurationrL   rM   ZUSBErrorargsr   r   Zset_configurationrb   r[   sysplatformZ
startswithZis_kernel_driver_activeZdetach_kernel_driverr\   )r   r[   r`   Zerrs   &&  r   r#   ZPyUsbDevice.open   s	   		++668C !% 6 6s ;.0E0EFLL##G,,33D4I4IJJMMEFKK,,T-B-BC!DN K - xx   	xx{55AB--/kk::<	s   C) )E5A!E0/E00E5c                s    \         P                  R4       \        P                  P	                  V P
                  V P                  4       R# )z0Explicitly claim the device from other programs.zexplicitly claim interfaceN)r   r   rL   utilZclaim_interfacerK   r[   r,   r-   r   claimZPyUsbDevice.claim  s-    23  d.C.CDr!   c                sB   \         P                  R8X  dA   \        P                  R4       \        P
                  P                  V P                  4       R# \        P                  R4       \        P
                  P                  V P                  V P                  4       R# )z%Release the device to other programs.win32zexplicitly release devicezexplicitly release interfaceN)
rd   re   r   r   rL   rf   Zdispose_resourcesrK   Zrelease_interfacer[   r,   r-   r   r   ZPyUsbDevice.release"  s`    <<7" MM56HH&&t{{3 MM89HH&&t{{D4I4IJr!   c                s    V P                  4        V P                  '       dD   \        P                  R4       V P                  P                  V P                  4       RV n        R# R# )zSDisconnect from the device.

Clean up and (Linux only) reattach the kernel driver.
zrestoring stock kernel driverFN)r   r\   r   r   rK   Zattach_kernel_driverr[   r,   r-   r   r(   ZPyUsbDevice.close/  sG    
 	>>>MM9:KK,,T-B-BC"DN r!   timeoutc               s     V P                   P                  WVR7      p\        P	                  R\        T4      \        T4      4       T#   \         d"    \        P	                  RT4       \        4       hi ; i)zRead from endpoint.ri   %failed to read, timed out after %d msread %d bytes: %r)rK   readr    r   r   r   lenr   )r   endpointlengthri   datas   &&&$ r   rm   ZPyUsbDevice.read:  sh    	;;##Hg#FD 	)3t9k$6GH	  	MMA7K)O	s   A
 
,A6c               s    \         P                  R\        V4      \        V4      4        V P                  P                  WVR7      #   \         d"    \         P                  RT4       \        4       hi ; i)zWrite to endpoint.zwriting %d bytes: %rrj   z#write failed, timed out after %d ms)r   r   rn   r   rK   writer    r   )r   ro   rq   ri   s   &&&$r   rr   ZPyUsbDevice.writeD  s`    ,c$iT9JK	;;$$XW$EE 	MM?I)O	s   A ,A4c               s    \         P                  RW#4        V P                  P                  ! V/ VB #   \         d"    \         P                  RT4       \        4       hi ; i)zSubmit a contrl transfer.z$sending control transfer with %r, %rz/control transfers failed, timed out after %d ms)r   r   rK   ctrl_transferr    r   )r   ri   rc   r   s   &$*,r   rs   ZPyUsbDevice.ctrl_transferM  sU    <dK	;;,,d=f== 	MMKWU)O	s	   4 ,A c              #  sd  "   / pV'       d   WR &   V'       d   W#R&   \         '       dQ   \        P                  R8X  g   \        P                  R8X  d'   \        P	                  R4       \         P
                  pM\        P                  P
                  pV! RRR/VB  F  pV ! V4      x  K  	  R# 5i)	rQ   rR   rh   Zcygwinzusing libusb_package.findZfind_allTNrA   )libusb_packagerd   re   r   r   findrL   rM   )r   r   r   rc   ru   r   s   &&&   r   rP   ZPyUsbDevice.enumerateV  s     " #>s||w6#,,(:RMM56!&&D88==D1D1D1Ff+ 2s   B0B0BB0c                r.   r   )rK   rQ   r,   r-   r   r	   ZPyUsbDevice.vendor_ide  s    {{###r!   c                r.   r   )rK   rR   r,   r-   r   r
   ZPyUsbDevice.product_idi      {{$$$r!   c                r.   r   )rK   Z	bcdDevicer,   r-   r   r   ZPyUsbDevice.release_numberm  rv   r!   c                r.   r   )rK   r   r,   r-   r   r   ZPyUsbDevice.serial_numberq  s    {{(((r!   c                s4    R V P                   P                   2# )rL   )rK   r/   r,   r-   r   r/   ZPyUsbDevice.busu  s    T[[__%&&r!   c                r.   r   )rK   r0   r,   r-   r   r0   ZPyUsbDevice.addressy  s    {{"""r!   c                r.   r   )rK   Zport_numbersr,   r-   r   r1   ZPyUsbDevice.port}  s    {{'''r!   c                    \        V 4      \        V4      8H  ;'       d;    V P                  VP                  8H  ;'       d    V P                  VP                  8H  # r   rD   r/   r0   r   Zotherra   r   __eq__ZPyUsbDevice.__eq__  B    DzT%[(ddTXX-Bddt||W\WdWdGddr!   )r\   rZ   r[   rK   r   r^   NN)r   r3   r4   r5   r6   r    rb   r#   rg   r   r(   _DEFAULT_TIMEOUT_MSrm   rr   rs   r7   rP   r8   r	   r
   r   r   r/   r0   r1   rz   r9   r:   r;   r=   r   rY   rY      s     *"<E
K	#0C /B +>    $ $ % % % % ) ) ' ' # # ( (e er!   rY   c                   s   a  ] tR tRt o RtR tR tR tR tR]	/R lt
R	 tR
 tR tR t]RR l4       t]R 4       t]R 4       t]R 4       t]R 4       t]R 4       t]R 4       t]R 4       t]R 4       tR tRtV tR# )rS   i  aB  A hidapi backed device.

Depending on the platform, the selected `hidapi` and how it was built, this
might use any of the following backends:

 - hid.dll on Windows
 - hidraw on Linux, if it was enabled during the build of hidapi
 - IOHidManager on MacOS
 - libusb-1.0 on all other cases

The default hidapi API is the module 'hid'.  On standard Linux builds of
the hidapi package, this might default to a libusb-1.0 backed
implementation; at the same time an alternate 'hidraw' module may also be
provided.  The latter is prefered, when available.

Note: if a libusb-backed 'hid' is used on Linux (assuming default build
options) it will detach the kernel driver, making hidraw and hwmon
unavailable for that device.  To fix, rebind the device to usbhid with:

    echo '<bus>-<port>:1.0' | sudo tee /sys/bus/usb/drivers/usbhid/bind
c                s\    Wn         W n        V P                   P                  4       V n        R # r   )rZ   rV   r   hiddev)r   ZhidapiZhidapi_dev_infor]   r   r    ZHidapiDevice.__init__  s    &hhoo'r!   c                s^    V P                   P                  V P                  R,          4       R# )r"   rT   N)r~   Z	open_pathrV   r,   r-   r   r#   ZHidapiDevice.open  s    dll623r!   c                r'   )zNOOP.N)r~   r(   r,   r-   r   r(   ZHidapiDevice.close  r*   r!   c                s    V P                   P                  R4      ^ 8X  d   ^ pM^p^ pV P                   P                  ^VR7      '       d   V^,          pK.  \        P	                  RV4       R# )aV  Clear already enqueued incoming reports.

The OS generally enqueues incomming reports for open HIDs, and hidapi
emulates this when running on top of libusb.  On Linux, up to 64
reports can be enqueued.

This method quickly reads and discards any already enqueued reports,
and is useful when later reads are not expected to return stale data.
TZ
max_length
timeout_msz(discarded %d previously enqueued reportsN)r~   set_nonblockingrm   r   r   )r   r   Z	discardeds   &  r   clear_enqueued_reportsZ#HidapiDevice.clear_enqueued_reports  s\     ;;&&t,1JJ	kk!
CCNI@)Lr!   ri   c               sF   V P                   P                  R4       Vf   ^ pM	V^ 8X  d   ^pV P                   P                  WR7      pV'       d)   V'       g!   \        P	                  RV4       \        4       h\        P	                  R\        V4      \        V4      4       V# )a  Read raw report from HID.

The returned data follows the semantics of the Linux HIDRAW API.

> On a device which uses numbered reports, the first byte of the
> returned data will be the report number; the report data follows,
> beginning in the second byte. For devices which do not use numbered
> reports, the report data will begin at the first byte.

Unlike the underlying cython-hidapi API this method wraps, pass
`timeout=None` to disable the default timeout.
Fr   rk   rl   )r~   r   rm   r   r   r   rn   r   )r   rp   ri   rq   s   &&$ r   rm   ZHidapiDevice.read  s}     	##E*?G\G{{6F4MMA7K)O)3t9k$6GHr!   c           
     4   \         P                  RV^ ,          \        V4      ^,
          \        V^R7      4       V P                  P                  V4      pV^ 8  d   \        R4      hV\        V4      8w  d!   \         P                  RV\        V4      4       V# )a?  Write raw report to HID.

The buffer should follow the semantics of the Linux HIDRAW API.

> The first byte of the buffer passed to write() should be set to the
> report number.  If the device does not use numbered reports, the
> first byte should be set to 0. The report data itself should begin
> at the second byte.
z'writing report 0x%02x with %d bytes: %rZstartzCould not write to devicez!wrote %d total bytes, expected %d)r   r   rn   r   r~   rr   OSErrorr   rq   Zres   && r   rr   ZHidapiDevice.write  s{     	?a$i!m[Q%?	Akk%7566#d)MM=sCIN
r!   c           
         V P                   P                  W4      p\        P                  RV^ ,          \	        V4      ^,
          \        V^R7      4       V# )aL  Get input report that matches `report_id` from HID.

If the device does not use numbered reports, set `report_id` to 0.

Unlike `read`, the returned data follows semantics similar to `write`
and `get_feature_report`: the first byte will always contain the
report ID (or 0), and the report data itself will being at the second
byte.
z)got input report 0x%02x with %d bytes: %rr   )r~   get_input_reportr   r   rn   r   r   Z	report_idrp   rq      &&& r   r   ZHidapiDevice.get_input_report  sG     {{++I>A47$i!m[Q%?	Ar!   c           
     r   )aO  Get feature report that matches `report_id` from HID.

If the device does not use numbered reports, set `report_id` to 0.

Unlike `read`, the returned data follows semantics similar to `write`
and `send_feature_report`: the first byte will always contain the
report ID (or 0), and the report data itself will being at the second
byte.
z+got feature report 0x%02x with %d bytes: %rr   )r~   get_feature_reportr   r   rn   r   r   r   r   r   ZHidapiDevice.get_feature_report  sG     {{--i@CT!W$i!m[Q%?	Ar!   c           
     r   )a5  Send feature report to HID.

The buffer should follow the semantics of `write`.

> The first byte of the buffer passed to write() should be set to the
> report number.  If the device does not use numbered reports, the
> first byte should be set to 0. The report data itself should begin
> at the second byte.
z/sending feature report 0x%02x with %d bytes: %rr   z'Could not send feature report to devicez sent %d total bytes, expected %d)r   r   rn   r   r~   send_feature_reportr   r   r   r   r   Z HidapiDevice.send_feature_report  s{     	G1gs4y1}k$a.H	Jkk--d37CDD#d)MM<c3t9M
r!   Nc              #  s   "   TP                  T;'       g    ^ T;'       g    ^ 4      p\        P                  R8X  d   \        VR R7      pV F  pV ! W4      x  K  	  R# 5i)r_   Zdarwinc                 s    V R ,          # rT   rA   )rJ   r-   r   <lambda>Z(HidapiDevice.enumerate.<locals>.<lambda>  s    4<r!   ZkeyN)rP   rd   re   sorted)r   rZ   r   r   ZinfosrJ   s   &&&&  r   rP   ZHidapiDevice.enumerate  sN     chhQq1<<8#5&?@EDc.  s
   A!?A!c                (    V P                   R ,          # r   rV   r,   r-   r   rT   ZHidapiDevice.path   s    ||F##r!   c                r   )r	   r   r,   r-   r   r	   ZHidapiDevice.vendor_id$  s    ||K((r!   c                r   )r
   r   r,   r-   r   r
   ZHidapiDevice.product_id(  s    ||L))r!   c                r   )r   r   r,   r-   r   r   ZHidapiDevice.release_number,  s    ||,--r!   c                r   rI   r   r,   r-   r   r   ZHidapiDevice.serial_number0  s    ||O,,r!   c                    R # )rO   rA   r,   r-   r   r/   ZHidapiDevice.bus4  s    r!   c                sH    V P                   R ,          P                  RR7      # )rT   Zreplace)Zerrors)rV   Zdecoder,   r-   r   r0   ZHidapiDevice.address8  s    ||F#**)*<<r!   c                r   r   rA   r,   r-   r   r1   ZHidapiDevice.port<  s    r!   c                rw   r   rx   ry   ra   r   rz   ZHidapiDevice.__eq__@  r{   r!   )rZ   r~   rV   r|   )r   r3   r4   r5   r6   r    r#   r(   r   r}   rm   rr   r   r   r   r7   rP   r8   rT   r	   r
   r   r   r/   r0   r1   rz   r9   r:   r;   r=   r   rS   rS     s     *(
4M&&9 2&& ! ! $ $ ) ) * * . . - -   = =  e er!   rS   c                   *   a  ] tR tRt o RR ltRtV tR# )rB   iD  Nc           
   +  s  "   \         P                  \        W4      p\        \	        \
        4      R R7      p\        P                  RV P                  P                  4       \        P                  RV P                  P                  RP                  \        R V4      4      4       V EF  p	V'       d   V	P                  V8w  d   K  V'       d   V	P                  V8w  d   K:  V'       d   V	P                  V8w  d   KU  RV	P                  9   db   RV	P                  9   dQ   \        P                  R	V	P                   V	P"                  V	P                  R,          V	P                  R,          4       M+\        P                  R
V	P                   V	P"                  4       V F"  p
V
P$                  ! V	3RVRV/VB  Rj  xL
  K$  	  EK  	  R#  L5i)zFind compatible HID devices.c                 r+   r   r   Zxr-   r   r   (HidapiBus.find_devices.<locals>.<lambda>I  s    !**r!   r   searching %s%s drivers: %s, c                 r+   r   r   r   r-   r   r   r   N      AJJr!   ZusageZ
usage_pagez4HID device: %04x:%04x (usage_page=%#06x usage=%#06x)z!HID device: %04x:%04x (usage n/a)r   r   N)rS   rP   rO   r   r   r>   r   r   rN   r   joinmapr/   r0   r1   rV   r	   r
   r   )r   r   r   r/   r0   usb_portr   Zhandlesdriversr   drvs   &&&&&&,    r   rC   ZHidapiBus.find_devicesE  s[     ((f>,\:@TUndnn&=&=>NN##IIc.89	

 FvzzS(6>>W4FKK83
 &..(\V^^-KJ$$%%NN<0NN7+ 7$$%%
 99VVFVGVvVVV 3 4 Ws   CGG+CG:G
;GrA   r2   r   r3   r4   r5   rC   r9   r:   r;   r=   r   rB   rB   D  s     %W %Wr!   rB   c                   r   )rX   im  Nc           
   +  s  "   \        \        \        4      R R7      p\        P	                  RV P
                  P                  4       \        P	                  RV P
                  P                  RP                  \        R V4      4      4       \        P                  W4       F  pV'       d   VP                  V8w  d   K  V'       d   \        VP                  4      V8w  d   KB  V'       d   VP                  V8w  d   K]  \        P	                  RVP                  VP                   4       V F"  p	V	P"                  ! V3RVR	V/VB  R
j  xL
  K$  	  K  	  R
#  L5i)z$Find compatible regular USB devices.c                 r+   r   r   r   r-   r   r   'PyUsbBus.find_devices.<locals>.<lambda>q  s    qzzr!   r   r   r   r   c                 r+   r   r   r   r-   r   r   r   v  r   r!   zUSB device: %04x:%04xr   r   N)r   r   rW   r   r   rN   r   r   r   rY   rP   r/   Zstrr0   r1   r	   r
   r   )
r   r   r   r/   r0   r   r   r   r   r   s
   &&&&&&,   r   rC   ZPyUsbBus.find_devicesn  s      ,Y7=QRndnn&=&=>NN##IIc.89	

 "++F<FvzzS(3v~~.'9FKK83MM163C3CVEVEVW99VVFVGVvVVV  = Ws   CE#E,AE	E
ErA   r2   r   r;   r=   r   rX   rX   m  s     W Wr!   rX   )r6   Zloggingrd   rL   Zusb.corer    ZhidrawrO   ZModuleNotFoundErrorrt   Zliquidctl.driver.baser   r   r   Zliquidctl.driver.hwmonr   Zliquidctl.errorr   Zliquidctl.utilr   r}   Z	getLoggerr   r   r   r>   rW   rY   rS   rB   rX   rA   r!   r   <module>r      s   7r  
 
 $  K J . # &
  


H
%` J ` F^= ^> "We Wet|e |e~&W &WRWw WS    Ns"   B B- B*)B*-	B98B9