j1939

This module holds definitions of J1939 Protocol Data Unit (PDU) frames.

Example of usage:

>>> from canlib import Frame, j1939
>>> from canlib.canlib import MessageFlag
>>> def frame_from_pdu(pdu):
...     can_id = j1939.can_id_from_pdu(pdu)
...     frame = Frame(
...         id_=can_id,
...         data=pdu.data,
...         flags=MessageFlag.EXT,
...     )
...     return frame
>>> pdu = j1939.Pdu1(
...     p=3, edp=0, dp=0, pf=0x99, ps=0xfe, sa=0xfe,
...     data=[1]
... )
>>> frame_from_pdu(pdu)
Frame(id=211418878, data=bytearray(b'\x01'), dlc=1, flags=<MessageFlag.EXT: 4>, timestamp=None)

The particular characteristics of J1939 are:

  • Extended CAN identifier (29 bit)

  • Bit rate 250 kbit/s

  • Peer-to-peer and broadcast communication

  • Transport protocols for up to 1785 data bytes

  • Network management

  • Definition of parameter groups for commercial vehicles and others

  • Manufacturer specific parameter groups are supported

  • Diagnostics features

(Extended) Data Page Bit

Extended Data page

Data page

Description

0

0

SAE J1939 Page 0 Parameter Groups

0

1

SAE J1939 Page 1 Parameter Groups (NMEA2000)

1

1

SAE J1939 reserved

1

1

ISO 15765-3 defined

New in version 1.18.

Protocol Data Units

class canlib.j1939.Pdu(*, p: int, edp: int, dp: int, pf: int, ps: int, sa: int, data: Optional[List[int]] = None)[source]

Protocol Data Unit in j1939.

Base class with attributes common to Pdu1 and Pdu2

data: Optional[List[int]]

data field

dp: int

data page

edp: int

extended data page

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'data': FieldInfo(annotation=Union[List[int], NoneType], required=False, default=None), 'dp': FieldInfo(annotation=int, required=True), 'edp': FieldInfo(annotation=int, required=True), 'p': FieldInfo(annotation=int, required=True), 'pf': FieldInfo(annotation=int, required=True), 'ps': FieldInfo(annotation=int, required=True), 'sa': FieldInfo(annotation=int, required=True)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

p: int

priority

pf: int

PDU format

ps: int

PDU specific

sa: int

source address

class canlib.j1939.Pdu1(*, p: int, edp: int, dp: int, pf: int, ps: int, sa: int, data: Optional[List[int]] = None, da: Optional[int] = None, pgn: Optional[int] = None)[source]

Protocol Data Unit, Format 1

When Pdu.pf < 240, the PDU Specific field is a Destination Address and

pgn = Extended Data Page + Data Page + PDU Format + “00”

da: Optional[int]

destination address, Pdu.ps

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'da': FieldInfo(annotation=Union[int, NoneType], required=False, default=None), 'data': FieldInfo(annotation=Union[List[int], NoneType], required=False, default=None), 'dp': FieldInfo(annotation=int, required=True), 'edp': FieldInfo(annotation=int, required=True), 'p': FieldInfo(annotation=int, required=True), 'pf': FieldInfo(annotation=int, required=True), 'pgn': FieldInfo(annotation=Union[int, NoneType], required=False, default=None), 'ps': FieldInfo(annotation=int, required=True), 'sa': FieldInfo(annotation=int, required=True)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

pgn: Optional[int]

parameter group number

class canlib.j1939.Pdu2(*, p: int, edp: int, dp: int, pf: int, ps: int, sa: int, data: Optional[List[int]] = None, ge: Optional[int] = None, pgn: Optional[int] = None)[source]

Protocol Data Unit, Format 2

When Pdu.pf >= 240, the PDU Specific field is the Group Extension

pgn = Extended Data Page + Data Page + PDU Format + Group Extension

ge: Optional[int]

group extension, equal to Pdu.ps

model_computed_fields: ClassVar[dict[str, ComputedFieldInfo]] = {}

A dictionary of computed field names and their corresponding ComputedFieldInfo objects.

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_fields: ClassVar[dict[str, FieldInfo]] = {'data': FieldInfo(annotation=Union[List[int], NoneType], required=False, default=None), 'dp': FieldInfo(annotation=int, required=True), 'edp': FieldInfo(annotation=int, required=True), 'ge': FieldInfo(annotation=Union[int, NoneType], required=False, default=None), 'p': FieldInfo(annotation=int, required=True), 'pf': FieldInfo(annotation=int, required=True), 'pgn': FieldInfo(annotation=Union[int, NoneType], required=False, default=None), 'ps': FieldInfo(annotation=int, required=True), 'sa': FieldInfo(annotation=int, required=True)}

Metadata about the fields defined on the model, mapping of field names to [FieldInfo][pydantic.fields.FieldInfo].

This replaces Model.__fields__ from Pydantic V1.

pgn: Optional[int]

parameter group number

Converting CAN Id

For a j1939 message, the CAN identifier is divided into the following fields:

Priority

Extended Data Page

Data Page

PDU Format

PDU Specific

Source Address

3 bit

1 bit

1 bit

8 bit

8 bit

8 bit

Use pdu_from_can_id and can_id_from_pdu to convert.

canlib.j1939.pdu_from_can_id(can_id)[source]

Create j1939 Protocol Data Unit object based on CAN Id.

Parameters

can_id (int) – CAN Identifier

Returns

Pdu1 or Pdu2 depending on value of can_id

canlib.j1939.can_id_from_pdu(pdu)[source]

Extract CAN Id based on j1939 Protocol Data Unit object.

Parameters

pdu (Pdu1 or Pdu2) – Protocol Data Unit

Returns

can_id (int) – CAN Identifier