Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
c21861e
Adding CAN FD frame support to asc writer
May 23, 2019
ceca74e
Merge branch 'develop' into asc-writer-canfd
pierreluctg May 23, 2019
525e779
Merge branch 'develop' into asc-writer-canfd
felixdivo Jun 9, 2019
12955ae
Merge branch 'develop' into asc-writer-canfd
felixdivo Jun 22, 2019
d6c5700
Merge branch 'develop' into asc-writer-canfd
felixdivo Jun 23, 2019
37dc484
reformat asc.py
felixdivo Jun 23, 2019
1753dc8
hope to make black happier
felixdivo Jun 24, 2019
296ad9e
Merge branch 'develop' into asc-writer-canfd
felixdivo Jun 24, 2019
27ea950
Merge branch 'develop' into asc-writer-canfd
felixdivo Jul 15, 2019
e37f44c
Merge branch 'develop' into asc-writer-canfd
felixdivo Jul 18, 2019
38bef11
Merge branch 'develop' into asc-writer-canfd
felixdivo Jul 21, 2019
8fef699
Add mypy type-checking to Travis CI builds
karlding Jul 17, 2019
acda992
refactoring and tests for vector interface (#646)
zariiii9003 Jul 22, 2019
d0a9b8f
Add sphinx-autodoc-typehints to sphinx docs
karlding Jul 23, 2019
cb315b2
Merge pull request #654 from karlding/add_sphinx_autodocs_typehints_e…
felixdivo Jul 24, 2019
8106c3e
Merge branch 'develop' of https://github.com/hardbyte/python-can into…
zariiii9003 Jul 24, 2019
6384baa
add event based cyclic send
zariiii9003 Jul 24, 2019
8e5a309
little fix
zariiii9003 Jul 24, 2019
8b66f09
little fix
zariiii9003 Jul 24, 2019
0019438
Add typing annotations for functions in can.bus (#652)
karlding Jul 29, 2019
bb6ac47
Merge branch 'develop' into event-based-send-task
felixdivo Jul 29, 2019
02d5032
Do not incorrectly reset CANMsg.MSGTYPE on remote frame.
craffert0 Jul 29, 2019
80cc665
Add typing annotations for can.broadcastmanager
karlding Jul 29, 2019
41e592c
Add typing annotations for can.message
karlding Aug 1, 2019
d58aac2
Add RedirectReader to the generated Listener docs
karlding Aug 3, 2019
089e29c
State "windows only" in Vector docs
felixdivo Aug 3, 2019
35402f2
raise more helpful exception if using vector on non-windows platforms
felixdivo Aug 3, 2019
451ac0b
add testing flag to vector
felixdivo Aug 3, 2019
39af904
syntax fixed
felixdivo Aug 3, 2019
4de88d2
add tiny test for new exception being thrown
felixdivo Aug 3, 2019
a333bca
Merge pull request #667 from hardbyte/felixdivo-vector-docs
felixdivo Aug 4, 2019
b4a4de3
Merge branch 'develop' into asc-writer-canfd
felixdivo Aug 4, 2019
c549f15
Merge branch 'develop' into event-based-send-task
zariiii9003 Aug 4, 2019
d035cab
install pywin32 on appveyor CI
zariiii9003 Aug 4, 2019
dd5cb66
Merge branch 'develop' into develop
craffert0 Aug 4, 2019
88b4a21
Add Vector dependencies to docs (#670)
zariiii9003 Aug 6, 2019
1204eb1
Merge branch 'develop' into develop
hardbyte Aug 6, 2019
20bac3b
Merge branch 'develop' into event-based-send-task
felixdivo Aug 6, 2019
866bd80
Merge pull request #659 from craffert0/develop
felixdivo Aug 6, 2019
a634ab1
Merge branch 'develop' into event-based-send-task
zariiii9003 Aug 6, 2019
93062bd
Revert "install pywin32 on appveyor CI"
zariiii9003 Aug 6, 2019
3c5edf8
add pywin32 to setup.py
zariiii9003 Aug 6, 2019
f301b49
Merge pull request #656 from zariiii9003/event-based-send-task
felixdivo Aug 6, 2019
78585da
Add the seeedstudio interface to docs
karlding Aug 3, 2019
3594d6b
Fix the docs for can.detect_available_configs
karlding Aug 3, 2019
7252e86
Add typing annotations for can.listener
karlding Aug 3, 2019
29e8e1f
Add .mypy_cache to gitignore file
felixdivo Aug 6, 2019
a7527a4
add mypy deamon config to gitignore
felixdivo Aug 8, 2019
ec4862f
Remove deprecated SocketCAN interfaces from list
karlding Aug 9, 2019
807fc54
resolves #680
bmeisels Aug 12, 2019
e6f3453
Add typing annotations for can.notifier
karlding Aug 8, 2019
a78c0d7
Merge branch 'develop' into asc-writer-canfd
pierreluctg Aug 15, 2019
cd3f81b
add typing to the generic IO module
felixdivo Aug 6, 2019
fb4e529
add io/logger.py
felixdivo Aug 7, 2019
3200713
fix problem with shpinx-build and typing
felixdivo Aug 7, 2019
dfa264a
fix formatting
felixdivo Aug 7, 2019
8f8c5e7
finalize IO typechecking, some import erros remain
felixdivo Aug 7, 2019
b8a1130
cleanups
felixdivo Aug 7, 2019
32d1ffc
fix problem in sphinx-build doc generation
felixdivo Aug 8, 2019
c01f49a
make linter happier
felixdivo Aug 8, 2019
219f482
fix grammar in doc string
felixdivo Aug 8, 2019
56c6adb
address review
felixdivo Aug 11, 2019
329f5bc
address review
felixdivo Aug 11, 2019
2ae5100
address review on typing of PathLike
felixdivo Aug 11, 2019
2dda623
address review comments, cleanup tests
felixdivo Aug 11, 2019
a4154a4
fix exception message if filetype is unknown
felixdivo Aug 15, 2019
31c23bb
Update Readme
felixdivo Aug 16, 2019
fca9827
Fix bitrate setting in slcan
christiansandberg Aug 19, 2019
3b68a54
Merge branch 'develop' into asc-writer-canfd
felixdivo Sep 4, 2019
908fd87
Merge branch 'asc-writer-canfd' into develop
felixdivo Sep 4, 2019
1ac5510
Ignore error frames in can.player by default
christiansandberg Aug 17, 2019
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
test/__tempdir__/
.pytest_cache/
.mypy_cache/
.dmypy.json
dmypy.json

# -------------------------
# below: https://github.com/github/gitignore/blob/da00310ccba9de9a988cc973ef5238ad2c1460e9/Python.gitignore
Expand Down
18 changes: 18 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,24 @@ jobs:
# warnings to the .pylintrc-wip file to prevent them from being
# re-introduced
- pylint --rcfile=.pylintrc-wip can/
# mypy checking
- mypy
--python-version=3.7
--ignore-missing-imports
--no-implicit-optional
can/bit_timing.py
can/broadcastmanager.py
can/bus.py
can/interface.py
can/listener.py
can/logger.py
can/message.py
can/notifier.py
can/player.py
can/thread_safe_bus.py
can/typechecking.py
can/util.py
can/io/**.py
- stage: linter
name: "Formatting Checks"
python: "3.7"
Expand Down
38 changes: 22 additions & 16 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
python-can
==========

|release| |docs| |build_travis| |build_appveyor| |coverage| |downloads| |formatter|
|release| |downloads| |downloads_monthly| |formatter|

|docs| |build_travis| |build_appveyor| |coverage|

.. |release| image:: https://img.shields.io/pypi/v/python-can.svg
:target: https://pypi.python.org/pypi/python-can/
:alt: Latest Version on PyPi

.. |downloads| image:: https://pepy.tech/badge/python-can
:target: https://pepy.tech/project/python-can
:alt: Downloads on PePy

.. |downloads_monthly| image:: https://pepy.tech/badge/python-can/month
:target: https://pepy.tech/project/python-can/month
:alt: Monthly downloads on PePy

.. |formatter| image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/python/black
:alt: This project uses the black formatter.

.. |docs| image:: https://readthedocs.org/projects/python-can/badge/?version=stable
:target: https://python-can.readthedocs.io/en/stable/
:alt: Documentation
Expand All @@ -23,14 +37,6 @@ python-can
:target: https://codecov.io/gh/hardbyte/python-can/branch/develop
:alt: Test coverage reports on Codecov.io

.. |downloads| image:: https://pepy.tech/badge/python-can
:target: https://pepy.tech/project/python-can
:alt: Downloads on PePy

.. |formatter| image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/python/black
:alt: This project uses the black formatter.

The **C**\ ontroller **A**\ rea **N**\ etwork is a bus standard designed
to allow microcontrollers and devices to communicate with each other. It
has priority based bus arbitration and reliable deterministic
Expand All @@ -44,13 +50,13 @@ messages on a can bus.
The library currently supports Python 3.6+ as well as PyPy 3 and runs
on Mac, Linux and Windows.

============================= ===========
Library Version Python
----------------------------- -----------
2.x 2.6+, 3.4+
3.x 2.7+, 3.5+
4.x *(currently on devlop)* 3.6+
============================= ===========
============================== ===========
Library Version Python
------------------------------ -----------
2.x 2.6+, 3.4+
3.x 2.7+, 3.5+
4.x *(currently on develop)* 3.6+
============================== ===========


Features
Expand Down
4 changes: 3 additions & 1 deletion can/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@

import logging

from typing import Dict, Any

__version__ = "3.2.0"

log = logging.getLogger("can")

rc = dict()
rc: Dict[str, Any] = dict()


class CanError(IOError):
Expand Down
18 changes: 9 additions & 9 deletions can/bit_timing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Union
from typing import Optional, Union


class BitTiming:
Expand Down Expand Up @@ -27,15 +27,15 @@ class BitTiming:

def __init__(
self,
bitrate: int = None,
f_clock: int = None,
brp: int = None,
tseg1: int = None,
tseg2: int = None,
sjw: int = None,
bitrate: Optional[int] = None,
f_clock: Optional[int] = None,
brp: Optional[int] = None,
tseg1: Optional[int] = None,
tseg2: Optional[int] = None,
sjw: Optional[int] = None,
nof_samples: int = 1,
btr0: int = None,
btr1: int = None,
btr0: Optional[int] = None,
btr1: Optional[int] = None,
):
"""
:param int bitrate:
Expand Down
108 changes: 81 additions & 27 deletions can/broadcastmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,27 @@
:meth:`can.BusABC.send_periodic`.
"""

from typing import Optional, Sequence, Tuple, Union, TYPE_CHECKING

from can import typechecking

if TYPE_CHECKING:
from can.bus import BusABC

from can.message import Message

import abc
import logging
import threading
import time

import can
# try to import win32event for event-based cyclic send task(needs pywin32 package)
try:
import win32event

HAS_EVENTS = True
except ImportError:
HAS_EVENTS = False

log = logging.getLogger("can.bcm")

Expand All @@ -36,11 +51,11 @@ class CyclicSendTaskABC(CyclicTask):
Message send task with defined period
"""

def __init__(self, messages, period):
def __init__(self, messages: Union[Sequence[Message], Message], period: float):
"""
:param Union[Sequence[can.Message], can.Message] messages:
:param messages:
The messages to be sent periodically.
:param float period: The rate in seconds at which to send the messages.
:param period: The rate in seconds at which to send the messages.
"""
messages = self._check_and_convert_messages(messages)

Expand All @@ -50,7 +65,9 @@ def __init__(self, messages, period):
self.messages = messages

@staticmethod
def _check_and_convert_messages(messages):
def _check_and_convert_messages(
messages: Union[Sequence[Message], Message]
) -> Tuple[Message, ...]:
"""Helper function to convert a Message or Sequence of messages into a
tuple, and raises an error when the given value is invalid.

Expand All @@ -60,7 +77,7 @@ def _check_and_convert_messages(messages):
Should be called when the cyclic task is initialized
"""
if not isinstance(messages, (list, tuple)):
if isinstance(messages, can.Message):
if isinstance(messages, Message):
messages = [messages]
else:
raise ValueError("Must be either a list, tuple, or a Message")
Expand All @@ -84,13 +101,18 @@ def _check_and_convert_messages(messages):


class LimitedDurationCyclicSendTaskABC(CyclicSendTaskABC):
def __init__(self, messages, period, duration):
def __init__(
self,
messages: Union[Sequence[Message], Message],
period: float,
duration: Optional[float],
):
"""Message send task with a defined duration and period.

:param Union[Sequence[can.Message], can.Message] messages:
:param messages:
The messages to be sent periodically.
:param float period: The rate in seconds at which to send the messages.
:param float duration:
:param period: The rate in seconds at which to send the messages.
:param duration:
Approximate duration in seconds to continue sending messages. If
no duration is provided, the task will continue indefinitely.
"""
Expand All @@ -110,7 +132,7 @@ def start(self):
class ModifiableCyclicTaskABC(CyclicSendTaskABC):
"""Adds support for modifying a periodic message"""

def _check_modified_messages(self, messages):
def _check_modified_messages(self, messages: Tuple[Message, ...]):
"""Helper function to perform error checking when modifying the data in
the cyclic task.

Expand All @@ -130,12 +152,12 @@ def _check_modified_messages(self, messages):
"from when the task was created"
)

def modify_data(self, messages):
def modify_data(self, messages: Union[Sequence[Message], Message]):
"""Update the contents of the periodically sent messages, without
altering the timing.

:param Union[Sequence[can.Message], can.Message] messages:
The messages with the new :attr:`can.Message.data`.
:param messages:
The messages with the new :attr:`Message.data`.

Note: The arbitration ID cannot be changed.

Expand All @@ -153,35 +175,57 @@ class MultiRateCyclicSendTaskABC(CyclicSendTaskABC):
"""A Cyclic send task that supports switches send frequency after a set time.
"""

def __init__(self, channel, messages, count, initial_period, subsequent_period):
def __init__(
self,
channel: typechecking.Channel,
messages: Union[Sequence[Message], Message],
count: int,
initial_period: float,
subsequent_period: float,
):
"""
Transmits a message `count` times at `initial_period` then continues to
transmit messages at `subsequent_period`.

:param channel: See interface specific documentation.
:param Union[Sequence[can.Message], can.Message] messages:
:param int count:
:param float initial_period:
:param float subsequent_period:
:param messages:
:param count:
:param initial_period:
:param subsequent_period:
"""
super().__init__(channel, messages, subsequent_period)
super().__init__(messages, subsequent_period)
self._channel = channel


class ThreadBasedCyclicSendTask(
ModifiableCyclicTaskABC, LimitedDurationCyclicSendTaskABC, RestartableCyclicTaskABC
):
"""Fallback cyclic send task using thread."""

def __init__(self, bus, lock, messages, period, duration=None):
def __init__(
self,
bus: "BusABC",
lock: threading.Lock,
messages: Union[Sequence[Message], Message],
period: float,
duration: Optional[float] = None,
):
super().__init__(messages, period, duration)
self.bus = bus
self.send_lock = lock
self.stopped = True
self.thread = None
self.end_time = time.time() + duration if duration else None
self.end_time = time.perf_counter() + duration if duration else None

if HAS_EVENTS:
self.period_ms: int = int(round(period * 1000, 0))
self.event = win32event.CreateWaitableTimer(None, False, None)

self.start()

def stop(self):
if HAS_EVENTS:
win32event.CancelWaitableTimer(self.event.handle)
self.stopped = True

def start(self):
Expand All @@ -190,22 +234,32 @@ def start(self):
name = "Cyclic send task for 0x%X" % (self.messages[0].arbitration_id)
self.thread = threading.Thread(target=self._run, name=name)
self.thread.daemon = True

if HAS_EVENTS:
win32event.SetWaitableTimer(
self.event.handle, 0, self.period_ms, None, None, False
)

self.thread.start()

def _run(self):
msg_index = 0
while not self.stopped:
# Prevent calling bus.send from multiple threads
with self.send_lock:
started = time.time()
started = time.perf_counter()
try:
self.bus.send(self.messages[msg_index])
except Exception as exc:
log.exception(exc)
break
if self.end_time is not None and time.time() >= self.end_time:
if self.end_time is not None and time.perf_counter() >= self.end_time:
break
msg_index = (msg_index + 1) % len(self.messages)
# Compensate for the time it takes to send the message
delay = self.period - (time.time() - started)
time.sleep(max(0.0, delay))

if HAS_EVENTS:
win32event.WaitForSingleObject(self.event.handle, self.period_ms)
else:
# Compensate for the time it takes to send the message
delay = self.period - (time.perf_counter() - started)
time.sleep(max(0.0, delay))
Loading