A2L

A2L parsing and writing library

list_of_strings

 list_of_strings (strings:str)

*split a string separated by ‘,’, ‘;’, or ‘’ to a list of strings. Descripttion: split a long string to a list of strings.

Args: strings (str): The string to split.

Returns: list: The list of strings.*

test_eq(list_of_strings(r'foo;123, bar ebi'), ['foo','123','bar','ebi'])
list_of_strings(r'"/PROJECT/MODULE[0]/MOD_COMMON, /PROJECT/IF_DATA[0]/Blob[0]/, /PROJECT/MODULE[0]/CHARACTERISTIC, TQD_trqTrqSetNormal_MAP_v"')
['"/PROJECT/MODULE[0]/MOD_COMMON',
 '/PROJECT/IF_DATA[0]/Blob[0]/',
 '/PROJECT/MODULE[0]/CHARACTERISTIC',
 'TQD_trqTrqSetNormal_MAP_v"']

JsonNodePathSegment

 JsonNodePathSegment (name:str, indices:list[int]=None,
                      index_range:list[int]=None)

*result of parsing json node path segment

Args: name (str): name of the node indices (list[int]): indices of the node index_range (list[int]): index range of the node

    if both indices and index_range are None, then the node is a dict, otherwise it is a list*

JsonNodePath

 JsonNodePath (node_path:str)

*result of parsing json node path

Args: segments (listJsonNodePathSegment): list of JsonNodePathSegment*

node_path = r"/PROJECT[0]/MODULE[0,3,5]/IF_DATA[3:2:8]/CHARACTERISTIC[3:5]/TQD_trqTrqSetNormal_MAP_v"
jnode_path = JsonNodePath(node_path)
print(jnode_path)
res = ['<PROJECT[0] list>', '<MODULE[0,3,5] list>', '<IF_DATA[3:2:8] list>', '<CHARACTERISTIC[3:5] list>', '<TQD_trqTrqSetNormal_MAP_v dict>'] 
for (s,r) in zip(jnode_path,res):
    print(s)
    test_eq(s.__str__(), r)
<JsonNodePath [<PROJECT[0] list>, <MODULE[0,3,5] list>, <IF_DATA[3:2:8] list>, <CHARACTERISTIC[3:5] list>, <TQD_trqTrqSetNormal_MAP_v dict>]>
<PROJECT[0] list>
<MODULE[0,3,5] list>
<IF_DATA[3:2:8] list>
<CHARACTERISTIC[3:5] list>
<TQD_trqTrqSetNormal_MAP_v dict>

get_argparser

 get_argparser ()

*Get the argument parser for the command line interface. Descripttion: Get the argument parser for the command line interface.

Returns: argparse.ArgumentParser: The argument parser for the command line interface.*

# jnode_paths = []
# for p in args.node_paths:
#   print(p)
#   jnode_path = JsonNodePath(p)
#   print(jnode_path)
#   jnode_paths.append(jnode_path)
#   pprint(jnode_path.lazy_path)
#   pprint(re.split(r'\.', jnode_path.lazy_path)) 
#   pprint(jnode_path.leaf.name)
#   print()
print(args.node_path)
jnode_path = JsonNodePath(args.node_path)
print(jnode_path)
pprint(jnode_path.lazy_path)
pprint(re.split(r'\.', jnode_path.lazy_path)) 
pprint(jnode_path.leaf.name)
print()
# node_path = r"/PROJECT/MODULE[]/CHARACTERISTIC[]"
# node_path = args.node_path
# jnode_path = JsonNodePath(node_path)
# res = ['<PROJECT[0] list>', '<MODULE[0,3,5] list>', '<IF_DATA[3:2:8] list>', '<CHARACTERISTIC[3:5] list>', '<TQD_trqTrqSetNormal_MAP_v dict>'] 
for s in jnode_path:
    print(s)
/PROJECT/MODULE[], 
<JsonNodePath [<PROJECT dict>, <MODULE[] list>]>
'PROJECT.MODULE.item'
['PROJECT', 'MODULE', 'item']
'MODULE'

<PROJECT dict>
<MODULE[] list>
node_path = r"/PROJECT/MODULE[]/CHARACTERISTIC[]"
re.split(r',\s*|;\s*|/\s*|\s+', node_path)  
re.split('(?:\[\d\])',  'foo, a[0], bar')
['', 'PROJECT', 'MODULE[]', 'CHARACTERISTIC[]']
['foo, a', ', bar']
prog = re.compile('(\[\d\])')
result = prog.search('/PROJECT/MODULE[0]/CHARACTERISTIC[0]').group(1)
print(result)
[0]
re.search('(?:\[(\d)\])',  'foo, a[0], bar').groups()
re.search('(?:\[(\d,?\s*\d*)\])',  'foo, a[0, 4], bar').groups()
('0',)
('0, 4',)
try:
    res = re.search('(?:\[(\d+),?\s*(\d*)\])',  'foo, a[0, 24], bar').groups()
    print(res)
    # re.search('(?:\[(\d,?\s*\d*)\])', 'foo, a[0, 4], bar').groups()
except AttributeError as exc:
    print(exc)
('0', '24')
try:
    res = re.search('(?:\[(\d+),?\s*(\d*)\])',  'foo, bar').groups()
    print(res)
    # re.search('(?:\[(\d,?\d*)\])',  'foo').groups()
except AttributeError as exc:
    print(exc)
'NoneType' object has no attribute 'groups'
# node_path = args.node_paths[0]
test_node_path = r"/PROJECT[0]/MODULE[0,3,5]/IF_DATA[3:2:8]/CHARACTERISTIC[3:5]/TQD_trqTrqSetNormal_MAP_v"
path_segments = re.split(r'/\s*', test_node_path)[1:]
print(path_segments)
['PROJECT[0]', 'MODULE[0,3,5]', 'IF_DATA[3:2:8]', 'CHARACTERISTIC[3:5]', 'TQD_trqTrqSetNormal_MAP_v']
# prefix = '.'.join(jnode_path.lazy_path.split('.')[:-1])
prefix = JsonNodePath(args.node_path).lazy_path
args.path, prefix
objects = ijson.items(open(args.path, 'r'), prefix)
module_items = list(objects)[0]
# pprint(module_items)
pprint(module_items['CHARACTERISTIC'][0]['Name'])
print('\n')
l = {k:v for k,v in module_items['CHARACTERISTIC'][0]['AXIS_DESCR'][0].items()}
pprint(l)
('/home/n/devel/candycan/res/vbu_sample.json', 'PROJECT.MODULE.item')
{'Value': 'TQD_trqTrqSetNormal_MAP_v'}


{'AXIS_PTS_REF': {'AxisPoints': {'Value': 'TQD_vSgndSpd_MAP_y'}},
 'Attribute': 'COM_AXIS',
 'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
 'InputQuantity': {'Value': 'TQD_vVehSpd'},
 'LowerLimit': {'DecimalSize': 5,
                'IntegralSign': '-',
                'IntegralSize': 1,
                'Value': Decimal('-3.4E+38')},
 'MaxAxisPoints': {'Base': 10, 'Size': 2, 'Value': 14},
 'UpperLimit': {'DecimalSize': 5,
                'IntegralSize': 1,
                'Value': Decimal('3.4E+38')}}
args.path, args.node_path, args.leaves
('/home/n/devel/candycan/res/vbu_sample.json',
 '/PROJECT/MODULE[], ',
 ['TQD_trqTrqSetNormal_MAP_v',
  'VBU_L045A_CWP_05_09T_AImode_CM_single',
  'Lookup2D_FLOAT32_IEEE',
  'Lookup2D_X_FLOAT32_IEEE',
  'Scalar_FLOAT32_IEEE',
  'TQD_vVehSpd',
  'TQD_vSgndSpd_MAP_y',
  'TQD_pctAccPedPosFlt',
  'TQD_pctAccPdl_MAP_x'])
calibs = []
node_paths = [r"/PROJECT/MODULE[]/CHARACTERISTIC[]",
            r"/PROJECT/MODULE[]/MEASUREMENT[]",
            r"/PROJECT/MODULE[]/AXIS_PTS[]",
            r"/PROJECT/MODULE[]/COMPU_METHOD[]"]
jnode_paths = [JsonNodePath(p) for p in node_paths]

for jp in jnode_paths:
    prefix = jp.lazy_path
    objects = ijson.items(open(args.path, "r"), prefix)
    # calib = [o for o in objects for k, v in o.items() if k == 'Name']
    # pprint(calib)
    # len(calib)
    # print(prefix)
    for o in objects:
        for k, v in o.items():
            if k == 'Name':
                if v['Value'] in args.leaves:
                    calibs.append(o)

pprint(calibs[3])
# calib['LowerLimit']['Value'], calib['UpperLimit']['Value']
    
# for c in calibs:
#   pprint(c)
{'Address': {'Base': 16, 'Size': 8, 'Value': '1879071450'},
 'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
 'DepositR': {'Value': 'Lookup2D_X_FLOAT32_IEEE'},
 'InputQuantity': {'Value': 'TQD_vVehSpd'},
 'LongIdentifier': {},
 'LowerLimit': {'DecimalSize': 5,
                'IntegralSign': '-',
                'IntegralSize': 1,
                'Value': Decimal('-3.4E+38')},
 'MaxAxisPoints': {'Base': 10, 'Size': 2, 'Value': 14},
 'MaxDiff': {},
 'Name': {'Value': 'TQD_vSgndSpd_MAP_y'},
 'UpperLimit': {'DecimalSize': 5,
                'IntegralSize': 1,
                'Value': Decimal('3.4E+38')}}

Bunch

 Bunch (key, **kwargs)

collector of a bunch of named stuff into one object; a generic record/struct type, indexed by keys


Record

 Record (**kwargs)

object with dynamic attributes


Calibration

 Calibration (**kwargs)

*Target calibration object for torque map; a2l section [“PROJECT”][“MODULE”][“CHARACTERISTIC”]

First level keys will be turned into attributes of the object, encoded registered values will be replaced with the corresponding objects. Otherwiese the key-value pairs will be kept as is.*


Measurement

 Measurement (**kwargs)

Measurement object like speed, acc pedal position, etc; a2l section [“PROJECT”][“MODULE”][“MEAUREMENT”]]


AxisScale

 AxisScale (**kwargs)

Target calibration object for torque map; a2l section [“PROJECT”][“MODULE”][“AXIS_PTS”]


DataConversion

 DataConversion (**kwargs)

Data conversion object for calibration; a2l section [“PROJECT”][“MODULE”][“COMPU_METHOD”]]


DataLayout

 DataLayout (**kwargs)

Data type object for calibration; a2l section [“PROJECT”][“MODULE”][“RECORD_LAYOUT”]

Record.subclass_registry
{'CHARACTERISTIC': 'Calibration',
 'MEASUREMENT': 'Measurement',
 'AXIS_PTS': 'AxisScale',
 'COMPU_METHOD': 'DataConversion',
 'RECORD_LAYOUT': 'DataLayout'}

load_class_type_a2l_lazy

 load_class_type_a2l_lazy (path:pathlib.Path,
                           jnode_path:Optional[__main__.JsonNodePath]=<Jso
                           nNodePath [<PROJECT dict>, <MODULE[] list>]>)

*Search for the calibration key in the A2L file. Descripttion: Load the A2L file as a dictionary.

Create record type (enum class) for the calibration parameter for the given a2l json file

Args: path (str): The path to the A2L file. section_key (str): The section key to search for the calibration type.

Returns: dict: The A2L file as a dictionary.*

Type Default Details
path Path
jnode_path OptionalJsonNodePath <JsonNodePath [, <MODULE[] list>]>
Returns type(Enum) return a class type
pprint(RecordTypes)
set(RecordTypes.__members__.keys())
Record.record_registry
<enum 'RecordType'>
{'AXIS_PTS',
 'CHARACTERISTIC',
 'COMPU_METHOD',
 'GROUP',
 'IF_DATA',
 'LongIdentifier',
 'MEASUREMENT',
 'MOD_COMMON',
 'MOD_PAR',
 'Name',
 'RECORD_LAYOUT'}

load_records_lazy

 load_records_lazy (path:pathlib.Path, leaves:list[str],
                    jnode_path:Optional[__main__.JsonNodePath]=<JsonNodePa
                    th [<PROJECT dict>, <MODULE[] list>]>)

*load records from a json file lazily

Args: path (Path): path to the json file # use ijson no need for jnode_paths, though sacrificing a little bit efficiency (listJsonNodePath): list of JsonNodePath to the leaves leaves (list[str]): list of leaf indices to the records, needs to be unique and in the first item of the a2l json file

