odxtools 9.7.0__py3-none-any.whl → 10.1.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 +7 -7
- odxtools/admindata.py +14 -13
- odxtools/audience.py +17 -17
- odxtools/basecomparam.py +9 -8
- odxtools/basevariantpattern.py +9 -10
- odxtools/basicstructure.py +15 -15
- odxtools/cli/_print_utils.py +34 -22
- odxtools/cli/browse.py +8 -8
- odxtools/cli/compare.py +24 -24
- odxtools/cli/decode.py +3 -4
- odxtools/cli/find.py +4 -5
- odxtools/cli/list.py +6 -6
- odxtools/cli/main.py +2 -2
- odxtools/cli/snoop.py +3 -3
- odxtools/codec.py +3 -3
- odxtools/commrelation.py +18 -17
- odxtools/companydata.py +13 -13
- odxtools/companydocinfo.py +15 -17
- odxtools/companyrevisioninfo.py +9 -9
- odxtools/companyspecificinfo.py +11 -13
- odxtools/comparam.py +8 -7
- odxtools/comparaminstance.py +14 -14
- odxtools/comparamspec.py +10 -11
- odxtools/comparamsubset.py +17 -25
- odxtools/complexcomparam.py +14 -14
- odxtools/complexdop.py +1 -1
- odxtools/compositecodec.py +8 -8
- odxtools/compumethods/compucodecompumethod.py +7 -7
- odxtools/compumethods/compuconst.py +5 -6
- odxtools/compumethods/compudefaultvalue.py +2 -3
- odxtools/compumethods/compuinternaltophys.py +13 -12
- odxtools/compumethods/compumethod.py +10 -9
- odxtools/compumethods/compuphystointernal.py +13 -12
- odxtools/compumethods/compurationalcoeffs.py +7 -7
- odxtools/compumethods/compuscale.py +15 -16
- odxtools/compumethods/createanycompumethod.py +12 -13
- odxtools/compumethods/identicalcompumethod.py +4 -5
- odxtools/compumethods/limit.py +14 -14
- odxtools/compumethods/linearcompumethod.py +5 -5
- odxtools/compumethods/linearsegment.py +10 -11
- odxtools/compumethods/ratfunccompumethod.py +6 -6
- odxtools/compumethods/ratfuncsegment.py +7 -8
- odxtools/compumethods/scalelinearcompumethod.py +9 -9
- odxtools/compumethods/scaleratfunccompumethod.py +7 -7
- odxtools/compumethods/tabintpcompumethod.py +10 -13
- odxtools/compumethods/texttablecompumethod.py +6 -6
- odxtools/createanycomparam.py +5 -7
- odxtools/createanydiagcodedtype.py +7 -8
- odxtools/database.py +34 -31
- odxtools/dataobjectproperty.py +19 -20
- odxtools/decodestate.py +5 -5
- odxtools/description.py +9 -9
- odxtools/determinenumberofitems.py +8 -7
- odxtools/diagcodedtype.py +10 -10
- odxtools/diagcomm.py +29 -30
- odxtools/diagdatadictionaryspec.py +36 -36
- odxtools/diaglayercontainer.py +35 -34
- odxtools/diaglayers/basevariant.py +14 -12
- odxtools/diaglayers/basevariantraw.py +22 -23
- odxtools/diaglayers/diaglayer.py +24 -22
- odxtools/diaglayers/diaglayerraw.py +43 -52
- odxtools/diaglayers/diaglayertype.py +1 -2
- odxtools/diaglayers/ecushareddata.py +9 -9
- odxtools/diaglayers/ecushareddataraw.py +15 -16
- odxtools/diaglayers/ecuvariant.py +15 -13
- odxtools/diaglayers/ecuvariantraw.py +21 -22
- odxtools/diaglayers/functionalgroup.py +12 -11
- odxtools/diaglayers/functionalgroupraw.py +17 -18
- odxtools/diaglayers/hierarchyelement.py +48 -54
- odxtools/diaglayers/hierarchyelementraw.py +10 -11
- odxtools/diaglayers/protocol.py +7 -7
- odxtools/diaglayers/protocolraw.py +13 -14
- odxtools/diagnostictroublecode.py +15 -17
- odxtools/diagservice.py +28 -27
- odxtools/diagvariable.py +24 -25
- odxtools/docrevision.py +18 -17
- odxtools/dopbase.py +13 -14
- odxtools/dtcconnector.py +8 -7
- odxtools/dtcdop.py +24 -20
- odxtools/dynamicendmarkerfield.py +10 -9
- odxtools/dynamiclengthfield.py +10 -9
- odxtools/dyndefinedspec.py +10 -10
- odxtools/dynenddopref.py +9 -9
- odxtools/dyniddefmodeinfo.py +21 -21
- odxtools/ecuvariantpattern.py +8 -10
- odxtools/element.py +12 -13
- odxtools/encodestate.py +11 -11
- odxtools/encoding.py +2 -3
- odxtools/endofpdufield.py +9 -10
- odxtools/envdataconnector.py +8 -8
- odxtools/environmentdata.py +7 -9
- odxtools/environmentdatadescription.py +18 -17
- odxtools/exceptions.py +5 -5
- odxtools/externalaccessmethod.py +4 -6
- odxtools/externaldoc.py +6 -6
- odxtools/field.py +15 -15
- odxtools/functionalclass.py +9 -9
- odxtools/inputparam.py +11 -10
- odxtools/internalconstr.py +10 -11
- odxtools/isotp_state_machine.py +12 -11
- odxtools/leadinglengthinfotype.py +4 -6
- odxtools/library.py +9 -8
- odxtools/linkeddtcdop.py +9 -8
- odxtools/loadfile.py +5 -6
- odxtools/matchingbasevariantparameter.py +5 -6
- odxtools/matchingparameter.py +10 -10
- odxtools/message.py +1 -1
- odxtools/minmaxlengthtype.py +6 -7
- odxtools/modification.py +7 -6
- odxtools/multiplexer.py +54 -18
- odxtools/multiplexercase.py +13 -13
- odxtools/multiplexerdefaultcase.py +11 -10
- odxtools/multiplexerswitchkey.py +8 -8
- odxtools/nameditemlist.py +13 -13
- odxtools/negoutputparam.py +8 -8
- odxtools/obd.py +1 -2
- odxtools/odxcategory.py +14 -26
- odxtools/odxdoccontext.py +16 -0
- odxtools/odxlink.py +23 -25
- odxtools/odxtypes.py +18 -15
- odxtools/outputparam.py +9 -8
- odxtools/parameterinfo.py +1 -1
- odxtools/parameters/codedconstparameter.py +10 -10
- odxtools/parameters/createanyparameter.py +15 -16
- odxtools/parameters/dynamicparameter.py +5 -7
- odxtools/parameters/lengthkeyparameter.py +10 -10
- odxtools/parameters/matchingrequestparameter.py +6 -7
- odxtools/parameters/nrcconstparameter.py +13 -13
- odxtools/parameters/parameter.py +17 -18
- odxtools/parameters/parameterwithdop.py +13 -13
- odxtools/parameters/physicalconstantparameter.py +8 -7
- odxtools/parameters/reservedparameter.py +6 -8
- odxtools/parameters/systemparameter.py +5 -7
- odxtools/parameters/tableentryparameter.py +8 -8
- odxtools/parameters/tablekeyparameter.py +17 -17
- odxtools/parameters/tablestructparameter.py +11 -11
- odxtools/parameters/valueparameter.py +11 -11
- odxtools/paramlengthinfotype.py +10 -9
- odxtools/parentref.py +15 -13
- odxtools/physicaldimension.py +15 -15
- odxtools/physicaltype.py +5 -6
- odxtools/posresponsesuppressible.py +11 -12
- odxtools/preconditionstateref.py +11 -11
- odxtools/progcode.py +11 -10
- odxtools/protstack.py +10 -9
- odxtools/relateddiagcommref.py +5 -6
- odxtools/relateddoc.py +11 -10
- odxtools/request.py +18 -19
- odxtools/response.py +19 -20
- odxtools/scaleconstr.py +8 -9
- odxtools/servicebinner.py +5 -5
- odxtools/singleecujob.py +16 -15
- odxtools/snrefcontext.py +3 -3
- odxtools/specialdata.py +8 -7
- odxtools/specialdatagroup.py +17 -17
- odxtools/specialdatagroupcaption.py +7 -6
- odxtools/standardlengthtype.py +14 -22
- odxtools/state.py +7 -6
- odxtools/statechart.py +12 -11
- odxtools/statemachine.py +4 -3
- odxtools/statetransition.py +9 -9
- odxtools/statetransitionref.py +19 -19
- odxtools/staticfield.py +9 -7
- odxtools/structure.py +5 -6
- odxtools/subcomponent.py +20 -18
- odxtools/subcomponentparamconnector.py +10 -9
- odxtools/subcomponentpattern.py +9 -9
- odxtools/swvariable.py +6 -7
- odxtools/table.py +25 -26
- odxtools/tablediagcommconnector.py +9 -8
- odxtools/tablerow.py +64 -43
- odxtools/tablerowconnector.py +8 -8
- odxtools/teammember.py +16 -15
- odxtools/templates/macros/printParentRef.xml.jinja2 +3 -1
- odxtools/text.py +4 -5
- odxtools/uds.py +2 -3
- odxtools/unit.py +14 -13
- odxtools/unitgroup.py +11 -10
- odxtools/unitspec.py +18 -19
- odxtools/utils.py +3 -3
- odxtools/variablegroup.py +5 -6
- odxtools/variantmatcher.py +10 -10
- odxtools/variantpattern.py +5 -6
- odxtools/version.py +2 -2
- odxtools/writepdxfile.py +5 -24
- odxtools/xdoc.py +13 -12
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/METADATA +4 -5
- odxtools-10.1.0.dist-info/RECORD +265 -0
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/WHEEL +1 -1
- odxtools-9.7.0.dist-info/RECORD +0 -264
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/entry_points.txt +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/licenses/LICENSE +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,13 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from ..diagvariable import DiagVariable
|
7
7
|
from ..exceptions import odxraise
|
8
8
|
from ..nameditemlist import NamedItemList
|
9
|
-
from ..
|
9
|
+
from ..odxdoccontext import OdxDocContext
|
10
|
+
from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
10
11
|
from ..parentref import ParentRef
|
11
12
|
from ..snrefcontext import SnRefContext
|
12
13
|
from ..utils import dataclass_fields_asdict
|
@@ -14,50 +15,48 @@ from ..variablegroup import VariableGroup
|
|
14
15
|
from .hierarchyelementraw import HierarchyElementRaw
|
15
16
|
|
16
17
|
|
17
|
-
@dataclass
|
18
|
+
@dataclass(kw_only=True)
|
18
19
|
class FunctionalGroupRaw(HierarchyElementRaw):
|
19
20
|
"""This is a diagnostic layer for common functionality of an ECU
|
20
21
|
"""
|
21
22
|
|
22
|
-
diag_variables_raw:
|
23
|
-
variable_groups: NamedItemList[VariableGroup]
|
24
|
-
parent_refs:
|
23
|
+
diag_variables_raw: list[DiagVariable | OdxLinkRef] = field(default_factory=list)
|
24
|
+
variable_groups: NamedItemList[VariableGroup] = field(default_factory=NamedItemList)
|
25
|
+
parent_refs: list[ParentRef] = field(default_factory=list)
|
25
26
|
|
26
27
|
@property
|
27
28
|
def diag_variables(self) -> NamedItemList[DiagVariable]:
|
28
29
|
return self._diag_variables
|
29
30
|
|
30
31
|
@staticmethod
|
31
|
-
def from_et(et_element: ElementTree.Element,
|
32
|
-
doc_frags: List[OdxDocFragment]) -> "FunctionalGroupRaw":
|
32
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "FunctionalGroupRaw":
|
33
33
|
# objects contained by diagnostic layers exibit an additional
|
34
34
|
# document fragment for the diag layer, so we use the document
|
35
35
|
# fragments of the odx id of the diag layer for IDs of
|
36
36
|
# contained objects.
|
37
|
-
her = HierarchyElementRaw.from_et(et_element,
|
37
|
+
her = HierarchyElementRaw.from_et(et_element, context)
|
38
38
|
kwargs = dataclass_fields_asdict(her)
|
39
|
-
doc_frags = her.odx_id.doc_fragments
|
40
39
|
|
41
|
-
diag_variables_raw:
|
40
|
+
diag_variables_raw: list[DiagVariable | OdxLinkRef] = []
|
42
41
|
if (dv_elems := et_element.find("DIAG-VARIABLES")) is not None:
|
43
42
|
for dv_proxy_elem in dv_elems:
|
44
|
-
dv_proxy:
|
43
|
+
dv_proxy: OdxLinkRef | DiagVariable
|
45
44
|
if dv_proxy_elem.tag == "DIAG-VARIABLE-REF":
|
46
|
-
dv_proxy = OdxLinkRef.from_et(dv_proxy_elem,
|
45
|
+
dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, context)
|
47
46
|
elif dv_proxy_elem.tag == "DIAG-VARIABLE":
|
48
|
-
dv_proxy = DiagVariable.from_et(dv_proxy_elem,
|
47
|
+
dv_proxy = DiagVariable.from_et(dv_proxy_elem, context)
|
49
48
|
else:
|
50
49
|
odxraise()
|
51
50
|
|
52
51
|
diag_variables_raw.append(dv_proxy)
|
53
52
|
|
54
53
|
variable_groups = NamedItemList([
|
55
|
-
VariableGroup.from_et(vg_elem,
|
54
|
+
VariableGroup.from_et(vg_elem, context)
|
56
55
|
for vg_elem in et_element.iterfind("VARIABLE-GROUPS/VARIABLE-GROUP")
|
57
56
|
])
|
58
57
|
|
59
58
|
parent_refs = [
|
60
|
-
ParentRef.from_et(pr_elem,
|
59
|
+
ParentRef.from_et(pr_elem, context)
|
61
60
|
for pr_elem in et_element.iterfind("PARENT-REFS/PARENT-REF")
|
62
61
|
]
|
63
62
|
|
@@ -67,7 +66,7 @@ class FunctionalGroupRaw(HierarchyElementRaw):
|
|
67
66
|
parent_refs=parent_refs,
|
68
67
|
**kwargs)
|
69
68
|
|
70
|
-
def _build_odxlinks(self) ->
|
69
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
71
70
|
result = super()._build_odxlinks()
|
72
71
|
|
73
72
|
for dv_proxy in self.diag_variables_raw:
|
@@ -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
|
@@ -17,7 +17,8 @@ from ..diagservice import DiagService
|
|
17
17
|
from ..exceptions import OdxWarning, odxassert, odxraise
|
18
18
|
from ..functionalclass import FunctionalClass
|
19
19
|
from ..nameditemlist import NamedItemList, OdxNamed
|
20
|
-
from ..
|
20
|
+
from ..odxdoccontext import OdxDocContext
|
21
|
+
from ..odxlink import OdxLinkDatabase, OdxLinkId
|
21
22
|
from ..parentref import ParentRef
|
22
23
|
from ..response import Response
|
23
24
|
from ..singleecujob import SingleEcuJob
|
@@ -30,13 +31,13 @@ from .diaglayer import DiagLayer
|
|
30
31
|
from .hierarchyelementraw import HierarchyElementRaw
|
31
32
|
|
32
33
|
if TYPE_CHECKING:
|
33
|
-
from
|
34
|
+
from ..database import Database
|
34
35
|
from .protocol import Protocol
|
35
36
|
|
36
37
|
TNamed = TypeVar("TNamed", bound=OdxNamed)
|
37
38
|
|
38
39
|
|
39
|
-
@dataclass
|
40
|
+
@dataclass(kw_only=True)
|
40
41
|
class HierarchyElement(DiagLayer):
|
41
42
|
"""This is the base class for diagnostic layers that may be involved in value inheritance
|
42
43
|
"""
|
@@ -46,9 +47,8 @@ class HierarchyElement(DiagLayer):
|
|
46
47
|
return cast(HierarchyElementRaw, self.diag_layer_raw)
|
47
48
|
|
48
49
|
@staticmethod
|
49
|
-
def from_et(et_element: ElementTree.Element,
|
50
|
-
|
51
|
-
hierarchy_element_raw = HierarchyElementRaw.from_et(et_element, doc_frags)
|
50
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "HierarchyElement":
|
51
|
+
hierarchy_element_raw = HierarchyElementRaw.from_et(et_element, context)
|
52
52
|
|
53
53
|
return HierarchyElement(diag_layer_raw=hierarchy_element_raw)
|
54
54
|
|
@@ -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 = 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 = 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 = 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,43 +1,42 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from ..comparaminstance import ComparamInstance
|
7
|
-
from ..
|
7
|
+
from ..odxdoccontext import OdxDocContext
|
8
|
+
from ..odxlink import OdxLinkDatabase, OdxLinkId
|
8
9
|
from ..snrefcontext import SnRefContext
|
9
10
|
from ..utils import dataclass_fields_asdict
|
10
11
|
from .diaglayerraw import DiagLayerRaw
|
11
12
|
|
12
13
|
|
13
|
-
@dataclass
|
14
|
+
@dataclass(kw_only=True)
|
14
15
|
class HierarchyElementRaw(DiagLayerRaw):
|
15
16
|
"""This is the base class for diagnostic layers that may be involved in value inheritance
|
16
17
|
|
17
18
|
This class represents the data present in the XML, not the "logical" view.
|
18
19
|
"""
|
19
20
|
|
20
|
-
comparam_refs:
|
21
|
+
comparam_refs: list[ComparamInstance] = field(default_factory=list)
|
21
22
|
|
22
23
|
@staticmethod
|
23
|
-
def from_et(et_element: ElementTree.Element,
|
24
|
-
doc_frags: List[OdxDocFragment]) -> "HierarchyElementRaw":
|
24
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "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
|
28
28
|
# contained objects.
|
29
|
-
dlr = DiagLayerRaw.from_et(et_element,
|
29
|
+
dlr = DiagLayerRaw.from_et(et_element, context)
|
30
30
|
kwargs = dataclass_fields_asdict(dlr)
|
31
|
-
doc_frags = dlr.odx_id.doc_fragments
|
32
31
|
|
33
32
|
comparam_refs = [
|
34
|
-
ComparamInstance.from_et(el,
|
33
|
+
ComparamInstance.from_et(el, context)
|
35
34
|
for el in et_element.iterfind("COMPARAM-REFS/COMPARAM-REF")
|
36
35
|
]
|
37
36
|
|
38
37
|
return HierarchyElementRaw(comparam_refs=comparam_refs, **kwargs)
|
39
38
|
|
40
|
-
def _build_odxlinks(self) ->
|
39
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
41
40
|
result = super()._build_odxlinks()
|
42
41
|
|
43
42
|
for comparam_ref in self.comparam_refs:
|
odxtools/diaglayers/protocol.py
CHANGED
@@ -1,18 +1,18 @@
|
|
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
|
8
8
|
from ..exceptions import odxassert
|
9
|
-
from ..
|
9
|
+
from ..odxdoccontext import OdxDocContext
|
10
10
|
from ..protstack import ProtStack
|
11
11
|
from .hierarchyelement import HierarchyElement
|
12
12
|
from .protocolraw import ProtocolRaw
|
13
13
|
|
14
14
|
|
15
|
-
@dataclass
|
15
|
+
@dataclass(kw_only=True)
|
16
16
|
class Protocol(HierarchyElement):
|
17
17
|
"""This is the class for primitives that are common for a given communication protocol
|
18
18
|
|
@@ -29,12 +29,12 @@ 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,
|
37
|
-
protocol_raw = ProtocolRaw.from_et(et_element,
|
36
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "Protocol":
|
37
|
+
protocol_raw = ProtocolRaw.from_et(et_element, context)
|
38
38
|
|
39
39
|
return Protocol(diag_layer_raw=protocol_raw)
|
40
40
|
|
@@ -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,20 +1,20 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from ..comparamspec import ComparamSpec
|
7
7
|
from ..exceptions import odxrequire
|
8
|
-
from ..
|
8
|
+
from ..odxdoccontext import OdxDocContext
|
9
|
+
from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
9
10
|
from ..parentref import ParentRef
|
10
11
|
from ..protstack import ProtStack
|
11
12
|
from ..snrefcontext import SnRefContext
|
12
13
|
from ..utils import dataclass_fields_asdict
|
13
|
-
#from .comparaminstance import ComparamInstance
|
14
14
|
from .hierarchyelementraw import HierarchyElementRaw
|
15
15
|
|
16
16
|
|
17
|
-
@dataclass
|
17
|
+
@dataclass(kw_only=True)
|
18
18
|
class ProtocolRaw(HierarchyElementRaw):
|
19
19
|
"""This is the base class for diagnostic layers that describe a
|
20
20
|
protocol which can be used to communicate with an ECU
|
@@ -24,36 +24,35 @@ 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 = None
|
28
|
+
parent_refs: list[ParentRef] = field(default_factory=list)
|
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,
|
39
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "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
|
43
43
|
# contained objects.
|
44
|
-
her = HierarchyElementRaw.from_et(et_element,
|
44
|
+
her = HierarchyElementRaw.from_et(et_element, context)
|
45
45
|
kwargs = dataclass_fields_asdict(her)
|
46
|
-
doc_frags = her.odx_id.doc_fragments
|
47
46
|
|
48
47
|
comparam_spec_ref = OdxLinkRef.from_et(
|
49
|
-
odxrequire(et_element.find("COMPARAM-SPEC-REF")),
|
48
|
+
odxrequire(et_element.find("COMPARAM-SPEC-REF")), context)
|
50
49
|
|
51
50
|
prot_stack_snref = None
|
52
51
|
if (prot_stack_snref_elem := et_element.find("PROT-STACK-SNREF")) is not None:
|
53
52
|
prot_stack_snref = odxrequire(prot_stack_snref_elem.get("SHORT-NAME"))
|
54
53
|
|
55
54
|
parent_refs = [
|
56
|
-
ParentRef.from_et(pr_el,
|
55
|
+
ParentRef.from_et(pr_el, context)
|
57
56
|
for pr_el in et_element.iterfind("PARENT-REFS/PARENT-REF")
|
58
57
|
]
|
59
58
|
|
@@ -63,7 +62,7 @@ class ProtocolRaw(HierarchyElementRaw):
|
|
63
62
|
parent_refs=parent_refs,
|
64
63
|
**kwargs)
|
65
64
|
|
66
|
-
def _build_odxlinks(self) ->
|
65
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
67
66
|
result = super()._build_odxlinks()
|
68
67
|
|
69
68
|
for parent_ref in self.parent_refs:
|