python-can-j1939 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,325 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-can-j1939
3
+ Version: 0.1.0
4
+ Summary: SAE J1939 stack implementation (fork of can-j1939 by Juergen Heilgemeir)
5
+ Author: Raul Sainz-Maza, Drew Rife, Grant Allan, Koltan Hauersperger, Mahesh Sharma, Todd Snider, Victor Klueber
6
+ Maintainer: Raul Sainz-Maza
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/RaulSMS/python-can-j1939
9
+ Project-URL: Bug Tracker, https://github.com/RaulSMS/python-can-j1939/issues
10
+ Project-URL: Documentation, https://python-can-j1939.readthedocs.io/en/latest/
11
+ Keywords: CAN,SAE,J1939,J1939-FD,J1939-22
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Intended Audience :: Developers
19
+ Classifier: Topic :: Scientific/Engineering
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: python-can>=4.2.0
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest>=6.2.5; extra == "test"
26
+ Dynamic: license-file
27
+
28
+ # SAE J1939 for Python
29
+
30
+ [![Latest Version on PyPi](https://img.shields.io/pypi/v/python-can-j1939)](https://pypi.org/project/python-can-j1939/)
31
+ [![Documentation build Status](https://readthedocs.org/projects/python-can-j1939/badge/?version=latest)](https://python-can-j1939.readthedocs.io/en/latest/)
32
+
33
+ An implementation of the CAN SAE J1939 standard for Python. This is the
34
+ first J1939-22 (J1939-FD) implementation!
35
+
36
+ If you experience a problem or think the stack would not behave
37
+ properly, do not hesitate to open a ticket or write an email.
38
+ Pull Requests (PR) are of course even more welcome!
39
+
40
+ The project uses the
41
+ [python-can](https://python-can.readthedocs.org/en/stable/) package to
42
+ support multiple hardware drivers. At the time of writing the supported
43
+ interfaces are
44
+
45
+ - CAN over Serial
46
+ - CAN over Serial / SLCAN
47
+ - CANalyst-II
48
+ - IXXAT Virtual CAN Interface
49
+ - Kvasers CANLIB
50
+ - NEOVI Interface
51
+ - NI-CAN
52
+ - PCAN Basic API
53
+ - Socketcan
54
+ - SYSTEC interface
55
+ - USB2CAN Interface
56
+ - Vector
57
+ - Virtual
58
+ - isCAN
59
+
60
+ ## Overview
61
+
62
+ An SAE J1939 CAN Network consists of multiple Electronic Control Units
63
+ (ECUs). Each ECU can have one or more Controller Applications (CAs).
64
+ Each CA has its own (unique) Address on the bus. This address is either
65
+ acquired within the address claiming procedure or set to a fixed value.
66
+ In the latter case, the CA has to announce its address to the bus to
67
+ check whether it is free.
68
+
69
+ The CAN messages in a SAE J1939 network are called Protocol Data Units
70
+ (PDUs). This definition is not completely correct, but close enough to
71
+ think of PDUs as the CAN messages.
72
+
73
+ ## Features
74
+
75
+ - one ElectronicControlUnit (ECU) can hold multiple
76
+ ControllerApplications (CA)
77
+ - ECU (CA) Naming according SAE J1939/81
78
+ - full featured address claiming procedure according SAE J1939/81
79
+ - full support of transport protocol (up to 1785 bytes) according SAE
80
+ J1939/21 for sending and receiving
81
+ - Connection Mode Data Transfers (CMDT)
82
+ - Broadcast Announce Message (BAM)
83
+ - support of Multi-PG according SAE J1939/22
84
+ - currently FEFF (Flexible Data Rate Extended Frame Format)
85
+ supported only
86
+ - full support of fd-transport protocol according SAE J1939/22
87
+ (J1939-FD) for sending and receiving
88
+ - RTS/CTS (Destination Specific) Transfer with up to 8 concurrent
89
+ sessions and up to 16777215 bytes of data per session
90
+ - Broadcast Announce Message (BAM) with up to 4 concurrent
91
+ sessions and up to 15300 bytes of data per session
92
+ - Requests (global and specific)
93
+ - correct timeout and deadline handling
94
+ - (under construction) almost complete testcoverage
95
+ - diagnostic messages (see
96
+ <https://github.com/RaulSMS/python-can-j1939/tree/master/examples/diagnostic_message.py>)
97
+ - support of DM1 Tool and ECU functionaliy (all four SAE J1939-73
98
+ SPN conversion methods: 1, 2, 3, 4)
99
+ - support of DM11 Tool functionaliy
100
+ - support of DM22 Tool functionaliy
101
+
102
+ ## Installation
103
+
104
+ Requires **Python 3.10 or later** and python-can_ >= 4.2.0.
105
+
106
+ Install python-can-j1939 with pip:
107
+
108
+ pip install python-can-j1939
109
+
110
+ or do the trick with:
111
+
112
+ git clone https://github.com/RaulSMS/python-can-j1939.git
113
+ cd python-can-j1939
114
+ pip install .
115
+
116
+ ## Upgrade
117
+
118
+ Upgrade an already installed python-can-j1939 package:
119
+
120
+ pip install --upgrade python-can-j1939
121
+
122
+ ## Quick start
123
+
124
+ To simply receive all passing (public) messages on the bus you can
125
+ subscribe to the ECU object.
126
+
127
+ ``` python
128
+ import logging
129
+ import time
130
+ import can
131
+ import j1939
132
+
133
+ logging.getLogger('j1939').setLevel(logging.DEBUG)
134
+ logging.getLogger('can').setLevel(logging.DEBUG)
135
+
136
+ def on_message(priority, pgn, sa, timestamp, data):
137
+ """Receive incoming messages from the bus
138
+
139
+ :param int priority:
140
+ Priority of the message
141
+ :param int pgn:
142
+ Parameter Group Number of the message
143
+ :param int sa:
144
+ Source Address of the message
145
+ :param int timestamp:
146
+ Timestamp of the message
147
+ :param bytearray data:
148
+ Data of the PDU
149
+ """
150
+ print("PGN {} length {}".format(pgn, len(data)))
151
+
152
+ def main():
153
+ print("Initializing")
154
+
155
+ # create the ElectronicControlUnit (one ECU can hold multiple ControllerApplications)
156
+ ecu = j1939.ElectronicControlUnit()
157
+
158
+ # Connect to the CAN bus
159
+ # Arguments are passed to python-can's can.interface.Bus() constructor
160
+ # (see https://python-can.readthedocs.io/en/stable/bus.html).
161
+ # ecu.connect(bustype='socketcan', channel='can0')
162
+ # ecu.connect(bustype='kvaser', channel=0, bitrate=250000)
163
+ ecu.connect(bustype='pcan', channel='PCAN_USBBUS1', bitrate=250000)
164
+ # ecu.connect(bustype='ixxat', channel=0, bitrate=250000)
165
+ # ecu.connect(bustype='vector', app_name='CANalyzer', channel=0, bitrate=250000)
166
+ # ecu.connect(bustype='nican', channel='CAN0', bitrate=250000)
167
+
168
+ # subscribe to all (global) messages on the bus
169
+ ecu.subscribe(on_message)
170
+
171
+ time.sleep(120)
172
+
173
+ print("Deinitializing")
174
+ ecu.disconnect()
175
+
176
+ if __name__ == '__main__':
177
+ main()
178
+ ```
179
+
180
+ A more sophisticated example in which the CA class was overloaded to
181
+ include its own functionality:
182
+
183
+ ``` python
184
+ import logging
185
+ import time
186
+ import can
187
+ import j1939
188
+
189
+ logging.getLogger('j1939').setLevel(logging.DEBUG)
190
+ logging.getLogger('can').setLevel(logging.DEBUG)
191
+
192
+ # compose the name descriptor for the new ca
193
+ name = j1939.Name(
194
+ arbitrary_address_capable=0,
195
+ industry_group=j1939.Name.IndustryGroup.Industrial,
196
+ vehicle_system_instance=1,
197
+ vehicle_system=1,
198
+ function=1,
199
+ function_instance=1,
200
+ ecu_instance=1,
201
+ manufacturer_code=666,
202
+ identity_number=1234567
203
+ )
204
+
205
+ # create the ControllerApplications
206
+ ca = j1939.ControllerApplication(name, 128)
207
+
208
+
209
+ def ca_receive(priority, pgn, source, timestamp, data):
210
+ """Feed incoming message to this CA.
211
+ (OVERLOADED function)
212
+ :param int priority:
213
+ Priority of the message
214
+ :param int pgn:
215
+ Parameter Group Number of the message
216
+ :param intsa:
217
+ Source Address of the message
218
+ :param int timestamp:
219
+ Timestamp of the message
220
+ :param bytearray data:
221
+ Data of the PDU
222
+ """
223
+ print("PGN {} length {}".format(pgn, len(data)))
224
+
225
+ def ca_timer_callback1(cookie):
226
+ """Callback for sending messages
227
+
228
+ This callback is registered at the ECU timer event mechanism to be
229
+ executed every 500ms.
230
+
231
+ :param cookie:
232
+ A cookie registered at 'add_timer'. May be None.
233
+ """
234
+ # wait until we have our device_address
235
+ if ca.state != j1939.ControllerApplication.State.NORMAL:
236
+ # returning true keeps the timer event active
237
+ return True
238
+
239
+ # create data with 8 bytes
240
+ data = [j1939.ControllerApplication.FieldValue.NOT_AVAILABLE_8] * 8
241
+
242
+ # sending normal broadcast message
243
+ ca.send_pgn(0, 0xFD, 0xED, 6, data)
244
+
245
+ # sending normal peer-to-peer message, destintion address is 0x04
246
+ ca.send_pgn(0, 0xE0, 0x04, 6, data)
247
+
248
+ # returning true keeps the timer event active
249
+ return True
250
+
251
+
252
+ def ca_timer_callback2(cookie):
253
+ """Callback for sending messages
254
+
255
+ This callback is registered at the ECU timer event mechanism to be
256
+ executed every 500ms.
257
+
258
+ :param cookie:
259
+ A cookie registered at 'add_timer'. May be None.
260
+ """
261
+ # wait until we have our device_address
262
+ if ca.state != j1939.ControllerApplication.State.NORMAL:
263
+ # returning true keeps the timer event active
264
+ return True
265
+
266
+ # create data with 100 bytes
267
+ data = [j1939.ControllerApplication.FieldValue.NOT_AVAILABLE_8] * 100
268
+
269
+ # sending multipacket message with TP-BAM
270
+ ca.send_pgn(0, 0xFE, 0xF6, 6, data)
271
+
272
+ # sending multipacket message with TP-CMDT, destination address is 0x05
273
+ ca.send_pgn(0, 0xD0, 0x05, 6, data)
274
+
275
+ # returning true keeps the timer event active
276
+ return True
277
+
278
+ def main():
279
+ print("Initializing")
280
+
281
+ # create the ElectronicControlUnit (one ECU can hold multiple ControllerApplications)
282
+ ecu = j1939.ElectronicControlUnit()
283
+
284
+ # Connect to the CAN bus
285
+ # Arguments are passed to python-can's can.interface.Bus() constructor
286
+ # (see https://python-can.readthedocs.io/en/stable/bus.html).
287
+ # ecu.connect(bustype='socketcan', channel='can0')
288
+ # ecu.connect(bustype='kvaser', channel=0, bitrate=250000)
289
+ ecu.connect(bustype='pcan', channel='PCAN_USBBUS1', bitrate=250000)
290
+ # ecu.connect(bustype='ixxat', channel=0, bitrate=250000)
291
+ # ecu.connect(bustype='vector', app_name='CANalyzer', channel=0, bitrate=250000)
292
+ # ecu.connect(bustype='nican', channel='CAN0', bitrate=250000)
293
+ # ecu.connect('testchannel_1', bustype='virtual')
294
+
295
+ # add CA to the ECU
296
+ ecu.add_ca(controller_application=ca)
297
+ ca.subscribe(ca_receive)
298
+ # callback every 0.5s
299
+ ca.add_timer(0.500, ca_timer_callback1)
300
+ # callback every 5s
301
+ ca.add_timer(5, ca_timer_callback2)
302
+ # by starting the CA it starts the address claiming procedure on the bus
303
+ ca.start()
304
+
305
+ time.sleep(120)
306
+
307
+ print("Deinitializing")
308
+ ca.stop()
309
+ ecu.disconnect()
310
+
311
+ if __name__ == '__main__':
312
+ main()
313
+ ```
314
+
315
+ ## Credits
316
+
317
+ This package is a fork of
318
+ [can-j1939](https://github.com/juergenH87/python-can-j1939) by Juergen
319
+ Heilgemeir, who greatly extended the original work and added J1939-22
320
+ (J1939-FD) support.
321
+
322
+ The original implementation was taken from
323
+ <https://github.com/benkfra/j1939> by Frank Benkert.
324
+
325
+ Thanks to all contributors for their great work!
@@ -0,0 +1,19 @@
1
+ j1939/Dm14Query.py,sha256=1SUGtwd23w56V0ZOxQs7KCHhff7GdMxGbPwEdc8PhcM,12226
2
+ j1939/Dm14Server.py,sha256=ftOtW1J6ix5cIbrtUZZcAwtkvb7Trk5jeEPQBDXvyI4,13838
3
+ j1939/__init__.py,sha256=Jr9uygL7C57iAgD0HHtHBn4onzAyEEJkpiQ2g6f8fv4,405
4
+ j1939/controller_application.py,sha256=wkDDZXqB5H6Z8ZWu-LqJhWzfCW4kX6mUBwobFeabBuI,16310
5
+ j1939/diagnostic_messages.py,sha256=HjzZ-dT_qMW7sLqYQXutDKBnHrPY_u2XP7J-sqmM9yo,15179
6
+ j1939/electronic_control_unit.py,sha256=0sYfpbf1GCwHl0U4ehw_evIE5qRL5rYxXV7yzJdG4G8,19649
7
+ j1939/error_info.py,sha256=oMT8QJUsPnXym3elmyHl4Hxt9ObXw1pxMTqBK1uVlGM,4154
8
+ j1939/j1939_21.py,sha256=Nt7yjdXuwtLxBD_KjJFLzB3yA6hCJLzZdomOQckqUHM,28526
9
+ j1939/j1939_22.py,sha256=yFiWa5dgfpLRd3-WD6p9VAVys-9392zsBmrLxIq6ApQ,44083
10
+ j1939/memory_access.py,sha256=2pHyjJsGXCUirKamPmItnhpYhrOnbUgmWdPV9tXxXyI,15304
11
+ j1939/message_id.py,sha256=AGU-sg74lqmqxlZFNNHjOYyz_jtASDY5kT76yb82GGU,1839
12
+ j1939/name.py,sha256=x-Tr6I2MUTChEf3C9BCQQe9qnvMzm5pseqRlnUr_OVI,10322
13
+ j1939/parameter_group_number.py,sha256=Q1U-GZuckYhQiIxAOjP1LGYDzQMla0nb232FQS5E9Jw,5323
14
+ j1939/version.py,sha256=Pru0BlFBASFCFo7McHdohtKkUtgMPDwbGfyUZlE2_Vw,21
15
+ python_can_j1939-0.1.0.dist-info/licenses/LICENSE,sha256=A5rtfN-Go8YRj8h812jydwJEPT6NIC1rLVQtHfVyOTs,1130
16
+ python_can_j1939-0.1.0.dist-info/METADATA,sha256=ccoR5VMWJjP3wlGCdgSZeugLPi1RaZpV8bWNMdaxWdQ,10455
17
+ python_can_j1939-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
18
+ python_can_j1939-0.1.0.dist-info/top_level.txt,sha256=DuSapIvGxz2GN_YXQAigYWEn-nqGoxEfJL12LrvTsrA,6
19
+ python_can_j1939-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Frank Benkert (opensource@frank-benkert.de)
4
+ Copyright (c) 2021 juergenH87
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ j1939