Returns: dict[str, Record]: dict of Records and its subclasses, indexed by the leaf indices*

# jnode_path = '.'.join(jnode_paths[0].lazy_path.split('.')[:-2])
args.path, args.leaves, args.node_path
('/home/n/devel/candycan/res/vbu_sample.json',
 ['TQD_trqTrqSetNormal_MAP_v',
  'VBU_L045A_CWP_05_09T_AImode_CM_single',
  'Lookup2D_FLOAT32_IEEE',
  'Lookup2D_X_FLOAT32_IEEE',
  'Scalar_FLOAT32_IEEE',
  'TQD_vVehSpd',
  'TQD_vSgndSpd_MAP_y',
  'TQD_pctAccPedPosFlt',
  'TQD_pctAccPdl_MAP_x'],
 '/PROJECT/MODULE[], ')
Record.load_records(args.path, args.leaves, JsonNodePath(args.node_path)) #, jnode_path= args.node_path.lazy_path)
Record.subclass_registry
sorted(Record.record_registry)
{'CHARACTERISTIC': 'Calibration',
 'MEASUREMENT': 'Measurement',
 'AXIS_PTS': 'AxisScale',
 'COMPU_METHOD': 'DataConversion',
 'RECORD_LAYOUT': 'DataLayout'}
['AxisScale.TQD_pctAccPdl_MAP_x',
 'AxisScale.TQD_vSgndSpd_MAP_y',
 'Calibration.TQD_trqTrqSetNormal_MAP_v',
 'DataConversion.VBU_L045A_CWP_05_09T_AImode_CM_single',
 'DataLayout.Lookup2D_FLOAT32_IEEE',
 'DataLayout.Lookup2D_X_FLOAT32_IEEE',
 'DataLayout.Scalar_FLOAT32_IEEE',
 'Measurement.TQD_pctAccPedPosFlt',
 'Measurement.TQD_vVehSpd']
args.leaves
['TQD_trqTrqSetNormal_MAP_v',
 'VBU_L045A_CWP_05_09T_AImode_CM_single',
 'Lookup2D_FLOAT32_IEEE',
 'Lookup2D_X_FLOAT32_IEEE',
 'Scalar_FLOAT32_IEEE',
 'TQD_vVehSpd',
 'TQD_vSgndSpd_MAP_y',
 'TQD_pctAccPedPosFlt',
 'TQD_pctAccPdl_MAP_x']
records = load_records_lazy(args.path, args.leaves, JsonNodePath(args.node_path))
pprint(list(records.keys()))
len(records)
key = 'AxisScale.' + args.leaves[6]
print(key)
measurement = records[key]
measurement, measurement.record_type, 
measurement.__dict__
key = 'AxisScale.' + args.leaves[8]
print(key)
measurement = records[key]
measurement, measurement.record_type, 
measurement.__dict__
['Calibration.TQD_trqTrqSetNormal_MAP_v',
 'Measurement.TQD_vVehSpd',
 'Measurement.TQD_pctAccPedPosFlt',
 'AxisScale.TQD_vSgndSpd_MAP_y',
 'AxisScale.TQD_pctAccPdl_MAP_x',
 'DataConversion.VBU_L045A_CWP_05_09T_AImode_CM_single',
 'DataLayout.Scalar_FLOAT32_IEEE',
 'DataLayout.Lookup2D_FLOAT32_IEEE',
 'DataLayout.Lookup2D_X_FLOAT32_IEEE']
AxisScale.TQD_vSgndSpd_MAP_y
AxisScale.TQD_pctAccPdl_MAP_x
9
(<AxisScale: 'TQD_vSgndSpd_MAP_y'>, <DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>)
{'Name': 'TQD_vSgndSpd_MAP_y',
 'LongIdentifier': {},
 'Address': {'Value': '1879071450', 'Base': 16, 'Size': 8},
 'InputQuantity': {'Value': 'TQD_vVehSpd'},
 'DepositR': {'Value': 'Lookup2D_X_FLOAT32_IEEE'},
 'MaxDiff': {},
 'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
 'MaxAxisPoints': {'Value': 14, 'Base': 10, 'Size': 2},
 'LowerLimit': {'Value': Decimal('-3.4E+38'),
  'IntegralSign': '-',
  'IntegralSize': 1,
  'DecimalSize': 5},
 'UpperLimit': {'Value': Decimal('3.4E+38'),
  'IntegralSize': 1,
  'DecimalSize': 5},
 'record_type': <DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>}
(<AxisScale: 'TQD_pctAccPdl_MAP_x'>, <DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>)
{'Name': 'TQD_pctAccPdl_MAP_x',
 'LongIdentifier': {},
 'Address': {'Value': '1879073310', 'Base': 16, 'Size': 8},
 'InputQuantity': {'Value': 'TQD_pctAccPedPosFlt'},
 'DepositR': {'Value': 'Lookup2D_X_FLOAT32_IEEE'},
 'MaxDiff': {},
 'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
 'MaxAxisPoints': {'Value': 17, 'Base': 10, 'Size': 2},
 'LowerLimit': {'Value': Decimal('-3.4E+38'),
  'IntegralSign': '-',
  'IntegralSize': 1,
  'DecimalSize': 5},
 'UpperLimit': {'Value': Decimal('3.4E+38'),
  'IntegralSize': 1,
  'DecimalSize': 5},
 'record_type': <DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>}
key = 'Measurement.' + args.leaves[5]
print(key)
measurement = records[key]
measurement, measurement.record_type, 
measurement.__dict__
key = 'Measurement.' + args.leaves[7]
print(key)
measurement = records[key]
measurement, measurement.record_type, 
measurement.__dict__
Measurement.TQD_vVehSpd
Measurement.TQD_pctAccPedPosFlt
(<Measurement: 'TQD_vVehSpd'>, <DataLayout: 'Scalar_FLOAT32_IEEE'>)
{'Name': 'TQD_vVehSpd',
 'LongIdentifier': {},
 'DataType': {'Value': 'FLOAT32_IEEE'},
 'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
 'Resolution': {'Base': 10, 'Size': 1},
 'Accuracy': {},
 'LowerLimit': {'Value': Decimal('-3.4E+38'),
  'IntegralSign': '-',
  'IntegralSize': 1,
  'DecimalSize': 5},
 'UpperLimit': {'Value': Decimal('3.4E+38'),
  'IntegralSize': 1,
  'DecimalSize': 5},
 'ECU_ADDRESS': {'Address': {'Value': '1879113976', 'Base': 16, 'Size': 8}},
 'record_type': <DataLayout: 'Scalar_FLOAT32_IEEE'>}
(<Measurement: 'TQD_pctAccPedPosFlt'>, <DataLayout: 'Scalar_FLOAT32_IEEE'>)
{'Name': 'TQD_pctAccPedPosFlt',
 'LongIdentifier': {},
 'DataType': {'Value': 'FLOAT32_IEEE'},
 'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
 'Resolution': {'Base': 10, 'Size': 1},
 'Accuracy': {},
 'LowerLimit': {'Value': Decimal('-3.4E+38'),
  'IntegralSign': '-',
  'IntegralSize': 1,
  'DecimalSize': 5},
 'UpperLimit': {'Value': Decimal('3.4E+38'),
  'IntegralSize': 1,
  'DecimalSize': 5},
 'ECU_ADDRESS': {'Address': {'Value': '1879113888', 'Base': 16, 'Size': 8}},
 'record_type': <DataLayout: 'Scalar_FLOAT32_IEEE'>}
key = 'DataLayout.' + args.leaves[4]
print(key)
record_type = records[key]
record_type, record_type.data_type, 
record_type.__dict__
key = 'DataLayout.' + args.leaves[3]
print(key)
record_type = records[key]
record_type, record_type.data_type, 
record_type.__dict__
DataLayout.Scalar_FLOAT32_IEEE
DataLayout.Lookup2D_X_FLOAT32_IEEE
(<DataLayout: 'Scalar_FLOAT32_IEEE'>, 'FLOAT32_IEEE')
{'Name': 'Scalar_FLOAT32_IEEE',
 'FNC_VALUES': {'Position': {'Value': 1, 'Base': 10, 'Size': 1},
  'DataType': {'Value': 'FLOAT32_IEEE'},
  'IndexMode': 'COLUMN_DIR',
  'AddressType': {'Value': 'DIRECT'}}}
(<DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>, 'FLOAT32_IEEE')
{'Name': 'Lookup2D_X_FLOAT32_IEEE',
 'AXIS_PTS_X': {'Position': {'Value': 1, 'Base': 10, 'Size': 1},
  'DataType': {'Value': 'FLOAT32_IEEE'},
  'IndexIncr': {'Value': 'INDEX_INCR'},
  'Addressing': {'Value': 'DIRECT'}}}
key = 'Calibration.' + args.leaves[0]
print(key)
records[key]
Calibration.TQD_trqTrqSetNormal_MAP_v
<Calibration: 'TQD_trqTrqSetNormal_MAP_v'>
calib = Record.fetch(key)
pprint(calib)

calib.axes[0].axis_scale.input
calib.axes[0].axis_scale.input.record_type
calib.axes[0].axis_scale.input.record_type.type_size
<Calibration: 'TQD_trqTrqSetNormal_MAP_v'>
<Measurement: 'TQD_vVehSpd'>
<DataLayout: 'Scalar_FLOAT32_IEEE'>
4
calib.record_type
calib.record_type.data_type
calib.record_type.type_size
calib.axes[0].axis_scale.record_type.type_size
<DataLayout: 'Lookup2D_FLOAT32_IEEE'>
'FLOAT32_IEEE'
4
4
calib.axes[0].axis_scale.input.record_type
calib.axes[0].axis_scale.input.record_type.type_size
calib.axes[0].axis_scale.data_conversion
calib.axes[0].data_conversion.Format
<DataLayout: 'Scalar_FLOAT32_IEEE'>
4
<DataConversion: 'VBU_L045A_CWP_05_09T_AImode_CM_single'>
{'Value': '%8.6'}
for k,v in records.items():
    pprint(v)

pprint(records['Calibration.TQD_trqTrqSetNormal_MAP_v'].axes[0].measurement.data_conversion.Name)
<Calibration: 'TQD_trqTrqSetNormal_MAP_v'>
<Measurement: 'TQD_vVehSpd'>
<Measurement: 'TQD_pctAccPedPosFlt'>
<AxisScale: 'TQD_vSgndSpd_MAP_y'>
<AxisScale: 'TQD_pctAccPdl_MAP_x'>
<DataConversion: 'VBU_L045A_CWP_05_09T_AImode_CM_single'>
<DataLayout: 'Scalar_FLOAT32_IEEE'>
<DataLayout: 'Lookup2D_FLOAT32_IEEE'>
<DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>
'VBU_L045A_CWP_05_09T_AImode_CM_single'
'0' < '1'
True

XCPConfig

 XCPConfig (channel:typing.Annotated[int,Ge(ge=0),Le(le=10000)]=3,
            download:typing.Annotated[int,Ge(ge=0),Lt(lt=10000)]=630,
            upload:typing.Annotated[int,Ge(ge=0),Lt(lt=10000)]=631)

XCP configuration for the calibration parameter

config = XCPConfig(channel=3, download=630, upload=631)
c = config.model_dump()
pprint(c)
# {**c}
# type(config.download_can_id), config.download_can_id, config.channel
# config.model_dump()
config.model_json_schema()
{'channel': 3, 'download_can_id': 630, 'upload_can_id': 631}
{'description': 'XCP configuration for the calibration parameter',
 'properties': {'channel': {'default': 3,
   'description': 'XCP channel',
   'maximum': 10000,
   'minimum': 0,
   'title': 'Channel',
   'type': 'integer'},
  'download': {'default': 630,
   'description': 'CAN ID for downloading',
   'exclusiveMaximum': 10000,
   'minimum': 0,
   'title': 'Download',
   'type': 'integer'},
  'upload': {'default': 631,
   'description': 'CAN ID for uploading',
   'exclusiveMaximum': 10000,
   'minimum': 0,
   'title': 'Upload',
   'type': 'integer'}},
 'title': 'XCPConfig',
 'type': 'object'}

check_a2l_type

 check_a2l_type (v:str)
class MyModel(BaseModel):
    foo: A2LDataType

try:
    m = MyModel(foo='FLOAT32_IEEE1')
except ValidationError as exc:
    print(exc)
1 validation error for MyModel
foo
  Assertion failed, Invalid data type FLOAT32_IEEE1 [type=assertion_error, input_value='FLOAT32_IEEE1', input_type=str]
    For further information visit https://errors.pydantic.dev/2.6/v/assertion_error
