@@ -105,8 +105,8 @@ def __init__(
105105 Example: ``pcan:PCAN_USBBUS1``
106106
107107 - Interface ``virtual`` is described in https://python-can.readthedocs.io/en/master/interfaces/virtual.html.
108- The channel name should be empty.
109- Example: ``virtual:``
108+ The channel name may be empty.
109+ Example: ``virtual:``, ``virtual:foo-can``
110110
111111 - Interface ``usb2can`` is described in https://python-can.readthedocs.io/en/stable/interfaces/usb2can.html.
112112 Example: ``usb2can:ED000100``
@@ -348,9 +348,17 @@ def close(self) -> None:
348348 @staticmethod
349349 def list_available_interface_names () -> typing .Iterable [str ]:
350350 """
351- Returns an empty list. TODO: provide minimally functional implementation .
351+ Returns a list of available interfaces .
352352 """
353- return []
353+ available_configs : typing .List [can .typechecking .AutoDetectedConfig ] = []
354+ for interface in _CONSTRUCTORS .keys ():
355+ # try each interface on its own to catch errors if the interface library is not available
356+ try :
357+ available_configs .extend (can .detect_available_configs (interfaces = [interface ]))
358+ except NotImplementedError :
359+ _logger .debug ("%s: Interface not supported" , interface )
360+ continue
361+ return [f"{ config ['interface' ]} :{ config ['channel' ]} " for config in available_configs ]
354362
355363 def _invoke_rx_handler (self , frs : typing .List [typing .Tuple [Timestamp , Envelope ]]) -> None :
356364 try :
@@ -425,7 +433,7 @@ class _FDInterfaceParameters(_InterfaceParameters):
425433 bitrate : typing .Tuple [int , int ]
426434
427435
428- def _construct_socketcan (parameters : _InterfaceParameters ) -> can .ThreadSafeBus :
436+ def _construct_socketcan (parameters : _InterfaceParameters ) -> typing . Tuple [ PythonCANBusOptions , can .ThreadSafeBus ] :
429437 if isinstance (parameters , _ClassicInterfaceParameters ):
430438 return (
431439 PythonCANBusOptions (),
@@ -439,7 +447,7 @@ def _construct_socketcan(parameters: _InterfaceParameters) -> can.ThreadSafeBus:
439447 assert False , "Internal error"
440448
441449
442- def _construct_kvaser (parameters : _InterfaceParameters ) -> can .ThreadSafeBus :
450+ def _construct_kvaser (parameters : _InterfaceParameters ) -> typing . Tuple [ PythonCANBusOptions , can .ThreadSafeBus ] :
443451 if isinstance (parameters , _ClassicInterfaceParameters ):
444452 return (
445453 PythonCANBusOptions (),
@@ -464,7 +472,7 @@ def _construct_kvaser(parameters: _InterfaceParameters) -> can.ThreadSafeBus:
464472 assert False , "Internal error"
465473
466474
467- def _construct_slcan (parameters : _InterfaceParameters ) -> can .ThreadSafeBus :
475+ def _construct_slcan (parameters : _InterfaceParameters ) -> typing . Tuple [ PythonCANBusOptions , can .ThreadSafeBus ] :
468476 if isinstance (parameters , _ClassicInterfaceParameters ):
469477 return (
470478 PythonCANBusOptions (),
@@ -479,7 +487,7 @@ def _construct_slcan(parameters: _InterfaceParameters) -> can.ThreadSafeBus:
479487 assert False , "Internal error"
480488
481489
482- def _construct_pcan (parameters : _InterfaceParameters ) -> can .ThreadSafeBus :
490+ def _construct_pcan (parameters : _InterfaceParameters ) -> typing . Tuple [ PythonCANBusOptions , can .ThreadSafeBus ] :
483491 if isinstance (parameters , _ClassicInterfaceParameters ):
484492 return (
485493 PythonCANBusOptions (),
@@ -514,18 +522,14 @@ def _construct_pcan(parameters: _InterfaceParameters) -> can.ThreadSafeBus:
514522 assert False , "Internal error"
515523
516524
517- def _construct_virtual (parameters : _InterfaceParameters ) -> can .ThreadSafeBus :
518- if isinstance (parameters , _ClassicInterfaceParameters ):
519- return (
520- PythonCANBusOptions (),
521- can .ThreadSafeBus (interface = parameters .interface_name , bitrate = parameters .bitrate ),
522- )
523- if isinstance (parameters , _FDInterfaceParameters ):
524- return (PythonCANBusOptions (), can .ThreadSafeBus (interface = parameters .interface_name ))
525- assert False , "Internal error"
525+ def _construct_virtual (parameters : _InterfaceParameters ) -> typing .Tuple [PythonCANBusOptions , can .ThreadSafeBus ]:
526+ return (
527+ PythonCANBusOptions (),
528+ can .ThreadSafeBus (interface = parameters .interface_name , channel = parameters .channel_name ),
529+ )
526530
527531
528- def _construct_usb2can (parameters : _InterfaceParameters ) -> can .ThreadSafeBus :
532+ def _construct_usb2can (parameters : _InterfaceParameters ) -> typing . Tuple [ PythonCANBusOptions , can .ThreadSafeBus ] :
529533 if isinstance (parameters , _ClassicInterfaceParameters ):
530534 return (
531535 PythonCANBusOptions (),
@@ -540,7 +544,7 @@ def _construct_usb2can(parameters: _InterfaceParameters) -> can.ThreadSafeBus:
540544 assert False , "Internal error"
541545
542546
543- def _construct_canalystii (parameters : _InterfaceParameters ) -> can .ThreadSafeBus :
547+ def _construct_canalystii (parameters : _InterfaceParameters ) -> typing . Tuple [ PythonCANBusOptions , can .ThreadSafeBus ] :
544548 if isinstance (parameters , _ClassicInterfaceParameters ):
545549 return (
546550 PythonCANBusOptions (),
@@ -553,7 +557,7 @@ def _construct_canalystii(parameters: _InterfaceParameters) -> can.ThreadSafeBus
553557 assert False , "Internal error"
554558
555559
556- def _construct_seeedstudio (parameters : _InterfaceParameters ) -> can .ThreadSafeBus :
560+ def _construct_seeedstudio (parameters : _InterfaceParameters ) -> typing . Tuple [ PythonCANBusOptions , can .ThreadSafeBus ] :
557561 if isinstance (parameters , _ClassicInterfaceParameters ):
558562 return (
559563 PythonCANBusOptions (),
@@ -568,7 +572,7 @@ def _construct_seeedstudio(parameters: _InterfaceParameters) -> can.ThreadSafeBu
568572 assert False , "Internal error"
569573
570574
571- def _construct_gs_usb (parameters : _InterfaceParameters ) -> can .ThreadSafeBus :
575+ def _construct_gs_usb (parameters : _InterfaceParameters ) -> typing . Tuple [ PythonCANBusOptions , can .ThreadSafeBus ] :
572576 if isinstance (parameters , _ClassicInterfaceParameters ):
573577 try :
574578 index = int (parameters .channel_name )
0 commit comments