odxtools 9.7.0__py3-none-any.whl → 10.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odxtools/additionalaudience.py +3 -3
- odxtools/admindata.py +8 -8
- odxtools/audience.py +10 -10
- odxtools/basecomparam.py +5 -5
- odxtools/basevariantpattern.py +4 -5
- odxtools/basicstructure.py +8 -8
- odxtools/cli/_print_utils.py +35 -23
- odxtools/cli/browse.py +9 -9
- odxtools/cli/compare.py +24 -24
- odxtools/cli/decode.py +3 -4
- odxtools/cli/find.py +4 -5
- odxtools/cli/list.py +7 -7
- odxtools/cli/main.py +2 -2
- odxtools/cli/snoop.py +3 -3
- odxtools/codec.py +3 -3
- odxtools/commrelation.py +11 -11
- odxtools/companydata.py +5 -5
- odxtools/companydocinfo.py +8 -8
- odxtools/companyrevisioninfo.py +5 -5
- odxtools/companyspecificinfo.py +5 -5
- odxtools/comparam.py +3 -3
- odxtools/comparaminstance.py +10 -10
- odxtools/comparamspec.py +3 -3
- odxtools/comparamsubset.py +5 -5
- odxtools/complexcomparam.py +7 -7
- odxtools/compositecodec.py +11 -11
- odxtools/compumethods/compucodecompumethod.py +4 -4
- odxtools/compumethods/compuconst.py +4 -5
- odxtools/compumethods/compudefaultvalue.py +1 -2
- odxtools/compumethods/compuinternaltophys.py +6 -6
- odxtools/compumethods/compumethod.py +5 -5
- odxtools/compumethods/compuphystointernal.py +6 -6
- odxtools/compumethods/compurationalcoeffs.py +4 -4
- odxtools/compumethods/compuscale.py +9 -10
- odxtools/compumethods/createanycompumethod.py +1 -2
- odxtools/compumethods/identicalcompumethod.py +1 -2
- odxtools/compumethods/limit.py +12 -12
- odxtools/compumethods/linearcompumethod.py +2 -2
- odxtools/compumethods/linearsegment.py +14 -15
- odxtools/compumethods/ratfunccompumethod.py +3 -3
- odxtools/compumethods/ratfuncsegment.py +7 -8
- odxtools/compumethods/scalelinearcompumethod.py +7 -7
- odxtools/compumethods/scaleratfunccompumethod.py +4 -4
- odxtools/compumethods/tabintpcompumethod.py +15 -18
- odxtools/compumethods/texttablecompumethod.py +3 -3
- odxtools/createanycomparam.py +2 -4
- odxtools/createanydiagcodedtype.py +1 -2
- odxtools/database.py +9 -8
- odxtools/dataobjectproperty.py +10 -10
- odxtools/decodestate.py +5 -5
- odxtools/description.py +5 -5
- odxtools/determinenumberofitems.py +4 -4
- odxtools/diagcodedtype.py +7 -7
- odxtools/diagcomm.py +17 -17
- odxtools/diagdatadictionaryspec.py +6 -6
- odxtools/diaglayercontainer.py +4 -4
- odxtools/diaglayers/basevariant.py +10 -9
- odxtools/diaglayers/basevariantraw.py +9 -9
- odxtools/diaglayers/diaglayer.py +20 -19
- odxtools/diaglayers/diaglayerraw.py +10 -10
- odxtools/diaglayers/diaglayertype.py +1 -2
- odxtools/diaglayers/ecushareddata.py +4 -4
- odxtools/diaglayers/ecushareddataraw.py +6 -6
- odxtools/diaglayers/ecuvariant.py +11 -10
- odxtools/diaglayers/ecuvariantraw.py +9 -9
- odxtools/diaglayers/functionalgroup.py +8 -7
- odxtools/diaglayers/functionalgroupraw.py +7 -7
- odxtools/diaglayers/hierarchyelement.py +43 -49
- odxtools/diaglayers/hierarchyelementraw.py +4 -4
- odxtools/diaglayers/protocol.py +4 -4
- odxtools/diaglayers/protocolraw.py +6 -6
- odxtools/diagnostictroublecode.py +8 -8
- odxtools/diagservice.py +18 -18
- odxtools/diagvariable.py +14 -14
- odxtools/docrevision.py +11 -11
- odxtools/dopbase.py +6 -6
- odxtools/dtcconnector.py +3 -3
- odxtools/dtcdop.py +13 -9
- odxtools/dynamicendmarkerfield.py +5 -4
- odxtools/dynamiclengthfield.py +5 -4
- odxtools/dyndefinedspec.py +5 -5
- odxtools/dynenddopref.py +5 -5
- odxtools/dyniddefmodeinfo.py +13 -13
- odxtools/ecuvariantpattern.py +4 -5
- odxtools/element.py +5 -6
- odxtools/encodestate.py +11 -11
- odxtools/encoding.py +2 -3
- odxtools/endofpdufield.py +6 -6
- odxtools/envdataconnector.py +3 -3
- odxtools/environmentdata.py +3 -4
- odxtools/environmentdatadescription.py +11 -11
- odxtools/exceptions.py +5 -5
- odxtools/externalaccessmethod.py +1 -2
- odxtools/externaldoc.py +4 -4
- odxtools/field.py +9 -10
- odxtools/functionalclass.py +4 -4
- odxtools/inputparam.py +6 -6
- odxtools/internalconstr.py +4 -5
- odxtools/isotp_state_machine.py +12 -11
- odxtools/leadinglengthinfotype.py +2 -3
- odxtools/library.py +5 -5
- odxtools/linkeddtcdop.py +4 -4
- odxtools/loadfile.py +5 -6
- odxtools/matchingbasevariantparameter.py +2 -3
- odxtools/matchingparameter.py +7 -7
- odxtools/minmaxlengthtype.py +4 -4
- odxtools/modification.py +4 -4
- odxtools/multiplexer.py +11 -11
- odxtools/multiplexercase.py +6 -6
- odxtools/multiplexerdefaultcase.py +6 -6
- odxtools/multiplexerswitchkey.py +4 -4
- odxtools/nameditemlist.py +14 -14
- odxtools/negoutputparam.py +3 -3
- odxtools/obd.py +1 -2
- odxtools/odxcategory.py +6 -6
- odxtools/odxlink.py +19 -20
- odxtools/odxtypes.py +21 -18
- odxtools/outputparam.py +4 -4
- odxtools/parameterinfo.py +1 -1
- odxtools/parameters/codedconstparameter.py +5 -5
- odxtools/parameters/createanyparameter.py +1 -2
- odxtools/parameters/dynamicparameter.py +2 -3
- odxtools/parameters/lengthkeyparameter.py +5 -5
- odxtools/parameters/matchingrequestparameter.py +3 -4
- odxtools/parameters/nrcconstparameter.py +7 -7
- odxtools/parameters/parameter.py +11 -11
- odxtools/parameters/parameterwithdop.py +9 -9
- odxtools/parameters/physicalconstantparameter.py +4 -4
- odxtools/parameters/reservedparameter.py +3 -4
- odxtools/parameters/systemparameter.py +2 -3
- odxtools/parameters/tableentryparameter.py +3 -3
- odxtools/parameters/tablekeyparameter.py +10 -10
- odxtools/parameters/tablestructparameter.py +7 -7
- odxtools/parameters/valueparameter.py +7 -7
- odxtools/paramlengthinfotype.py +5 -3
- odxtools/parentref.py +9 -9
- odxtools/physicaldimension.py +11 -11
- odxtools/physicaltype.py +3 -4
- odxtools/posresponsesuppressible.py +9 -10
- odxtools/preconditionstateref.py +7 -7
- odxtools/progcode.py +6 -6
- odxtools/protstack.py +4 -4
- odxtools/relateddiagcommref.py +1 -2
- odxtools/relateddoc.py +6 -6
- odxtools/request.py +9 -9
- odxtools/response.py +10 -10
- odxtools/scaleconstr.py +3 -4
- odxtools/servicebinner.py +5 -5
- odxtools/singleecujob.py +4 -4
- odxtools/snrefcontext.py +2 -2
- odxtools/specialdata.py +5 -5
- odxtools/specialdatagroup.py +9 -9
- odxtools/specialdatagroupcaption.py +3 -3
- odxtools/standardlengthtype.py +10 -10
- odxtools/state.py +3 -3
- odxtools/statechart.py +4 -4
- odxtools/statemachine.py +4 -3
- odxtools/statetransition.py +4 -4
- odxtools/statetransitionref.py +18 -18
- odxtools/staticfield.py +5 -4
- odxtools/structure.py +2 -3
- odxtools/subcomponent.py +5 -5
- odxtools/subcomponentparamconnector.py +5 -5
- odxtools/subcomponentpattern.py +4 -4
- odxtools/swvariable.py +3 -4
- odxtools/table.py +14 -14
- odxtools/tablediagcommconnector.py +5 -5
- odxtools/tablerow.py +30 -30
- odxtools/tablerowconnector.py +3 -3
- odxtools/teammember.py +11 -11
- odxtools/text.py +2 -3
- odxtools/uds.py +2 -3
- odxtools/unit.py +9 -9
- odxtools/unitgroup.py +5 -5
- odxtools/unitspec.py +6 -6
- odxtools/utils.py +3 -3
- odxtools/variablegroup.py +2 -2
- odxtools/variantmatcher.py +10 -10
- odxtools/variantpattern.py +3 -3
- odxtools/version.py +2 -2
- odxtools/writepdxfile.py +5 -5
- odxtools/xdoc.py +9 -9
- {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/METADATA +4 -5
- odxtools-10.0.0.dist-info/RECORD +264 -0
- odxtools-9.7.0.dist-info/RECORD +0 -264
- {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/WHEEL +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/entry_points.txt +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/licenses/LICENSE +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.0.0.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,11 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import re
|
3
3
|
import warnings
|
4
|
+
from collections.abc import Callable, Iterable
|
4
5
|
from copy import deepcopy
|
5
6
|
from dataclasses import dataclass
|
6
7
|
from functools import cached_property
|
7
|
-
from typing import
|
8
|
-
Union, cast)
|
8
|
+
from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
|
9
9
|
from xml.etree import ElementTree
|
10
10
|
|
11
11
|
from ..additionalaudience import AdditionalAudience
|
@@ -47,7 +47,7 @@ class HierarchyElement(DiagLayer):
|
|
47
47
|
|
48
48
|
@staticmethod
|
49
49
|
def from_et(et_element: ElementTree.Element,
|
50
|
-
doc_frags:
|
50
|
+
doc_frags: list[OdxDocFragment]) -> "HierarchyElement":
|
51
51
|
hierarchy_element_raw = HierarchyElementRaw.from_et(et_element, doc_frags)
|
52
52
|
|
53
53
|
return HierarchyElement(diag_layer_raw=hierarchy_element_raw)
|
@@ -62,7 +62,7 @@ class HierarchyElement(DiagLayer):
|
|
62
62
|
"The raw diagnostic layer passed to HierarchyElement "
|
63
63
|
"must be a HierarchyElementRaw")
|
64
64
|
|
65
|
-
def _build_odxlinks(self) ->
|
65
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
66
66
|
result = super()._build_odxlinks()
|
67
67
|
|
68
68
|
return result
|
@@ -73,7 +73,7 @@ class HierarchyElement(DiagLayer):
|
|
73
73
|
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
74
74
|
super()._resolve_snrefs(context)
|
75
75
|
|
76
|
-
def __deepcopy__(self, memo:
|
76
|
+
def __deepcopy__(self, memo: dict[int, Any]) -> Any:
|
77
77
|
"""Create a deep copy of the hierarchy element
|
78
78
|
|
79
79
|
Note that the copied diagnostic layer is not fully
|
@@ -121,13 +121,13 @@ class HierarchyElement(DiagLayer):
|
|
121
121
|
unit_groups = self._compute_available_unit_groups()
|
122
122
|
|
123
123
|
# convenience variable for the locally-defined unit spec
|
124
|
-
local_unit_spec:
|
124
|
+
local_unit_spec: UnitSpec | None
|
125
125
|
if self.diag_layer_raw.diag_data_dictionary_spec is not None:
|
126
126
|
local_unit_spec = self.diag_layer_raw.diag_data_dictionary_spec.unit_spec
|
127
127
|
else:
|
128
128
|
local_unit_spec = None
|
129
129
|
|
130
|
-
unit_spec:
|
130
|
+
unit_spec: UnitSpec | None
|
131
131
|
if local_unit_spec is None and not unit_groups:
|
132
132
|
# no locally defined unit spec and no inherited unit groups
|
133
133
|
unit_spec = None
|
@@ -188,8 +188,8 @@ class HierarchyElement(DiagLayer):
|
|
188
188
|
tables = self._compute_available_ddd_spec_items(
|
189
189
|
lambda ddd_spec: ddd_spec.tables, lambda parent_ref: parent_ref.not_inherited_tables)
|
190
190
|
|
191
|
-
ddds_admin_data:
|
192
|
-
ddds_sdgs:
|
191
|
+
ddds_admin_data: AdminData | None = None
|
192
|
+
ddds_sdgs: list[SpecialDataGroup] = []
|
193
193
|
if self.diag_layer_raw.diag_data_dictionary_spec:
|
194
194
|
ddds_admin_data = self.diag_layer_raw.diag_data_dictionary_spec.admin_data
|
195
195
|
ddds_sdgs = self.diag_layer_raw.diag_data_dictionary_spec.sdgs
|
@@ -291,7 +291,7 @@ class HierarchyElement(DiagLayer):
|
|
291
291
|
|
292
292
|
local_objects = get_local_objects(self)
|
293
293
|
local_object_short_names = {x.short_name for x in local_objects}
|
294
|
-
result_dict:
|
294
|
+
result_dict: dict[str, tuple[TNamed, DiagLayer]] = {}
|
295
295
|
|
296
296
|
# populate the result dictionary with the inherited objects
|
297
297
|
for parent_ref in self._get_parent_refs_sorted_by_priority(reverse=True):
|
@@ -361,7 +361,7 @@ class HierarchyElement(DiagLayer):
|
|
361
361
|
def get_local_objects_fn(dl: DiagLayer) -> Iterable[DiagComm]:
|
362
362
|
return dl._get_local_diag_comms(odxlinks)
|
363
363
|
|
364
|
-
def not_inherited_fn(parent_ref: ParentRef) ->
|
364
|
+
def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
|
365
365
|
return parent_ref.not_inherited_diag_comms
|
366
366
|
|
367
367
|
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
@@ -372,7 +372,7 @@ class HierarchyElement(DiagLayer):
|
|
372
372
|
def get_local_objects_fn(dl: DiagLayer) -> Iterable[Response]:
|
373
373
|
return dl.diag_layer_raw.global_negative_responses
|
374
374
|
|
375
|
-
def not_inherited_fn(parent_ref: ParentRef) ->
|
375
|
+
def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
|
376
376
|
return parent_ref.not_inherited_global_neg_responses
|
377
377
|
|
378
378
|
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
@@ -380,7 +380,7 @@ class HierarchyElement(DiagLayer):
|
|
380
380
|
def _compute_available_ddd_spec_items(
|
381
381
|
self,
|
382
382
|
include: Callable[[DiagDataDictionarySpec], Iterable[TNamed]],
|
383
|
-
exclude: Callable[["ParentRef"],
|
383
|
+
exclude: Callable[["ParentRef"], list[str]],
|
384
384
|
) -> NamedItemList[TNamed]:
|
385
385
|
|
386
386
|
def get_local_objects_fn(dl: DiagLayer) -> Iterable[TNamed]:
|
@@ -396,7 +396,7 @@ class HierarchyElement(DiagLayer):
|
|
396
396
|
def get_local_objects_fn(dl: DiagLayer) -> Iterable[FunctionalClass]:
|
397
397
|
return dl.diag_layer_raw.functional_classes
|
398
398
|
|
399
|
-
def not_inherited_fn(parent_ref: ParentRef) ->
|
399
|
+
def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
|
400
400
|
return []
|
401
401
|
|
402
402
|
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
@@ -406,7 +406,7 @@ class HierarchyElement(DiagLayer):
|
|
406
406
|
def get_local_objects_fn(dl: DiagLayer) -> Iterable[AdditionalAudience]:
|
407
407
|
return dl.diag_layer_raw.additional_audiences
|
408
408
|
|
409
|
-
def not_inherited_fn(parent_ref: ParentRef) ->
|
409
|
+
def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
|
410
410
|
return []
|
411
411
|
|
412
412
|
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
@@ -416,7 +416,7 @@ class HierarchyElement(DiagLayer):
|
|
416
416
|
def get_local_objects_fn(dl: DiagLayer) -> Iterable[StateChart]:
|
417
417
|
return dl.diag_layer_raw.state_charts
|
418
418
|
|
419
|
-
def not_inherited_fn(parent_ref: ParentRef) ->
|
419
|
+
def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
|
420
420
|
return []
|
421
421
|
|
422
422
|
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
@@ -426,7 +426,7 @@ class HierarchyElement(DiagLayer):
|
|
426
426
|
def get_local_objects_fn(dl: DiagLayer) -> Iterable[UnitGroup]:
|
427
427
|
return dl._get_local_unit_groups()
|
428
428
|
|
429
|
-
def not_inherited_fn(parent_ref: ParentRef) ->
|
429
|
+
def not_inherited_fn(parent_ref: ParentRef) -> list[str]:
|
430
430
|
return []
|
431
431
|
|
432
432
|
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
@@ -502,7 +502,7 @@ class HierarchyElement(DiagLayer):
|
|
502
502
|
#####
|
503
503
|
# <communication parameter handling>
|
504
504
|
#####
|
505
|
-
def _compute_available_commmunication_parameters(self) ->
|
505
|
+
def _compute_available_commmunication_parameters(self) -> list[ComparamInstance]:
|
506
506
|
"""Compute the list of communication parameters that apply to
|
507
507
|
the diagnostic layer
|
508
508
|
|
@@ -526,7 +526,7 @@ class HierarchyElement(DiagLayer):
|
|
526
526
|
without a specified protocol are taken as fallbacks...
|
527
527
|
|
528
528
|
"""
|
529
|
-
com_params_dict:
|
529
|
+
com_params_dict: dict[tuple[str, str | None], ComparamInstance] = {}
|
530
530
|
|
531
531
|
# Look in parent refs for inherited communication
|
532
532
|
# parameters. First fetch the communication parameters from
|
@@ -564,7 +564,7 @@ class HierarchyElement(DiagLayer):
|
|
564
564
|
"""
|
565
565
|
from .protocol import Protocol
|
566
566
|
|
567
|
-
result_dict:
|
567
|
+
result_dict: dict[str, Protocol] = {}
|
568
568
|
|
569
569
|
for parent_ref in getattr(self, "parent_refs", []):
|
570
570
|
for prot in getattr(parent_ref.layer, "protocols", []):
|
@@ -579,15 +579,15 @@ class HierarchyElement(DiagLayer):
|
|
579
579
|
self,
|
580
580
|
cp_short_name: str,
|
581
581
|
*,
|
582
|
-
protocol:
|
583
|
-
) ->
|
582
|
+
protocol: Union[str, "Protocol"] | None = None,
|
583
|
+
) -> ComparamInstance | None:
|
584
584
|
"""Find a specific communication parameter according to some criteria.
|
585
585
|
|
586
586
|
Setting a given parameter to `None` means "don't care"."""
|
587
587
|
|
588
588
|
from .protocol import Protocol
|
589
589
|
|
590
|
-
protocol_name:
|
590
|
+
protocol_name: str | None
|
591
591
|
if isinstance(protocol, Protocol):
|
592
592
|
protocol_name = protocol.short_name
|
593
593
|
else:
|
@@ -611,8 +611,7 @@ class HierarchyElement(DiagLayer):
|
|
611
611
|
return cps[0]
|
612
612
|
|
613
613
|
def get_max_can_payload_size(self,
|
614
|
-
protocol:
|
615
|
-
"Protocol"]] = None) -> Optional[int]:
|
614
|
+
protocol: Union[str, "Protocol"] | None = None) -> int | None:
|
616
615
|
"""Return the maximum size of a CAN frame payload that can be
|
617
616
|
transmitted in bytes.
|
618
617
|
|
@@ -642,13 +641,13 @@ class HierarchyElement(DiagLayer):
|
|
642
641
|
# unexpected format of parameter value
|
643
642
|
return 8
|
644
643
|
|
645
|
-
def uses_can(self, protocol:
|
644
|
+
def uses_can(self, protocol: Union[str, "Protocol"] | None = None) -> bool:
|
646
645
|
"""
|
647
646
|
Check if CAN ought to be used as the link layer protocol.
|
648
647
|
"""
|
649
648
|
return self.get_can_receive_id(protocol=protocol) is not None
|
650
649
|
|
651
|
-
def uses_can_fd(self, protocol:
|
650
|
+
def uses_can_fd(self, protocol: Union[str, "Protocol"] | None = None) -> bool:
|
652
651
|
"""Check if CAN-FD ought to be used.
|
653
652
|
|
654
653
|
If the ECU is not using CAN-FD for the specified protocol, `False`
|
@@ -667,7 +666,7 @@ class HierarchyElement(DiagLayer):
|
|
667
666
|
|
668
667
|
return "CANFD" in com_param.value
|
669
668
|
|
670
|
-
def get_can_baudrate(self, protocol:
|
669
|
+
def get_can_baudrate(self, protocol: Union[str, "Protocol"] | None = None) -> int | None:
|
671
670
|
"""Baudrate of the CAN bus which is used by the ECU [bits/s]
|
672
671
|
|
673
672
|
If the ECU is not using CAN for the specified protocol, None
|
@@ -684,8 +683,7 @@ class HierarchyElement(DiagLayer):
|
|
684
683
|
|
685
684
|
return int(val)
|
686
685
|
|
687
|
-
def get_can_fd_baudrate(self,
|
688
|
-
protocol: Optional[Union[str, "Protocol"]] = None) -> Optional[int]:
|
686
|
+
def get_can_fd_baudrate(self, protocol: Union[str, "Protocol"] | None = None) -> int | None:
|
689
687
|
"""Data baudrate of the CAN bus which is used by the ECU [bits/s]
|
690
688
|
|
691
689
|
If the ECU is not using CAN-FD for the specified protocol,
|
@@ -704,8 +702,7 @@ class HierarchyElement(DiagLayer):
|
|
704
702
|
|
705
703
|
return int(val)
|
706
704
|
|
707
|
-
def get_can_receive_id(self,
|
708
|
-
protocol: Optional[Union[str, "Protocol"]] = None) -> Optional[int]:
|
705
|
+
def get_can_receive_id(self, protocol: Union[str, "Protocol"] | None = None) -> int | None:
|
709
706
|
"""CAN ID to which the ECU listens for diagnostic messages"""
|
710
707
|
com_param = self.get_comparam("CP_UniqueRespIdTable", protocol=protocol)
|
711
708
|
if com_param is None:
|
@@ -724,7 +721,7 @@ class HierarchyElement(DiagLayer):
|
|
724
721
|
|
725
722
|
return int(result)
|
726
723
|
|
727
|
-
def get_can_send_id(self, protocol:
|
724
|
+
def get_can_send_id(self, protocol: Union[str, "Protocol"] | None = None) -> int | None:
|
728
725
|
"""CAN ID to which the ECU sends replies to diagnostic messages"""
|
729
726
|
|
730
727
|
# this hopefully resolves to the 'CP_UniqueRespIdTable'
|
@@ -749,8 +746,7 @@ class HierarchyElement(DiagLayer):
|
|
749
746
|
|
750
747
|
return int(result)
|
751
748
|
|
752
|
-
def get_can_func_req_id(self,
|
753
|
-
protocol: Optional[Union[str, "Protocol"]] = None) -> Optional[int]:
|
749
|
+
def get_can_func_req_id(self, protocol: Union[str, "Protocol"] | None = None) -> int | None:
|
754
750
|
"""CAN Functional Request Id."""
|
755
751
|
com_param = self.get_comparam("CP_CanFuncReqId", protocol=protocol)
|
756
752
|
if com_param is None:
|
@@ -764,8 +760,7 @@ class HierarchyElement(DiagLayer):
|
|
764
760
|
return int(result)
|
765
761
|
|
766
762
|
def get_doip_logical_ecu_address(self,
|
767
|
-
protocol:
|
768
|
-
"Protocol"]] = None) -> Optional[int]:
|
763
|
+
protocol: Union[str, "Protocol"] | None = None) -> int | None:
|
769
764
|
"""Return the address of the ECU when using functional addressing.
|
770
765
|
|
771
766
|
The parameter protocol is used to distinguish between
|
@@ -796,8 +791,8 @@ class HierarchyElement(DiagLayer):
|
|
796
791
|
return int(ecu_addr)
|
797
792
|
|
798
793
|
def get_doip_logical_gateway_address(self,
|
799
|
-
protocol:
|
800
|
-
) ->
|
794
|
+
protocol: Union[str, "Protocol"] | None = None
|
795
|
+
) -> int | None:
|
801
796
|
"""The logical gateway address for the diagnosis over IP transport protocol"""
|
802
797
|
|
803
798
|
# retrieve CP_DoIPLogicalGatewayAddress from the
|
@@ -814,8 +809,8 @@ class HierarchyElement(DiagLayer):
|
|
814
809
|
return int(result)
|
815
810
|
|
816
811
|
def get_doip_logical_tester_address(self,
|
817
|
-
protocol:
|
818
|
-
) ->
|
812
|
+
protocol: Union[str, "Protocol"] | None = None
|
813
|
+
) -> int | None:
|
819
814
|
"""DoIp logical gateway address"""
|
820
815
|
|
821
816
|
# retrieve CP_DoIPLogicalTesterAddress from the
|
@@ -832,8 +827,8 @@ class HierarchyElement(DiagLayer):
|
|
832
827
|
return int(result)
|
833
828
|
|
834
829
|
def get_doip_logical_functional_address(self,
|
835
|
-
protocol:
|
836
|
-
) ->
|
830
|
+
protocol: Union[str, "Protocol"] | None = None
|
831
|
+
) -> int | None:
|
837
832
|
"""The logical functional DoIP address of the ECU."""
|
838
833
|
|
839
834
|
# retrieve CP_DoIPLogicalFunctionalAddress from the
|
@@ -853,8 +848,8 @@ class HierarchyElement(DiagLayer):
|
|
853
848
|
return int(result)
|
854
849
|
|
855
850
|
def get_doip_routing_activation_timeout(self,
|
856
|
-
protocol:
|
857
|
-
) ->
|
851
|
+
protocol: Union[str, "Protocol"] | None = None
|
852
|
+
) -> float | None:
|
858
853
|
"""The timout for the DoIP routing activation request in seconds"""
|
859
854
|
|
860
855
|
# retrieve CP_DoIPRoutingActivationTimeout from the
|
@@ -871,8 +866,8 @@ class HierarchyElement(DiagLayer):
|
|
871
866
|
return float(result) / 1e6
|
872
867
|
|
873
868
|
def get_doip_routing_activation_type(self,
|
874
|
-
protocol:
|
875
|
-
) ->
|
869
|
+
protocol: Union[str, "Protocol"] | None = None
|
870
|
+
) -> int | None:
|
876
871
|
"""The DoIP routing activation type
|
877
872
|
|
878
873
|
The number returned has the following meaning:
|
@@ -897,8 +892,7 @@ class HierarchyElement(DiagLayer):
|
|
897
892
|
return int(result)
|
898
893
|
|
899
894
|
def get_tester_present_time(self,
|
900
|
-
protocol:
|
901
|
-
"Protocol"]] = None) -> Optional[float]:
|
895
|
+
protocol: Union[str, "Protocol"] | None = None) -> float | None:
|
902
896
|
"""Timeout on inactivity in seconds.
|
903
897
|
|
904
898
|
This is defined by the communication parameter "CP_TesterPresentTime".
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from ..comparaminstance import ComparamInstance
|
@@ -17,11 +17,11 @@ class HierarchyElementRaw(DiagLayerRaw):
|
|
17
17
|
This class represents the data present in the XML, not the "logical" view.
|
18
18
|
"""
|
19
19
|
|
20
|
-
comparam_refs:
|
20
|
+
comparam_refs: list[ComparamInstance]
|
21
21
|
|
22
22
|
@staticmethod
|
23
23
|
def from_et(et_element: ElementTree.Element,
|
24
|
-
doc_frags:
|
24
|
+
doc_frags: list[OdxDocFragment]) -> "HierarchyElementRaw":
|
25
25
|
# objects contained by diagnostic layers exibit an additional
|
26
26
|
# document fragment for the diag layer, so we use the document
|
27
27
|
# fragments of the odx id of the diag layer for IDs of
|
@@ -37,7 +37,7 @@ class HierarchyElementRaw(DiagLayerRaw):
|
|
37
37
|
|
38
38
|
return HierarchyElementRaw(comparam_refs=comparam_refs, **kwargs)
|
39
39
|
|
40
|
-
def _build_odxlinks(self) ->
|
40
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
41
41
|
result = super()._build_odxlinks()
|
42
42
|
|
43
43
|
for comparam_ref in self.comparam_refs:
|
odxtools/diaglayers/protocol.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from copy import deepcopy
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import Any,
|
4
|
+
from typing import Any, cast
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from ..comparamspec import ComparamSpec
|
@@ -29,11 +29,11 @@ class Protocol(HierarchyElement):
|
|
29
29
|
return self.protocol_raw.comparam_spec
|
30
30
|
|
31
31
|
@property
|
32
|
-
def prot_stack(self) ->
|
32
|
+
def prot_stack(self) -> ProtStack | None:
|
33
33
|
return self.protocol_raw.prot_stack
|
34
34
|
|
35
35
|
@staticmethod
|
36
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
36
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Protocol":
|
37
37
|
protocol_raw = ProtocolRaw.from_et(et_element, doc_frags)
|
38
38
|
|
39
39
|
return Protocol(diag_layer_raw=protocol_raw)
|
@@ -46,7 +46,7 @@ class Protocol(HierarchyElement):
|
|
46
46
|
"The raw diagnostic layer passed to Protocol "
|
47
47
|
"must be a ProtocolRaw")
|
48
48
|
|
49
|
-
def __deepcopy__(self, memo:
|
49
|
+
def __deepcopy__(self, memo: dict[int, Any]) -> Any:
|
50
50
|
"""Create a deep copy of the protocol layer
|
51
51
|
|
52
52
|
Note that the copied diagnostic layer is not fully
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from ..comparamspec import ComparamSpec
|
@@ -24,19 +24,19 @@ class ProtocolRaw(HierarchyElementRaw):
|
|
24
24
|
"""
|
25
25
|
|
26
26
|
comparam_spec_ref: OdxLinkRef
|
27
|
-
prot_stack_snref:
|
28
|
-
parent_refs:
|
27
|
+
prot_stack_snref: str | None
|
28
|
+
parent_refs: list[ParentRef]
|
29
29
|
|
30
30
|
@property
|
31
31
|
def comparam_spec(self) -> ComparamSpec:
|
32
32
|
return self._comparam_spec
|
33
33
|
|
34
34
|
@property
|
35
|
-
def prot_stack(self) ->
|
35
|
+
def prot_stack(self) -> ProtStack | None:
|
36
36
|
return self._prot_stack
|
37
37
|
|
38
38
|
@staticmethod
|
39
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
39
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "ProtocolRaw":
|
40
40
|
# objects contained by diagnostic layers exibit an additional
|
41
41
|
# document fragment for the diag layer, so we use the document
|
42
42
|
# fragments of the odx id of the diag layer for IDs of
|
@@ -63,7 +63,7 @@ class ProtocolRaw(HierarchyElementRaw):
|
|
63
63
|
parent_refs=parent_refs,
|
64
64
|
**kwargs)
|
65
65
|
|
66
|
-
def _build_odxlinks(self) ->
|
66
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
67
67
|
result = super()._build_odxlinks()
|
68
68
|
|
69
69
|
for parent_ref in self.parent_refs:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import IdentifiableElement
|
@@ -16,12 +16,12 @@ from .utils import dataclass_fields_asdict
|
|
16
16
|
@dataclass
|
17
17
|
class DiagnosticTroubleCode(IdentifiableElement):
|
18
18
|
trouble_code: int
|
19
|
-
display_trouble_code:
|
19
|
+
display_trouble_code: str | None
|
20
20
|
text: Text
|
21
|
-
level:
|
22
|
-
sdgs:
|
21
|
+
level: int | None
|
22
|
+
sdgs: list[SpecialDataGroup]
|
23
23
|
|
24
|
-
is_temporary_raw:
|
24
|
+
is_temporary_raw: bool | None
|
25
25
|
|
26
26
|
@property
|
27
27
|
def is_temporary(self) -> bool:
|
@@ -29,7 +29,7 @@ class DiagnosticTroubleCode(IdentifiableElement):
|
|
29
29
|
|
30
30
|
@staticmethod
|
31
31
|
def from_et(et_element: ElementTree.Element,
|
32
|
-
doc_frags:
|
32
|
+
doc_frags: list[OdxDocFragment]) -> "DiagnosticTroubleCode":
|
33
33
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
34
34
|
|
35
35
|
trouble_code = int(odxrequire(et_element.findtext("TROUBLE-CODE")))
|
@@ -53,8 +53,8 @@ class DiagnosticTroubleCode(IdentifiableElement):
|
|
53
53
|
is_temporary_raw=is_temporary_raw,
|
54
54
|
**kwargs)
|
55
55
|
|
56
|
-
def _build_odxlinks(self) ->
|
57
|
-
result:
|
56
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
57
|
+
result: dict[OdxLinkId, Any] = {}
|
58
58
|
|
59
59
|
result[self.odx_id] = self
|
60
60
|
|
odxtools/diagservice.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any,
|
3
|
+
from typing import Any, cast
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .addressing import Addressing
|
@@ -25,23 +25,23 @@ class DiagService(DiagComm):
|
|
25
25
|
"""Representation of a diagnostic service description.
|
26
26
|
"""
|
27
27
|
|
28
|
-
comparam_refs:
|
28
|
+
comparam_refs: list[ComparamInstance]
|
29
29
|
request_ref: OdxLinkRef
|
30
|
-
pos_response_refs:
|
31
|
-
neg_response_refs:
|
32
|
-
pos_response_suppressible:
|
30
|
+
pos_response_refs: list[OdxLinkRef]
|
31
|
+
neg_response_refs: list[OdxLinkRef]
|
32
|
+
pos_response_suppressible: PosResponseSuppressible | None
|
33
33
|
|
34
|
-
is_cyclic_raw:
|
35
|
-
is_multiple_raw:
|
36
|
-
addressing_raw:
|
37
|
-
transmission_mode_raw:
|
34
|
+
is_cyclic_raw: bool | None
|
35
|
+
is_multiple_raw: bool | None
|
36
|
+
addressing_raw: Addressing | None
|
37
|
+
transmission_mode_raw: TransMode | None
|
38
38
|
|
39
39
|
@property
|
40
40
|
def comparams(self) -> NamedItemList[ComparamInstance]:
|
41
41
|
return self._comparams
|
42
42
|
|
43
43
|
@property
|
44
|
-
def request(self) ->
|
44
|
+
def request(self) -> Request | None:
|
45
45
|
return self._request
|
46
46
|
|
47
47
|
@property
|
@@ -69,14 +69,14 @@ class DiagService(DiagComm):
|
|
69
69
|
return self.transmission_mode_raw or TransMode.SEND_AND_RECEIVE
|
70
70
|
|
71
71
|
@property
|
72
|
-
def free_parameters(self) ->
|
72
|
+
def free_parameters(self) -> list[Parameter]:
|
73
73
|
"""Return the list of parameters which can be freely specified by
|
74
74
|
the user when encoding the service's request.
|
75
75
|
"""
|
76
76
|
return self.request.free_parameters if self.request is not None else []
|
77
77
|
|
78
78
|
@staticmethod
|
79
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
79
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "DiagService":
|
80
80
|
|
81
81
|
kwargs = dataclass_fields_asdict(DiagComm.from_et(et_element, doc_frags))
|
82
82
|
|
@@ -104,7 +104,7 @@ class DiagService(DiagComm):
|
|
104
104
|
is_cyclic_raw = odxstr_to_bool(et_element.get("IS-CYCLIC"))
|
105
105
|
is_multiple_raw = odxstr_to_bool(et_element.get("IS-MULTIPLE"))
|
106
106
|
|
107
|
-
addressing_raw:
|
107
|
+
addressing_raw: Addressing | None = None
|
108
108
|
if (addressing_raw_str := et_element.get("ADDRESSING")) is not None:
|
109
109
|
try:
|
110
110
|
addressing_raw = Addressing(addressing_raw_str)
|
@@ -112,7 +112,7 @@ class DiagService(DiagComm):
|
|
112
112
|
addressing_raw = cast(Addressing, None)
|
113
113
|
odxraise(f"Encountered unknown addressing type '{addressing_raw_str}'")
|
114
114
|
|
115
|
-
transmission_mode_raw:
|
115
|
+
transmission_mode_raw: TransMode | None = None
|
116
116
|
if (transmission_mode_raw_str := et_element.get("TRANSMISSION-MODE")) is not None:
|
117
117
|
try:
|
118
118
|
transmission_mode_raw = TransMode(transmission_mode_raw_str)
|
@@ -132,7 +132,7 @@ class DiagService(DiagComm):
|
|
132
132
|
transmission_mode_raw=transmission_mode_raw,
|
133
133
|
**kwargs)
|
134
134
|
|
135
|
-
def _build_odxlinks(self) ->
|
135
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
136
136
|
result = super()._build_odxlinks()
|
137
137
|
|
138
138
|
for cpr in self.comparam_refs:
|
@@ -180,20 +180,20 @@ class DiagService(DiagComm):
|
|
180
180
|
|
181
181
|
def decode_message(self, raw_message: bytes) -> Message:
|
182
182
|
request_prefix = b''
|
183
|
-
candidate_coding_objects:
|
183
|
+
candidate_coding_objects: list[Request | Response] = [
|
184
184
|
*self.positive_responses, *self.negative_responses
|
185
185
|
]
|
186
186
|
if self.request is not None:
|
187
187
|
request_prefix = self.request.coded_const_prefix()
|
188
188
|
candidate_coding_objects.append(self.request)
|
189
189
|
|
190
|
-
coding_objects:
|
190
|
+
coding_objects: list[Request | Response] = []
|
191
191
|
for candidate_coding_object in candidate_coding_objects:
|
192
192
|
prefix = candidate_coding_object.coded_const_prefix(request_prefix=request_prefix)
|
193
193
|
if len(raw_message) >= len(prefix) and prefix == raw_message[:len(prefix)]:
|
194
194
|
coding_objects.append(candidate_coding_object)
|
195
195
|
|
196
|
-
result_list:
|
196
|
+
result_list: list[Message] = []
|
197
197
|
for coding_object in coding_objects:
|
198
198
|
try:
|
199
199
|
result_list.append(
|
odxtools/diagvariable.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import typing
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import Any,
|
4
|
+
from typing import Any, runtime_checkable
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from .admindata import AdminData
|
@@ -33,32 +33,32 @@ class DiagVariable(IdentifiableElement):
|
|
33
33
|
"""Representation of a diagnostic variable
|
34
34
|
"""
|
35
35
|
|
36
|
-
admin_data:
|
37
|
-
variable_group_ref:
|
38
|
-
sw_variables:
|
36
|
+
admin_data: AdminData | None
|
37
|
+
variable_group_ref: OdxLinkRef | None
|
38
|
+
sw_variables: list[SwVariable]
|
39
39
|
|
40
40
|
# a diag variable must specify either COMM-RELATIONS or a
|
41
41
|
# reference to a table row
|
42
|
-
comm_relations:
|
42
|
+
comm_relations: list[CommRelation]
|
43
43
|
|
44
44
|
# these are nested inside the SNREF-TO-TABLEROW tag
|
45
|
-
table_snref:
|
46
|
-
table_row_snref:
|
45
|
+
table_snref: str | None
|
46
|
+
table_row_snref: str | None
|
47
47
|
|
48
|
-
sdgs:
|
48
|
+
sdgs: list[SpecialDataGroup]
|
49
49
|
|
50
|
-
is_read_before_write_raw:
|
50
|
+
is_read_before_write_raw: bool | None
|
51
51
|
|
52
52
|
@property
|
53
|
-
def table(self) ->
|
53
|
+
def table(self) -> Table | None:
|
54
54
|
return self._table
|
55
55
|
|
56
56
|
@property
|
57
|
-
def table_row(self) ->
|
57
|
+
def table_row(self) -> TableRow | None:
|
58
58
|
return self._table_row
|
59
59
|
|
60
60
|
@property
|
61
|
-
def variable_group(self) ->
|
61
|
+
def variable_group(self) -> VariableGroup | None:
|
62
62
|
return self._variable_group
|
63
63
|
|
64
64
|
@property
|
@@ -66,7 +66,7 @@ class DiagVariable(IdentifiableElement):
|
|
66
66
|
return self.is_read_before_write_raw is True
|
67
67
|
|
68
68
|
@staticmethod
|
69
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
69
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "DiagVariable":
|
70
70
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
71
71
|
|
72
72
|
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
|
@@ -106,7 +106,7 @@ class DiagVariable(IdentifiableElement):
|
|
106
106
|
is_read_before_write_raw=is_read_before_write_raw,
|
107
107
|
**kwargs)
|
108
108
|
|
109
|
-
def _build_odxlinks(self) ->
|
109
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
110
110
|
result = {self.odx_id: self}
|
111
111
|
|
112
112
|
if self.admin_data is not None:
|