Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 29 additions & 22 deletions can/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,37 +60,44 @@ class Bus(BusABC): # pylint: disable=abstract-method

Instantiates a CAN Bus of the given ``interface``, falls back to reading a
configuration file from default locations.
"""

@staticmethod
def __new__( # type: ignore # pylint: disable=keyword-arg-before-vararg
cls: Any, channel: Optional[Channel] = None, *args: Any, **kwargs: Any
) -> BusABC:
"""
Takes the same arguments as :class:`can.BusABC.__init__`.
Some might have a special meaning, see below.
:param channel:
Channel identification. Expected type is backend dependent.
Set to ``None`` to let it be resolved automatically from the default
:ref:`configuration`.

:param channel:
Set to ``None`` to let it be resolved automatically from the default
configuration. That might fail, see below.
:param interface:
See :ref:`interface names` for a list of supported interfaces.
Set to ``None`` to let it be resolved automatically from the default
:ref:`configuration`.

Expected type is backend dependent.
:param args:
``interface`` specific positional arguments.

:param dict kwargs:
Should contain an ``interface`` key with a valid interface name. If not,
it is completed using :meth:`can.util.load_config`.
:param kwargs:
``interface`` specific keyword arguments.

:raises: can.CanInterfaceNotImplementedError
if the ``interface`` isn't recognized or cannot be loaded
:raises ~can.exceptions.CanInterfaceNotImplementedError:
if the ``interface`` isn't recognized or cannot be loaded

:raises: can.CanInitializationError
if the bus cannot be instantiated
:raises ~can.exceptions.CanInitializationError:
if the bus cannot be instantiated

:raises: ValueError
if the ``channel`` could not be determined
"""
:raises ValueError:
if the ``channel`` could not be determined
"""

