durand


Namedurand JSON
Version 0.4.12 PyPI version JSON
download
home_pagehttps://github.com/semiversus/python-durand
SummaryCANopen library providing functionality to implement responder nodes
upload_time2024-03-14 08:16:03
maintainer
docs_urlNone
authorGünther Jena
requires_python>=3.7
licenseMIT license
keywords canopen can node ds301
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ================================================
Python Durand - CANopen Responder Device Library
================================================

CANopen library to implement responder nodes.

Backends:

- CAN interfaces via python-can_

.. header

Synopsis
========

- Pure python implementation
- Under MIT license (2021 Günther Jena)
- Source is hosted on GitHub.com_
- Tested on Python 3.7, 3.8, 3.9 and 3.10
- Unit tested with pytest_, coding style done with Black_, static type checked with mypy_, static code checked with Pylint_, documented with Sphinx_
- Supporting CiA301_ (EN 50325-4)

.. _pytest: https://docs.pytest.org/en/latest
.. _Black: https://black.readthedocs.io/en/stable/
.. _mypy: http://mypy-lang.org/
.. _Pylint: https://www.pylint.org/
.. _Sphinx: http://www.sphinx-doc.org
.. _GitHub.com: https://github.com/semiversus/python-durand
.. _CiA301: http://can-cia.org/standardization/technical-documents

Feature List
============

* Object dictionary

  * provides callbacks for *validation*, *update*, *download* and *read*
  * supports records, arrays and variables

* EDS support

  * dynamically generation of EDS file
  * automatically provided via object 0x1021 ("Store EDS")

* up to 128 SDO servers

  * expetited, segmented and block transfer for up- and download
  * COB-IDs dynamically configurable
  * custom up- and download handlers supported

* up to 512 TPDOs and 512 RPDOs

  * dynamically configurable
  * transmission types: synchronous (acyclic and every nth sync) and event driven
  * inhibit time supported

* EMCY producer service

  * COB-ID dynamically configurable
  * inhibit time supported

* Heartbeat producer service

  * dynamically configurable

* NMT slave service

  * boot-up service
  * callback for state change provided

* SYNC consumer service

  * COB-ID dynamically configurable
  * callback for received sync provided

* CiA305 Layer Setting Service

  * fast scan supported
  * bitrate and node id configuring supported
  * identify remote responder supported

* CAN interface abstraction
  
  * python-can_ fully supported
  * automatic CAN id filtering by subscripted services

* Scheduling supporting threaded and async operation

TODO
  * build object dictionary via reading an EDS file
  * supporting MPDOs
  * TIME consumer service
  * Up- and download handler as io streams

Examples
========

Creating a node
---------------

.. code-block:: python

    import can
    from durand import CANBusNetwork, Node, Variable, Record, DatatypeEnum

    bus = can.Bus(bustype='socketcan', channel='vcan0')
    network = CANBusNetwork(bus)

    node = Node(network, node_id=0x01)

Congratulations! You have a CiA-301 compliant node running. Layer Setting Service is also supported out of the box.

Adding objects
--------------

.. code-block:: python

    od = node.object_dictionary

    # add variable at index 0x2000
    od[0x2000] = Variable(DatatypeEnum.UNSIGNED16, access='rw', value=10, name='Parameter 1')

    # add record at index 0x2001
    record = Record(name='Parameter Record')
    record[1] = Variable(DatatypeEnum.UNSIGNED8, access='ro', value=0, name='Parameter 2a')
    record[2] = Variable(DatatypeEnum.REAL32, access='rw', value=0, name='Parameter 2b')
    od[0x2001] = record

Access values
-------------

The objects can be read and written directly by accessing the object dictionary:

.. code-block:: python

    print(f'Value of Parameter 1: {od.read(0x2000, 0)}')
    od.write(0x2001, 1, value=0xAA)

Add callbacks
-------------

A more event driven approach is using of callbacks. Following callbacks are available:

* `validate_callbacks` - called before a value in the object dictionary is going to be updated
* `update_callbacks` - called when the value has been changed (via `od.write` or via CAN bus)
* `download_callbacks` - called when the value has been changed via CAN bus
* `read_callback` - called when a object is read (return value is used )

.. code-block:: python

    od.validate_callbacks[(0x2000, 0)].add(lambda v: v % 2 == 0)
    od.update_callbacks[(0x2001, 2)].add(lambda v: print(f'Update for Parameter 2b: {v}'))
    od.download_callbacks[(0x2000, 0)].add(lambda v: print(f'Download for Parmeter 1: {v}'))
    od.set_read_callback(0x2001, 1, lambda: 17)