t = A2LDataType('FLOAT32_IEEE')
t in type_collection
t = A2LDataType(23)
t
t in type_collection
True
'23'
False
'FLOAT32_IEEE1' in type_collection
t = A2LDataType('FLOAT32_IEEE1')
t
t in type_collection
k
False
'FLOAT32_IEEE1'
False
'DataLayout.Lookup2D_X_FLOAT32_IEEE'
# Testing forward referencing
class MyClass:
    def __init__(self, value: int):
        self.value = value

    def compare(self, other: MyClass):  # this is default for python 3.7+ or "other: 'MyClass'"
        if self.value > other.value:
            print("This instance has a greater value.")
        else:
            print("The other instance has a greater or equal value.")

# Create instances
instance1 = MyClass(10)
instance2 = MyClass(5)

# Call the compare method on instance1, passing instance2 as an argument
instance2.compare(instance1)  # Output: "This instance has a greater value."
The other instance has a greater or equal value.
def func_a():
    print(func_b())  # Forward reference to func_b

def func_b():
    return "Hello from func_b!"

func_a()  # Output: "Hello from func_b!"
Hello from func_b!

XCPData

 XCPData (name:str='TQD_trqTrqSetNormal_MAP_v', address:Annotated[Optional
          [str],_PydanticGeneralMetadata(pattern='^[0-9A-Fa-
          f]{8}$')]='7000aa2a', dim:Annotated[List[Annotated[int,FieldInfo
          (annotation=NoneType,required=True,frozen=True,metadata=[Gt(gt=0
          ),Lt(lt=50)])]],Len(min_length=2,max_length=2)], value_type:typi
          ng.Annotated[str,AfterValidator(func=<functioncheck_a2l_typeat0x
          7f1cede5ab60>)]='FLOAT32_IEEE', value_length:typing.Annotated[in
          t,Gt(gt=0),MultipleOf(multiple_of=2)]=4, value:typing.Annotated[
          str,MinLen(min_length=1),MaxLen(max_length=3000),_PydanticGenera
          lMetadata(pattern='^[0-9A-Fa-f]{0,3000}$')])

XCP data for the calibration parameter


Get_Init_XCPData

 Get_Init_XCPData
                   (path:pathlib.Path=Path('../res/init_value_17rows.json'
                   ))
try:
    xcp_data_list = Get_Init_XCPData('../res/init_value_17rows.json')
    len(xcp_data_list)
except ValidationError as exc:
    print(exc)
# xcp_data[0], f'value byte length: {len(xcp_data[0].value)}'
# xcp_data[1], f'value byte length: {len(xcp_data[1].value)}'
2
xcp_data_list[0].value_bytes[:2], f"{xcp_data_list[0].value_bytes[:2].hex()}"
xcp_data_list[0]
len(xcp_data_list[0].value_bytes), len(xcp_data_list[0].value)
(b'\x1fZ', '1f5a')
{   'address': '7000aa2a',
    'dim': [21, 17],
    'name': 'TQD_trqTrqSetNormal_MAP_v',
    'type_size': 4,
    'value': '1f5a84441f...444',
    'value_array_view': array([[ 1058.816,  1058.816,  1058.816, ...,  4075.653,  4435.98 ,
         4435.98 ],
       [   70.079,   152.178,   234.277, ...,  4026.657,  4526.757,
         4526.757],
       [-3235.127, -1510.53 ,   214.067, ...,  4006.447,  4566.45 ,
         4566.45 ],
       ...,
       [-2999.402, -2441.199, -1882.996, ...,  1958.867,  1984.853,
         1984.853],
       [-2973.497, -2419.99 , -1866.482, ...,  1810.322,  1826.58 ,
         1826.58 ],
       [-2946.278, -2461.24 , -1976.201, ...,  1667.968,  1826.58 ,
         1826.58 ]], dtype=float32),
    'value_bytes': "b'\\x1f'...b'D'",
    'value_length': 4,
    'value_type': 'FLOAT32_IEEE'}
(1428, 2856)
t = tuple(xcp_data_list[0].dim)
t
xcp_data_0 = xcp_data_list[0].value_array_view
xcp_data_0
(21, 17)
array([[ 1058.816,  1058.816,  1058.816, ...,  4075.653,  4435.98 ,
         4435.98 ],
       [   70.079,   152.178,   234.277, ...,  4026.657,  4526.757,
         4526.757],
       [-3235.127, -1510.53 ,   214.067, ...,  4006.447,  4566.45 ,
         4566.45 ],
       ...,
       [-2999.402, -2441.199, -1882.996, ...,  1958.867,  1984.853,
         1984.853],
       [-2973.497, -2419.99 , -1866.482, ...,  1810.322,  1826.58 ,
         1826.58 ],
       [-2946.278, -2461.24 , -1976.201, ...,  1667.968,  1826.58 ,
         1826.58 ]], dtype=float32)
a = xcp_data_list[0].value_array_view
a.shape, a.dtype
a
((21, 17), dtype('float32'))
array([[ 1058.816,  1058.816,  1058.816, ...,  4075.653,  4435.98 ,
         4435.98 ],
       [   70.079,   152.178,   234.277, ...,  4026.657,  4526.757,
         4526.757],
       [-3235.127, -1510.53 ,   214.067, ...,  4006.447,  4566.45 ,
         4566.45 ],
       ...,
       [-2999.402, -2441.199, -1882.996, ...,  1958.867,  1984.853,
         1984.853],
       [-2973.497, -2419.99 , -1866.482, ...,  1810.322,  1826.58 ,
         1826.58 ],
       [-2946.278, -2461.24 , -1976.201, ...,  1667.968,  1826.58 ,
         1826.58 ]], dtype=float32)
# xcp_data[0].hex_to_float(a)
# s = ''.join([h[i:i+2] for i in range(0, len(h), 2)][::-1])
# xcp_data[0].value
b = bytes.fromhex(xcp_data_list[0].value)  # fromhex() takes a string and returns a bytes object
b.hex()
xcp_data_list[0].value
b[0], b[1]
hex(b[0])
hex(b[1])
'1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444'
'1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444'
(31, 90)
'0x1f'
'0x5a'
bb = bytes.fromhex(xcp_data_list[0].value)[::-1]
len(bb), len(xcp_data_list[0].value), xcp_data_list[0].dim
bb
(1428, 2856, [21, 17])
b'D\xe4R\x8fD\xe4R\x8fD\xd0~\xfbD\xab\xed8D\x87[vDj%)DE\x93gD!\x01\xa4D\x08\xa0xC\xe0~\x97\xc2\x102@\xc4\x02E\x94\xc4{\x88\x04\xc4\xbae:\xc4\xf7\x06r\xc5\x19\xd3\xd5\xc58$qD\xe4R\x8fD\xe4R\x8fD\xe2JPD\xb9\xa8\\D\x91\x06gDyj\xdaDP\xc8\xe5D(&\xf1D\r\x10NC\xe3\xf3UC\xad\xc6\x0f\xc3M\xf5\xc5\xc4=\xdd\xea\xc4\xa4\x1f1\xc4\xe9On\xc5\x17?\xd5\xc59\xd7\xf3D\xf8\x1bND\xf8\x1bND\xf4\xdb\xbcD\xc8)\x96D\x9bwoD\x85\x1e\\D]\x8a\x91D0\xd8kD\x13\x0cQC\xea\x80nC\xae\xe8;\xc3Pcn\xc4?\xa5\xd4\xc4\xa5\x99g\xc4\xeb_\xe3\xc5\x18\x930\xc5;vnE\x02xRE\x02xRE\x02xRD\xd7p\xe7D\xa6\xae\x8eD\x8eMbDk\xd8kD;\x16\x12D\x1a\x94\x82C\xf4%\xe3C\xb3"\xc2\xc3Mpj\xc4@I\x96\xc4\xa6\x9b\x89\xc4\xed\x12G\xc5\x19\xc4\x82\xc5<\xff\xe1E\tsmE\tsmE\tsmD\xe7~OD\xb2\xab\xc4D\x98B\x7fD{\xb2sDF\xdf\xe8D#\xa8\xe1D\x00q\xdaC\xbau\xa5\xc3E\x1c\xba\xc4?\xc9/\xc4\xa7%\x98\xc4\xeef\x99\xc5\x1a\xd3\xcd\xc5>tME\x18M\xd5E\x18M\xd5E\x18M\xd5D\xf8Q\xcdD\xbfo\x11D\xa2\xfd\xb2D\x86\x8cTDT5\xebD.ImD\x08\\\xefC\xc4\xe0\xe3Cr\x0f\xcf\xc3\xd2\x19.\xc4\x87N\x91\xc4\xda\x16\xd6\xc5\x16o\x8e\xc5?\xd3\xb1E\'(=E\'(=E#o)E\x04\xf5\xb2D\xcc\xf8tD\xae~\xfdD\x90\x05\x85Dc\x18\x1cD:v(D\x11\xd43C\xd2d}C\x81 \x94\xc3\xcd\xaf\x9e\xc4\x87\x1f\xf4\xc4\xda\xd4\x01\xc5\x17D\x07\xc5A\x1e\rE%\xb3\x9aE%\xb3\x9aE%\xb3\x9aE\x0c\xcb\x85D\xd9AGD\xb9\x16fD\x98\xeb\x84Dq\x81EDF\x9dnD\x1b\xb9\x97C\xe1\xab~C\x8b\xe3\xcf\xc3\xc7\x02\\\xc4\x86z"\xc4\xdb3\xad\xc5\x17\xf6\x9c\xc5BSaE5\xb6\x94E5\xb6\x94E5\xb6\x94E\x14\xf7dD\xe660D\xc4Y\xe5D\xa2}\x99D\x80\xa1MDT\x1c\xe0D&\xf7%C\xf3\xa2\xd6C\x99Wa\xc3\xbe\x0c\xc9\xc4\x85\\=\xc4\xdb5G\xc5\x18\x87)\xc5Cs\xaeESkdESkdE<\xac\xc7E\x19\xf7\xc6D\xee\x85\x8aD\xcb\xd0\x89D\xa9\x1b\x88D\x86f\x87D^\x86bD0?\xb7D\x01\xf9\x0bC\xa7d\xbe\xc3\xb4z\x87\xc4\x84\x16s\xc4\xdb\x0eD\xc5\x19\x03\x0b\xc5D~\xf3Eb\x91\xdcEb\x91\xdcEB\xbbgE\x1f-\xb1D\xf7?\xf6D\xd3\xb2@D\xb0$\x8aD\x8c\x96\xd4Di\xc6\nD:^mD\n\xf6\xd0C\xb7\x1eeC0\x9eT\xc4$W\x81\xc4\xbakK\xc5\x11Uk\xc5Eu1EqlDEme\xfbEH\xff\x90E$\x99%E\x002\xbaD\xdb\xff\tD\xb7\x98\x9eD\x9323Du\xdb\xd7DESHD\x14\xca\xb9C\xc8\x84UCN\xe6p\xc4\x1f\x8b1\xc4\xb9g\xff\xc5\x11\x853\xc5FVfE\x85\xf5\xdfEt\xb8cEOyCE*:#E\x04\xfb\x02D\xe4\xb6\xe5D\xbfw\xc5D\x9a8\xa4D\x81c\xe4DQ\x1eHD\x1ft\xc8C\xdb\x96\x90Cp\x87\x1f\xc4\x1a\t?\xc4\xb8\x1a#\xc5\x11\x97\xd3\xc5G"\x94E\x8a\x9f\xd7E{)#EU<\xa5E/P\'E\tc\xa9D\xec\xda\xd5D\xc6\xeeWD\xa1\x01\xd9D\x87\xb9\x85D\\\xe2cD*Q\xbbC\xef\x82\'C\x8a`\xd7\xc4\x13\xf5j\xc4\xb6\x8d\xa0\xc5\x11\x90E\xc5G\xd9\xbbE\x8a\x9f\xd7E\x80\xe4vE[/\x10E4\x955E\r\xfbYD\xf5\\\xd7D\xce\xc2\xfcD\xa8) D\x8em8Dib\xa1D5\xea\xd2D\x02s\x03C\x9d\xf6gB\xdc\x1b \xc4x\xf85\xc5\x03\\\xf3\xc5H{\xdaE\x8a\x9f\xd7E\x84K\xdfEaP\x84E:\tKE\x12\xc2\x12D\xfe<\xebD\xd6\xf5\xb2D\xaf\xaeyD\x95~\xfdDv\x9f\x03DB@\x0cD\r\xe1\x16C\xb3\x04=C\x14\x8c\x9f\xc4sI\xd1\xc5\x02\xed\xb2\xc5I\x08\xf1E\x8a\x9f\xd7E\x87\xca\xccEg\xa1\x02E?\xackE\x17\xb7\xd4E\x03\xbd\x88D\xdf\x86zD\xb7\x91\xe3D\x9c\xee\xd4D\x82K\xc5DOQkD\x1a\x0bLC\xc9\x8a[C=\xfc=\xc4m\x01\xf6\xc5\x02`\xbf\xc5I\x81\x00E\x8a\x9f\xd7E\x8a\x9f\xd7Ep\xe8\xe4EH\x9d\x9fE RYE\x0c,\xb6D\xf0\x0e\'D\xc7\xc2\xe1D\xac\xe6\x08D\x92\t/DnX\xabD8\x9e\xf9D\x02\xe5GC\x9aW)B\xbb\x8f\x11\xc4\xc4\x07\x8f\xc5I\xe4\x08E\x8e\xb3\x9aE\x8e\xb3\x9aEzg&EQ\xc51E)#=E\x14\xd2CE\x00\x81HD\xd8`\x9cD\xbdI\xf9D\xa23VD\x87\x1c\xb3DX\x0c D!\xde\xdaC\xd7c(CV\x118\xc4\xbc\xd0\xf4\xc5J2\x08E\x8dv\x0eE\x8dv\x0eE{\xaa\x82ES\x08\x8dE*f\x99E\x16\x15\x9eE\x01\xc4\xa4D\xda\xe7SD\xbf\xd0\xb0D\xa4\xba\rD\x89\xa3jD]\x19\x8fD&\xecIC\xe1~\x05CjF\xf3C\x18-\x97B\x8c(vE\x8a\x9f\xd7E\x8a\x9f\xd7E~\xbasEV\x18\x7fE-v\x8aE\x19%\x90E\x04\xd4\x96D\xe1\x077D\xc5\xf0\x94D\xaa\xd9\xf1D\x8f\xc3ND\x84Z\x1fD\x84Z\x1fD\x84Z\x1fD\x84Z\x1fD\x84Z\x1fD\x84Z\x1f'
# bb = b[::-1]
a = [struct.unpack('!f',bb[i:i+4])[0] for i in range(0, len(bb), 4)]
n = np.array(a)
n
array([1826.58 , 1826.58 , 1667.968, ..., 1058.816, 1058.816, 1058.816])
len(xcp_data_list[0].value), xcp_data_list[0].value
len(bytes.fromhex(xcp_data_list[0].value)), bytes.fromhex(xcp_data_list[0].value)
len(xcp_data_list[0].value_bytes), xcp_data_list[0].value_bytes
xcp_data_list[0].dim, xcp_data_list[0].value_array_view.dtype
xcp_data_list[0].value_array_view
(2856,
 '1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444')
