odxtools 6.7.0__py3-none-any.whl → 9.3.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/__init__.py +6 -4
- odxtools/additionalaudience.py +3 -5
- odxtools/admindata.py +5 -7
- odxtools/audience.py +10 -13
- odxtools/basecomparam.py +3 -5
- odxtools/basicstructure.py +55 -240
- odxtools/cli/_parser_utils.py +1 -1
- odxtools/cli/_print_utils.py +168 -134
- odxtools/cli/browse.py +111 -92
- odxtools/cli/compare.py +90 -71
- odxtools/cli/list.py +24 -15
- odxtools/cli/snoop.py +28 -5
- odxtools/codec.py +211 -0
- odxtools/commrelation.py +122 -0
- odxtools/companydata.py +5 -7
- odxtools/companydocinfo.py +7 -8
- odxtools/companyrevisioninfo.py +3 -5
- odxtools/companyspecificinfo.py +8 -9
- odxtools/comparam.py +4 -6
- odxtools/comparaminstance.py +7 -9
- odxtools/comparamspec.py +16 -54
- odxtools/comparamsubset.py +22 -62
- odxtools/complexcomparam.py +5 -7
- odxtools/compumethods/compucodecompumethod.py +63 -0
- odxtools/compumethods/compuconst.py +31 -0
- odxtools/compumethods/compudefaultvalue.py +27 -0
- odxtools/compumethods/compuinternaltophys.py +56 -0
- odxtools/compumethods/compuinversevalue.py +7 -0
- odxtools/compumethods/compumethod.py +93 -12
- odxtools/compumethods/compuphystointernal.py +56 -0
- odxtools/compumethods/compurationalcoeffs.py +20 -9
- odxtools/compumethods/compuscale.py +30 -35
- odxtools/compumethods/createanycompumethod.py +28 -161
- odxtools/compumethods/identicalcompumethod.py +31 -6
- odxtools/compumethods/linearcompumethod.py +69 -189
- odxtools/compumethods/linearsegment.py +190 -0
- odxtools/compumethods/ratfunccompumethod.py +106 -0
- odxtools/compumethods/ratfuncsegment.py +87 -0
- odxtools/compumethods/scalelinearcompumethod.py +132 -26
- odxtools/compumethods/scaleratfunccompumethod.py +113 -0
- odxtools/compumethods/tabintpcompumethod.py +119 -99
- odxtools/compumethods/texttablecompumethod.py +107 -43
- odxtools/createanydiagcodedtype.py +10 -67
- odxtools/database.py +167 -87
- odxtools/dataobjectproperty.py +15 -25
- odxtools/decodestate.py +9 -15
- odxtools/description.py +47 -0
- odxtools/determinenumberofitems.py +4 -5
- odxtools/diagcodedtype.py +36 -106
- odxtools/diagcomm.py +24 -12
- odxtools/diagdatadictionaryspec.py +33 -34
- odxtools/diaglayercontainer.py +46 -54
- odxtools/diaglayers/basevariant.py +128 -0
- odxtools/diaglayers/basevariantraw.py +123 -0
- odxtools/diaglayers/diaglayer.py +432 -0
- odxtools/{diaglayerraw.py → diaglayers/diaglayerraw.py} +105 -120
- odxtools/diaglayers/ecushareddata.py +96 -0
- odxtools/diaglayers/ecushareddataraw.py +87 -0
- odxtools/diaglayers/ecuvariant.py +124 -0
- odxtools/diaglayers/ecuvariantraw.py +129 -0
- odxtools/diaglayers/functionalgroup.py +110 -0
- odxtools/diaglayers/functionalgroupraw.py +106 -0
- odxtools/{diaglayer.py → diaglayers/hierarchyelement.py} +209 -448
- odxtools/diaglayers/hierarchyelementraw.py +58 -0
- odxtools/diaglayers/protocol.py +64 -0
- odxtools/diaglayers/protocolraw.py +91 -0
- odxtools/diagnostictroublecode.py +8 -9
- odxtools/diagservice.py +56 -43
- odxtools/diagvariable.py +113 -0
- odxtools/docrevision.py +5 -7
- odxtools/dopbase.py +15 -17
- odxtools/dtcdop.py +168 -50
- odxtools/dynamicendmarkerfield.py +134 -0
- odxtools/dynamiclengthfield.py +41 -37
- odxtools/dyndefinedspec.py +177 -0
- odxtools/dynenddopref.py +38 -0
- odxtools/ecuvariantmatcher.py +6 -7
- odxtools/element.py +13 -15
- odxtools/encodestate.py +199 -22
- odxtools/endofpdufield.py +31 -18
- odxtools/environmentdata.py +8 -1
- odxtools/environmentdatadescription.py +198 -38
- odxtools/exceptions.py +11 -2
- odxtools/field.py +10 -10
- odxtools/functionalclass.py +3 -5
- odxtools/inputparam.py +3 -12
- odxtools/leadinglengthinfotype.py +37 -18
- odxtools/library.py +66 -0
- odxtools/loadfile.py +64 -0
- odxtools/matchingparameter.py +3 -3
- odxtools/message.py +0 -7
- odxtools/minmaxlengthtype.py +61 -33
- odxtools/modification.py +3 -5
- odxtools/multiplexer.py +128 -73
- odxtools/multiplexercase.py +13 -14
- odxtools/multiplexerdefaultcase.py +15 -12
- odxtools/multiplexerswitchkey.py +4 -5
- odxtools/nameditemlist.py +29 -5
- odxtools/negoutputparam.py +3 -5
- odxtools/odxcategory.py +83 -0
- odxtools/odxlink.py +60 -51
- odxtools/odxtypes.py +37 -5
- odxtools/outputparam.py +4 -15
- odxtools/parameterinfo.py +218 -67
- odxtools/parameters/codedconstparameter.py +16 -24
- odxtools/parameters/dynamicparameter.py +5 -4
- odxtools/parameters/lengthkeyparameter.py +60 -26
- odxtools/parameters/matchingrequestparameter.py +23 -11
- odxtools/parameters/nrcconstparameter.py +45 -46
- odxtools/parameters/parameter.py +54 -56
- odxtools/parameters/parameterwithdop.py +15 -25
- odxtools/parameters/physicalconstantparameter.py +15 -18
- odxtools/parameters/reservedparameter.py +6 -2
- odxtools/parameters/systemparameter.py +55 -11
- odxtools/parameters/tableentryparameter.py +3 -2
- odxtools/parameters/tablekeyparameter.py +103 -49
- odxtools/parameters/tablestructparameter.py +47 -48
- odxtools/parameters/valueparameter.py +16 -20
- odxtools/paramlengthinfotype.py +52 -32
- odxtools/parentref.py +16 -2
- odxtools/physicaldimension.py +3 -8
- odxtools/progcode.py +26 -11
- odxtools/protstack.py +3 -5
- odxtools/py.typed +0 -0
- odxtools/relateddoc.py +7 -9
- odxtools/request.py +120 -10
- odxtools/response.py +123 -23
- odxtools/scaleconstr.py +3 -3
- odxtools/servicebinner.py +1 -1
- odxtools/singleecujob.py +12 -10
- odxtools/snrefcontext.py +29 -0
- odxtools/specialdata.py +3 -5
- odxtools/specialdatagroup.py +7 -9
- odxtools/specialdatagroupcaption.py +3 -6
- odxtools/standardlengthtype.py +80 -14
- odxtools/state.py +3 -5
- odxtools/statechart.py +13 -19
- odxtools/statetransition.py +7 -17
- odxtools/staticfield.py +31 -25
- odxtools/subcomponent.py +288 -0
- odxtools/swvariable.py +21 -0
- odxtools/table.py +7 -8
- odxtools/tablerow.py +19 -11
- odxtools/teammember.py +3 -5
- odxtools/templates/comparam-spec.odx-c.xml.jinja2 +4 -24
- odxtools/templates/comparam-subset.odx-cs.xml.jinja2 +5 -26
- odxtools/templates/diag_layer_container.odx-d.xml.jinja2 +15 -31
- odxtools/templates/{index.xml.xml.jinja2 → index.xml.jinja2} +1 -1
- odxtools/templates/macros/printAudience.xml.jinja2 +1 -1
- odxtools/templates/macros/printBaseVariant.xml.jinja2 +53 -0
- odxtools/templates/macros/printCompanyData.xml.jinja2 +4 -7
- odxtools/templates/macros/printComparam.xml.jinja2 +6 -4
- odxtools/templates/macros/printComparamRef.xml.jinja2 +5 -12
- odxtools/templates/macros/printCompuMethod.xml.jinja2 +147 -0
- odxtools/templates/macros/printDOP.xml.jinja2 +27 -133
- odxtools/templates/macros/printDescription.xml.jinja2 +18 -0
- odxtools/templates/macros/printDiagComm.xml.jinja2 +1 -1
- odxtools/templates/macros/printDiagLayer.xml.jinja2 +222 -0
- odxtools/templates/macros/printDiagVariable.xml.jinja2 +66 -0
- odxtools/templates/macros/printDynDefinedSpec.xml.jinja2 +48 -0
- odxtools/templates/macros/printDynamicEndmarkerField.xml.jinja2 +16 -0
- odxtools/templates/macros/printDynamicLengthField.xml.jinja2 +1 -1
- odxtools/templates/macros/printEcuSharedData.xml.jinja2 +30 -0
- odxtools/templates/macros/printEcuVariant.xml.jinja2 +53 -0
- odxtools/templates/macros/printEcuVariantPattern.xml.jinja2 +1 -1
- odxtools/templates/macros/printElementId.xml.jinja2 +8 -3
- odxtools/templates/macros/printEndOfPdu.xml.jinja2 +1 -1
- odxtools/templates/macros/printEnvDataDesc.xml.jinja2 +1 -1
- odxtools/templates/macros/printFunctionalClass.xml.jinja2 +1 -1
- odxtools/templates/macros/printFunctionalGroup.xml.jinja2 +40 -0
- odxtools/templates/macros/printHierarchyElement.xml.jinja2 +24 -0
- odxtools/templates/macros/printLibrary.xml.jinja2 +21 -0
- odxtools/templates/macros/printMux.xml.jinja2 +4 -3
- odxtools/templates/macros/printOdxCategory.xml.jinja2 +28 -0
- odxtools/templates/macros/printParam.xml.jinja2 +11 -12
- odxtools/templates/macros/printProtStack.xml.jinja2 +1 -1
- odxtools/templates/macros/printProtocol.xml.jinja2 +30 -0
- odxtools/templates/macros/printRequest.xml.jinja2 +1 -1
- odxtools/templates/macros/printResponse.xml.jinja2 +1 -1
- odxtools/templates/macros/printService.xml.jinja2 +3 -2
- odxtools/templates/macros/printSingleEcuJob.xml.jinja2 +5 -26
- odxtools/templates/macros/printSpecialData.xml.jinja2 +1 -1
- odxtools/templates/macros/printState.xml.jinja2 +1 -1
- odxtools/templates/macros/printStateChart.xml.jinja2 +1 -1
- odxtools/templates/macros/printStateTransition.xml.jinja2 +1 -1
- odxtools/templates/macros/printStaticField.xml.jinja2 +1 -1
- odxtools/templates/macros/printStructure.xml.jinja2 +1 -1
- odxtools/templates/macros/printSubComponent.xml.jinja2 +104 -0
- odxtools/templates/macros/printTable.xml.jinja2 +4 -5
- odxtools/templates/macros/printUnitSpec.xml.jinja2 +3 -5
- odxtools/uds.py +2 -10
- odxtools/unit.py +4 -8
- odxtools/unitgroup.py +3 -5
- odxtools/unitspec.py +17 -17
- odxtools/utils.py +38 -20
- odxtools/variablegroup.py +32 -0
- odxtools/version.py +2 -2
- odxtools/{write_pdx_file.py → writepdxfile.py} +20 -10
- odxtools/xdoc.py +3 -5
- {odxtools-6.7.0.dist-info → odxtools-9.3.0.dist-info}/METADATA +20 -21
- odxtools-9.3.0.dist-info/RECORD +228 -0
- {odxtools-6.7.0.dist-info → odxtools-9.3.0.dist-info}/WHEEL +1 -1
- odxtools/createcompanydatas.py +0 -17
- odxtools/createsdgs.py +0 -19
- odxtools/load_file.py +0 -13
- odxtools/load_odx_d_file.py +0 -6
- odxtools/load_pdx_file.py +0 -8
- odxtools/templates/macros/printVariant.xml.jinja2 +0 -216
- odxtools-6.7.0.dist-info/RECORD +0 -182
- /odxtools/{diaglayertype.py → diaglayers/diaglayertype.py} +0 -0
- {odxtools-6.7.0.dist-info → odxtools-9.3.0.dist-info}/LICENSE +0 -0
- {odxtools-6.7.0.dist-info → odxtools-9.3.0.dist-info}/entry_points.txt +0 -0
- {odxtools-6.7.0.dist-info → odxtools-9.3.0.dist-info}/top_level.txt +0 -0
odxtools/diaglayercontainer.py
CHANGED
@@ -1,32 +1,39 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
3
|
from itertools import chain
|
4
|
-
from typing import Any, Dict, List,
|
4
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Union
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
|
-
from .
|
8
|
-
from .
|
9
|
-
from .
|
10
|
-
from .
|
11
|
-
from .
|
12
|
-
from .
|
13
|
-
from .exceptions import odxrequire
|
7
|
+
from .diaglayers.basevariant import BaseVariant
|
8
|
+
from .diaglayers.diaglayer import DiagLayer
|
9
|
+
from .diaglayers.ecushareddata import EcuSharedData
|
10
|
+
from .diaglayers.ecuvariant import EcuVariant
|
11
|
+
from .diaglayers.functionalgroup import FunctionalGroup
|
12
|
+
from .diaglayers.protocol import Protocol
|
14
13
|
from .nameditemlist import NamedItemList
|
14
|
+
from .odxcategory import OdxCategory
|
15
15
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
16
|
-
from .
|
16
|
+
from .snrefcontext import SnRefContext
|
17
17
|
from .utils import dataclass_fields_asdict
|
18
18
|
|
19
|
+
if TYPE_CHECKING:
|
20
|
+
from .database import Database
|
21
|
+
|
19
22
|
|
20
23
|
@dataclass
|
21
|
-
class DiagLayerContainer(
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
24
|
+
class DiagLayerContainer(OdxCategory):
|
25
|
+
ecu_shared_datas: NamedItemList[EcuSharedData]
|
26
|
+
protocols: NamedItemList[Protocol]
|
27
|
+
functional_groups: NamedItemList[FunctionalGroup]
|
28
|
+
base_variants: NamedItemList[BaseVariant]
|
29
|
+
ecu_variants: NamedItemList[EcuVariant]
|
30
|
+
|
31
|
+
@property
|
32
|
+
def ecus(self) -> NamedItemList[EcuVariant]:
|
33
|
+
"""ECU variants defined in the container
|
34
|
+
|
35
|
+
This property is an alias for `.ecu_variants`"""
|
36
|
+
return self.ecu_variants
|
30
37
|
|
31
38
|
def __post_init__(self) -> None:
|
32
39
|
self._diag_layers = NamedItemList[DiagLayer](chain(
|
@@ -41,56 +48,41 @@ class DiagLayerContainer(IdentifiableElement):
|
|
41
48
|
def from_et(et_element: ElementTree.Element,
|
42
49
|
doc_frags: List[OdxDocFragment]) -> "DiagLayerContainer":
|
43
50
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
doc_frags = [OdxDocFragment(short_name, "CONTAINER")]
|
48
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
51
|
+
cat = OdxCategory.category_from_et(et_element, doc_frags, doc_type="CONTAINER")
|
52
|
+
doc_frags = cat.odx_id.doc_fragments
|
53
|
+
kwargs = dataclass_fields_asdict(cat)
|
49
54
|
|
50
|
-
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
|
51
|
-
company_datas = create_company_datas_from_et(et_element.find("COMPANY-DATAS"), doc_frags)
|
52
55
|
ecu_shared_datas = NamedItemList([
|
53
|
-
|
56
|
+
EcuSharedData.from_et(dl_element, doc_frags)
|
54
57
|
for dl_element in et_element.iterfind("ECU-SHARED-DATAS/ECU-SHARED-DATA")
|
55
58
|
])
|
56
59
|
protocols = NamedItemList([
|
57
|
-
|
60
|
+
Protocol.from_et(dl_element, doc_frags)
|
58
61
|
for dl_element in et_element.iterfind("PROTOCOLS/PROTOCOL")
|
59
62
|
])
|
60
63
|
functional_groups = NamedItemList([
|
61
|
-
|
64
|
+
FunctionalGroup.from_et(dl_element, doc_frags)
|
62
65
|
for dl_element in et_element.iterfind("FUNCTIONAL-GROUPS/FUNCTIONAL-GROUP")
|
63
66
|
])
|
64
67
|
base_variants = NamedItemList([
|
65
|
-
|
68
|
+
BaseVariant.from_et(dl_element, doc_frags)
|
66
69
|
for dl_element in et_element.iterfind("BASE-VARIANTS/BASE-VARIANT")
|
67
70
|
])
|
68
71
|
ecu_variants = NamedItemList([
|
69
|
-
|
72
|
+
EcuVariant.from_et(dl_element, doc_frags)
|
70
73
|
for dl_element in et_element.iterfind("ECU-VARIANTS/ECU-VARIANT")
|
71
74
|
])
|
72
|
-
sdgs = create_sdgs_from_et(et_element.find("SDGS"), doc_frags)
|
73
75
|
|
74
76
|
return DiagLayerContainer(
|
75
|
-
admin_data=admin_data,
|
76
|
-
company_datas=company_datas,
|
77
77
|
ecu_shared_datas=ecu_shared_datas,
|
78
78
|
protocols=protocols,
|
79
79
|
functional_groups=functional_groups,
|
80
80
|
base_variants=base_variants,
|
81
81
|
ecu_variants=ecu_variants,
|
82
|
-
sdgs=sdgs,
|
83
82
|
**kwargs)
|
84
83
|
|
85
84
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
86
|
-
result =
|
87
|
-
|
88
|
-
if self.admin_data is not None:
|
89
|
-
result.update(self.admin_data._build_odxlinks())
|
90
|
-
for cd in self.company_datas:
|
91
|
-
result.update(cd._build_odxlinks())
|
92
|
-
for sdg in self.sdgs:
|
93
|
-
result.update(sdg._build_odxlinks())
|
85
|
+
result = super()._build_odxlinks()
|
94
86
|
|
95
87
|
for ecu_shared_data in self.ecu_shared_datas:
|
96
88
|
result.update(ecu_shared_data._build_odxlinks())
|
@@ -106,12 +98,7 @@ class DiagLayerContainer(IdentifiableElement):
|
|
106
98
|
return result
|
107
99
|
|
108
100
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
109
|
-
|
110
|
-
self.admin_data._resolve_odxlinks(odxlinks)
|
111
|
-
for cd in self.company_datas:
|
112
|
-
cd._resolve_odxlinks(odxlinks)
|
113
|
-
for sdg in self.sdgs:
|
114
|
-
sdg._resolve_odxlinks(odxlinks)
|
101
|
+
super()._resolve_odxlinks(odxlinks)
|
115
102
|
|
116
103
|
for ecu_shared_data in self.ecu_shared_datas:
|
117
104
|
ecu_shared_data._resolve_odxlinks(odxlinks)
|
@@ -124,17 +111,22 @@ class DiagLayerContainer(IdentifiableElement):
|
|
124
111
|
for ecu_variant in self.ecu_variants:
|
125
112
|
ecu_variant._resolve_odxlinks(odxlinks)
|
126
113
|
|
127
|
-
def _finalize_init(self, odxlinks: OdxLinkDatabase) -> None:
|
114
|
+
def _finalize_init(self, database: "Database", odxlinks: OdxLinkDatabase) -> None:
|
115
|
+
super()._finalize_init(database, odxlinks)
|
116
|
+
|
128
117
|
for ecu_shared_data in self.ecu_shared_datas:
|
129
|
-
ecu_shared_data._finalize_init(odxlinks)
|
118
|
+
ecu_shared_data._finalize_init(database, odxlinks)
|
130
119
|
for protocol in self.protocols:
|
131
|
-
protocol._finalize_init(odxlinks)
|
120
|
+
protocol._finalize_init(database, odxlinks)
|
132
121
|
for functional_group in self.functional_groups:
|
133
|
-
functional_group._finalize_init(odxlinks)
|
122
|
+
functional_group._finalize_init(database, odxlinks)
|
134
123
|
for base_variant in self.base_variants:
|
135
|
-
base_variant._finalize_init(odxlinks)
|
124
|
+
base_variant._finalize_init(database, odxlinks)
|
136
125
|
for ecu_variant in self.ecu_variants:
|
137
|
-
ecu_variant._finalize_init(odxlinks)
|
126
|
+
ecu_variant._finalize_init(database, odxlinks)
|
127
|
+
|
128
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
129
|
+
super()._resolve_snrefs(context)
|
138
130
|
|
139
131
|
@property
|
140
132
|
def diag_layers(self) -> NamedItemList[DiagLayer]:
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from copy import deepcopy
|
3
|
+
from dataclasses import dataclass
|
4
|
+
from typing import Any, Dict, Iterable, List, Optional, Union, cast
|
5
|
+
from xml.etree import ElementTree
|
6
|
+
|
7
|
+
from typing_extensions import override
|
8
|
+
|
9
|
+
from ..diagvariable import DiagVariable
|
10
|
+
from ..dyndefinedspec import DynDefinedSpec
|
11
|
+
from ..exceptions import odxassert
|
12
|
+
from ..nameditemlist import NamedItemList
|
13
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef
|
14
|
+
from ..parentref import ParentRef
|
15
|
+
from ..variablegroup import VariableGroup
|
16
|
+
from .basevariantraw import BaseVariantRaw
|
17
|
+
from .diaglayer import DiagLayer
|
18
|
+
from .hierarchyelement import HierarchyElement
|
19
|
+
|
20
|
+
|
21
|
+
@dataclass
|
22
|
+
class BaseVariant(HierarchyElement):
|
23
|
+
"""This is a diagnostic layer for common functionality of an ECU
|
24
|
+
"""
|
25
|
+
|
26
|
+
@property
|
27
|
+
def base_variant_raw(self) -> BaseVariantRaw:
|
28
|
+
return cast(BaseVariantRaw, self.diag_layer_raw)
|
29
|
+
|
30
|
+
#####
|
31
|
+
# <properties forwarded to the "raw" base variant>
|
32
|
+
#####
|
33
|
+
@property
|
34
|
+
def diag_variables_raw(self) -> List[Union[DiagVariable, OdxLinkRef]]:
|
35
|
+
return self.base_variant_raw.diag_variables_raw
|
36
|
+
|
37
|
+
@property
|
38
|
+
def dyn_defined_spec(self) -> Optional[DynDefinedSpec]:
|
39
|
+
return self.base_variant_raw.dyn_defined_spec
|
40
|
+
|
41
|
+
@property
|
42
|
+
def parent_refs(self) -> List[ParentRef]:
|
43
|
+
return self.base_variant_raw.parent_refs
|
44
|
+
|
45
|
+
#####
|
46
|
+
# </properties forwarded to the "raw" base variant>
|
47
|
+
#####
|
48
|
+
|
49
|
+
#######
|
50
|
+
# <properties subject to value inheritance>
|
51
|
+
#######
|
52
|
+
@property
|
53
|
+
def diag_variables(self) -> NamedItemList[DiagVariable]:
|
54
|
+
return self._diag_variables
|
55
|
+
|
56
|
+
@property
|
57
|
+
def variable_groups(self) -> NamedItemList[VariableGroup]:
|
58
|
+
return self._variable_groups
|
59
|
+
|
60
|
+
#######
|
61
|
+
# </properties subject to value inheritance>
|
62
|
+
#######
|
63
|
+
|
64
|
+
@staticmethod
|
65
|
+
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "BaseVariant":
|
66
|
+
base_variant_raw = BaseVariantRaw.from_et(et_element, doc_frags)
|
67
|
+
|
68
|
+
return BaseVariant(diag_layer_raw=base_variant_raw)
|
69
|
+
|
70
|
+
def __post_init__(self) -> None:
|
71
|
+
super().__post_init__()
|
72
|
+
|
73
|
+
odxassert(
|
74
|
+
isinstance(self.diag_layer_raw, BaseVariantRaw),
|
75
|
+
"The raw diagnostic layer passed to BaseVariant "
|
76
|
+
"must be a BaseVariantRaw")
|
77
|
+
|
78
|
+
def __deepcopy__(self, memo: Dict[int, Any]) -> Any:
|
79
|
+
"""Create a deep copy of the base variant
|
80
|
+
|
81
|
+
Note that the copied diagnostic layer is not fully
|
82
|
+
initialized, so `_finalize_init()` should to be called on it
|
83
|
+
before it can be used normally.
|
84
|
+
"""
|
85
|
+
|
86
|
+
result = super().__deepcopy__(memo)
|
87
|
+
|
88
|
+
# note that the self.base_variant_raw object is *not* copied at
|
89
|
+
# this place because the attribute points to the same object
|
90
|
+
# as self.diag_layer_raw.
|
91
|
+
result.base_variant_raw = deepcopy(self.base_variant_raw, memo)
|
92
|
+
|
93
|
+
return result
|
94
|
+
|
95
|
+
@override
|
96
|
+
def _compute_value_inheritance(self, odxlinks: OdxLinkDatabase) -> None:
|
97
|
+
super()._compute_value_inheritance(odxlinks)
|
98
|
+
|
99
|
+
self._diag_variables = NamedItemList(self._compute_available_diag_variables(odxlinks))
|
100
|
+
self._variable_groups = NamedItemList(self._compute_available_variable_groups(odxlinks))
|
101
|
+
|
102
|
+
def _compute_available_diag_variables(self,
|
103
|
+
odxlinks: OdxLinkDatabase) -> Iterable[DiagVariable]:
|
104
|
+
|
105
|
+
def get_local_objects_fn(dl: DiagLayer) -> Iterable[DiagVariable]:
|
106
|
+
if not hasattr(dl.diag_layer_raw, "diag_variables"):
|
107
|
+
return []
|
108
|
+
|
109
|
+
return dl.diag_layer_raw.diag_variables # type: ignore[no-any-return]
|
110
|
+
|
111
|
+
def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
|
112
|
+
return parent_ref.not_inherited_variables
|
113
|
+
|
114
|
+
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
115
|
+
|
116
|
+
def _compute_available_variable_groups(self,
|
117
|
+
odxlinks: OdxLinkDatabase) -> Iterable[VariableGroup]:
|
118
|
+
|
119
|
+
def get_local_objects_fn(dl: DiagLayer) -> Iterable[VariableGroup]:
|
120
|
+
if not hasattr(dl.diag_layer_raw, "variable_groups"):
|
121
|
+
return []
|
122
|
+
|
123
|
+
return dl.diag_layer_raw.variable_groups # type: ignore[no-any-return]
|
124
|
+
|
125
|
+
def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
|
126
|
+
return []
|
127
|
+
|
128
|
+
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import Any, Dict, List, Optional, Union
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from ..diagvariable import DiagVariable
|
7
|
+
from ..dyndefinedspec import DynDefinedSpec
|
8
|
+
from ..exceptions import odxraise
|
9
|
+
from ..nameditemlist import NamedItemList
|
10
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
11
|
+
from ..parentref import ParentRef
|
12
|
+
from ..snrefcontext import SnRefContext
|
13
|
+
from ..utils import dataclass_fields_asdict
|
14
|
+
from ..variablegroup import VariableGroup
|
15
|
+
from .hierarchyelementraw import HierarchyElementRaw
|
16
|
+
|
17
|
+
|
18
|
+
@dataclass
|
19
|
+
class BaseVariantRaw(HierarchyElementRaw):
|
20
|
+
"""This is a diagnostic layer for common functionality of an ECU
|
21
|
+
"""
|
22
|
+
|
23
|
+
diag_variables_raw: List[Union[DiagVariable, OdxLinkRef]]
|
24
|
+
variable_groups: NamedItemList[VariableGroup]
|
25
|
+
dyn_defined_spec: Optional[DynDefinedSpec]
|
26
|
+
# TODO: base_variant_pattern: Optional[BaseVariantPattern]
|
27
|
+
parent_refs: List[ParentRef]
|
28
|
+
|
29
|
+
@property
|
30
|
+
def diag_variables(self) -> NamedItemList[DiagVariable]:
|
31
|
+
return self._diag_variables
|
32
|
+
|
33
|
+
@staticmethod
|
34
|
+
def from_et(et_element: ElementTree.Element,
|
35
|
+
doc_frags: List[OdxDocFragment]) -> "BaseVariantRaw":
|
36
|
+
# objects contained by diagnostic layers exibit an additional
|
37
|
+
# document fragment for the diag layer, so we use the document
|
38
|
+
# fragments of the odx id of the diag layer for IDs of
|
39
|
+
# contained objects.
|
40
|
+
her = HierarchyElementRaw.from_et(et_element, doc_frags)
|
41
|
+
kwargs = dataclass_fields_asdict(her)
|
42
|
+
doc_frags = her.odx_id.doc_fragments
|
43
|
+
|
44
|
+
diag_variables_raw: List[Union[DiagVariable, OdxLinkRef]] = []
|
45
|
+
if (dv_elems := et_element.find("DIAG-VARIABLES")) is not None:
|
46
|
+
for dv_proxy_elem in dv_elems:
|
47
|
+
dv_proxy: Union[OdxLinkRef, DiagVariable]
|
48
|
+
if dv_proxy_elem.tag == "DIAG-VARIABLE-REF":
|
49
|
+
dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, doc_frags)
|
50
|
+
elif dv_proxy_elem.tag == "DIAG-VARIABLE":
|
51
|
+
dv_proxy = DiagVariable.from_et(dv_proxy_elem, doc_frags)
|
52
|
+
else:
|
53
|
+
odxraise()
|
54
|
+
|
55
|
+
diag_variables_raw.append(dv_proxy)
|
56
|
+
|
57
|
+
variable_groups = NamedItemList([
|
58
|
+
VariableGroup.from_et(vg_elem, doc_frags)
|
59
|
+
for vg_elem in et_element.iterfind("VARIABLE-GROUPS/VARIABLE-GROUP")
|
60
|
+
])
|
61
|
+
|
62
|
+
dyn_defined_spec = None
|
63
|
+
if (dds_elem := et_element.find("DYN-DEFINED-SPEC")) is not None:
|
64
|
+
dyn_defined_spec = DynDefinedSpec.from_et(dds_elem, doc_frags)
|
65
|
+
|
66
|
+
parent_refs = [
|
67
|
+
ParentRef.from_et(pr_elem, doc_frags)
|
68
|
+
for pr_elem in et_element.iterfind("PARENT-REFS/PARENT-REF")
|
69
|
+
]
|
70
|
+
|
71
|
+
return BaseVariantRaw(
|
72
|
+
diag_variables_raw=diag_variables_raw,
|
73
|
+
variable_groups=variable_groups,
|
74
|
+
dyn_defined_spec=dyn_defined_spec,
|
75
|
+
parent_refs=parent_refs,
|
76
|
+
**kwargs)
|
77
|
+
|
78
|
+
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
79
|
+
result = super()._build_odxlinks()
|
80
|
+
|
81
|
+
for dv_proxy in self.diag_variables_raw:
|
82
|
+
if not isinstance(dv_proxy, OdxLinkRef):
|
83
|
+
result.update(dv_proxy._build_odxlinks())
|
84
|
+
|
85
|
+
if self.dyn_defined_spec is not None:
|
86
|
+
result.update(self.dyn_defined_spec._build_odxlinks())
|
87
|
+
|
88
|
+
for parent_ref in self.parent_refs:
|
89
|
+
result.update(parent_ref._build_odxlinks())
|
90
|
+
|
91
|
+
return result
|
92
|
+
|
93
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
94
|
+
super()._resolve_odxlinks(odxlinks)
|
95
|
+
|
96
|
+
self._diag_variables: NamedItemList[DiagVariable] = NamedItemList()
|
97
|
+
for dv_proxy in self.diag_variables_raw:
|
98
|
+
if isinstance(dv_proxy, OdxLinkRef):
|
99
|
+
dv = odxlinks.resolve(dv_proxy, DiagVariable)
|
100
|
+
else:
|
101
|
+
dv_proxy._resolve_odxlinks(odxlinks)
|
102
|
+
dv = dv_proxy
|
103
|
+
|
104
|
+
self._diag_variables.append(dv)
|
105
|
+
|
106
|
+
if self.dyn_defined_spec is not None:
|
107
|
+
self.dyn_defined_spec._resolve_odxlinks(odxlinks)
|
108
|
+
|
109
|
+
for parent_ref in self.parent_refs:
|
110
|
+
parent_ref._resolve_odxlinks(odxlinks)
|
111
|
+
|
112
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
113
|
+
super()._resolve_snrefs(context)
|
114
|
+
|
115
|
+
for dv_proxy in self.diag_variables_raw:
|
116
|
+
if not isinstance(dv_proxy, OdxLinkRef):
|
117
|
+
dv_proxy._resolve_snrefs(context)
|
118
|
+
|
119
|
+
if self.dyn_defined_spec is not None:
|
120
|
+
self.dyn_defined_spec._resolve_snrefs(context)
|
121
|
+
|
122
|
+
for parent_ref in self.parent_refs:
|
123
|
+
parent_ref._resolve_snrefs(context)
|