11import logging
2+ from typing import Any
23
34import usb
45from gs_usb .constants import CAN_EFF_FLAG , CAN_ERR_FLAG , CAN_MAX_DLC , CAN_RTR_FLAG
1213logger = logging .getLogger (__name__ )
1314
1415
15- def _scan_gs_usb_devices () -> list [GsUsb ]:
16- """Scan for gs_usb devices using auto-detected backend.
16+ def _find_gs_usb_devices (
17+ bus : int | None = None , address : int | None = None
18+ ) -> list [GsUsb ]:
19+ """Find gs_usb devices using auto-detected backend.
1720
1821 Unlike :meth:`GsUsb.scan`, this does not force the ``libusb1`` backend,
1922 allowing ``pyusb`` to auto-detect the best available backend. This enables
2023 support for WinUSB on Windows in addition to libusbK.
24+
25+ :param bus: number of the bus that the device is connected to
26+ :param address: address of the device on the bus it is connected to
27+ :return: a list of found GsUsb devices
2128 """
29+ kwargs = {}
30+ if bus is not None :
31+ kwargs ["bus" ] = bus
32+ if address is not None :
33+ kwargs ["address" ] = address
34+
2235 return [
2336 GsUsb (dev )
2437 for dev in (
2538 usb .core .find (
2639 find_all = True ,
2740 custom_match = GsUsb .is_gs_usb_device ,
41+ ** kwargs ,
2842 )
2943 or []
3044 )
3145 ]
3246
3347
34- def _find_gs_usb_device (bus : int , address : int ) -> GsUsb | None :
35- """Find a specific gs_usb device using auto-detected backend.
36-
37- Unlike :meth:`GsUsb.find`, this does not force the ``libusb1`` backend,
38- allowing ``pyusb`` to auto-detect the best available backend. This enables
39- support for WinUSB on Windows in addition to libusbK.
40- """
41- dev = usb .core .find (
42- custom_match = GsUsb .is_gs_usb_device ,
43- bus = bus ,
44- address = address ,
45- )
46- if dev :
47- return GsUsb (dev )
48- return None
49-
50-
5148class GsUsbBus (can .BusABC ):
5249 def __init__ (
5350 self ,
54- channel ,
51+ channel : can . typechecking . Channel ,
5552 bitrate : int = 500_000 ,
56- index = None ,
57- bus = None ,
58- address = None ,
59- can_filters = None ,
60- ** kwargs ,
61- ):
53+ index : int | None = None ,
54+ bus : int | None = None ,
55+ address : int | None = None ,
56+ can_filters : can . typechecking . CanFilters | None = None ,
57+ ** kwargs : Any ,
58+ ) -> None :
6259 """
6360 :param channel: usb device name
6461 :param index: device number if using automatic scan, starting from 0.
@@ -74,24 +71,35 @@ def __init__(
7471 )
7572
7673 if index is None and address is None and bus is None :
77- index = channel
74+ _index : Any = channel
75+ else :
76+ _index = index
7877
79- self ._index = None
80- if index is not None :
81- devs = _scan_gs_usb_devices ()
82- if len (devs ) <= index :
78+ self ._index : int | None = None
79+ if _index is not None :
80+ if not isinstance (_index , int ):
81+ try :
82+ _index = int (_index )
83+ except (ValueError , TypeError ):
84+ raise CanInitializationError (
85+ f"index must be an integer, but got { type (_index ).__name__ } ({ _index } )"
86+ ) from None
87+
88+ devs = _find_gs_usb_devices ()
89+ if len (devs ) <= _index :
8390 raise CanInitializationError (
84- f"Cannot find device { index } . Devices found: { len (devs )} "
91+ f"Cannot find device { _index } . Devices found: { len (devs )} "
8592 )
86- gs_usb = devs [index ]
87- self ._index = index
93+ gs_usb = devs [_index ]
94+ self ._index = _index
8895 else :
89- gs_usb = _find_gs_usb_device (bus = bus , address = address )
90- if not gs_usb :
96+ devs = _find_gs_usb_devices (bus = bus , address = address )
97+ if not devs :
9198 raise CanInitializationError (f"Cannot find device { channel } " )
99+ gs_usb = devs [0 ]
92100
93101 self .gs_usb = gs_usb
94- self .channel_info = channel
102+ self .channel_info = str ( channel )
95103 self ._can_protocol = can .CanProtocol .CAN_20
96104
97105 bit_timing = can .BitTiming .from_sample_point (
@@ -116,7 +124,7 @@ def __init__(
116124 ** kwargs ,
117125 )
118126
119- def send (self , msg : can .Message , timeout : float | None = None ):
127+ def send (self , msg : can .Message , timeout : float | None = None ) -> None :
120128 """Transmit a message to the CAN bus.
121129
122130 :param Message msg: A message object.
@@ -200,9 +208,10 @@ def shutdown(self):
200208
201209 self .gs_usb .stop ()
202210 if self ._index is not None :
203- # Avoid errors on subsequent __init() by repeating the .scan() and .start() that would otherwise fail
204- # the next time the device is opened in __init__()
205- devs = _scan_gs_usb_devices ()
211+ # Avoid errors on subsequent __init() by repeating the .scan() and
212+ # .start() that would otherwise fail the next time the device is
213+ # opened in __init__()
214+ devs = _find_gs_usb_devices ()
206215 if self ._index < len (devs ):
207216 gs_usb = devs [self ._index ]
208217 try :
0 commit comments