(1428,
 b'\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84DN\xc3\x8fD\xf1\xd9\xaaD\x94\xf0\xc5D7\x07\xe1D\x96\xd4\x04E\x90%\x19E\x8av-E\x7f\x18VEs\xba~E\xd7\x9f\x8aE\xd7\x9f\x8aEv(\x8cB\x97-\x18C\xf3FjC\x05~\xe1CI\xec&D\x8f\x19]Dj\xa3\x89D\r\xba\xa4D\xb0\xd0\xbfDS\xe7\xdaD\xa4\xc4\x01E\x9e\x15\x16E\x99f*E\x8d\x08SE\x82\xaa{E\x0ev\x8dE\x0ev\x8dE\x082J\xc5\xf4\xd0\xbc\xc48\x11VC(c\xd7C\xda\xde!D \x0cXD\xb3\x1c\x87DV3\xa2D\xf9I\xbdD\x9c`\xd8DH\x81\x00EC\xd2\x14E=#)E1\xc5QE&gzE\x9a\xb3\x8eE\x9a\xb3\x8eE\x08\xe4I\xc5\x8f\x07\xc4\xc4\x11\x8f\xbbB)W\x9aCG\xe5\x02D\xf9\x9e8D\xabXnD/\t\x92D\x08\xe6\xacD\xe1\xc2\xc7D\'\x0e\xf0D\xb6,\x0cEYR E\x9f\x9dHE\xe4\xe8pE\xd7\x9f\x8aE\xd7\x9f\x8aE\x00\x81I\xc5\xbf`\x02\xc5\xf6\x01m\xc4=\xfc=C[\x8a\xc9CL\x0b\x1aDkQOD\xc5K\x82D\xd4\xee\x9cD\xe3\x91\xb7Dz\x86\xdfD\x88\xbd\x03E\xd4\xb7\x17Ek\xac?E\x02\xa1gE\xcc\xca\x87E\xd7\x9f\x8aE\xf1\x08I\xc5\xb2\xed\x02\xc5\xd1Is\xc4\x9f\x8c\x14C=\x04\xb3C\x16\xe1\rD\x0c@BD\x03\x9fvD\xfd~\x95Dy\xae\xafD\xb2\xf5\xd6D\xeb<\xfeD\x12\xc2\x12EK\t:E\x84PaE\xdfK\x84E\xd7\x9f\x8aE\xda{H\xc5\xf3\\\x03\xc55\xf8x\xc4 \x1b\xdcBg\xf6\x9dC\x03s\x02D\xd2\xea5D\xa1biD8m\x8eD )\xa8D\xfc\xc2\xceD\xd7\\\xf5DY\xfb\rE5\x954E\x10/[Ev\xe4\x80E\xd7\x9f\x8aE\xbb\xd9G\xc5E\x90\x11\xc5\xa0\x8d\xb6\xc4j\xf5\x13\xc4\xd7`\x8aC\'\x82\xefC\xbbQ*Dc\xe2\\D\x85\xb9\x87D\xd9\x01\xa1DW\xee\xc6D\xd5\xda\xecD\xa9c\tE\'P/E\xa5<UE#){E\xd7\x9f\x8aE\x94"G\xc5\xd3\x97\x11\xc5#\x1a\xb8\xc4?\t\x1a\xc4\x1f\x87pC\x90\x96\xdbC\xc8t\x1fDH\x1eQD\xe4c\x81D\xa48\x9aD\xc5w\xbfD\xe5\xb6\xe4D\x02\xfb\x04E#:*ECyOEc\xb8tE\xdf\xf5\x85EfVF\xc53\x85\x11\xc5\xffg\xb9\xc41\x8b\x1f\xc4p\xe6NCU\x84\xc8C\xb9\xca\x14DHSED\xd7\xdbuD32\x93D\x9e\x98\xb7D\t\xff\xdbD\xba2\x00E%\x99$E\x90\xffHE\xfbemEDlqE1uE\xc5kU\x11\xc5Kk\xba\xc4\x81W$\xc4T\x9e0Ce\x1e\xb7C\xd0\xf6\nDm^:D\n\xc6iD\xd4\x96\x8cD\x8a$\xb0D@\xb2\xd3D\xf6?\xf7D\xb1-\x1fEg\xbbBE\xdc\x91bE\xdc\x91bE\xf3~D\xc5\x0b\x03\x19\xc5D\x0e\xdb\xc4s\x16\x84\xc4\x87z\xb4\xc3\xbed\xa7C\x0b\xf9\x01D\xb7?0Db\x86^D\x87f\x86D\x88\x1b\xa9D\x89\xd0\xcbD\x8a\x85\xeeD\xc6\xf7\x19E\xc7\xac<EdkSEdkSE\xaesC\xc5)\x87\x18\xc5G5\xdb\xc4=\\\x85\xc4\xc9\x0c\xbe\xc3aW\x99C\xd6\xa2\xf3C%\xf7&D\xe0\x1cTDM\xa1\x80D\x99}\xa2D\xe5Y\xc4D06\xe6Dd\xf7\x14E\x94\xb65E\x94\xb65E\x94\xb65EaSB\xc5\x9c\xf6\x17\xc5\xad3\xdb\xc4"z\x86\xc4\\\x02\xc7\xc3\xcf\xe3\x8bC~\xab\xe1C\x97\xb9\x1bDn\x9dFDE\x81qD\x84\xeb\x98Df\x16\xb9DGA\xd9D\x85\xcb\x0cE\x9a\xb3%E\x9a\xb3%E\x9a\xb3%E\r\x1eA\xc5\x07D\x17\xc5\x01\xd4\xda\xc4\xf4\x1f\x87\xc4\x9e\xaf\xcd\xc3\x94 \x81C}d\xd2C3\xd4\x11D(v:D\x1c\x18cD\x85\x05\x90D\xfd~\xaeDt\xf8\xccD\xb2\xf5\x04E)o#E=(\'E=(\'E\xb1\xd3?\xc5\x8eo\x16\xc5\xd6\x16\xda\xc4\x91N\x87\xc4.\x19\xd2\xc3\xcf\x0frC\xe3\xe0\xc4C\xef\\\x08DmI.D\xeb5TDT\x8c\x86D\xb2\xfd\xa2D\x11o\xbfD\xcdQ\xf8D\xd5M\x18E\xd5M\x18E\xd5M\x18EMt>\xc5\xcd\xd3\x1a\xc5\x99f\xee\xc4\x98%\xa7\xc4/\xc9?\xc4\xba\x1cE\xc3\xa5u\xbaC\xdaq\x00D\xe1\xa8#D\xe8\xdfFDs\xb2{D\x7fB\x98D\xc4\xab\xb2DO~\xe7Dms\tEms\tEms\tE\xe1\xff<\xc5\x82\xc4\x19\xc5G\x12\xed\xc4\x89\x9b\xa6\xc4\x96I@\xc4jpM\xc3\xc2"\xb3C\xe3%\xf4C\x82\x94\x1aD\x12\x16;Dk\xd8kDbM\x8eD\x8e\xae\xa6D\xe7p\xd7DRx\x02ERx\x02ERx\x02Env;\xc50\x93\x18\xc5\xe3_\xeb\xc4g\x99\xa5\xc4\xd4\xa5?\xc4ncP\xc3;\xe8\xaeCn\x80\xeaCQ\x0c\x13Dk\xd80D\x91\x8a]D\\\x1e\x85Dow\x9bD\x96)\xc8D\xbc\xdb\xf4DN\x1b\xf8DN\x1b\xf8D\xf3\xd79\xc5\xd5?\x17\xc5nO\xe9\xc41\x1f\xa4\xc4\xea\xdd=\xc4\xc5\xf5M\xc3\x0f\xc6\xadCU\xf3\xe3CN\x10\rD\xf1&(D\xe5\xc8PD\xdajyDg\x06\x91D\\\xa8\xb9DPJ\xe2D\x8fR\xe4D\x8fR\xe4Dq$8\xc5\xd5\xd3\x19\xc5r\x06\xf7\xc4:e\xba\xc4\x04\x88{\xc4\x94E\x02\xc4@2\x10\xc2\x97~\xe0Cx\xa0\x08D\xa4\x01!Dg\x93ED)%jDv[\x87D8\xed\xabD\xfb~\xd0D\x8fR\xe4D\x8fR\xe4D')