PDO mapping
-----------

PDOs can dynamically mapped via the SDO server or programmatically. The PDO indices
start at 0.

.. code-block:: python

    node.tpdo[0].mapping = [(0x2001, 1), (0x2001, 2)]
    node.tpdo[0].transmission_type = 1  # transmit on every SYNC

    node.rpdo[0].mapping = [(0x2000, 0)]
    node.tpdo[0].transmission_type = 255  # event driven (processed when received)

Install
=======

.. code-block:: bash

    pip install durand

Credits
=======

This library would not be possible without:

* python-canopen_: CANopen library (by Christian Sandberg)
* python-can_: CAN interface library (by Brian Thorne)

.. _python-canopen: https://github.com/christiansandberg/canopen
.. _python-can: https://github.com/hardbyte/python-can

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/semiversus/python-durand",
    "name": "durand",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "canopen can node ds301",
    "author": "G\u00fcnther Jena",
    "author_email": "guenther@jena.at",
    "download_url": "https://files.pythonhosted.org/packages/42/21/9461442dd6735bbcaa429aa4d9a9ad2adc144a317d0ab4c41a018aabb8bc/durand-0.4.12.tar.gz",
    "platform": null,
    "description": "================================================\nPython Durand - CANopen Responder Device Library\n================================================\n\nCANopen library to implement responder nodes.\n\nBackends:\n\n- CAN interfaces via python-can_\n\n.. header\n\nSynopsis\n========\n\n- Pure python implementation\n- Under MIT license (2021 G\u00fcnther Jena)\n- Source is hosted on GitHub.com_\n- Tested on Python 3.7, 3.8, 3.9 and 3.10\n- Unit tested with pytest_, coding style done with Black_, static type checked with mypy_, static code checked with Pylint_, documented with Sphinx_\n- Supporting CiA301_ (EN 50325-4)\n\n.. _pytest: https://docs.pytest.org/en/latest\n.. _Black: https://black.readthedocs.io/en/stable/\n.. _mypy: http://mypy-lang.org/\n.. _Pylint: https://www.pylint.org/\n.. _Sphinx: http://www.sphinx-doc.org\n.. _GitHub.com: https://github.com/semiversus/python-durand\n.. _CiA301: http://can-cia.org/standardization/technical-documents\n\nFeature List\n============\n\n* Object dictionary\n\n  * provides callbacks for *validation*, *update*, *download* and *read*\n  * supports records, arrays and variables\n\n* EDS support\n\n  * dynamically generation of EDS file\n  * automatically provided via object 0x1021 (\"Store EDS\")\n\n* up to 128 SDO servers\n\n  * expetited, segmented and block transfer for up- and download\n  * COB-IDs dynamically configurable\n  * custom up- and download handlers supported\n\n* up to 512 TPDOs and 512 RPDOs\n\n  * dynamically configurable\n  * transmission types: synchronous (acyclic and every nth sync) and event driven\n  * inhibit time supported\n\n* EMCY producer service\n\n  * COB-ID dynamically configurable\n  * inhibit time supported\n\n* Heartbeat producer service\n\n  * dynamically configurable\n\n* NMT slave service\n\n  * boot-up service\n  * callback for state change provided\n\n* SYNC consumer service\n\n  * COB-ID dynamically configurable\n  * callback for received sync provided\n\n* CiA305 Layer Setting Service\n\n  * fast scan supported\n  * bitrate and node id configuring supported\n  * identify remote responder supported\n\n* CAN interface abstraction\n  \n  * python-can_ fully supported\n  * automatic CAN id filtering by subscripted services\n\n* Scheduling supporting threaded and async operation\n\nTODO\n  * build object dictionary via reading an EDS file\n  * supporting MPDOs\n  * TIME consumer service\n  * Up- and download handler as io streams\n\nExamples\n========\n\nCreating a node\n---------------\n\n.. code-block:: python\n\n    import can\n    from durand import CANBusNetwork, Node, Variable, Record, DatatypeEnum\n\n    bus = can.Bus(bustype='socketcan', channel='vcan0')\n    network = CANBusNetwork(bus)\n\n    node = Node(network, node_id=0x01)\n\nCongratulations! You have a CiA-301 compliant node running. Layer Setting Service is also supported out of the box.\n\nAdding objects\n--------------\n\n.. code-block:: python\n\n    od = node.object_dictionary\n\n    # add variable at index 0x2000\n    od[0x2000] = Variable(DatatypeEnum.UNSIGNED16, access='rw', value=10, name='Parameter 1')\n\n    # add record at index 0x2001\n    record = Record(name='Parameter Record')\n    record[1] = Variable(DatatypeEnum.UNSIGNED8, access='ro', value=0, name='Parameter 2a')\n    record[2] = Variable(DatatypeEnum.REAL32, access='rw', value=0, name='Parameter 2b')\n    od[0x2001] = record\n\nAccess values\n-------------\n\nThe objects can be read and written directly by accessing the object dictionary:\n\n.. code-block:: python\n\n    print(f'Value of Parameter 1: {od.read(0x2000, 0)}')\n    od.write(0x2001, 1, value=0xAA)\n\nAdd callbacks\n-------------\n\nA more event driven approach is using of callbacks. Following callbacks are available:\n\n* `validate_callbacks` - called before a value in the object dictionary is going to be updated\n* `update_callbacks` - called when the value has been changed (via `od.write` or via CAN bus)\n* `download_callbacks` - called when the value has been changed via CAN bus\n* `read_callback` - called when a object is read (return value is used )\n\n.. code-block:: python\n\n    od.validate_callbacks[(0x2000, 0)].add(lambda v: v % 2 == 0)\n    od.update_callbacks[(0x2001, 2)].add(lambda v: print(f'Update for Parameter 2b: {v}'))\n    od.download_callbacks[(0x2000, 0)].add(lambda v: print(f'Download for Parmeter 1: {v}'))\n    od.set_read_callback(0x2001, 1, lambda: 17)\n\nPDO mapping\n-----------\n\nPDOs can dynamically mapped via the SDO server or programmatically. The PDO indices\nstart at 0.\n\n.. code-block:: python\n\n    node.tpdo[0].mapping = [(0x2001, 1), (0x2001, 2)]\n    node.tpdo[0].transmission_type = 1  # transmit on every SYNC\n\n    node.rpdo[0].mapping = [(0x2000, 0)]\n    node.tpdo[0].transmission_type = 255  # event driven (processed when received)\n\nInstall\n=======\n\n.. code-block:: bash\n\n    pip install durand\n\nCredits\n=======\n\nThis library would not be possible without:\n\n* python-canopen_: CANopen library (by Christian Sandberg)\n* python-can_: CAN interface library (by Brian Thorne)\n\n.. _python-canopen: https://github.com/christiansandberg/canopen\n.. _python-can: https://github.com/hardbyte/python-can\n",
    "bugtrack_url": null,
    "license": "MIT license",
    "summary": "CANopen library providing functionality to implement responder nodes",
    "version": "0.4.12",
    "project_urls": {
        "Homepage": "https://github.com/semiversus/python-durand"
    },
    "split_keywords": [
        "canopen",
        "can",
        "node",
        "ds301"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0a2eab4011a15753a5161af24789c6d4c9bbb18c8d87f4299cfea376bcbfc713",
                "md5": "44b3e63da6181ba06a609da7a566b1b0",
                "sha256": "b217043d6f2d552c007a810bd3a1b119063497fbd6002077e5091d5988a33ff9"
            },
            "downloads": -1,
            "filename": "durand-0.4.12-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "44b3e63da6181ba06a609da7a566b1b0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 31133,
            "upload_time": "2024-03-14T08:16:01",
            "upload_time_iso_8601": "2024-03-14T08:16:01.329063Z",
            "url": "https://files.pythonhosted.org/packages/0a/2e/ab4011a15753a5161af24789c6d4c9bbb18c8d87f4299cfea376bcbfc713/durand-0.4.12-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "42219461442dd6735bbcaa429aa4d9a9ad2adc144a317d0ab4c41a018aabb8bc",
                "md5": "86dc2c8d198d8746796eeb7e87070237",
                "sha256": "12782ae48b729ac4e1022bf3d075e79ece925d4863e8ef89305d241209a71bb0"
            },
            "downloads": -1,
            "filename": "durand-0.4.12.tar.gz",
            "has_sig": false,
            "md5_digest": "86dc2c8d198d8746796eeb7e87070237",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 36293,
            "upload_time": "2024-03-14T08:16:03",
            "upload_time_iso_8601": "2024-03-14T08:16:03.294730Z",
            "url": "https://files.pythonhosted.org/packages/42/21/9461442dd6735bbcaa429aa4d9a9ad2adc144a317d0ab4c41a018aabb8bc/durand-0.4.12.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-14 08:16:03",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "semiversus",
    "github_project": "python-durand",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "durand"
}
        
Elapsed time: 0.21347s