From c01f603cdaa8edf5497020f000756b2e168f4693 Mon Sep 17 00:00:00 2001 From: JoshuaArking Date: Fri, 4 Oct 2019 12:26:13 -0400 Subject: [PATCH] Rewrite of J1979 to use a pid dictionary rather than if - elif. --- Pipeline_multi-file/J1979.py | 100 +++++------------------------------ 1 file changed, 14 insertions(+), 86 deletions(-) diff --git a/Pipeline_multi-file/J1979.py b/Pipeline_multi-file/J1979.py index 6c1730c..a0364ca 100644 --- a/Pipeline_multi-file/J1979.py +++ b/Pipeline_multi-file/J1979.py @@ -1,97 +1,25 @@ from pandas import DataFrame, Series -from numpy import int8, float16, uint8, uint16 +from numpy import dtype class J1979: - def __init__(self, pid: int, original_data: DataFrame): + def __init__(self, pid: int, original_data: DataFrame, pid_dict: DataFrame): self.pid: int = pid - self.title: str = "" - self.data: Series = self.process_response_data(original_data) + self.title: str = pid_dict.at[pid, 'title'] + self.data: Series = self.process_response_data(original_data, pid_dict) print("Found " + str(self.data.shape[0]) + " responses for J1979 PID " + str(hex(self.pid)) + ":", self.title) - def process_response_data(self, original_data) -> Series: - # ISO-TP formatted Universal Diagnostic Service (UDS) requests that were sent by the CAN collection device - # during sampling. Request made using Arb ID 0x7DF with DLC of 8. Response should use Arb ID 7E8 (0x7DF + 0x8). - - # DataFrame Columns: b0 b1 b2 b3 ... b7 - # -- -- -- -- -- - # PID 0x0C (12 dec) (Engine RPM): 02 01 0c 00 ... 00 - # PID 0x0D (13 dec) (Vehicle Speed): 02 01 0d 00 ... 00 - # PID 0x11 (17 dec) (Trottle Pos.): 02 01 11 00 ... 00 - # PID 0x61 (97 dec) (Demand % Torque): 02 01 61 00 ... 00 - # PID 0x62 (98 dec) (Engine % Torque): 02 01 62 00 ... 00 - # PID 0x63 (99 dec) (Ref. Torque): 02 01 63 00 ... 00 - # PID 0x8e (142 dec) (Friction Torque): 02 01 8e 00 ... 00 - - # Responses being managed here should follow the ISO-TP + UDS per-byte format AA BB CC DD .. DD - # BYTE: AA BB CC DD ... DD - # USE: response size (bytes) UDS mode + 0x40 UDS PID response data - # DF COLUMN: b0 b1 b2 b3 ... b7 - - # Remember that this response data is already converted to decimal. Thus, byte BB = 65 = 0x41 = 0x01 + 0x40. - # If BB isn't 0x41, check what the error code is. Some error code are listed in the UDS chapter of the car - # hacker's handbook available at http://opengarages.org/handbook/ebook/. - if self.pid == 12: - self.title = 'Engine RPM' - # PID is 0x0C: Engine RPM. 2 byte of data AA BB converted using 1/4 RPM per bit: (256*AA+BB)/4 - # Min value: 0 Max value: 16,383.75 units: rpm - return Series(data=(256*original_data['b3']+original_data['b4'])/4, + def process_response_data(self, original_data, pid_dict) -> Series: + A = original_data['b3'] + B = original_data['b4'] + C = original_data['b5'] + D = original_data['b6'] + try: + return Series(data=pid_dict.at[self.pid, 'formula'](A,B,C,D), index=original_data.index, name=self.title, - dtype=float16) - elif self.pid == 13: - self.title = 'Speed km/h' - # PID is 0x0D: Vehicle Speed. 1 byte of data AA using 1km/h per bit: no conversion necessary - # Min value: 0 Max value: 255 (158.44965mph) units: km/h - return Series(data=original_data['b3'], - index=original_data.index, - name=self.title, - dtype=uint8) - elif self.pid == 17: - self.title = 'Throttle %' - # PID is 0x11: Throttle Position. 1 byte of data AA using 100/255 % per bit: AA * 100/255% throttle. - # Min value: 0 Max value: 100 units: % - return Series(data=100 * original_data['b3'] / 255, - index=original_data.index, - name=self.title, - dtype=uint8) - elif self.pid == 97: - self.title = 'Demand Torque %' - # PID is 0x61: Driver's demand engine - percent torque. 1 byte of data AA using 1%/bit with -125 offset - # AA - 125 - # Min value: -125 Max value: 130 units: % - return Series(data=original_data['b3'] - 125, - index=original_data.index, - name=self.title, - dtype=int8) - elif self.pid == 98: - self.title = 'Actual Torque %' - # PID is 0x62: Actual engine - percent torque. 1 byte of data AA using 1%/bit with -125 offset - # AA - 125 - # Min value: -125 Max value: 130 units: % - return Series(data=original_data['b3'] - 125, - index=original_data.index, - name=self.title, - dtype=int8) - elif self.pid == 99: - self.title = 'Reference Torque Nm' - # PID is 0x63: Engine reference torque. 2 byte of data AA BB using 1 Nm/bit: 256*AA + BB Nm torque - # Min value: 0 Max value: 65,535 units: Nm - return Series(data=256*original_data['b3'] + original_data['b4'], - index=original_data.index, - name=self.title, - dtype=uint16) - elif self.pid == 142: - self.title = 'Engine Friction Torque %' - # PID is 0x8E: Engine Friction - Percent Torque. 1 byte of data AA using 1%/bit with -125 offset. AA - 125 - # Min value: -125 Max value: 130 units: % - return Series(data=original_data['b3'] - 125, - index=original_data.index, - name=self.title, - dtype=int8) - else: - # Looks like you were requesting J1979 data with your sniffer that hasn't been implemented in this code. - # Time to do the leg work to expand this class accordingly then re-run the pipeline. + dtype=dtype(pid_dict.at[self.pid, 'formula'](A,B,C,D))) + except: raise ValueError("Encountered J1979 PID " + str(hex(self.pid)) + - " in Pre-Processing that hasn't been programmed. Expand the J1979 class to handle all " + " in Pre-Processing that hasn't been programmed. Expand the OBD2_pids.csv file to handle all " "J1979 requests made during data collection.")