10
10
import logging
11
11
import time
12
12
import os
13
- from typing import List , NamedTuple , Optional , Tuple , Sequence , Union
13
+ from types import ModuleType
14
+ from typing import List , NamedTuple , Optional , Tuple , Sequence , Union , Any , Dict
14
15
15
16
try :
16
17
# Try builtin Python 3 Windows API
17
18
from _winapi import WaitForSingleObject , INFINITE
18
19
19
20
HAS_EVENTS = True
20
21
except ImportError :
21
- try :
22
- # Try pywin32 package
23
- from win32event import WaitForSingleObject , INFINITE
24
-
25
- HAS_EVENTS = True
26
- except ImportError :
27
- # Use polling instead
28
- HAS_EVENTS = False
22
+ HAS_EVENTS = False
29
23
30
24
# Import Modules
31
25
# ==============
36
30
deprecated_args_alias ,
37
31
time_perfcounter_correlation ,
38
32
)
39
- from can .typechecking import AutoDetectedConfig , CanFilters
33
+ from can .typechecking import AutoDetectedConfig , CanFilters , Channel
40
34
41
35
# Define Module Logger
42
36
# ====================
48
42
from . import xldefine , xlclass
49
43
50
44
# Import safely Vector API module for Travis tests
51
- xldriver = None
45
+ xldriver : Optional [ ModuleType ] = None
52
46
try :
53
47
from . import xldriver
54
48
except Exception as exc :
@@ -73,20 +67,20 @@ def __init__(
73
67
channel : Union [int , Sequence [int ], str ],
74
68
can_filters : Optional [CanFilters ] = None ,
75
69
poll_interval : float = 0.01 ,
76
- receive_own_messages : bool = False ,
77
- bitrate : int = None ,
70
+ receive_own_messages : Optional [ bool ] = False ,
71
+ bitrate : Optional [ int ] = None ,
78
72
rx_queue_size : int = 2 ** 14 ,
79
- app_name : str = "CANalyzer" ,
80
- serial : int = None ,
81
- fd : bool = False ,
82
- data_bitrate : int = None ,
73
+ app_name : Optional [ str ] = "CANalyzer" ,
74
+ serial : Optional [ int ] = None ,
75
+ fd : Optional [ bool ] = False ,
76
+ data_bitrate : Optional [ int ] = None ,
83
77
sjw_abr : int = 2 ,
84
78
tseg1_abr : int = 6 ,
85
79
tseg2_abr : int = 3 ,
86
80
sjw_dbr : int = 2 ,
87
81
tseg1_dbr : int = 6 ,
88
82
tseg2_dbr : int = 3 ,
89
- ** kwargs ,
83
+ ** kwargs : Any ,
90
84
) -> None :
91
85
"""
92
86
:param channel:
@@ -144,16 +138,18 @@ def __init__(
144
138
145
139
if xldriver is None :
146
140
raise CanInterfaceNotImplementedError ("The Vector API has not been loaded" )
141
+ self .xldriver = xldriver # keep reference so mypy knows it is not None
147
142
148
143
self .poll_interval = poll_interval
149
144
150
- if isinstance (channel , str ): # must be checked before generic Sequence
145
+ self .channels : Sequence [int ]
146
+ if isinstance (channel , int ):
147
+ self .channels = [channel ]
148
+ elif isinstance (channel , str ): # must be checked before generic Sequence
151
149
# Assume comma separated string of channels
152
150
self .channels = [int (ch .strip ()) for ch in channel .split ("," )]
153
- elif isinstance (channel , int ):
154
- self .channels = [channel ]
155
151
elif isinstance (channel , Sequence ):
156
- self .channels = channel
152
+ self .channels = [ int ( ch ) for ch in channel ]
157
153
else :
158
154
raise TypeError (
159
155
f"Invalid type for channels parameter: { type (channel ).__name__ } "
@@ -185,12 +181,12 @@ def __init__(
185
181
"None of the configured channels could be found on the specified hardware."
186
182
)
187
183
188
- xldriver .xlOpenDriver ()
184
+ self . xldriver .xlOpenDriver ()
189
185
self .port_handle = xlclass .XLportHandle (xldefine .XL_INVALID_PORTHANDLE )
190
186
self .mask = 0
191
187
self .fd = fd
192
188
# Get channels masks
193
- self .channel_masks = {}
189
+ self .channel_masks : Dict [ Optional [ Channel ], int ] = {}
194
190
self .index_to_channel = {}
195
191
196
192
for channel in self .channels :
@@ -200,7 +196,7 @@ def __init__(
200
196
app_name , channel
201
197
)
202
198
LOG .debug ("Channel index %d found" , channel )
203
- idx = xldriver .xlGetChannelIndex (hw_type , hw_index , hw_channel )
199
+ idx = self . xldriver .xlGetChannelIndex (hw_type , hw_index , hw_channel )
204
200
if idx < 0 :
205
201
# Undocumented behavior! See issue #353.
206
202
# If hardware is unavailable, this function returns -1.
@@ -224,7 +220,7 @@ def __init__(
224
220
if bitrate or fd :
225
221
permission_mask .value = self .mask
226
222
if fd :
227
- xldriver .xlOpenPort (
223
+ self . xldriver .xlOpenPort (
228
224
self .port_handle ,
229
225
self ._app_name ,
230
226
self .mask ,
@@ -234,7 +230,7 @@ def __init__(
234
230
xldefine .XL_BusTypes .XL_BUS_TYPE_CAN ,
235
231
)
236
232
else :
237
- xldriver .xlOpenPort (
233
+ self . xldriver .xlOpenPort (
238
234
self .port_handle ,
239
235
self ._app_name ,
240
236
self .mask ,
@@ -267,7 +263,7 @@ def __init__(
267
263
self .canFdConf .tseg1Dbr = int (tseg1_dbr )
268
264
self .canFdConf .tseg2Dbr = int (tseg2_dbr )
269
265
270
- xldriver .xlCanFdSetConfiguration (
266
+ self . xldriver .xlCanFdSetConfiguration (
271
267
self .port_handle , self .mask , self .canFdConf
272
268
)
273
269
LOG .info (
@@ -289,7 +285,7 @@ def __init__(
289
285
)
290
286
else :
291
287
if bitrate :
292
- xldriver .xlCanSetChannelBitrate (
288
+ self . xldriver .xlCanSetChannelBitrate (
293
289
self .port_handle , permission_mask , bitrate
294
290
)
295
291
LOG .info ("SetChannelBitrate: baudr.=%u" , bitrate )
@@ -298,16 +294,16 @@ def __init__(
298
294
299
295
# Enable/disable TX receipts
300
296
tx_receipts = 1 if receive_own_messages else 0
301
- xldriver .xlCanSetChannelMode (self .port_handle , self .mask , tx_receipts , 0 )
297
+ self . xldriver .xlCanSetChannelMode (self .port_handle , self .mask , tx_receipts , 0 )
302
298
303
299
if HAS_EVENTS :
304
300
self .event_handle = xlclass .XLhandle ()
305
- xldriver .xlSetNotification (self .port_handle , self .event_handle , 1 )
301
+ self . xldriver .xlSetNotification (self .port_handle , self .event_handle , 1 )
306
302
else :
307
303
LOG .info ("Install pywin32 to avoid polling" )
308
304
309
305
try :
310
- xldriver .xlActivateChannel (
306
+ self . xldriver .xlActivateChannel (
311
307
self .port_handle , self .mask , xldefine .XL_BusTypes .XL_BUS_TYPE_CAN , 0
312
308
)
313
309
except VectorOperationError as error :
@@ -320,17 +316,17 @@ def __init__(
320
316
if time .get_clock_info ("time" ).resolution > 1e-5 :
321
317
ts , perfcounter = time_perfcounter_correlation ()
322
318
try :
323
- xldriver .xlGetSyncTime (self .port_handle , offset )
319
+ self . xldriver .xlGetSyncTime (self .port_handle , offset )
324
320
except VectorInitializationError :
325
- xldriver .xlGetChannelTime (self .port_handle , self .mask , offset )
321
+ self . xldriver .xlGetChannelTime (self .port_handle , self .mask , offset )
326
322
current_perfcounter = time .perf_counter ()
327
323
now = ts + (current_perfcounter - perfcounter )
328
324
self ._time_offset = now - offset .value * 1e-9
329
325
else :
330
326
try :
331
- xldriver .xlGetSyncTime (self .port_handle , offset )
327
+ self . xldriver .xlGetSyncTime (self .port_handle , offset )
332
328
except VectorInitializationError :
333
- xldriver .xlGetChannelTime (self .port_handle , self .mask , offset )
329
+ self . xldriver .xlGetChannelTime (self .port_handle , self .mask , offset )
334
330
self ._time_offset = time .time () - offset .value * 1e-9
335
331
336
332
except VectorInitializationError :
@@ -339,7 +335,7 @@ def __init__(
339
335
self ._is_filtered = False
340
336
super ().__init__ (channel = channel , can_filters = can_filters , ** kwargs )
341
337
342
- def _apply_filters (self , filters ) -> None :
338
+ def _apply_filters (self , filters : Optional [ CanFilters ] ) -> None :
343
339
if filters :
344
340
# Only up to one filter per ID type allowed
345
341
if len (filters ) == 1 or (
@@ -348,7 +344,7 @@ def _apply_filters(self, filters) -> None:
348
344
):
349
345
try :
350
346
for can_filter in filters :
351
- xldriver .xlCanSetChannelAcceptance (
347
+ self . xldriver .xlCanSetChannelAcceptance (
352
348
self .port_handle ,
353
349
self .mask ,
354
350
can_filter ["can_id" ],
@@ -370,14 +366,14 @@ def _apply_filters(self, filters) -> None:
370
366
# fallback: reset filters
371
367
self ._is_filtered = False
372
368
try :
373
- xldriver .xlCanSetChannelAcceptance (
369
+ self . xldriver .xlCanSetChannelAcceptance (
374
370
self .port_handle ,
375
371
self .mask ,
376
372
0x0 ,
377
373
0x0 ,
378
374
xldefine .XL_AcceptanceFilter .XL_CAN_EXT ,
379
375
)
380
- xldriver .xlCanSetChannelAcceptance (
376
+ self . xldriver .xlCanSetChannelAcceptance (
381
377
self .port_handle ,
382
378
self .mask ,
383
379
0x0 ,
@@ -417,14 +413,14 @@ def _recv_internal(
417
413
else :
418
414
time_left = end_time - time .time ()
419
415
time_left_ms = max (0 , int (time_left * 1000 ))
420
- WaitForSingleObject (self .event_handle .value , time_left_ms )
416
+ WaitForSingleObject (self .event_handle .value , time_left_ms ) # type: ignore
421
417
else :
422
418
# Wait a short time until we try again
423
419
time .sleep (self .poll_interval )
424
420
425
421
def _recv_canfd (self ) -> Optional [Message ]:
426
422
xl_can_rx_event = xlclass .XLcanRxEvent ()
427
- xldriver .xlCanReceive (self .port_handle , xl_can_rx_event )
423
+ self . xldriver .xlCanReceive (self .port_handle , xl_can_rx_event )
428
424
429
425
if xl_can_rx_event .tag == xldefine .XL_CANFD_RX_EventTags .XL_CAN_EV_TAG_RX_OK :
430
426
is_rx = True
@@ -470,7 +466,7 @@ def _recv_canfd(self) -> Optional[Message]:
470
466
def _recv_can (self ) -> Optional [Message ]:
471
467
xl_event = xlclass .XLevent ()
472
468
event_count = ctypes .c_uint (1 )
473
- xldriver .xlReceive (self .port_handle , event_count , xl_event )
469
+ self . xldriver .xlReceive (self .port_handle , event_count , xl_event )
474
470
475
471
if xl_event .tag != xldefine .XL_EventTags .XL_RECEIVE_MSG :
476
472
self .handle_can_event (xl_event )
@@ -523,7 +519,7 @@ def handle_canfd_event(self, event: xlclass.XLcanRxEvent) -> None:
523
519
`XL_CAN_EV_TAG_TX_ERROR`, `XL_TIMER` or `XL_CAN_EV_TAG_CHIP_STATE` tag.
524
520
"""
525
521
526
- def send (self , msg : Message , timeout : Optional [float ] = None ):
522
+ def send (self , msg : Message , timeout : Optional [float ] = None ) -> None :
527
523
self ._send_sequence ([msg ])
528
524
529
525
def _send_sequence (self , msgs : Sequence [Message ]) -> int :
@@ -548,7 +544,9 @@ def _send_can_msg_sequence(self, msgs: Sequence[Message]) -> int:
548
544
* map (self ._build_xl_event , msgs )
549
545
)
550
546
551
- xldriver .xlCanTransmit (self .port_handle , mask , message_count , xl_event_array )
547
+ self .xldriver .xlCanTransmit (
548
+ self .port_handle , mask , message_count , xl_event_array
549
+ )
552
550
return message_count .value
553
551
554
552
@staticmethod
@@ -580,7 +578,7 @@ def _send_can_fd_msg_sequence(self, msgs: Sequence[Message]) -> int:
580
578
)
581
579
582
580
msg_count_sent = ctypes .c_uint (0 )
583
- xldriver .xlCanTransmitEx (
581
+ self . xldriver .xlCanTransmitEx (
584
582
self .port_handle , mask , message_count , msg_count_sent , xl_can_tx_event_array
585
583
)
586
584
return msg_count_sent .value
@@ -611,17 +609,17 @@ def _build_xl_can_tx_event(msg: Message) -> xlclass.XLcanTxEvent:
611
609
return xl_can_tx_event
612
610
613
611
def flush_tx_buffer (self ) -> None :
614
- xldriver .xlCanFlushTransmitQueue (self .port_handle , self .mask )
612
+ self . xldriver .xlCanFlushTransmitQueue (self .port_handle , self .mask )
615
613
616
614
def shutdown (self ) -> None :
617
615
super ().shutdown ()
618
- xldriver .xlDeactivateChannel (self .port_handle , self .mask )
619
- xldriver .xlClosePort (self .port_handle )
620
- xldriver .xlCloseDriver ()
616
+ self . xldriver .xlDeactivateChannel (self .port_handle , self .mask )
617
+ self . xldriver .xlClosePort (self .port_handle )
618
+ self . xldriver .xlCloseDriver ()
621
619
622
620
def reset (self ) -> None :
623
- xldriver .xlDeactivateChannel (self .port_handle , self .mask )
624
- xldriver .xlActivateChannel (
621
+ self . xldriver .xlDeactivateChannel (self .port_handle , self .mask )
622
+ self . xldriver .xlActivateChannel (
625
623
self .port_handle , self .mask , xldefine .XL_BusTypes .XL_BUS_TYPE_CAN , 0
626
624
)
627
625
@@ -657,7 +655,7 @@ def _detect_available_configs() -> List[AutoDetectedConfig]:
657
655
"vector_channel_config" : channel_config ,
658
656
}
659
657
)
660
- return configs
658
+ return configs # type: ignore
661
659
662
660
@staticmethod
663
661
def popup_vector_hw_configuration (wait_for_finish : int = 0 ) -> None :
@@ -666,6 +664,9 @@ def popup_vector_hw_configuration(wait_for_finish: int = 0) -> None:
666
664
:param wait_for_finish:
667
665
Time to wait for user input in milliseconds.
668
666
"""
667
+ if xldriver is None :
668
+ raise CanInterfaceNotImplementedError ("The Vector API has not been loaded" )
669
+
669
670
xldriver .xlPopupHwConfig (ctypes .c_char_p (), ctypes .c_uint (wait_for_finish ))
670
671
671
672
@staticmethod
@@ -685,14 +686,17 @@ def get_application_config(
685
686
:raises can.interfaces.vector.VectorInitializationError:
686
687
If the application name does not exist in the Vector hardware configuration.
687
688
"""
689
+ if xldriver is None :
690
+ raise CanInterfaceNotImplementedError ("The Vector API has not been loaded" )
691
+
688
692
hw_type = ctypes .c_uint ()
689
693
hw_index = ctypes .c_uint ()
690
694
hw_channel = ctypes .c_uint ()
691
- app_channel = ctypes .c_uint (app_channel )
695
+ _app_channel = ctypes .c_uint (app_channel )
692
696
693
697
xldriver .xlGetApplConfig (
694
698
app_name .encode (),
695
- app_channel ,
699
+ _app_channel ,
696
700
hw_type ,
697
701
hw_index ,
698
702
hw_channel ,
@@ -707,7 +711,7 @@ def set_application_config(
707
711
hw_type : xldefine .XL_HardwareType ,
708
712
hw_index : int ,
709
713
hw_channel : int ,
710
- ** kwargs ,
714
+ ** kwargs : Any ,
711
715
) -> None :
712
716
"""Modify the application settings in Vector Hardware Configuration.
713
717
@@ -737,6 +741,9 @@ def set_application_config(
737
741
:raises can.interfaces.vector.VectorInitializationError:
738
742
If the application name does not exist in the Vector hardware configuration.
739
743
"""
744
+ if xldriver is None :
745
+ raise CanInterfaceNotImplementedError ("The Vector API has not been loaded" )
746
+
740
747
xldriver .xlSetApplConfig (
741
748
app_name .encode (),
742
749
app_channel ,
@@ -758,7 +765,7 @@ def set_timer_rate(self, timer_rate_ms: int) -> None:
758
765
the timer events.
759
766
"""
760
767
timer_rate_10us = timer_rate_ms * 100
761
- xldriver .xlSetTimerRate (self .port_handle , timer_rate_10us )
768
+ self . xldriver .xlSetTimerRate (self .port_handle , timer_rate_10us )
762
769
763
770
764
771
class VectorChannelConfig (NamedTuple ):
0 commit comments