Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for automatic configuration detection #303

Closed
9 of 14 tasks
felixdivo opened this issue Apr 30, 2018 · 8 comments
Closed
9 of 14 tasks

Support for automatic configuration detection #303

felixdivo opened this issue Apr 30, 2018 · 8 comments

Comments

@felixdivo
Copy link
Collaborator

felixdivo commented Apr 30, 2018

Pull request #278 adds a new API for detecting available channels of a specific interface or multiple ones. By default, an interface does not need to provide this functionality, but can simply be extended to do so. (See below.)

Overview

These interfaces already have the automatic detection of available channels/configurations implemented:

How to extend an interface to support this:

  1. Make the bus instance of the interface extend the BusABC::_detect_available_configs() static method.
  2. Add tests to test/test_detect_available_configs.py where required.
  3. Submit a pull request.
  4. Done.
@marcel-kanter
Copy link
Contributor

marcel-kanter commented May 26, 2019

I didn't look onto the code, but its a nice feature. For 4.0.0 i'll add the ixxat to your list.
BUT:
Should we change the signature of the constructor of the Interface classes to unify the selection of the device?
I would change it, so that the interfaces constructor look like:
def init(device, channel)

and drop can_filters since (as i think) many dont even use the filters.

the device argument for the bus should be returned by your method. So the user of python-can can let the end-user select the adaptor und simply pass the selection to the constructor of the bus class.

The value and the usage of device can be implementation specific but it should select an specific device. For the vector can adaptors it may be the serial, the ixxat can adaptors have an unique hw id.

@felixdivo
Copy link
Collaborator Author

Hey Marcel, (@marcel-kanter)

I must've missed your message. I do agree with your point, that the signature might be confusing. I'd say that none of them should take positional arguments, besides maybe the interface (pcan, vector, ...). Even device does not make sense in all interfaces, like when you use for example socketcan as it uses channels. In general, these should all be keyword arguments.

We can let the can_filters stay in there, since we can implement it quite easily in BusABC, but it should be a keyword-only argument.

But the idea of the return value of detect_available_configs is right, thats also what the documentation states: https://github.com/hardbyte/python-can/blob/develop/can/interface.py#L135.

@jsee23
Copy link
Contributor

jsee23 commented Jul 18, 2019

After using can.detect_available_configs() the first time, here are the things I would like to improve:

  1. print a unified/common warning if the backend doesn't support detect_available_configs()
  2. add to doc which backend doesn't support it
  3. add an example to the documentation how the dict looks like
  4. add something like a 'name' for every channel: should consists of the 'adapter' name and its 'adapter channel number'. E.g. for PCAN, it should be something like 'PCAN-USB FD Channel 0'. This will also helps with the Vector backend, where you have something like 'Virtual Channels' => a newbie won't know which channels belong to its CAN adapter

I would volunteer for point 1-3 and point 4 for Vector and PCAN backend. What do you think about it (especially point 4)?

@christiansandberg
Copy link
Collaborator

Maybe we should switch to some Channel class instead which could contain even more info when available like serial number etc.

@felixdivo
Copy link
Collaborator Author

Maybe we should switch to some Channel class instead which could contain even more info when available like serial number etc.

Yeah, but it shouldn't make the creation of a bus more complicated than it needs to, I think that the current keyword arguments (with simple short strings) are nice and intuitive.

@felixdivo felixdivo added this to the 2.2 Release milestone Apr 15, 2021
@felixdivo
Copy link
Collaborator Author

I think this issue can be closed. Many interfaces support it, there were no huge problems with it and the docs for adding a new interfaces tell developers how to support it/remind them of the feature. The only feature remaining is that a table/documentation page stating which interface supports which feature (like this one, _detect_available_configs) should be added. However, this is somewhat of a separate thing and should be tracked elsewhere.

@Kochise
Copy link

Kochise commented Nov 10, 2021

The 'ixxat' interface is not detected with python-can 3.3.4 :

import can

can.interface.detect_available_configs()

Kvaser canlib is unavailable.
fcntl not available on this platform
libc is unavailable
failed to fetch opened can devices: [WinError 2] Le fichier spécifié est introuvable
Failed to load NI-CAN driver: [WinError 126] Le module spécifié est introuvable
Failed to load IS-CAN driver: [WinError 126] Le module spécifié est introuvable
Could not import vxlapi: [WinError 126] Le module spécifié est introuvable
Cannot load SYSTEC ucan library: [WinError 126] Le module spécifié est introuvable.
The SYSTEC ucan library has not been initialized.