(1428,
 b'\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84DN\xc3\x8fD\xf1\xd9\xaaD\x94\xf0\xc5D7\x07\xe1D\x96\xd4\x04E\x90%\x19E\x8av-E\x7f\x18VEs\xba~E\xd7\x9f\x8aE\xd7\x9f\x8aEv(\x8cB\x97-\x18C\xf3FjC\x05~\xe1CI\xec&D\x8f\x19]Dj\xa3\x89D\r\xba\xa4D\xb0\xd0\xbfDS\xe7\xdaD\xa4\xc4\x01E\x9e\x15\x16E\x99f*E\x8d\x08SE\x82\xaa{E\x0ev\x8dE\x0ev\x8dE\x082J\xc5\xf4\xd0\xbc\xc48\x11VC(c\xd7C\xda\xde!D \x0cXD\xb3\x1c\x87DV3\xa2D\xf9I\xbdD\x9c`\xd8DH\x81\x00EC\xd2\x14E=#)E1\xc5QE&gzE\x9a\xb3\x8eE\x9a\xb3\x8eE\x08\xe4I\xc5\x8f\x07\xc4\xc4\x11\x8f\xbbB)W\x9aCG\xe5\x02D\xf9\x9e8D\xabXnD/\t\x92D\x08\xe6\xacD\xe1\xc2\xc7D\'\x0e\xf0D\xb6,\x0cEYR E\x9f\x9dHE\xe4\xe8pE\xd7\x9f\x8aE\xd7\x9f\x8aE\x00\x81I\xc5\xbf`\x02\xc5\xf6\x01m\xc4=\xfc=C[\x8a\xc9CL\x0b\x1aDkQOD\xc5K\x82D\xd4\xee\x9cD\xe3\x91\xb7Dz\x86\xdfD\x88\xbd\x03E\xd4\xb7\x17Ek\xac?E\x02\xa1gE\xcc\xca\x87E\xd7\x9f\x8aE\xf1\x08I\xc5\xb2\xed\x02\xc5\xd1Is\xc4\x9f\x8c\x14C=\x04\xb3C\x16\xe1\rD\x0c@BD\x03\x9fvD\xfd~\x95Dy\xae\xafD\xb2\xf5\xd6D\xeb<\xfeD\x12\xc2\x12EK\t:E\x84PaE\xdfK\x84E\xd7\x9f\x8aE\xda{H\xc5\xf3\\\x03\xc55\xf8x\xc4 \x1b\xdcBg\xf6\x9dC\x03s\x02D\xd2\xea5D\xa1biD8m\x8eD )\xa8D\xfc\xc2\xceD\xd7\\\xf5DY\xfb\rE5\x954E\x10/[Ev\xe4\x80E\xd7\x9f\x8aE\xbb\xd9G\xc5E\x90\x11\xc5\xa0\x8d\xb6\xc4j\xf5\x13\xc4\xd7`\x8aC\'\x82\xefC\xbbQ*Dc\xe2\\D\x85\xb9\x87D\xd9\x01\xa1DW\xee\xc6D\xd5\xda\xecD\xa9c\tE\'P/E\xa5<UE#){E\xd7\x9f\x8aE\x94"G\xc5\xd3\x97\x11\xc5#\x1a\xb8\xc4?\t\x1a\xc4\x1f\x87pC\x90\x96\xdbC\xc8t\x1fDH\x1eQD\xe4c\x81D\xa48\x9aD\xc5w\xbfD\xe5\xb6\xe4D\x02\xfb\x04E#:*ECyOEc\xb8tE\xdf\xf5\x85EfVF\xc53\x85\x11\xc5\xffg\xb9\xc41\x8b\x1f\xc4p\xe6NCU\x84\xc8C\xb9\xca\x14DHSED\xd7\xdbuD32\x93D\x9e\x98\xb7D\t\xff\xdbD\xba2\x00E%\x99$E\x90\xffHE\xfbemEDlqE1uE\xc5kU\x11\xc5Kk\xba\xc4\x81W$\xc4T\x9e0Ce\x1e\xb7C\xd0\xf6\nDm^:D\n\xc6iD\xd4\x96\x8cD\x8a$\xb0D@\xb2\xd3D\xf6?\xf7D\xb1-\x1fEg\xbbBE\xdc\x91bE\xdc\x91bE\xf3~D\xc5\x0b\x03\x19\xc5D\x0e\xdb\xc4s\x16\x84\xc4\x87z\xb4\xc3\xbed\xa7C\x0b\xf9\x01D\xb7?0Db\x86^D\x87f\x86D\x88\x1b\xa9D\x89\xd0\xcbD\x8a\x85\xeeD\xc6\xf7\x19E\xc7\xac<EdkSEdkSE\xaesC\xc5)\x87\x18\xc5G5\xdb\xc4=\\\x85\xc4\xc9\x0c\xbe\xc3aW\x99C\xd6\xa2\xf3C%\xf7&D\xe0\x1cTDM\xa1\x80D\x99}\xa2D\xe5Y\xc4D06\xe6Dd\xf7\x14E\x94\xb65E\x94\xb65E\x94\xb65EaSB\xc5\x9c\xf6\x17\xc5\xad3\xdb\xc4"z\x86\xc4\\\x02\xc7\xc3\xcf\xe3\x8bC~\xab\xe1C\x97\xb9\x1bDn\x9dFDE\x81qD\x84\xeb\x98Df\x16\xb9DGA\xd9D\x85\xcb\x0cE\x9a\xb3%E\x9a\xb3%E\x9a\xb3%E\r\x1eA\xc5\x07D\x17\xc5\x01\xd4\xda\xc4\xf4\x1f\x87\xc4\x9e\xaf\xcd\xc3\x94 \x81C}d\xd2C3\xd4\x11D(v:D\x1c\x18cD\x85\x05\x90D\xfd~\xaeDt\xf8\xccD\xb2\xf5\x04E)o#E=(\'E=(\'E\xb1\xd3?\xc5\x8eo\x16\xc5\xd6\x16\xda\xc4\x91N\x87\xc4.\x19\xd2\xc3\xcf\x0frC\xe3\xe0\xc4C\xef\\\x08DmI.D\xeb5TDT\x8c\x86D\xb2\xfd\xa2D\x11o\xbfD\xcdQ\xf8D\xd5M\x18E\xd5M\x18E\xd5M\x18EMt>\xc5\xcd\xd3\x1a\xc5\x99f\xee\xc4\x98%\xa7\xc4/\xc9?\xc4\xba\x1cE\xc3\xa5u\xbaC\xdaq\x00D\xe1\xa8#D\xe8\xdfFDs\xb2{D\x7fB\x98D\xc4\xab\xb2DO~\xe7Dms\tEms\tEms\tE\xe1\xff<\xc5\x82\xc4\x19\xc5G\x12\xed\xc4\x89\x9b\xa6\xc4\x96I@\xc4jpM\xc3\xc2"\xb3C\xe3%\xf4C\x82\x94\x1aD\x12\x16;Dk\xd8kDbM\x8eD\x8e\xae\xa6D\xe7p\xd7DRx\x02ERx\x02ERx\x02Env;\xc50\x93\x18\xc5\xe3_\xeb\xc4g\x99\xa5\xc4\xd4\xa5?\xc4ncP\xc3;\xe8\xaeCn\x80\xeaCQ\x0c\x13Dk\xd80D\x91\x8a]D\\\x1e\x85Dow\x9bD\x96)\xc8D\xbc\xdb\xf4DN\x1b\xf8DN\x1b\xf8D\xf3\xd79\xc5\xd5?\x17\xc5nO\xe9\xc41\x1f\xa4\xc4\xea\xdd=\xc4\xc5\xf5M\xc3\x0f\xc6\xadCU\xf3\xe3CN\x10\rD\xf1&(D\xe5\xc8PD\xdajyDg\x06\x91D\\\xa8\xb9DPJ\xe2D\x8fR\xe4D\x8fR\xe4Dq$8\xc5\xd5\xd3\x19\xc5r\x06\xf7\xc4:e\xba\xc4\x04\x88{\xc4\x94E\x02\xc4@2\x10\xc2\x97~\xe0Cx\xa0\x08D\xa4\x01!Dg\x93ED)%jDv[\x87D8\xed\xabD\xfb~\xd0D\x8fR\xe4D\x8fR\xe4D')
([21, 17], dtype('float32'))
array([[ 1058.816,  1058.816,  1058.816, ...,  4075.653,  4435.98 ,
         4435.98 ],
       [   70.079,   152.178,   234.277, ...,  4026.657,  4526.757,
         4526.757],
       [-3235.127, -1510.53 ,   214.067, ...,  4006.447,  4566.45 ,
         4566.45 ],
       ...,
       [-2999.402, -2441.199, -1882.996, ...,  1958.867,  1984.853,
         1984.853],
       [-2973.497, -2419.99 , -1866.482, ...,  1810.322,  1826.58 ,
         1826.58 ],
       [-2946.278, -2461.24 , -1976.201, ...,  1667.968,  1826.58 ,
         1826.58 ]], dtype=float32)
struct.unpack('!f', bytes.fromhex('41973333'))[0]

s = '1f5a8444'

# s = bytearray(s, encoding='utf-8')
# s.reverse()
b = [s[i:i+2] for i in range(0, len(s), 2)]
b = ''.join(b[::-1])
"b:",b
"bytes.fromhex(b):", bytes.fromhex(b)
struct.unpack('!f', bytes.fromhex(b))[0]
# s.reverse()
# ss = struct.pack('<I', s)

# struct.unpack('!f', bytes.fromhex('1f5a8444'))[0]
# s = s[::-1]
# s
# s = '44845a1f'
# struct.unpack('!f', bytes.fromhex(s))[0]
# struct.unpack('!f', bytes.fromhex('25ea8d44'))[0]
# struct.unpack('!f', bytes.fromhex('f647d344'))[0]
# struct.unpack('!f', bytes.fromhex('41995C29'))[0]
18.899999618530273
('b:', '44845a1f')
('bytes.fromhex(b):', b'D\x84Z\x1f')
1058.8162841796875
addr_dec = int(xcp_data_list[0].address, 16)
addr_dec
addr_hex = hex(addr_dec)
addr_hex
addr_oct = oct(addr_dec)
add_dec_o = int(addr_oct,8)
add_dec_o
1879091754
'0x7000aa2a'
1879091754
xcp_data_list[0].__dict__
# xcp_data[0].value_array_view
# xcp_data[0].__dict__

