mercedes-benz / odxtools

odxtools is a collection of utilities to interact with the diagnostic functionality of automotive electronic control units using python
MIT License
182 stars 76 forks source link

How to encode a ReadDataByIdentifier request? #160

Closed zzpbuaa closed 1 year ago

zzpbuaa commented 1 year ago

Hi guys, I'm trying to encode a ReadDataByIdentifier request. It should provide a DID, how can I do this? I don't have an ecu in my pdx file. So I tried to use function like db.diag_layers['myLayer'].services['ReadDataByIdentifier'].request.encode(). But I don't know how to pass the DID to the function encode() I can get DID list from db.diag_layers['myLayer'].diag_data_dictionary_spec.tables['TABLE_Service22_DataID'] for ReadDataByIdentifier because its did number is 22.

andlaus commented 1 year ago

if you call encode() for the request, it should complain about missing mandatory parameters. Alternatively you can use db.diag_layers.myLayer.services.ReadDataByIdentifier.request.print_free_parameters_info(). passing parameters works by simply passing them to the encode() method, e.g.

rq.encode(foo_param=123, bar="HELLO_TEXTTABLE_KEY")

note that encode() expects physical quantities, not unscaled ones...

zzpbuaa commented 1 year ago

Hi @andlaus, could you do me a favor to modify the layer name VC*S to myLayer** in your comment? It's my bad. Because this word may be a keyword related to my customer's information. I'm not sure if I'll be in trouble for unintentionally leaking this info or not. If you can help to modify it I'll appreciate it very much.

Back to the question, when I use 'print_free_parameters...', I got the below output:

DataIds : <optional> list({
  DataId : <unhandled parameter type>
})

It needs a DataId parameter, it's a composite type, not a simple type like int or string. So I don't know which type I should pass in.

andlaus commented 1 year ago

Back to the question, when I use 'print_free_parameters...', I got the below output:

this means that the kind of parameter used by DataIds is not yet implemented for en-/decoding. Amongst others, this could e.g. be STATIC-FIELD, DYNAMIC-FIELD, or TABLE-STRUCT. (I'm currently working on support for table parameters, but it will be a week or two until this is hits the main branch...) You can find out what it is via

dl = db.diag_layers.myLayer
rq = dl.services.ReadDataByIdentifier.request
param = rq.DataIds
print(param.parameter_type)

the name DataIds and the fact that is a list hints to the fact that it is a static or dynamic field...

zzpbuaa commented 1 year ago

After running the code, the parameter_type is "VALUE". param.dop is an EndOfPduField. param.dop.structure is a Structure "STRUCT_DataId_RQ". And STRUCT_DataId_RQ has a parameter DataId, type is "TABLE-KEY". I guess if I can pass in a dynamic "Table-KEY" object. It may work. I'm trying to find out how to create a "Table-KEY" object.

Btw, thanks very much for the modification to myLayer

andlaus commented 1 year ago

table key parameters in themselves do not make too much sense, as they only specify which row ought to apply to a subsequent table struct parameter (i.e., they are the multiplexor IDs of a multiplexer mechanism). As mentioned above, I'm currently working on table en- and decoding, so stay tuned for a few days/weeks...

andlaus commented 1 year ago

this seems to be solved? if it isn't, feel free to re-open the issue...