Skip to content

Commit efd1456

Browse files
authored
Merge pull request #8 from Nakakiyo092/feature/refactoring
Refactoring code
2 parents 93326e6 + 1157315 commit efd1456

File tree

1 file changed

+105
-43
lines changed

1 file changed

+105
-43
lines changed

reader/reader.py

Lines changed: 105 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
#!/usr/bin/env python3
22

3+
"""
4+
A Python script to retreive Event Data Recorder (EDR) data via CAN bus
5+
according to the Chinese standard GB39732-2020.
6+
7+
License:
8+
MIT License.
9+
See the accompanying LICENSE file for full terms.
10+
"""
11+
312
import os
413
import shutil
14+
import sys
515
import time
616
import csv
717

818
import can
919
import isotp
10-
from udsoncan import Request, Response
20+
from udsoncan import Response
1121
from udsoncan.services import ReadDataByIdentifier
1222

1323
def read_did(did, bus, notifier, tx_addr, rx_addrs, addr_type, isotp_params) -> bytearray:
24+
"""Read one data by identifier (DID) from the target ECU."""
1425

1526
print("")
1627
if tx_addr.is_tx_29bits():
@@ -21,19 +32,35 @@ def read_did(did, bus, notifier, tx_addr, rx_addrs, addr_type, isotp_params) ->
2132
print("Reading data id", hex(did), "with 11bits physical address.")
2233

2334
# Setup ISOTP stacks
24-
tx_stack = isotp.NotifierBasedCanStack(bus=bus, notifier=notifier, address=tx_addr, params=isotp_params)
35+
tx_stack = isotp.NotifierBasedCanStack(
36+
bus=bus,
37+
notifier=notifier,
38+
address=tx_addr,
39+
params=isotp_params
40+
)
2541
rx_stacks = []
2642
rx_stacks.append(tx_stack) # Add tx_stack itself to support Physical addressing
2743
for rx_addr in rx_addrs:
28-
rx_stack = isotp.NotifierBasedCanStack(bus=bus, notifier=notifier, address=rx_addr, params=isotp_params)
44+
rx_stack = isotp.NotifierBasedCanStack(
45+
bus=bus, notifier=notifier,
46+
address=rx_addr,
47+
params=isotp_params
48+
)
2949
rx_stacks.append(rx_stack)
3050

3151
# Request message
3252
request = ReadDataByIdentifier.make_request(didlist=[did], didconfig={'default':'s'})
3353

3454
# Response message (positive/pending)
35-
response = Response(service=ReadDataByIdentifier, code=Response.Code.PositiveResponse, data=bytes([(did>>8)&0xFF,did&0xFF]))
36-
pend_response = Response(service=ReadDataByIdentifier, code=Response.Code.RequestCorrectlyReceived_ResponsePending)
55+
response = Response(
56+
service=ReadDataByIdentifier,
57+
code=Response.Code.PositiveResponse,
58+
data=bytes([(did>>8)&0xFF,did&0xFF])
59+
)
60+
pend_response = Response(
61+
service=ReadDataByIdentifier,
62+
code=Response.Code.RequestCorrectlyReceived_ResponsePending
63+
)
3764

3865
# Start stacks
3966
for rx_stack in rx_stacks:
@@ -84,15 +111,17 @@ def read_did(did, bus, notifier, tx_addr, rx_addrs, addr_type, isotp_params) ->
84111

85112

86113
def output_data(payload) -> bytearray:
114+
"""Output the data to a CSV file according to the format defined in the 'format' folder."""
115+
87116
# Get target did from payload
88117
if payload is None:
89-
print(f"No data to output.")
118+
print("No data to output.")
90119
return
91-
elif len(payload) < 3:
92-
print(f"The payload is too short.")
120+
if len(payload) < 3:
121+
print("The payload is too short.")
93122
return
94-
else:
95-
did = f"{payload[1]:02x}{payload[2]:02x}"
123+
124+
did = f"{payload[1]:02x}{payload[2]:02x}"
96125

97126
# File paths for source and destination
98127
source_file = "format/did_" + did + ".csv"
@@ -117,15 +146,18 @@ def output_data(payload) -> bytearray:
117146