# f"{xcp_data[0].value:.10s}...{xcp_data[0].value[-3:]}"
# xcp_data[0].value_array_view
{'name': 'TQD_trqTrqSetNormal_MAP_v',
 'address': '7000aa2a',
 'dim': [21, 17],
 'value_type': 'FLOAT32_IEEE',
 'value_length': 4,
 'value': '1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444',
 'type_size': 4,
 'value_bytes': b'\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84DN\xc3\x8fD\xf1\xd9\xaaD\x94\xf0\xc5D7\x07\xe1D\x96\xd4\x04E\x90%\x19E\x8av-E\x7f\x18VEs\xba~E\xd7\x9f\x8aE\xd7\x9f\x8aEv(\x8cB\x97-\x18C\xf3FjC\x05~\xe1CI\xec&D\x8f\x19]Dj\xa3\x89D\r\xba\xa4D\xb0\xd0\xbfDS\xe7\xdaD\xa4\xc4\x01E\x9e\x15\x16E\x99f*E\x8d\x08SE\x82\xaa{E\x0ev\x8dE\x0ev\x8dE\x082J\xc5\xf4\xd0\xbc\xc48\x11VC(c\xd7C\xda\xde!D \x0cXD\xb3\x1c\x87DV3\xa2D\xf9I\xbdD\x9c`\xd8DH\x81\x00EC\xd2\x14E=#)E1\xc5QE&gzE\x9a\xb3\x8eE\x9a\xb3\x8eE\x08\xe4I\xc5\x8f\x07\xc4\xc4\x11\x8f\xbbB)W\x9aCG\xe5\x02D\xf9\x9e8D\xabXnD/\t\x92D\x08\xe6\xacD\xe1\xc2\xc7D\'\x0e\xf0D\xb6,\x0cEYR E\x9f\x9dHE\xe4\xe8pE\xd7\x9f\x8aE\xd7\x9f\x8aE\x00\x81I\xc5\xbf`\x02\xc5\xf6\x01m\xc4=\xfc=C[\x8a\xc9CL\x0b\x1aDkQOD\xc5K\x82D\xd4\xee\x9cD\xe3\x91\xb7Dz\x86\xdfD\x88\xbd\x03E\xd4\xb7\x17Ek\xac?E\x02\xa1gE\xcc\xca\x87E\xd7\x9f\x8aE\xf1\x08I\xc5\xb2\xed\x02\xc5\xd1Is\xc4\x9f\x8c\x14C=\x04\xb3C\x16\xe1\rD\x0c@BD\x03\x9fvD\xfd~\x95Dy\xae\xafD\xb2\xf5\xd6D\xeb<\xfeD\x12\xc2\x12EK\t:E\x84PaE\xdfK\x84E\xd7\x9f\x8aE\xda{H\xc5\xf3\\\x03\xc55\xf8x\xc4 \x1b\xdcBg\xf6\x9dC\x03s\x02D\xd2\xea5D\xa1biD8m\x8eD )\xa8D\xfc\xc2\xceD\xd7\\\xf5DY\xfb\rE5\x954E\x10/[Ev\xe4\x80E\xd7\x9f\x8aE\xbb\xd9G\xc5E\x90\x11\xc5\xa0\x8d\xb6\xc4j\xf5\x13\xc4\xd7`\x8aC\'\x82\xefC\xbbQ*Dc\xe2\\D\x85\xb9\x87D\xd9\x01\xa1DW\xee\xc6D\xd5\xda\xecD\xa9c\tE\'P/E\xa5<UE#){E\xd7\x9f\x8aE\x94"G\xc5\xd3\x97\x11\xc5#\x1a\xb8\xc4?\t\x1a\xc4\x1f\x87pC\x90\x96\xdbC\xc8t\x1fDH\x1eQD\xe4c\x81D\xa48\x9aD\xc5w\xbfD\xe5\xb6\xe4D\x02\xfb\x04E#:*ECyOEc\xb8tE\xdf\xf5\x85EfVF\xc53\x85\x11\xc5\xffg\xb9\xc41\x8b\x1f\xc4p\xe6NCU\x84\xc8C\xb9\xca\x14DHSED\xd7\xdbuD32\x93D\x9e\x98\xb7D\t\xff\xdbD\xba2\x00E%\x99$E\x90\xffHE\xfbemEDlqE1uE\xc5kU\x11\xc5Kk\xba\xc4\x81W$\xc4T\x9e0Ce\x1e\xb7C\xd0\xf6\nDm^:D\n\xc6iD\xd4\x96\x8cD\x8a$\xb0D@\xb2\xd3D\xf6?\xf7D\xb1-\x1fEg\xbbBE\xdc\x91bE\xdc\x91bE\xf3~D\xc5\x0b\x03\x19\xc5D\x0e\xdb\xc4s\x16\x84\xc4\x87z\xb4\xc3\xbed\xa7C\x0b\xf9\x01D\xb7?0Db\x86^D\x87f\x86D\x88\x1b\xa9D\x89\xd0\xcbD\x8a\x85\xeeD\xc6\xf7\x19E\xc7\xac<EdkSEdkSE\xaesC\xc5)\x87\x18\xc5G5\xdb\xc4=\\\x85\xc4\xc9\x0c\xbe\xc3aW\x99C\xd6\xa2\xf3C%\xf7&D\xe0\x1cTDM\xa1\x80D\x99}\xa2D\xe5Y\xc4D06\xe6Dd\xf7\x14E\x94\xb65E\x94\xb65E\x94\xb65EaSB\xc5\x9c\xf6\x17\xc5\xad3\xdb\xc4"z\x86\xc4\\\x02\xc7\xc3\xcf\xe3\x8bC~\xab\xe1C\x97\xb9\x1bDn\x9dFDE\x81qD\x84\xeb\x98Df\x16\xb9DGA\xd9D\x85\xcb\x0cE\x9a\xb3%E\x9a\xb3%E\x9a\xb3%E\r\x1eA\xc5\x07D\x17\xc5\x01\xd4\xda\xc4\xf4\x1f\x87\xc4\x9e\xaf\xcd\xc3\x94 \x81C}d\xd2C3\xd4\x11D(v:D\x1c\x18cD\x85\x05\x90D\xfd~\xaeDt\xf8\xccD\xb2\xf5\x04E)o#E=(\'E=(\'E\xb1\xd3?\xc5\x8eo\x16\xc5\xd6\x16\xda\xc4\x91N\x87\xc4.\x19\xd2\xc3\xcf\x0frC\xe3\xe0\xc4C\xef\\\x08DmI.D\xeb5TDT\x8c\x86D\xb2\xfd\xa2D\x11o\xbfD\xcdQ\xf8D\xd5M\x18E\xd5M\x18E\xd5M\x18EMt>\xc5\xcd\xd3\x1a\xc5\x99f\xee\xc4\x98%\xa7\xc4/\xc9?\xc4\xba\x1cE\xc3\xa5u\xbaC\xdaq\x00D\xe1\xa8#D\xe8\xdfFDs\xb2{D\x7fB\x98D\xc4\xab\xb2DO~\xe7Dms\tEms\tEms\tE\xe1\xff<\xc5\x82\xc4\x19\xc5G\x12\xed\xc4\x89\x9b\xa6\xc4\x96I@\xc4jpM\xc3\xc2"\xb3C\xe3%\xf4C\x82\x94\x1aD\x12\x16;Dk\xd8kDbM\x8eD\x8e\xae\xa6D\xe7p\xd7DRx\x02ERx\x02ERx\x02Env;\xc50\x93\x18\xc5\xe3_\xeb\xc4g\x99\xa5\xc4\xd4\xa5?\xc4ncP\xc3;\xe8\xaeCn\x80\xeaCQ\x0c\x13Dk\xd80D\x91\x8a]D\\\x1e\x85Dow\x9bD\x96)\xc8D\xbc\xdb\xf4DN\x1b\xf8DN\x1b\xf8D\xf3\xd79\xc5\xd5?\x17\xc5nO\xe9\xc41\x1f\xa4\xc4\xea\xdd=\xc4\xc5\xf5M\xc3\x0f\xc6\xadCU\xf3\xe3CN\x10\rD\xf1&(D\xe5\xc8PD\xdajyDg\x06\x91D\\\xa8\xb9DPJ\xe2D\x8fR\xe4D\x8fR\xe4Dq$8\xc5\xd5\xd3\x19\xc5r\x06\xf7\xc4:e\xba\xc4\x04\x88{\xc4\x94E\x02\xc4@2\x10\xc2\x97~\xe0Cx\xa0\x08D\xa4\x01!Dg\x93ED)%jDv[\x87D8\xed\xabD\xfb~\xd0D\x8fR\xe4D\x8fR\xe4D',
 'value_array_view': array([[ 1058.816,  1058.816,  1058.816, ...,  4075.653,  4435.98 ,
          4435.98 ],
        [   70.079,   152.178,   234.277, ...,  4026.657,  4526.757,
          4526.757],
        [-3235.127, -1510.53 ,   214.067, ...,  4006.447,  4566.45 ,
          4566.45 ],
        ...,
        [-2999.402, -2441.199, -1882.996, ...,  1958.867,  1984.853,
          1984.853],
        [-2973.497, -2419.99 , -1866.482, ...,  1810.322,  1826.58 ,
          1826.58 ],
        [-2946.278, -2461.24 , -1976.201, ...,  1667.968,  1826.58 ,
          1826.58 ]], dtype=float32)}
# xcp_data[0].value_array_view
xcp_data_list[0]
xcp_data_list[0].__dict__
xcp_data_list[0].model_dump()

test_eq(xcp_data_list[0].value_array_view.tobytes(), xcp_data_list[0].value_bytes)
{   'address': '7000aa2a',
    'dim': [21, 17],
    'name': 'TQD_trqTrqSetNormal_MAP_v',
    'type_size': 4,
    'value': '1f5a84441f...444',
    'value_array_view': array([[ 1058.816,  1058.816,  1058.816, ...,  4075.653,  4435.98 ,
         4435.98 ],
       [   70.079,   152.178,   234.277, ...,  4026.657,  4526.757,
         4526.757],
       [-3235.127, -1510.53 ,   214.067, ...,  4006.447,  4566.45 ,
         4566.45 ],
       ...,
       [-2999.402, -2441.199, -1882.996, ...,  1958.867,  1984.853,
         1984.853],
       [-2973.497, -2419.99 , -1866.482, ...,  1810.322,  1826.58 ,
         1826.58 ],
       [-2946.278, -2461.24 , -1976.201, ...,  1667.968,  1826.58 ,
         1826.58 ]], dtype=float32),
    'value_bytes': "b'\\x1f'...b'D'",
    'value_length': 4,
    'value_type': 'FLOAT32_IEEE'}
{'name': 'TQD_trqTrqSetNormal_MAP_v',
 'address': '7000aa2a',
 'dim': [21, 17],
 'value_type': 'FLOAT32_IEEE',
 'value_length': 4,
 'value': '1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444',
 'type_size': 4,
 'value_bytes': b'\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84DN\xc3\x8fD\xf1\xd9\xaaD\x94\xf0\xc5D7\x07\xe1D\x96\xd4\x04E\x90%\x19E\x8av-E\x7f\x18VEs\xba~E\xd7\x9f\x8aE\xd7\x9f\x8aEv(\x8cB\x97-\x18C\xf3FjC\x05~\xe1CI\xec&D\x8f\x19]Dj\xa3\x89D\r\xba\xa4D\xb0\xd0\xbfDS\xe7\xdaD\xa4\xc4\x01E\x9e\x15\x16E\x99f*E\x8d\x08SE\x82\xaa{E\x0ev\x8dE\x0ev\x8dE\x082J\xc5\xf4\xd0\xbc\xc48\x11VC(c\xd7C\xda\xde!D \x0cXD\xb3\x1c\x87DV3\xa2D\xf9I\xbdD\x9c`\xd8DH\x81\x00EC\xd2\x14E=#)E1\xc5QE&gzE\x9a\xb3\x8eE\x9a\xb3\x8eE\x08\xe4I\xc5\x8f\x07\xc4\xc4\x11\x8f\xbbB)W\x9aCG\xe5\x02D\xf9\x9e8D\xabXnD/\t\x92D\x08\xe6\xacD\xe1\xc2\xc7D\'\x0e\xf0D\xb6,\x0cEYR E\x9f\x9dHE\xe4\xe8pE\xd7\x9f\x8aE\xd7\x9f\x8aE\x00\x81I\xc5\xbf`\x02\xc5\xf6\x01m\xc4=\xfc=C[\x8a\xc9CL\x0b\x1aDkQOD\xc5K\x82D\xd4\xee\x9cD\xe3\x91\xb7Dz\x86\xdfD\x88\xbd\x03E\xd4\xb7\x17Ek\xac?E\x02\xa1gE\xcc\xca\x87E\xd7\x9f\x8aE\xf1\x08I\xc5\xb2\xed\x02\xc5\xd1Is\xc4\x9f\x8c\x14C=\x04\xb3C\x16\xe1\rD\x0c@BD\x03\x9fvD\xfd~\x95Dy\xae\xafD\xb2\xf5\xd6D\xeb<\xfeD\x12\xc2\x12EK\t:E\x84PaE\xdfK\x84E\xd7\x9f\x8aE\xda{H\xc5\xf3\\\x03\xc55\xf8x\xc4 \x1b\xdcBg\xf6\x9dC\x03s\x02D\xd2\xea5D\xa1biD8m\x8eD )\xa8D\xfc\xc2\xceD\xd7\\\xf5DY\xfb\rE5\x954E\x10/[Ev\xe4\x80E\xd7\x9f\x8aE\xbb\xd9G\xc5E\x90\x11\xc5\xa0\x8d\xb6\xc4j\xf5\x13\xc4\xd7`\x8aC\'\x82\xefC\xbbQ*Dc\xe2\\D\x85\xb9\x87D\xd9\x01\xa1DW\xee\xc6D\xd5\xda\xecD\xa9c\tE\'P/E\xa5<UE#){E\xd7\x9f\x8aE\x94"G\xc5\xd3\x97\x11\xc5#\x1a\xb8\xc4?\t\x1a\xc4\x1f\x87pC\x90\x96\xdbC\xc8t\x1fDH\x1eQD\xe4c\x81D\xa48\x9aD\xc5w\xbfD\xe5\xb6\xe4D\x02\xfb\x04E#:*ECyOEc\xb8tE\xdf\xf5\x85EfVF\xc53\x85\x11\xc5\xffg\xb9\xc41\x8b\x1f\xc4p\xe6NCU\x84\xc8C\xb9\xca\x14DHSED\xd7\xdbuD32\x93D\x9e\x98\xb7D\t\xff\xdbD\xba2\x00E%\x99$E\x90\xffHE\xfbemEDlqE1uE\xc5kU\x11\xc5Kk\xba\xc4\x81W$\xc4T\x9e0Ce\x1e\xb7C\xd0\xf6\nDm^:D\n\xc6iD\xd4\x96\x8cD\x8a$\xb0D@\xb2\xd3D\xf6?\xf7D\xb1-\x1fEg\xbbBE\xdc\x91bE\xdc\x91bE\xf3~D\xc5\x0b\x03\x19\xc5D\x0e\xdb\xc4s\x16\x84\xc4\x87z\xb4\xc3\xbed\xa7C\x0b\xf9\x01D\xb7?0Db\x86^D\x87f\x86D\x88\x1b\xa9D\x89\xd0\xcbD\x8a\x85\xeeD\xc6\xf7\x19E\xc7\xac<EdkSEdkSE\xaesC\xc5)\x87\x18\xc5G5\xdb\xc4=\\\x85\xc4\xc9\x0c\xbe\xc3aW\x99C\xd6\xa2\xf3C%\xf7&D\xe0\x1cTDM\xa1\x80D\x99}\xa2D\xe5Y\xc4D06\xe6Dd\xf7\x14E\x94\xb65E\x94\xb65E\x94\xb65EaSB\xc5\x9c\xf6\x17\xc5\xad3\xdb\xc4"z\x86\xc4\\\x02\xc7\xc3\xcf\xe3\x8bC~\xab\xe1C\x97\xb9\x1bDn\x9dFDE\x81qD\x84\xeb\x98Df\x16\xb9DGA\xd9D\x85\xcb\x0cE\x9a\xb3%E\x9a\xb3%E\x9a\xb3%E\r\x1eA\xc5\x07D\x17\xc5\x01\xd4\xda\xc4\xf4\x1f\x87\xc4\x9e\xaf\xcd\xc3\x94 \x81C}d\xd2C3\xd4\x11D(v:D\x1c\x18cD\x85\x05\x90D\xfd~\xaeDt\xf8\xccD\xb2\xf5\x04E)o#E=(\'E=(\'E\xb1\xd3?\xc5\x8eo\x16\xc5\xd6\x16\xda\xc4\x91N\x87\xc4.\x19\xd2\xc3\xcf\x0frC\xe3\xe0\xc4C\xef\\\x08DmI.D\xeb5TDT\x8c\x86D\xb2\xfd\xa2D\x11o\xbfD\xcdQ\xf8D\xd5M\x18E\xd5M\x18E\xd5M\x18EMt>\xc5\xcd\xd3\x1a\xc5\x99f\xee\xc4\x98%\xa7\xc4/\xc9?\xc4\xba\x1cE\xc3\xa5u\xbaC\xdaq\x00D\xe1\xa8#D\xe8\xdfFDs\xb2{D\x7fB\x98D\xc4\xab\xb2DO~\xe7Dms\tEms\tEms\tE\xe1\xff<\xc5\x82\xc4\x19\xc5G\x12\xed\xc4\x89\x9b\xa6\xc4\x96I@\xc4jpM\xc3\xc2"\xb3C\xe3%\xf4C\x82\x94\x1aD\x12\x16;Dk\xd8kDbM\x8eD\x8e\xae\xa6D\xe7p\xd7DRx\x02ERx\x02ERx\x02Env;\xc50\x93\x18\xc5\xe3_\xeb\xc4g\x99\xa5\xc4\xd4\xa5?\xc4ncP\xc3;\xe8\xaeCn\x80\xeaCQ\x0c\x13Dk\xd80D\x91\x8a]D\\\x1e\x85Dow\x9bD\x96)\xc8D\xbc\xdb\xf4DN\x1b\xf8DN\x1b\xf8D\xf3\xd79\xc5\xd5?\x17\xc5nO\xe9\xc41\x1f\xa4\xc4\xea\xdd=\xc4\xc5\xf5M\xc3\x0f\xc6\xadCU\xf3\xe3CN\x10\rD\xf1&(D\xe5\xc8PD\xdajyDg\x06\x91D\\\xa8\xb9DPJ\xe2D\x8fR\xe4D\x8fR\xe4Dq$8\xc5\xd5\xd3\x19\xc5r\x06\xf7\xc4:e\xba\xc4\x04\x88{\xc4\x94E\x02\xc4@2\x10\xc2\x97~\xe0Cx\xa0\x08D\xa4\x01!Dg\x93ED)%jDv[\x87D8\xed\xabD\xfb~\xd0D\x8fR\xe4D\x8fR\xe4D',
 'value_array_view': array([[ 1058.816,  1058.816,  1058.816, ...,  4075.653,  4435.98 ,
          4435.98 ],
        [   70.079,   152.178,   234.277, ...,  4026.657,  4526.757,
          4526.757],
        [-3235.127, -1510.53 ,   214.067, ...,  4006.447,  4566.45 ,
          4566.45 ],
        ...,
        [-2999.402, -2441.199, -1882.996, ...,  1958.867,  1984.853,
          1984.853],
        [-2973.497, -2419.99 , -1866.482, ...,  1810.322,  1826.58 ,
          1826.58 ],
        [-2946.278, -2461.24 , -1976.201, ...,  1667.968,  1826.58 ,
          1826.58 ]], dtype=float32)}
{'name': 'TQD_trqTrqSetNormal_MAP_v',
 'address': '7000aa2a',
 'dim': [21, 17],
 'value_type': 'FLOAT32_IEEE',
 'value_length': 4,
 'value': '1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444'}