@staticmethod
def __new__( # type: ignore # pylint: disable=keyword-arg-before-vararg
cls: Any,
channel: Optional[Channel] = None,
interface: Optional[str] = None,
*args: Any,
**kwargs: Any,
) -> BusABC:
# figure out the rest of the configuration; this might raise an error
if interface is not None:
kwargs["interface"] = interface
if channel is not None:
kwargs["channel"] = channel
if "context" in kwargs:
Expand Down
2 changes: 1 addition & 1 deletion can/interfaces/cantact.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def __init__(
Bitrate in bits/s
:param bool monitor:
If true, operate in listen-only monitoring mode
:param BitTiming bit_timing
:param BitTiming bit_timing:
Optional BitTiming to use for custom bit timing setting. Overrides bitrate if not None.
"""

Expand Down
2 changes: 1 addition & 1 deletion doc/api.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Library API
===========

The main objects are the :class:`~can.BusABC` and the :class:`~can.Message`.
The main objects are the :class:`~can.Bus` and the :class:`~can.Message`.
A form of CAN interface is also required.

.. hint::
Expand Down
21 changes: 4 additions & 17 deletions doc/bus.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,11 @@ and implements the :class:`~can.BusABC` API.

A thread safe bus wrapper is also available, see `Thread safe bus`_.

Autoconfig Bus
''''''''''''''

.. autoclass:: can.Bus
:class-doc-from: class
:show-inheritance:
:members:


API
'''

.. autoclass:: can.BusABC
:members:

.. automethod:: __iter__
.. automethod:: _recv_internal
.. automethod:: _apply_filters
.. automethod:: _detect_available_configs
.. automethod:: _send_periodic_internal
:inherited-members:

.. autoclass:: can.bus.BusState
:members:
Expand Down Expand Up @@ -81,7 +68,7 @@ Example defining two filters, one to pass 11-bit ID ``0x451``, the other to pass
See :meth:`~can.BusABC.set_filters` for the implementation.

Thread safe bus
---------------
'''''''''''''''

This thread safe version of the :class:`~can.BusABC` class can be used by multiple threads at once.
Sending and receiving is locked separately to avoid unnecessary delays.
Expand Down
1 change: 1 addition & 0 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"sphinx.ext.viewcode",
"sphinx.ext.graphviz",
"sphinxcontrib.programoutput",
"sphinx_inline_tabs",
"sphinx_rtd_theme",
]

Expand Down
45 changes: 34 additions & 11 deletions doc/configuration.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _configuration:

Configuration
=============

Expand Down Expand Up @@ -100,6 +102,7 @@ For example:

``CAN_INTERFACE=socketcan CAN_CONFIG={"receive_own_messages": true, "fd": true}``

.. _interface names:

Interface Names
---------------
Expand All @@ -109,31 +112,51 @@ Lookup table of interface names:
+---------------------+-------------------------------------+
| Name | Documentation |
+=====================+=====================================+
| ``"socketcan"`` | :doc:`interfaces/socketcan` |
| ``"canalystii"`` | :doc:`interfaces/canalystii` |
+---------------------+-------------------------------------+
| ``"kvaser"`` | :doc:`interfaces/kvaser` |
| ``"cantact"`` | :doc:`interfaces/cantact` |
+---------------------+-------------------------------------+
| ``"serial"`` | :doc:`interfaces/serial` |
| ``"etas"`` | :doc:`interfaces/etas` |
+---------------------+-------------------------------------+
| ``"slcan"`` | :doc:`interfaces/slcan` |
| ``"gs_usb"`` | :doc:`interfaces/gs_usb` |
+---------------------+-------------------------------------+
| ``"iscan"`` | :doc:`interfaces/iscan` |
+---------------------+-------------------------------------+
| ``"ixxat"`` | :doc:`interfaces/ixxat` |
+---------------------+-------------------------------------+
| ``"pcan"`` | :doc:`interfaces/pcan` |
| ``"kvaser"`` | :doc:`interfaces/kvaser` |
+---------------------+-------------------------------------+
| ``"usb2can"`` | :doc:`interfaces/usb2can` |
| ``"neousys"`` | :doc:`interfaces/neousys` |
+---------------------+-------------------------------------+
| ``"neovi"`` | :doc:`interfaces/neovi` |
+---------------------+-------------------------------------+
| ``"nican"`` | :doc:`interfaces/nican` |
+---------------------+-------------------------------------+
| ``"iscan"`` | :doc:`interfaces/iscan` |
| ``"nixnet"`` | :doc:`interfaces/nixnet` |
+---------------------+-------------------------------------+
| ``"neovi"`` | :doc:`interfaces/neovi` |
| ``"pcan"`` | :doc:`interfaces/pcan` |
+---------------------+-------------------------------------+
| ``"vector"`` | :doc:`interfaces/vector` |
| ``"robotell"`` | :doc:`interfaces/robotell` |
+---------------------+-------------------------------------+
| ``"virtual"`` | :doc:`interfaces/virtual` |
| ``"seeedstudio"`` | :doc:`interfaces/seeedstudio` |
+---------------------+-------------------------------------+
| ``"canalystii"`` | :doc:`interfaces/canalystii` |
| ``"serial"`` | :doc:`interfaces/serial` |
+---------------------+-------------------------------------+
| ``"slcan"`` | :doc:`interfaces/slcan` |
+---------------------+-------------------------------------+
| ``"socketcan"`` | :doc:`interfaces/socketcan` |
+---------------------+-------------------------------------+
| ``"socketcand"`` | :doc:`interfaces/socketcand` |
+---------------------+-------------------------------------+
| ``"systec"`` | :doc:`interfaces/systec` |
+---------------------+-------------------------------------+
| ``"udp_multicast"`` | :doc:`interfaces/udp_multicast` |
+---------------------+-------------------------------------+
| ``"usb2can"`` | :doc:`interfaces/usb2can` |
+---------------------+-------------------------------------+
| ``"vector"`` | :doc:`interfaces/vector` |
+---------------------+-------------------------------------+
| ``"virtual"`` | :doc:`interfaces/virtual` |
+---------------------+-------------------------------------+

Additional interface types can be added via the :ref:`plugin interface`.
12 changes: 8 additions & 4 deletions doc/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,16 @@ The following assumes that the commands are executed from the root of the reposi

The project can be built with::

pip install wheel
python setup.py sdist bdist_wheel
pipx run build
pipx run twine check dist/*

The project can be installed in editable mode with::

pip install -e .

The unit tests can be run with::

pip install tox
tox -e py
pipx run tox -e py

The documentation can be built with::

Expand Down Expand Up @@ -79,6 +78,11 @@ These steps are a guideline on how to add a new backend to python-can.
To get started, have a look at ``back2back_test.py``:
Simply add a test case like ``BasicTestSocketCan`` and some basic tests will be executed for the new interface.

.. attention::
We strongly recommend using the :ref:`plugin interface` to extend python-can.
Publish a python package that contains your :class:`can.BusABC` subclass and use
it within the python-can API. We will mention your package inside this documentation
and add it as an optional dependency.

Code Structure
--------------
Expand Down
1 change: 1 addition & 0 deletions doc/doc-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
sphinx>=5.2.3
sphinxcontrib-programoutput
sphinx_rtd_theme
sphinx-inline-tabs
65 changes: 54 additions & 11 deletions doc/interfaces.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _can interface modules:

CAN Interface Modules
---------------------

Expand All @@ -12,11 +14,13 @@ The available interfaces are:
:maxdepth: 1

interfaces/canalystii
interfaces/cantact
interfaces/etas
interfaces/gs_usb
interfaces/iscan
interfaces/ixxat
interfaces/kvaser
interfaces/neousys
interfaces/neovi
interfaces/nican
interfaces/nixnet
Expand All @@ -33,19 +37,58 @@ The available interfaces are:
interfaces/vector
interfaces/virtual

Additional interfaces can be added via a plugin interface. An external package
can register a new interface by using the ``can.interface`` entry point in its setup.py.
The *Interface Names* are listed in :doc:`configuration`.

The format of the entry point is ``interface_name=module:classname`` where
``classname`` is a concrete :class:`can.BusABC` implementation.

::
.. _plugin interface:

entry_points={
'can.interface': [
"interface_name=module:classname",
]
},
Plugin Interface
^^^^^^^^^^^^^^^^
Comment on lines +45 to +46
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯


External packages can register a new interfaces by using the ``can.interface`` entry point
in its project configuration. The format of the entry point depends on your project
configuration format (*pyproject.toml*, *setup.cfg* or *setup.py*).

The *Interface Names* are listed in :doc:`configuration`.
In the following example ``module`` defines the location of your bus class inside your
package e.g. ``my_package.subpackage.bus_module`` and ``classname`` is the name of
your :class:`can.BusABC` subclass.

.. tab:: pyproject.toml (PEP 621)

.. code-block:: toml

# Note the quotes around can.interface in order to escape the dot .
[project.entry-points."can.interface"]
interface_name = "module:classname"

.. tab:: setup.cfg

.. code-block:: ini

[options.entry_points]
can.interface =
interface_name = module:classname

.. tab:: setup.py

.. code-block:: python

from setuptools import setup

setup(
# ...,
entry_points = {
'can.interface': [
'interface_name = module:classname'
]
}
)

The ``interface_name`` can be used to
create an instance of the bus in the **python-can** API:

.. code-block:: python

import can

bus = can.Bus(interface="interface_name", channel=0)
8 changes: 8 additions & 0 deletions doc/interfaces/cantact.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CANtact CAN Interface
=====================

Interface for CANtact devices from Linklayer Labs

.. autoclass:: can.interfaces.cantact.CantactBus
:show-inheritance:
:members:
13 changes: 13 additions & 0 deletions doc/interfaces/neousys.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Neousys CAN Interface
=====================

This kind of interface can be found for example on Neousys POC-551VTC
One needs to have correct drivers and DLL (Share object for Linux) from
`Neousys <https://www.neousys-tech.com/en/support-service/resources/category/299-poc-551vtc-driver>`_.

Beware this is only tested on Linux kernel higher than v5.3. This should be drop in
with Windows but you have to replace with correct named DLL

.. autoclass:: can.interfaces.neousys.NeousysBus
:show-inheritance:
:members:
4 changes: 2 additions & 2 deletions doc/internal-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ configuration into account.
Bus Internals
~~~~~~~~~~~~~

Several methods are not documented in the main :class:`can.BusABC`
Several methods are not documented in the main :class:`can.Bus`
as they are primarily useful for library developers as opposed to
library users. This is the entire ABC bus class with all internal
methods:

.. autoclass:: can.BusABC
:members:
:private-members:
:special-members:
:noindex:



Expand Down
Loading