118147
# Read the input CSV file and write to the output file with the additional column
119148
try:
120-
with open(source_file, mode="r", encoding="utf-8") as infile, open(destination_file, mode="w", encoding="utf-8", newline="") as outfile:
149+
with (
150+
open(source_file, mode="r", encoding="utf-8") as infile,
151+
open(destination_file, mode="w", encoding="utf-8", newline="") as outfile
152+
):
121153
reader = csv.reader(infile)
122154
writer = csv.writer(outfile)
123-
155+
124156
# Read header and add new column name
125157
header = next(reader)
126158
header.append("Raw value") # Add a new column named 'Raw value'
127159
writer.writerow(header)
128-
160+
129161
# Process rows
130162
for row in reader:
131163
no = int(row[0]) # Convert No column to integer
@@ -134,7 +166,7 @@ def output_data(payload) -> bytearray:
134166
else:
135167
row.append("N/A") # Handle cases where No is out of range
136168
writer.writerow(row)
137-
169+
138170
except FileNotFoundError:
139171
print(f"The file '{source_file}' or '{destination_file}' does not exist.")
140172
return
@@ -153,7 +185,7 @@ def output_data(payload) -> bytearray:
153185
#bus = can.Bus('test', interface='virtual')
154186
except Exception as err:
155187
print(err)
156-
exit()
188+
sys.exit()
157189

158190
# Setup a debug listener that print all messages
159191
#notifier = can.Notifier(bus, [can.Printer()])
@@ -162,22 +194,41 @@ def output_data(payload) -> bytearray:
162194

163195
# Isotp parameters
164196
isotp_params = {
165-
'stmin': 0, # Will request the sender to wait 0ms between consecutive frame. 0-127ms or 100-900ns with values from 0xF1-0xF9
166-
'blocksize': 0, # Request the sender to send all consecutives frames without waiting a new flow control message
167-
'wftmax': 0, # Number of wait frame allowed before triggering an error
168-
'tx_data_length': 8, # Link layer (CAN layer) works with 8 byte payload (CAN 2.0)
169-
'tx_data_min_length': 8, # Minimum length of CAN messages. Messages are padded to meet this length.
170-
'tx_padding': 0, # Will pad all transmitted CAN messages with byte 0x00.
171-
'rx_flowcontrol_timeout': 1000, # Triggers a timeout if a flow control is awaited for more than 1000 milliseconds
172-
'rx_consecutive_frame_timeout': 1000, # Triggers a timeout if a consecutive frame is awaited for more than 1000 milliseconds
173-
'override_receiver_stmin': None, # When sending, respect the stmin requirement of the receiver. Could be set to a float value in seconds.
174-
'max_frame_size': 4095, # Limit the size of receive frame.
175-
'can_fd': False, # Does not set the can_fd flag on the output CAN messages
176-
'bitrate_switch': False, # Does not set the bitrate_switch flag on the output CAN messages
177-
'rate_limit_enable': False, # Disable the rate limiter
178-
'rate_limit_max_bitrate': 1000000, # Ignored when rate_limit_enable=False. Sets the max bitrate when rate_limit_enable=True
179-
'rate_limit_window_size': 0.2, # Ignored when rate_limit_enable=False. Sets the averaging window size for bitrate calculation when rate_limit_enable=True
180-
'listen_mode': False, # Does not use the listen_mode which prevent transmission.
197+
# Will request the sender to wait 0ms between consecutive frame.
198+
# 0-127ms or 100-900ns with values from 0xF1-0xF9.
199+
'stmin': 0,
200+
# Request the sender to send all consecutives frames without waiting a new flow control message.
201+
'blocksize': 0,
202+
# Number of wait frame allowed before triggering an error.
203+
'wftmax': 0,
204+
# Link layer (CAN layer) works with 8 byte payload (CAN 2.0).
205+
'tx_data_length': 8,
206+
# Minimum length of CAN messages. Messages are padded to meet this length.
207+
'tx_data_min_length': 8,
208+
# Will pad all transmitted CAN messages with byte 0x00.
209+
'tx_padding': 0,
210+
# Triggers a timeout if a flow control is awaited for more than 1000 milliseconds.
211+
'rx_flowcontrol_timeout': 1000,
212+
# Triggers a timeout if a consecutive frame is awaited for more than 1000 milliseconds.
213+
'rx_consecutive_frame_timeout': 1000,
214+
# When sending, respect the stmin requirement of the receiver.
215+
# Could be set to a float value in seconds.
216+
'override_receiver_stmin': None,
217+
# Limit the size of receive frame.
218+
'max_frame_size': 4095,
219+
# Does not set the can_fd flag on the output CAN messages.
220+
'can_fd': False,
221+
# Does not set the bitrate_switch flag on the output CAN messages.
222+
'bitrate_switch': False,
223+
# Disable the rate limiter.
224+
'rate_limit_enable': False,
225+
# Ignored when rate_limit_enable=False. Sets the max bitrate when rate_limit_enable=True.
226+
'rate_limit_max_bitrate': 1000000,
227+
# Ignored when rate_limit_enable=False.
228+
# Sets the averaging window size for bitrate calculation when rate_limit_enable=True.
229+
'rate_limit_window_size': 0.2,
230+
# Does not use the listen_mode which prevent transmission.
231+
'listen_mode': False,
181232
}
182233

