pylessard / python-udsoncan

Python implementation of UDS (ISO-14229) standard.
MIT License
564 stars 195 forks source link

Unable to read continuous frames #234

Closed EmperorHeyman closed 1 month ago

EmperorHeyman commented 1 month ago

Hello, I've got an issue with reading continuous frames: When I send 0xfd05 to the ECU I expect it to return with multiframe. This is what I see in canalyzer: Time Chn ID Name Event Type Dir DLC Data length Data ID / Name
[+] 61.970119 CAN 1 17FE009Cx ISOx_BMS_48V_Resp_XIX_HCP5_CANFD02 FF Rx 31 8 [10 1F] 62 FD 05 27 0F 27 17FE009Cx
[+] 61.970397 CAN 1 17FC009Cx ISOx_BMS_48V_Req_XIX_HCP5_CANFD02 FC.CTS Tx 0 8 [30 00 05 CC CC CC CC CC] 17FC009Cx
[+] 61.970552 CAN 1 17FC009Cx ISOx_BMS_48V_Req_XIX_HCP5_CANFD02 FC.CTS Rx 0 8 [30 20 00 CC CC CC CC CC] 17FC009Cx
[+] 61.970701 CAN 1 17FE009Cx ISOx_BMS_48V_Resp_XIX_HCP5_CANFD02 CF Rx 0 8 [21] 0F 27 0F 27 0F 27 0F 17FE009Cx
[+] 61.979542 CAN 1 17FE009Cx ISOx_BMS_48V_Resp_XIX_HCP5_CANFD02 CF Rx 0 8 [22] 27 0F 27 0F 27 0F 27 17FE009Cx
[+] 61.989514 CAN 1 17FE009Cx ISOx_BMS_48V_Resp_XIX_HCP5_CANFD02 CF Rx 0 8 [23] 0F 27 0F 27 0F 27 0F 17FE009Cx
[+] 61.999536 CAN 1 17FE009Cx ISOx_BMS_48V_Resp_XIX_HCP5_CANFD02 CF Rx 0 8 [24] 27 0F 27 0F [CC CC CC] 17FE009Cx
[+] 61.999536 CAN 1 17FE009Cx DID__CAPY_FADE Read::pos pos 31 62 FD 05 27 0F 27 0F 27 0F 27 0F 27 0F 27 0F 27 0F 27 0F 27 0F 27 0F 27 0F 27 0F 27 0F 27 0F

But the udsoncan library returs this: [UnexpectedResponseException] : ReadDataByIdentifier service execution returned a valid response but unexpected. Details : Server returned values for data identifier 0x270f that was not requested and no Codec was defined for it. Parsing must be stopped. did_payload: b"'\x0f" unpack requires a buffer of 28 bytes [UnexpectedResponseException] : ReadDataByIdentifier service execution returned a valid response but unexpected. Details : Server returned values for data identifier 0x270f that was not requested and no Codec was defined for it. Parsing must be stopped. [UnexpectedResponseException] : ReadDataByIdentifier service execution returned a valid response but unexpected. Details : Server returned values for data identifier 0x270f that was not requested and no Codec was defined for it. Parsing must be stopped.

this data is SOH of individual cells in AUDI battery.

Iam stuck at this and need help.

isotp config:

   __isotp_params = {
        'stmin': 0,
        'blocksize': 32,
        'wftmax': 5,
        'tx_data_length': 8,
        'tx_data_min_length': None,
        'tx_padding': 0xCC,
        'rx_flowcontrol_timeout': 1000,
        'rx_consecutive_frame_timeout': 1000,
        'override_receiver_stmin':None,
        'max_frame_size': 4095,
        'can_fd': True,    
        'bitrate_switch':True
    }

The configuration of what to send:

CONF={
    'AUDI': {
        'addr_mode': isotp.Address(isotp.AddressingMode.Normal_29bits,
                       txid=0x17FC009C,
                       rxid=0x17FE009C),
        'codecs': {
            0xfd05: audi_codecs.SOH,
            # 0xfe47: audi_codecs.PostVoltage,
        },
        'names': {
            0xfd05: 'soh',
            # 0xfe47: 'post_voltage',
        }
    }
}

codec:

class SOH(udsoncan.DidCodec):

        def decode(self, did_payload: bytes):
            try:
                # Reassemble the payload if it is in multiple frames
                # Assume payload is passed completely as 'did_payload'
                print(f'did_payload: {did_payload}')

                decoded_values = struct.unpack('>14H', did_payload)
                print(f'decoded_values: {decoded_values}')
                soh_values = [val * 0.1 for val in decoded_values]
                print(soh_values)
                return soh_values
            except Exception as e:
                print(e)

        def __len__(self):
            return 2

And this is the run function that reads from UDS:

    def run(self) -> None:
        time.sleep(1)
        if self._conn.error:
            return

        with Client(conn=self._isotp_connection) as client:
            client.set_config('request_timeout', 2)
            client.set_config('p2_timeout', 2.5)
            client.set_config('data_identifiers', self._codecs)

            self._codec_keys = set(self._codecs.keys())

            while self._conn.connection_active:

                for codec_key in self._codec_keys:

                    if codec_key in self._constant_dids:
                        continue

                    try:
                        response = client.read_data_by_identifier_first(codec_key)
                    except udsoncan.TimeoutException:
                        continue
                    except udsoncan.NegativeResponseException:
                        self._log_signal.emit(
                            f'ECU odpovědělo negativním kódem (DataIdentifier={hex(codec_key)}, '
                            f'Name: {self._names[codec_key]}) -- NegativeResponse',
                            'error')
                        self._error_signal.emit('ECU ERROR CANT READ -<br>BATTERY IN WRONG MODE?')                
                        return
                    except udsoncan.InvalidResponseException:
                        self._log_signal.emit(
                            f'ECU returned error -- InvalidResponse', 'error')  # noqa: F541
                        return
                    except udsoncan.UnexpectedResponseException:
                        continue
                    except udsoncan.ConfigError:
                        self._log_signal.emit(f'Wrong global uds config', 'error')  # noqa: F541
                        return

                    self.read_data(codec_key, response)

Iam using the newest version of the library 1.23.0 and can-isotp==2.0.4

EmperorHeyman commented 1 month ago

Nevermind, I found the issue. In the codec settings I thought that the len is the lenght of the data I was sending.

I've changed the len to 28 and it works now.