xcp_data = Get_Init_XCPData('../res/init_value_17rows_broken.json')
# xcp_data[0], f'value byte length: {len(xcp_data[0].value)}'
# xcp_data[1], f'value byte length: {len(xcp_data[1].value)}'
1 validation error for XCPData
  Value error, value length 2855!=(dimension [21, 17])*(value length 2856)! [type=value_error, input_value={'name': 'TQD_trqTrqSetNo...7ed0448f52e4448f52e444'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.6/v/value_error
1 validation error for XCPData
value_type
  Assertion failed, Invalid data type FLOAT32_IEEE1 [type=assertion_error, input_value='FLOAT32_IEEE1', input_type=str]
    For further information visit https://errors.pydantic.dev/2.6/v/assertion_error
1 validation error for XCPData
  Value error, Value length 8 doesn't match data type FLOAT32_IEEE(4)! [type=value_error, input_value={'name': 'TQD_trqTrqSetEC...7ed0448f52e4448f52e444'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.6/v/value_error

XCPCalib

 XCPCalib (config:__main__.XCPConfig=None,
           data:List[__main__.XCPData]=None)

XCP calibration parameter

Type Details
data Any
Returns None type: ignore

Get_XCPCalib_From_XCPJSon

 Get_XCPCalib_From_XCPJSon
                            (path:pathlib.Path=Path('../res/download.json'
                            ))

Generate_Init_XCPData_From_A2L

 Generate_Init_XCPData_From_A2L
                                 (a2l:pathlib.Path=Path('../res/vbu_sample
                                 .json'), keys:List[str]=['TQD_trqTrqSetNo
                                 rmal_MAP_v',
                                 'VBU_L045A_CWP_05_09T_AImode_CM_single',
                                 'Lookup2D_FLOAT32_IEEE',
                                 'Lookup2D_X_FLOAT32_IEEE, TQD_vVehSpd',
                                 'TQD_vSgndSpd_MAP_y',
                                 'TQD_pctAccPedPosFlt',
                                 'TQD_pctAccPdl_MAP_x'],
                                 node_path:str='/PROJECT/MODULE[]')

*Generate XCP calibration header from A2L file and calibration parameter name

Args: a2l (Path): path to the A2L file keys (List[str]): calibration parameter name node_path (str): path to the calibration parameter in the A2L json file

Returns: XCPCalib: XCP calibration parameter*

args.leaves, args.node_path
(['TQD_trqTrqSetNormal_MAP_v',
  'VBU_L045A_CWP_05_09T_AImode_CM_single',
  'Lookup2D_FLOAT32_IEEE',
  'Lookup2D_X_FLOAT32_IEEE',
  'Scalar_FLOAT32_IEEE',
  'TQD_vVehSpd',
  'TQD_vSgndSpd_MAP_y',
  'TQD_pctAccPedPosFlt',
  'TQD_pctAccPdl_MAP_x'],
 '/PROJECT/MODULE[], ')
# init_xcpdata = Get_Init_XCPData('../res/init_value_17rows.json')
init_xcp_calib = Get_XCPCalib_From_XCPJSon('../res/download.json')
init_xcp_calib.config
len(init_xcp_calib.data)
init_xcp_calib.data[0]
type(init_xcp_calib.data[0])
init_xcp_calib.model_dump()
init_xcp_calib.data[0].value_array_view.shape
XCPConfig(channel=3, download_can_id=630, upload_can_id=631)
1
{   'address': '7000aa2a',
    'dim': [14, 17],
    'name': 'TQD_trqTrqSetNormal_MAP_v',
    'type_size': 4,
    'value': '0000000025...344',
    'value_array_view': array([[    0.   ,  1135.317,  1135.317, ...,  4436.   ,  4436.   ,
         4436.   ],
       [    0.   ,   148.09 ,   148.09 , ...,  4436.   ,  4436.   ,
         4436.   ],
       [-1338.534,  -833.344,  -328.155, ...,  4436.   ,  4436.   ,
         4436.   ],
       ...,
       [-1316.842, -1086.408,  -855.974, ...,  2034.368,  2034.368,
         2034.368],
       [-1141.171,  -926.042,  -710.912, ...,  1859.521,  1859.521,
         1859.521],
       [ -286.008,  -135.973,    14.062, ...,  1690.249,  1690.249,
         1690.249]], dtype=float32),
    'value_bytes': "b'\\x00'...b'D'",
    'value_length': 4,
    'value_type': 'FLOAT32_IEEE'}
__main__.XCPData
{'config': {'channel': 3, 'download_can_id': 630, 'upload_can_id': 631},
 'data': [{'name': 'TQD_trqTrqSetNormal_MAP_v',
   'address': '7000aa2a',
   'dim': [14, 17],
   'value_type': 'FLOAT32_IEEE',
   'value_length': 4,
   'value': '0000000025ea8d4425ea8d4425ea8d4425ea8d44db349544b31eb6448c08d74464f2f7441e6e0c45811d2545e3cc3d45467c564585ed834500a08a4500a08a4500a08a4500000000ed161443ed1614434eba8d431a791e44cb4c60443e10914417fab144efe3d244c8cdf34446961245a9452b450bf54345d053754500a08a4500a08a4500a08a451451a7c40b5650c4dd13a4c3b80831434da9f94356254144847c81445c66a2443550c3440d3ae44469cc0a45cb7b23452e2b3c45f3896d4500a08a4500a08a4500a08a45fffc0fc5a4fcd0c44bff81c4c807ccc339db5f4376a00944f8d74744bd0783447f23a244403fc144e2e8ef4442490f45139e2645b5475545abf8814500a08a4500a08a45771f0dc59f6adac451969ac4078435c4ab6d57c3629a9343eb8d18443f2953444ae28644f42fa4447424d044f318fc44b906144539fb3f45b8ef6b4500a08a4500a08a45483e09c51dd0dcc4a923a7c46cee62c40a2befc3dcc943c29338be43be142944e413604485898b44e1c8b4443e08de44cda303452ae32c4586225645e3617f4500a08a45735904c5aa24dac46c96abc45f107ac4e5f31cc4ac5d7fc37928ea4212c3f443ff0b3e44f76e7144b5419f44efcbc5442856ec444eb51c45873f4345c1c96945f1378345efe1fcc4bac2d3c485a3aac44f8481c434ca30c49117bdc3ddd544c21ae28b43782f1844d5ca5444823a8e44990fb244b0e4d5446fc70e45869c32459e715645d52c5745ab09efc4be0dcac4d111a5c4e31580c4eb3336c42178d8c3d81009c393ce1e43ff56e3435aa33b4499f082448d10a4448130c54435b8034529d8244576423545764235451a2adfc4846cbcc4eeae99c4b0e26dc4846728c4afd8c5c35b89ebc2032820435a0adb4359003344857b784494a89a446513b94408e9f544555f194515471e4515471e453c43cdc4c4f8acc44dae8cc4abc758c4bc3218c49b3bafc3f646b8c240302643fd41d443eeb52a44dc4a6b44cce696447b9cb244d807ea44ef260e45ef260e45ef260e45f49aa4c40fcd87c455fe55c48c621cc4868dc5c3e8ab24c3798683423019944361a803442a443d44f3df7644de3d98446b3eb144833fe344c44bfe44c44bfe44c44bfe447ba58ec4ae8267c466ba31c43ce4f7c3ac538cc3700c83c2e89a1543045eb6434af7104492bf4644da877c4411289944149ab444e730e144ab70e844ab70e844ab70e8440b018fc329f907c359fc6041b4182443d1109d434815e843e08c19441b0f3f4457916444c9098544e7ca9744058caa44224dbd44f647d344f647d344f647d344f647d344'}]}
(14, 17)
# xcp_data[0].name, xcp_data[0].dim, xcp_data[0].value_type, xcp_data[0].value_length, len(xcp_data[0].value)
xcp_data = Generate_Init_XCPData_From_A2L(a2l=Path('../res/VBU_AI.json'),
                            keys=args.leaves,
                            node_path=args.node_path)
# len(xcp_data.value)
xcp_data.value  = 12
try:
    XCPData.model_validate(xcp_data)
except ValidationError as exc:
    print(exc)
1 validation error for XCPData
value
  Input should be a valid string [type=string_type, input_value=12, input_type=int]
    For further information visit https://errors.pydantic.dev/2.6/v/string_type
xcp_data.value = init_xcp_calib.data[0].value
xcp_data
# xcp_data.value_array_view
{   'address': '7000aa2a',
    'dim': [14, 17],
    'name': 'TQD_trqTrqSetNormal_MAP_v',
    'type_size': 4,
    'value': '0000000025...344',
    'value_array_view': array([[    0.   ,  1135.317,  1135.317, ...,  4436.   ,  4436.   ,
         4436.   ],
       [    0.   ,   148.09 ,   148.09 , ...,  4436.   ,  4436.   ,
         4436.   ],
       [-1338.534,  -833.344,  -328.155, ...,  4436.   ,  4436.   ,
         4436.   ],
       ...,
       [-1316.842, -1086.408,  -855.974, ...,  2034.368,  2034.368,
         2034.368],
       [-1141.171,  -926.042,  -710.912, ...,  1859.521,  1859.521,
         1859.521],
       [ -286.008,  -135.973,    14.062, ...,  1690.249,  1690.249,
         1690.249]], dtype=float32),
    'value_bytes': "b'\\x00'...b'D'",
    'value_length': 4,
    'value_type': 'FLOAT32_IEEE'}
xcp_calib = XCPCalib(config=XCPConfig(channel=3, download=630, upload=631),data=[xcp_data])
xcp_calib.model_dump()
xcp_calib
{'config': {'channel': 3, 'download_can_id': 630, 'upload_can_id': 631},
 'data': [{'name': 'TQD_trqTrqSetNormal_MAP_v',
   'address': '7000aa2a',
   'dim': [14, 17],
   'value_type': 'FLOAT32_IEEE',
   'value_length': 4,
   'value': '0000000025ea8d4425ea8d4425ea8d4425ea8d44db349544b31eb6448c08d74464f2f7441e6e0c45811d2545e3cc3d45467c564585ed834500a08a4500a08a4500a08a4500000000ed161443ed1614434eba8d431a791e44cb4c60443e10914417fab144efe3d244c8cdf34446961245a9452b450bf54345d053754500a08a4500a08a4500a08a451451a7c40b5650c4dd13a4c3b80831434da9f94356254144847c81445c66a2443550c3440d3ae44469cc0a45cb7b23452e2b3c45f3896d4500a08a4500a08a4500a08a45fffc0fc5a4fcd0c44bff81c4c807ccc339db5f4376a00944f8d74744bd0783447f23a244403fc144e2e8ef4442490f45139e2645b5475545abf8814500a08a4500a08a45771f0dc59f6adac451969ac4078435c4ab6d57c3629a9343eb8d18443f2953444ae28644f42fa4447424d044f318fc44b906144539fb3f45b8ef6b4500a08a4500a08a45483e09c51dd0dcc4a923a7c46cee62c40a2befc3dcc943c29338be43be142944e413604485898b44e1c8b4443e08de44cda303452ae32c4586225645e3617f4500a08a45735904c5aa24dac46c96abc45f107ac4e5f31cc4ac5d7fc37928ea4212c3f443ff0b3e44f76e7144b5419f44efcbc5442856ec444eb51c45873f4345c1c96945f1378345efe1fcc4bac2d3c485a3aac44f8481c434ca30c49117bdc3ddd544c21ae28b43782f1844d5ca5444823a8e44990fb244b0e4d5446fc70e45869c32459e715645d52c5745ab09efc4be0dcac4d111a5c4e31580c4eb3336c42178d8c3d81009c393ce1e43ff56e3435aa33b4499f082448d10a4448130c54435b8034529d8244576423545764235451a2adfc4846cbcc4eeae99c4b0e26dc4846728c4afd8c5c35b89ebc2032820435a0adb4359003344857b784494a89a446513b94408e9f544555f194515471e4515471e453c43cdc4c4f8acc44dae8cc4abc758c4bc3218c49b3bafc3f646b8c240302643fd41d443eeb52a44dc4a6b44cce696447b9cb244d807ea44ef260e45ef260e45ef260e45f49aa4c40fcd87c455fe55c48c621cc4868dc5c3e8ab24c3798683423019944361a803442a443d44f3df7644de3d98446b3eb144833fe344c44bfe44c44bfe44c44bfe447ba58ec4ae8267c466ba31c43ce4f7c3ac538cc3700c83c2e89a1543045eb6434af7104492bf4644da877c4411289944149ab444e730e144ab70e844ab70e844ab70e8440b018fc329f907c359fc6041b4182443d1109d434815e843e08c19441b0f3f4457916444c9098544e7ca9744058caa44224dbd44f647d344f647d344f647d344f647d344'}]}
XCPCalib(config=XCPConfig(channel=3, download_can_id=630, upload_can_id=631), data=[{   'address': '7000aa2a',
    'dim': [14, 17],
    'name': 'TQD_trqTrqSetNormal_MAP_v',
    'type_size': 4,
    'value': '0000000025...344',
    'value_array_view': array([[    0.   ,  1135.317,  1135.317, ...,  4436.   ,  4436.   ,
         4436.   ],
       [    0.   ,   148.09 ,   148.09 , ...,  4436.   ,  4436.   ,
         4436.   ],
       [-1338.534,  -833.344,  -328.155, ...,  4436.   ,  4436.   ,
         4436.   ],
       ...,
       [-1316.842, -1086.408,  -855.974, ...,  2034.368,  2034.368,
         2034.368],
       [-1141.171,  -926.042,  -710.912, ...,  1859.521,  1859.521,
         1859.521],
       [ -286.008,  -135.973,    14.062, ...,  1690.249,  1690.249,
         1690.249]], dtype=float32),
    'value_bytes': "b'\\x00'...b'D'",
    'value_length': 4,
    'value_type': 'FLOAT32_IEEE'}])
Record.record_registry
{'Calibration.TQD_trqTrqSetNormal_MAP_v': <Calibration: 'TQD_trqTrqSetNormal_MAP_v'>,
 'Measurement.TQD_vVehSpd': <Measurement: 'TQD_vVehSpd'>,
 'Measurement.TQD_pctAccPedPosFlt': <Measurement: 'TQD_pctAccPedPosFlt'>,
 'AxisScale.TQD_vSgndSpd_MAP_y': <AxisScale: 'TQD_vSgndSpd_MAP_y'>,
 'AxisScale.TQD_pctAccPdl_MAP_x': <AxisScale: 'TQD_pctAccPdl_MAP_x'>,
 'DataConversion.VBU_L045A_CWP_05_09T_AImode_CM_single': <DataConversion: 'VBU_L045A_CWP_05_09T_AImode_CM_single'>,
 'DataLayout.Scalar_FLOAT32_IEEE': <DataLayout: 'Scalar_FLOAT32_IEEE'>,
 'DataLayout.Lookup2D_FLOAT32_IEEE': <DataLayout: 'Lookup2D_FLOAT32_IEEE'>,
 'DataLayout.Lookup2D_X_FLOAT32_IEEE': <DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>}
key = 'DataLayout.FLOAT32_IEEE'
key.split('.')[-1]
'FLOAT32_IEEE'
calib = Record.fetch('Calibration.TQD_trqTrqSetNormal_MAP_v')
pprint(calib)

calib.record_type
calib.axes[0].axis_scale.record_type
calib.axes[0].axis_scale.record_type.data_type
<Calibration: 'TQD_trqTrqSetNormal_MAP_v'>
<DataLayout: 'Lookup2D_FLOAT32_IEEE'>
<DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>
'FLOAT32_IEEE'
calib.axes[0].axis_scale.input
calib.axes[0].axis_scale.input.address
calib.axes[0].axis_scale.input.record_type
calib.axes[0].axis_scale.input.record_type.data_type
calib.axes[0].axis_scale.record_type
calib.axes[0].axis_scale.data_conversion
calib.axes[0].data_conversion.Format
<Measurement: 'TQD_vVehSpd'>
'700100f8'
<DataLayout: 'Scalar_FLOAT32_IEEE'>
'FLOAT32_IEEE'
<DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>
<DataConversion: 'VBU_L045A_CWP_05_09T_AImode_CM_single'>
{'Value': '%8.6'}
calib.axes[1].axis_scale.input
calib.axes[1].axis_scale.input.address
calib.axes[1].axis_scale.input.record_type
calib.axes[1].axis_scale.input.record_type.data_type
calib.axes[1].axis_scale.record_type
calib.axes[1].axis_scale.data_conversion
calib.axes[1].data_conversion.Format
<Measurement: 'TQD_pctAccPedPosFlt'>
'700100a0'
<DataLayout: 'Scalar_FLOAT32_IEEE'>
'FLOAT32_IEEE'
<DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>
<DataConversion: 'VBU_L045A_CWP_05_09T_AImode_CM_single'>
{'Value': '%8.6'}

load_a2l_lazy

 load_a2l_lazy (path:pathlib.Path, leaves:list[str])

*Search for the calibration key in the A2L file. Descripttion: Load the A2L file as a dictionary.

Args: path (str): The path to the A2L file. calib_key (str): The node path to the calibration parameters.

Returns: dict: The A2L file as a dictionary.*

# parser = get_argparser()
args = parser.parse_args(
    [
        "-p",
        # r"../res/VBU_AI.json",
        r"../res/VBU_AI.json",
        "-n",
        r"/PROJECT/MODULE[], ",
        # r"/PROJECT/MODULE[]/CHARACTERISTIC[], "
        #   r"/PROJECT/MODULE[]/MEASUREMENT[], "
        #   r"/PROJECT/MODULE[]/AXIS_PTS[], "
        #   r"/PROJECT/MODULE[]/COMPU_METHOD[]",
        "-l",
        r"TQD_trqTrqSetNormal_MAP_v, " 
                r"VBU_L045A_CWP_05_09T_AImode_CM_single, " 
                r"Lookup2D_FLOAT32_IEEE, "
                r"Lookup2D_X_FLOAT32_IEEE, "
                r"TQD_vVehSpd, "
                r"TQD_vSgndSpd_MAP_y, "
                r"TQD_pctAccPedPosFlt, "
                r"TQD_pctAccPdl_MAP_x",
    ]
)
# args.__dict__
args.path, args.leaves, args.node_path
('../res/VBU_AI.json',
 ['TQD_trqTrqSetNormal_MAP_v',
  'VBU_L045A_CWP_05_09T_AImode_CM_single',
  'Lookup2D_FLOAT32_IEEE',
  'Lookup2D_X_FLOAT32_IEEE',
  'TQD_vVehSpd',
  'TQD_vSgndSpd_MAP_y',
  'TQD_pctAccPedPosFlt',
  'TQD_pctAccPdl_MAP_x'],
 '/PROJECT/MODULE[], ')

load_a2l_eager

 load_a2l_eager (path:pathlib.Path,
                 jnode_path:__main__.JsonNodePath=<JsonNodePath [<PROJECT
                 dict>, <MODULE[] list>]>)

*Load the A2L file as a dictionary. Descripttion: Load the A2L file as a dictionary.

Args: path (Path): The path to the A2L file. node (str): The node to search for, e.g. “/PROJECT/MODULE[0]/CHARACTERISTIC”.

Returns: dict: The A2L file as a dictionary.*

args.path, args.node_path, args.leaves
('../res/VBU_AI.json',
 '/PROJECT/MODULE[], ',
 ['TQD_trqTrqSetNormal_MAP_v',
  'VBU_L045A_CWP_05_09T_AImode_CM_single',
  'Lookup2D_FLOAT32_IEEE',
  'Lookup2D_X_FLOAT32_IEEE',
  'TQD_vVehSpd',
  'TQD_vSgndSpd_MAP_y',
  'TQD_pctAccPedPosFlt',
  'TQD_pctAccPdl_MAP_x'])
records = load_records_lazy(args.path, args.leaves, JsonNodePath(args.node_path))
918 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
records = load_a2l_lazy(args.path, args.leaves)
3.45 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
# %%timeit -n 1 -r 1
calibs = load_a2l_eager(args.path, JsonNodePath(args.node_path))
calibs[0]['CHARACTERISTIC'][0]
{'Name': {'Value': 'INP_pVacPres_CUR_v'},
 'LongIdentifier': {},
 'Type': 'CURVE',
 'Address': {'Value': '1879065574', 'Base': 16, 'Size': 8},
 'Deposit': {'Value': 'Lookup1D_FLOAT32_IEEE'},
 'MaxDiff': {},
 'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
 'LowerLimit': {'Value': -3.4e+38,
  'IntegralSign': '-',
  'IntegralSize': 1,
  'DecimalSize': 5},
 'UpperLimit': {'Value': 3.4e+38, 'IntegralSize': 1, 'DecimalSize': 5},
 'AXIS_DESCR': [{'Attribute': 'COM_AXIS',
   'InputQuantity': {'Value': 'NO_INPUT_QUANTITY'},
   'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
   'MaxAxisPoints': {'Value': 6, 'Base': 10, 'Size': 1},
   'LowerLimit': {'Value': -3.4e+38,
    'IntegralSign': '-',
    'IntegralSize': 1,
    'DecimalSize': 5},
   'UpperLimit': {'Value': 3.4e+38, 'IntegralSize': 1, 'DecimalSize': 5},
   'AXIS_PTS_REF': {'AxisPoints': {'Value': 'INP_uVacPres_CUR_x'}}}]}