183234

@@ -189,11 +240,12 @@ def output_data(payload) -> bytearray:
189240
rx_addrs.append(rx_addr)
190241

191242
try:
192-
payload = read_did(0xfa13, bus, notifier, tx_addr, rx_addrs, isotp.TargetAddressType.Functional, isotp_params)
243+
func = isotp.TargetAddressType.Functional
244+
payload = read_did(0xfa13, bus, notifier, tx_addr, rx_addrs, func, isotp_params)
193245
output_data(payload)
194-
payload = read_did(0xfa14, bus, notifier, tx_addr, rx_addrs, isotp.TargetAddressType.Functional, isotp_params)
246+
payload = read_did(0xfa14, bus, notifier, tx_addr, rx_addrs, func, isotp_params)
195247
output_data(payload)
196-
payload = read_did(0xfa15, bus, notifier, tx_addr, rx_addrs, isotp.TargetAddressType.Functional, isotp_params)
248+
payload = read_did(0xfa15, bus, notifier, tx_addr, rx_addrs, func, isotp_params)
197249
output_data(payload)
198250
except Exception as err:
199251
print(err)
@@ -204,30 +256,40 @@ def output_data(payload) -> bytearray:
204256
rx_addrs = []
205257

206258
try:
207-
payload = read_did(0xfa13, bus, notifier, tx_addr, rx_addrs, isotp.TargetAddressType.Physical, isotp_params)
259+
phys = isotp.TargetAddressType.Physical
260+
payload = read_did(0xfa13, bus, notifier, tx_addr, rx_addrs, phys, isotp_params)
208261
output_data(payload)
209-
payload = read_did(0xfa14, bus, notifier, tx_addr, rx_addrs, isotp.TargetAddressType.Physical, isotp_params)
262+
payload = read_did(0xfa14, bus, notifier, tx_addr, rx_addrs, phys, isotp_params)
210263
output_data(payload)
211-
payload = read_did(0xfa15, bus, notifier, tx_addr, rx_addrs, isotp.TargetAddressType.Physical, isotp_params)
264+
payload = read_did(0xfa15, bus, notifier, tx_addr, rx_addrs, phys, isotp_params)
212265
output_data(payload)
213266
except Exception as err:
214267
print(err)
215268

216269

217270
# Read with 29bits address
218-
tx_addr = isotp.Address(isotp.AddressingMode.NormalFixed_29bits, target_address=0xFF, source_address=0xF1)
271+
tx_addr = isotp.Address(
272+
isotp.AddressingMode.NormalFixed_29bits,
273+
target_address=0xFF,
274+
source_address=0xF1
275+
)
219276
rx_addrs = []
220277
for i in range(0xF0):
221278
if i != 0x33:
222-
rx_addr = isotp.Address(isotp.AddressingMode.NormalFixed_29bits, target_address=i, source_address=0xF1)
279+
rx_addr = isotp.Address(
280+
isotp.AddressingMode.NormalFixed_29bits,
281+
target_address=i,
282+
source_address=0xF1
283+
)
223284
rx_addrs.append(rx_addr)
224285

225286
try:
226-
payload = read_did(0xfa13, bus, notifier, tx_addr, rx_addrs, isotp.TargetAddressType.Functional, isotp_params)
287+
func = isotp.TargetAddressType.Functional
288+
payload = read_did(0xfa13, bus, notifier, tx_addr, rx_addrs, func, isotp_params)
227289
output_data(payload)
228-
payload = read_did(0xfa14, bus, notifier, tx_addr, rx_addrs, isotp.TargetAddressType.Functional, isotp_params)
290+
payload = read_did(0xfa14, bus, notifier, tx_addr, rx_addrs, func, isotp_params)
229291
output_data(payload)
230-
payload = read_did(0xfa15, bus, notifier, tx_addr, rx_addrs, isotp.TargetAddressType.Functional, isotp_params)
292+
payload = read_did(0xfa15, bus, notifier, tx_addr, rx_addrs, func, isotp_params)
231293
output_data(payload)
232294
except Exception as err:
233295
print(err)
@@ -237,7 +299,7 @@ def output_data(payload) -> bytearray:
237299
try:
238300
shutil.copy("format/README.md", "result/README.md")
239301
except FileNotFoundError:
240-
print(f"The source file format/README.md does not exist.")
302+
print("The source file format/README.md does not exist.")
241303
except PermissionError:
242304
print("You do not have the necessary permissions to read or write the file.")
243305
except Exception as err:

0 commit comments

Comments
 (0)