[{'interface': 'virtual', 'channel': 'channel-3439'},
 {'interface': 'neovi', 'serial': '120216'}]

If I loop on all interfaces, I can detect it though :

# List possible CAN adapters (from 'python-can')
l_dict_valid = {}
l_list_cards = list(can.interfaces.BACKENDS.keys())
l_list_cards.sort()

# Drivers for supported cards :
# 'canalystii'	: http
# 'iscan'		: http
# 'ixxat'		: https://www.ixxat.com/docs/librariesprovider8/ixxat-english-new/pc-can-interfaces/windows-drivers/vci-v4-windows-10-8-7.zip?sfvrsn=9ceb48d7_75
# 'kvaser'		: http
# 'neovi'		: https://cdn.intrepidcs.net/updates/files/RP1210KitInstall.zip
# 	old driver	 (https://cdn.intrepidcs.net/updates/files/ICSDrivers.zip)
# 'nican'		: http
# 'pcan'		: http
# 'serial'		: http
# 'slcan'		: http
# 'socketcan'	: http
# 'systec'		: http
# 'usb2can'		: http
# 'vector'		: http
# 'virtual'		: http

# Virtual in an useless stub
l_list_cards.remove('virtual')

print(f"=== Loading CAN drivers ===")
for loop_str_card in l_list_cards:
	# Try all l_list_cards
	print(f"\n... Loading '{loop_str_card}' ...")
	for loop_int_chan in range(4):
		# Try only first 4 channels
		for loop_str_baud, loop_int_baud in dict_CANP_CARD__BAUD.items():
			# Try all bauds (1m, 500k, 250k, 125k)
			try:
				# Try connecting
				with can.interface.Bus(
							bustype = str(loop_str_card),
							channel = str(loop_int_chan),
							bitrate = int(loop_int_baud)
						) as l_obj_bus:
					# Register the combination as valid
					try:
						l_dict_valid[loop_str_card]
						# - except KeyError -
						try:
							l_dict_valid[loop_str_card][loop_int_chan]
							# - except KeyError -
							try:
								l_dict_valid[loop_str_card][loop_int_chan][loop_str_baud]
								# - except KeyError -
								# Register baudrate
								raise KeyError
							except KeyError:
								l_dict_valid[loop_str_card][loop_int_chan][loop_str_baud] = loop_int_baud
						except KeyError:
							l_dict_valid[loop_str_card][loop_int_chan] = {loop_str_baud: loop_int_baud}
					except KeyError:
						l_dict_valid[loop_str_card] = {loop_int_chan: {loop_str_baud: loop_int_baud}}
			except:
				# Connection failed
				pass
C:\Program Files\Spyder\Python>enaml-run "c:\Users\dkoch\Downloads\CAN\canp\canp_card_view.enaml"
=== Loading CAN drivers ===

... Loading 'canalystii' ...

... Loading 'iscan' ...
Failed to load IS-CAN driver: [WinError 126] Le module spécifié est introuvable

... Loading 'ixxat' ...

... Loading 'kvaser' ...
Kvaser canlib is unavailable.

... Loading 'neovi' ...
Error: set_bit_rate(): icsneoSetBitRate() Failed
Error: set_bit_rate(): icsneoSetBitRate() Failed
Error: set_bit_rate(): icsneoSetBitRate() Failed
Error: set_bit_rate(): icsneoSetBitRate() Failed
Error: set_bit_rate(): icsneoSetBitRate() Failed
Error: set_bit_rate(): icsneoSetBitRate() Failed
Error: set_bit_rate(): icsneoSetBitRate() Failed
Error: set_bit_rate(): icsneoSetBitRate() Failed

... Loading 'nican' ...
Failed to load NI-CAN driver: [WinError 126] Le module spécifié est introuvable

... Loading 'pcan' ...

... Loading 'serial' ...

... Loading 'slcan' ...

... Loading 'socketcan' ...
fcntl not available on this platform
libc is unavailable

... Loading 'systec' ...
Cannot load SYSTEC ucan library: [WinError 126] Le module spécifié est introuvable.

... Loading 'usb2can' ...

... Loading 'vector' ...
Could not import vxlapi: [WinError 126] Le module spécifié est introuvable

Yet trying all channels and all baud-rates pretty much hurts the CAN bus a lot (if not resilient to such invasion).

Regards.

@felixdivo
Copy link
Collaborator Author

@Kochise I created #1164 for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants