Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
11 changes: 7 additions & 4 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ jobs:
- uses: actions/setup-python@v6.3.0
with:
python-version: '3.10'
cache: 'pip'
cache: 'pip' # Safely caches dependencies

- name: Install dependencies
run: pip install vermin -e .[lint]
run: pip install -e .[lint]

- name: Check style and syntax (Ruff)
run: ruff check .

- name: Check minimum Python version (must not exceed 3.10)
run: vermin --target=3.10- --backport enum j1939/
- name: Check minimum Python version compatibility (Vermin)
run: vermin --target=3.10- --no-parse-comments --no-tips j1939/

- name: Run Pyright
run: pyright
Expand Down
1 change: 1 addition & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from test.helpers.feeder import Feeder


@pytest.fixture()
def feeder():
# setup
Expand Down
3 changes: 1 addition & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
Expand Down Expand Up @@ -233,4 +232,4 @@ def _generate_examples_rst():
]


# -- Extension configuration -------------------------------------------------
# -- Extension configuration -------------------------------------------------
4 changes: 2 additions & 2 deletions examples/diagnostic_message.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import time
import can

import j1939

logging.getLogger('j1939').setLevel(logging.DEBUG)
Expand Down Expand Up @@ -130,4 +130,4 @@ def main():
ecu.disconnect()

if __name__ == '__main__':
main()
main()
3 changes: 1 addition & 2 deletions examples/j1939_21_cmdt_send_receive/j1939_receive.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import logging
import time
import can

import j1939
from hexdump import hexdump

logging.getLogger('j1939').setLevel(logging.DEBUG)
logging.getLogger('can').setLevel(logging.DEBUG)
Expand Down
8 changes: 4 additions & 4 deletions examples/j1939_21_cmdt_send_receive/j1939_send.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import logging
import time
import can
import j1939
import os

from hexdump import hexdump

import j1939

logging.getLogger('j1939').setLevel(logging.DEBUG)
logging.getLogger('can').setLevel(logging.DEBUG)

Expand Down Expand Up @@ -129,4 +129,4 @@ def main():
ecu.disconnect()

if __name__ == '__main__':
main()
main()
6 changes: 3 additions & 3 deletions examples/j1939_22_multi_pg.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import logging
import time

import j1939
from j1939.message_id import FrameFormat


logging.getLogger('j1939').setLevel(logging.DEBUG)
logging.getLogger('can').setLevel(logging.DEBUG)

Expand All @@ -22,7 +22,7 @@ def on_message(priority, pgn, sa, timestamp, data):
:param bytearray data:
Data of the PDU
"""
print("PGN {} length {}".format(pgn, len(data)), timestamp)
print(f"PGN {pgn} length {len(data)}", timestamp)


def ca_timer_callback1(ca : j1939.ControllerApplication):
Expand Down Expand Up @@ -99,4 +99,4 @@ def main():
ecu.disconnect()

if __name__ == '__main__':
main()
main()
6 changes: 3 additions & 3 deletions examples/j1939_22_transport_protocols.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
import time
import j1939

import j1939

logging.getLogger('j1939').setLevel(logging.DEBUG)
logging.getLogger('can').setLevel(logging.DEBUG)
Expand All @@ -21,7 +21,7 @@ def on_message(priority, pgn, sa, timestamp, data):
:param bytearray data:
Data of the PDU
"""
print("PGN {} length {}".format(pgn, len(data)), timestamp)
print(f"PGN {pgn} length {len(data)}", timestamp)


def ca_timer_callback1(ca):
Expand Down Expand Up @@ -95,4 +95,4 @@ def main():
ecu.disconnect()

if __name__ == '__main__':
main()
main()
6 changes: 3 additions & 3 deletions examples/own_ca_producer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import time
import can

import j1939

logging.getLogger('j1939').setLevel(logging.DEBUG)
Expand Down Expand Up @@ -37,7 +37,7 @@ def ca_receive(priority, pgn, source, timestamp, data):
:param bytearray data:
Data of the PDU
"""
print("PGN {} length {}".format(pgn, len(data)))
print(f"PGN {pgn} length {len(data)}")

def ca_timer_callback1(cookie):
"""Callback for sending messages
Expand Down Expand Up @@ -126,4 +126,4 @@ def main():
ecu.disconnect()

if __name__ == '__main__':
main()
main()
6 changes: 3 additions & 3 deletions examples/simple_receive_global.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import time
import can

import j1939

logging.getLogger('j1939').setLevel(logging.DEBUG)
Expand All @@ -20,7 +20,7 @@ def on_message(priority, pgn, sa, timestamp, data):
:param bytearray data:
Data of the PDU
"""
print("PGN {} length {}".format(pgn, len(data)))
print(f"PGN {pgn} length {len(data)}")

def main():
print("Initializing")
Expand All @@ -47,4 +47,4 @@ def main():
ecu.disconnect()

if __name__ == '__main__':
main()
main()
6 changes: 3 additions & 3 deletions examples/simple_receive_peer_to_peer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import time
import can

import j1939

logging.getLogger('j1939').setLevel(logging.DEBUG)
Expand All @@ -20,7 +20,7 @@ def on_message(priority, pgn, sa, timestamp, data):
:param bytearray data:
Data of the PDU
"""
print("PGN {} length {}".format(hex(pgn), len(data)))
print(f"PGN {hex(pgn)} length {len(data)}")

def main():
print("Initializing")
Expand All @@ -47,4 +47,4 @@ def main():
ecu.disconnect()

if __name__ == '__main__':
main()
main()
14 changes: 8 additions & 6 deletions j1939/Dm14Query.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@

from __future__ import annotations

import queue
from collections.abc import Callable
from enum import Enum
from typing import Optional
import queue

import j1939


Expand Down Expand Up @@ -42,14 +44,14 @@ def __init__(self, ca: j1939.ControllerApplication, user_level=7) -> None:

self._ca = ca
self.state = QueryState.IDLE
self._seed_from_key: Optional[Callable[[int], int]] = None
self._seed_from_key: Callable[[int], int] | None = None
self.data_queue: queue.Queue = queue.Queue()
self.mem_data = None
self.exception_queue: queue.Queue = queue.Queue()
self.user_level = user_level
self._dest_address: Optional[int] = None
self.address: Optional[int] = None
self.command: Optional[Command] = None
self._dest_address: int | None = None
self.address: int | None = None
self.command: Command | None = None

def unsubscribe_all(self) -> None:
"""
Expand Down
29 changes: 16 additions & 13 deletions j1939/Dm14Server.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

from __future__ import annotations
from collections.abc import Callable
from enum import Enum
from typing import Optional

import queue
import secrets
from collections.abc import Callable
from enum import Enum

import j1939


Expand All @@ -27,13 +29,13 @@ def __init__(self, ca: j1939.ControllerApplication) -> None:

self._ca = ca
self._busy = False
self.sa: Optional[int] = None
self.sa: int | None = None
self.state = ResponseState.IDLE
self._key_from_seed: Optional[Callable[[int], int]] = None
self._key_from_seed: Callable[[int], int] | None = None
self.data_queue: queue.Queue = queue.Queue()
self._seed_generator: Callable[[], int] = self.generate_seed
self._verify_key: Optional[Callable[..., bool]] = None
self.address: Optional[bytearray] = None
self._verify_key: Callable[..., bool] | None = None
self.address: bytearray | None = None
self.length = 8
self.proceed = False
self.data: bytearray | list = []
Expand Down Expand Up @@ -180,9 +182,10 @@ def _send_dm15(
state: ResponseState,
object_count: int,
sa: int,
pgn: int = j1939.ParameterGroupNumber.PGN.DM15,
error: Optional[int] = None,
edcp: Optional[int] = None,
pgn: int = 55296, # FIXME: we should use constants, like we used to: j1939.ParameterGroupNumber.PGN.DM15, but we get into circular imports errors. https://github.com/RaulSMS/python-can-j1939/issues/24
error: int | None = None,
edcp: int | None = None,

) -> None:
"""
Send DM15 message to device, used to send the proceed message,
Expand Down Expand Up @@ -244,7 +247,7 @@ def _send_dm16(self) -> None:
data = []
byte_count = len(self.data)
data.append(0xFF if byte_count > 7 else byte_count)
for i in range((byte_count)):
for i in range(byte_count):
data.append(self.data[i])

data.extend([0xFF] * (self.length - byte_count - 1))
Expand Down Expand Up @@ -379,7 +382,7 @@ def respond(
error: int = 0xFFFFFF,
edcp: int = 0xFF,
max_timeout: int = 3,
) -> Optional[list]:
) -> list | None:
"""
Respond to DM14 query with the requested data or confimation of operation is good to proceed
:param bool proceed: whether the operation is good to proceed
Expand All @@ -404,7 +407,7 @@ def respond(
else:
self.state = ResponseState.SEND_ERROR
self._wait_for_data()
mem_data: Optional[list] = None
mem_data: list | None = None
if self.state == ResponseState.WAIT_FOR_DM16:
try:
mem_data = self.data_queue.get(block=True, timeout=max_timeout)
Expand Down
22 changes: 11 additions & 11 deletions j1939/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from .version import __version__
from .electronic_control_unit import ElectronicControlUnit
from .controller_application import ControllerApplication
from .name import Name
from .message_id import MessageId
from .parameter_group_number import ParameterGroupNumber
from .diagnostic_messages import *
from .memory_access import *
from .error_info import *
from .Dm14Query import *
from .Dm14Server import *
from .controller_application import ControllerApplication as ControllerApplication
from .diagnostic_messages import * # noqa: F403
from .Dm14Query import * # noqa: F403
from .Dm14Server import * # noqa: F403
from .electronic_control_unit import ElectronicControlUnit as ElectronicControlUnit
from .error_info import * # noqa: F403
from .memory_access import * # noqa: F403
from .message_id import MessageId as MessageId
from .name import Name as Name
from .parameter_group_number import ParameterGroupNumber as ParameterGroupNumber
from .version import __version__ as __version__
10 changes: 6 additions & 4 deletions j1939/controller_application.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from __future__ import annotations

import logging
from typing import Optional

import j1939

from .message_id import FrameFormat

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -54,7 +56,7 @@ def __init__(self, name, device_address_preferred=None, bypass_address_claim=Fal
self._device_address_announced = j1939.ParameterGroupNumber.Address.NULL
self._device_address = j1939.ParameterGroupNumber.Address.NULL
self._device_address_state = ControllerApplication.State.NONE
self._ecu: Optional[j1939.ElectronicControlUnit] = None
self._ecu: j1939.ElectronicControlUnit | None = None
self._subscribers_request = []
self._subscribers_acknowledge = []
self._started = False
Expand Down Expand Up @@ -174,7 +176,7 @@ def stop(self):
def _process_claim_async(self, cookie):
time_to_sleep = 0.500
if self._device_address_state == ControllerApplication.State.NONE:
if self._device_address_preferred != None:
if self._device_address_preferred is not None:
self._device_address_announced = self._device_address_preferred
self._send_address_claimed(self._device_address_announced)
if self._device_address_announced > 127 and self._device_address_announced < 248:
Expand Down Expand Up @@ -231,7 +233,7 @@ def _process_addressclaim(self, mid, data, timestamp):
# TODO: are there any state variables we have to care about?
self._device_address = j1939.ParameterGroupNumber.Address.NULL
# TODO: maybe we should call an overloadable function here
if self._name.arbitrary_address_capable == False:
if not self._name.arbitrary_address_capable:
# bad luck
logger.error("After releasing our address we are configured to stop operation (CANNOT CLAIM)")
self._device_address_state = ControllerApplication.State.CANNOT_CLAIM
Expand Down
Loading
Loading