odxtools 6.6.1__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 +7 -5
- odxtools/additionalaudience.py +3 -5
- odxtools/admindata.py +5 -7
- odxtools/audience.py +10 -13
- odxtools/basecomparam.py +3 -5
- odxtools/basicstructure.py +55 -241
- odxtools/cli/_parser_utils.py +16 -1
- odxtools/cli/_print_utils.py +169 -134
- odxtools/cli/browse.py +127 -103
- odxtools/cli/compare.py +114 -87
- odxtools/cli/decode.py +2 -1
- odxtools/cli/dummy_sub_parser.py +3 -1
- odxtools/cli/find.py +2 -1
- odxtools/cli/list.py +26 -16
- odxtools/cli/main.py +1 -0
- odxtools/cli/snoop.py +32 -6
- 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 +14 -14
- 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 +94 -15
- odxtools/compumethods/compuphystointernal.py +56 -0
- odxtools/compumethods/compurationalcoeffs.py +20 -9
- odxtools/compumethods/compuscale.py +67 -32
- odxtools/compumethods/createanycompumethod.py +31 -172
- odxtools/compumethods/identicalcompumethod.py +31 -6
- odxtools/compumethods/limit.py +70 -36
- odxtools/compumethods/linearcompumethod.py +70 -181
- 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 +123 -92
- odxtools/compumethods/texttablecompumethod.py +117 -57
- odxtools/createanydiagcodedtype.py +10 -67
- odxtools/database.py +167 -87
- odxtools/dataobjectproperty.py +25 -32
- odxtools/decodestate.py +14 -17
- odxtools/description.py +47 -0
- odxtools/determinenumberofitems.py +4 -5
- odxtools/diagcodedtype.py +37 -106
- odxtools/diagcomm.py +24 -12
- odxtools/diagdatadictionaryspec.py +120 -96
- 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/diaglayertype.py +42 -0
- 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} +273 -472
- 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 +57 -44
- odxtools/diagvariable.py +113 -0
- odxtools/docrevision.py +5 -7
- odxtools/dopbase.py +15 -15
- odxtools/dtcdop.py +170 -50
- odxtools/dynamicendmarkerfield.py +134 -0
- odxtools/dynamiclengthfield.py +47 -42
- 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 -36
- odxtools/exceptions.py +11 -2
- odxtools/field.py +10 -10
- odxtools/functionalclass.py +3 -5
- odxtools/inputparam.py +3 -12
- odxtools/internalconstr.py +14 -5
- odxtools/isotp_state_machine.py +14 -6
- 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 +135 -75
- odxtools/multiplexercase.py +39 -18
- odxtools/multiplexerdefaultcase.py +15 -12
- odxtools/multiplexerswitchkey.py +4 -5
- odxtools/nameditemlist.py +33 -8
- odxtools/negoutputparam.py +3 -5
- odxtools/odxcategory.py +83 -0
- odxtools/odxlink.py +62 -53
- odxtools/odxtypes.py +93 -8
- odxtools/outputparam.py +5 -16
- odxtools/parameterinfo.py +219 -61
- odxtools/parameters/codedconstparameter.py +45 -32
- odxtools/parameters/createanyparameter.py +19 -193
- odxtools/parameters/dynamicparameter.py +25 -4
- odxtools/parameters/lengthkeyparameter.py +83 -25
- odxtools/parameters/matchingrequestparameter.py +48 -18
- odxtools/parameters/nrcconstparameter.py +76 -54
- odxtools/parameters/parameter.py +97 -73
- odxtools/parameters/parameterwithdop.py +41 -38
- odxtools/parameters/physicalconstantparameter.py +41 -20
- odxtools/parameters/reservedparameter.py +36 -18
- odxtools/parameters/systemparameter.py +74 -7
- odxtools/parameters/tableentryparameter.py +47 -7
- odxtools/parameters/tablekeyparameter.py +142 -55
- odxtools/parameters/tablestructparameter.py +79 -58
- odxtools/parameters/valueparameter.py +39 -21
- odxtools/paramlengthinfotype.py +56 -33
- odxtools/parentref.py +20 -3
- 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 +14 -8
- 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 +8 -18
- odxtools/staticfield.py +107 -0
- odxtools/subcomponent.py +288 -0
- odxtools/swvariable.py +21 -0
- odxtools/table.py +9 -9
- odxtools/tablerow.py +30 -15
- 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 -137
- 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 +5 -3
- odxtools/templates/macros/printOdxCategory.xml.jinja2 +28 -0
- odxtools/templates/macros/printParam.xml.jinja2 +18 -19
- 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 +15 -0
- 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} +22 -12
- odxtools/xdoc.py +3 -5
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/METADATA +44 -33
- odxtools-9.3.0.dist-info/RECORD +228 -0
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/WHEEL +1 -1
- odxtools/createcompanydatas.py +0 -17
- odxtools/createsdgs.py +0 -19
- odxtools/diaglayertype.py +0 -30
- 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 -208
- odxtools-6.6.1.dist-info/RECORD +0 -180
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/LICENSE +0 -0
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/entry_points.txt +0 -0
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/top_level.txt +0 -0
@@ -1,36 +1,30 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from copy import copy
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import
|
4
|
+
from typing import Any, Dict, List, Optional, Union, cast
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
|
-
from
|
8
|
-
from
|
9
|
-
from
|
10
|
-
from
|
11
|
-
from
|
12
|
-
from
|
13
|
-
from
|
14
|
-
from
|
7
|
+
from ..additionalaudience import AdditionalAudience
|
8
|
+
from ..admindata import AdminData
|
9
|
+
from ..companydata import CompanyData
|
10
|
+
from ..diagcomm import DiagComm
|
11
|
+
from ..diagdatadictionaryspec import DiagDataDictionarySpec
|
12
|
+
from ..diagservice import DiagService
|
13
|
+
from ..element import IdentifiableElement
|
14
|
+
from ..exceptions import odxassert, odxraise, odxrequire
|
15
|
+
from ..functionalclass import FunctionalClass
|
16
|
+
from ..library import Library
|
17
|
+
from ..nameditemlist import NamedItemList
|
18
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
19
|
+
from ..request import Request
|
20
|
+
from ..response import Response
|
21
|
+
from ..singleecujob import SingleEcuJob
|
22
|
+
from ..snrefcontext import SnRefContext
|
23
|
+
from ..specialdatagroup import SpecialDataGroup
|
24
|
+
from ..statechart import StateChart
|
25
|
+
from ..subcomponent import SubComponent
|
26
|
+
from ..utils import dataclass_fields_asdict
|
15
27
|
from .diaglayertype import DiagLayerType
|
16
|
-
from .diagservice import DiagService
|
17
|
-
from .ecuvariantpattern import EcuVariantPattern
|
18
|
-
from .element import IdentifiableElement
|
19
|
-
from .exceptions import odxassert, odxraise, odxrequire
|
20
|
-
from .functionalclass import FunctionalClass
|
21
|
-
from .nameditemlist import NamedItemList
|
22
|
-
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
23
|
-
from .parentref import ParentRef
|
24
|
-
from .protstack import ProtStack
|
25
|
-
from .request import Request
|
26
|
-
from .response import Response
|
27
|
-
from .singleecujob import SingleEcuJob
|
28
|
-
from .specialdatagroup import SpecialDataGroup
|
29
|
-
from .statechart import StateChart
|
30
|
-
from .utils import dataclass_fields_asdict
|
31
|
-
|
32
|
-
if TYPE_CHECKING:
|
33
|
-
from .diaglayer import DiagLayer
|
34
28
|
|
35
29
|
|
36
30
|
@dataclass
|
@@ -46,7 +40,7 @@ class DiagLayerRaw(IdentifiableElement):
|
|
46
40
|
company_datas: NamedItemList[CompanyData]
|
47
41
|
functional_classes: NamedItemList[FunctionalClass]
|
48
42
|
diag_data_dictionary_spec: Optional[DiagDataDictionarySpec]
|
49
|
-
|
43
|
+
diag_comms_raw: List[Union[OdxLinkRef, DiagComm]]
|
50
44
|
requests: NamedItemList[Request]
|
51
45
|
positive_responses: NamedItemList[Response]
|
52
46
|
negative_responses: NamedItemList[Response]
|
@@ -54,21 +48,26 @@ class DiagLayerRaw(IdentifiableElement):
|
|
54
48
|
import_refs: List[OdxLinkRef]
|
55
49
|
state_charts: NamedItemList[StateChart]
|
56
50
|
additional_audiences: NamedItemList[AdditionalAudience]
|
57
|
-
|
58
|
-
|
51
|
+
sub_components: NamedItemList[SubComponent]
|
52
|
+
libraries: NamedItemList[Library]
|
59
53
|
sdgs: List[SpecialDataGroup]
|
60
54
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
55
|
+
@property
|
56
|
+
def diag_comms(self) -> NamedItemList[DiagComm]:
|
57
|
+
return self._diag_comms
|
58
|
+
|
59
|
+
@property
|
60
|
+
def diag_services(self) -> NamedItemList[DiagService]:
|
61
|
+
return self._diag_services
|
62
|
+
|
63
|
+
@property
|
64
|
+
def services(self) -> NamedItemList[DiagService]:
|
65
|
+
"""This property is an alias for `.diag_services`"""
|
66
|
+
return self._diag_services
|
67
|
+
|
68
|
+
@property
|
69
|
+
def single_ecu_jobs(self) -> NamedItemList[SingleEcuJob]:
|
70
|
+
return self._single_ecu_jobs
|
72
71
|
|
73
72
|
@staticmethod
|
74
73
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "DiagLayerRaw":
|
@@ -103,7 +102,7 @@ class DiagLayerRaw(IdentifiableElement):
|
|
103
102
|
if (ddds_elem := et_element.find("DIAG-DATA-DICTIONARY-SPEC")) is not None:
|
104
103
|
diag_data_dictionary_spec = DiagDataDictionarySpec.from_et(ddds_elem, doc_frags)
|
105
104
|
|
106
|
-
|
105
|
+
diag_comms_raw: List[Union[OdxLinkRef, DiagComm]] = []
|
107
106
|
if (dc_elems := et_element.find("DIAG-COMMS")) is not None:
|
108
107
|
for dc_proxy_elem in dc_elems:
|
109
108
|
dc: Union[OdxLinkRef, DiagComm]
|
@@ -115,7 +114,7 @@ class DiagLayerRaw(IdentifiableElement):
|
|
115
114
|
odxassert(dc_proxy_elem.tag == "SINGLE-ECU-JOB")
|
116
115
|
dc = SingleEcuJob.from_et(dc_proxy_elem, doc_frags)
|
117
116
|
|
118
|
-
|
117
|
+
diag_comms_raw.append(dc)
|
119
118
|
|
120
119
|
requests = NamedItemList([
|
121
120
|
Request.from_et(rq_elem, doc_frags)
|
@@ -152,31 +151,18 @@ class DiagLayerRaw(IdentifiableElement):
|
|
152
151
|
for el in et_element.iterfind("ADDITIONAL-AUDIENCES/ADDITIONAL-AUDIENCE")
|
153
152
|
]
|
154
153
|
|
155
|
-
|
156
|
-
|
157
|
-
parent_refs = [
|
158
|
-
ParentRef.from_et(pr_el, doc_frags)
|
159
|
-
for pr_el in et_element.iterfind("PARENT-REFS/PARENT-REF")
|
154
|
+
libraries = [
|
155
|
+
Library.from_et(el, doc_frags) for el in et_element.iterfind("LIBRARYS/LIBRARY")
|
160
156
|
]
|
161
157
|
|
162
|
-
|
163
|
-
|
164
|
-
for el in et_element.iterfind("
|
158
|
+
sub_components = [
|
159
|
+
SubComponent.from_et(el, doc_frags)
|
160
|
+
for el in et_element.iterfind("SUB-COMPONENTS/SUB-COMPONENT")
|
165
161
|
]
|
166
162
|
|
167
|
-
|
168
|
-
|
169
|
-
for el in et_element.iterfind("ECU-VARIANT-PATTERNS/ECU-VARIANT-PATTERN")
|
163
|
+
sdgs = [
|
164
|
+
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
170
165
|
]
|
171
|
-
if variant_type is not DiagLayerType.ECU_VARIANT:
|
172
|
-
odxassert(
|
173
|
-
len(ecu_variant_patterns) == 0,
|
174
|
-
"DiagLayer of type other than 'ECU-VARIANT' must not define a ECU-VARIANT-PATTERN")
|
175
|
-
|
176
|
-
comparam_spec_ref = OdxLinkRef.from_et(et_element.find("COMPARAM-SPEC-REF"), doc_frags)
|
177
|
-
prot_stack_snref: Optional[str] = None
|
178
|
-
if (prot_stack_snref_elem := et_element.find("PROT-STACK-SNREF")) is not None:
|
179
|
-
prot_stack_snref = odxrequire(prot_stack_snref_elem.get("SHORT-NAME"))
|
180
166
|
|
181
167
|
# Create DiagLayer
|
182
168
|
return DiagLayerRaw(
|
@@ -185,7 +171,7 @@ class DiagLayerRaw(IdentifiableElement):
|
|
185
171
|
company_datas=NamedItemList(company_datas),
|
186
172
|
functional_classes=NamedItemList(functional_classes),
|
187
173
|
diag_data_dictionary_spec=diag_data_dictionary_spec,
|
188
|
-
|
174
|
+
diag_comms_raw=diag_comms_raw,
|
189
175
|
requests=requests,
|
190
176
|
positive_responses=positive_responses,
|
191
177
|
negative_responses=negative_responses,
|
@@ -193,12 +179,9 @@ class DiagLayerRaw(IdentifiableElement):
|
|
193
179
|
import_refs=import_refs,
|
194
180
|
state_charts=NamedItemList(state_charts),
|
195
181
|
additional_audiences=NamedItemList(additional_audiences),
|
182
|
+
libraries=NamedItemList(libraries),
|
183
|
+
sub_components=NamedItemList(sub_components),
|
196
184
|
sdgs=sdgs,
|
197
|
-
parent_refs=parent_refs,
|
198
|
-
comparams=comparams,
|
199
|
-
ecu_variant_patterns=ecu_variant_patterns,
|
200
|
-
comparam_spec_ref=comparam_spec_ref,
|
201
|
-
prot_stack_snref=prot_stack_snref,
|
202
185
|
**kwargs)
|
203
186
|
|
204
187
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
@@ -214,10 +197,10 @@ class DiagLayerRaw(IdentifiableElement):
|
|
214
197
|
odxlinks.update(company_data._build_odxlinks())
|
215
198
|
for functional_class in self.functional_classes:
|
216
199
|
odxlinks.update(functional_class._build_odxlinks())
|
217
|
-
for
|
218
|
-
if isinstance(
|
200
|
+
for dc_proxy in self.diag_comms_raw:
|
201
|
+
if isinstance(dc_proxy, OdxLinkRef):
|
219
202
|
continue
|
220
|
-
odxlinks.update(
|
203
|
+
odxlinks.update(dc_proxy._build_odxlinks())
|
221
204
|
for request in self.requests:
|
222
205
|
odxlinks.update(request._build_odxlinks())
|
223
206
|
for positive_response in self.positive_responses:
|
@@ -230,21 +213,18 @@ class DiagLayerRaw(IdentifiableElement):
|
|
230
213
|
odxlinks.update(state_chart._build_odxlinks())
|
231
214
|
for additional_audience in self.additional_audiences:
|
232
215
|
odxlinks.update(additional_audience._build_odxlinks())
|
216
|
+
for library in self.libraries:
|
217
|
+
odxlinks.update(library._build_odxlinks())
|
218
|
+
for sub_comp in self.sub_components:
|
219
|
+
odxlinks.update(sub_comp._build_odxlinks())
|
233
220
|
for sdg in self.sdgs:
|
234
221
|
odxlinks.update(sdg._build_odxlinks())
|
235
|
-
for parent_ref in self.parent_refs:
|
236
|
-
odxlinks.update(parent_ref._build_odxlinks())
|
237
|
-
for comparam in self.comparams:
|
238
|
-
odxlinks.update(comparam._build_odxlinks())
|
239
222
|
|
240
223
|
return odxlinks
|
241
224
|
|
242
225
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
243
226
|
"""Recursively resolve all references."""
|
244
227
|
|
245
|
-
if self.comparam_spec_ref is not None:
|
246
|
-
self._comparam_spec = odxlinks.resolve(self.comparam_spec_ref, ComparamSpec)
|
247
|
-
|
248
228
|
# do ODXLINK reference resolution
|
249
229
|
if self.admin_data is not None:
|
250
230
|
self.admin_data._resolve_odxlinks(odxlinks)
|
@@ -255,10 +235,28 @@ class DiagLayerRaw(IdentifiableElement):
|
|
255
235
|
company_data._resolve_odxlinks(odxlinks)
|
256
236
|
for functional_class in self.functional_classes:
|
257
237
|
functional_class._resolve_odxlinks(odxlinks)
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
238
|
+
|
239
|
+
# resolve references to diagnostic communication objects and
|
240
|
+
# separate them into services and single-ecu jobs
|
241
|
+
self._diag_comms = NamedItemList[DiagComm]()
|
242
|
+
self._diag_services = NamedItemList[DiagService]()
|
243
|
+
self._single_ecu_jobs = NamedItemList[SingleEcuJob]()
|
244
|
+
for dc_proxy in self.diag_comms_raw:
|
245
|
+
if isinstance(dc_proxy, OdxLinkRef):
|
246
|
+
dc = odxlinks.resolve(dc_proxy, DiagComm)
|
247
|
+
else:
|
248
|
+
dc = dc_proxy
|
249
|
+
dc._resolve_odxlinks(odxlinks)
|
250
|
+
|
251
|
+
self._diag_comms.append(dc)
|
252
|
+
|
253
|
+
if isinstance(dc, DiagService):
|
254
|
+
self._diag_services.append(dc)
|
255
|
+
elif isinstance(dc, SingleEcuJob):
|
256
|
+
self._single_ecu_jobs.append(dc)
|
257
|
+
else:
|
258
|
+
odxraise()
|
259
|
+
|
262
260
|
for request in self.requests:
|
263
261
|
request._resolve_odxlinks(odxlinks)
|
264
262
|
for positive_response in self.positive_responses:
|
@@ -271,56 +269,43 @@ class DiagLayerRaw(IdentifiableElement):
|
|
271
269
|
state_chart._resolve_odxlinks(odxlinks)
|
272
270
|
for additional_audience in self.additional_audiences:
|
273
271
|
additional_audience._resolve_odxlinks(odxlinks)
|
272
|
+
for library in self.libraries:
|
273
|
+
library._resolve_odxlinks(odxlinks)
|
274
|
+
for sub_component in self.sub_components:
|
275
|
+
sub_component._resolve_odxlinks(odxlinks)
|
274
276
|
for sdg in self.sdgs:
|
275
277
|
sdg._resolve_odxlinks(odxlinks)
|
276
|
-
for parent_ref in self.parent_refs:
|
277
|
-
parent_ref._resolve_odxlinks(odxlinks)
|
278
|
-
for comparam in self.comparams:
|
279
|
-
comparam._resolve_odxlinks(odxlinks)
|
280
|
-
|
281
|
-
def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
|
282
|
-
self._prot_stack: Optional[ProtStack] = None
|
283
|
-
if self.prot_stack_snref is not None:
|
284
|
-
self._prot_stack = odxrequire(
|
285
|
-
odxrequire(self.comparam_spec).prot_stacks.get(self.prot_stack_snref))
|
286
278
|
|
279
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
287
280
|
# do short-name reference resolution
|
288
281
|
if self.admin_data is not None:
|
289
|
-
self.admin_data._resolve_snrefs(
|
282
|
+
self.admin_data._resolve_snrefs(context)
|
290
283
|
if self.diag_data_dictionary_spec is not None:
|
291
|
-
self.diag_data_dictionary_spec._resolve_snrefs(
|
284
|
+
self.diag_data_dictionary_spec._resolve_snrefs(context)
|
292
285
|
|
293
286
|
for company_data in self.company_datas:
|
294
|
-
company_data._resolve_snrefs(
|
295
|
-
for
|
296
|
-
|
297
|
-
for
|
298
|
-
if isinstance(
|
287
|
+
company_data._resolve_snrefs(context)
|
288
|
+
for functional_class in self.functional_classes:
|
289
|
+
functional_class._resolve_snrefs(context)
|
290
|
+
for dc_proxy in self.diag_comms_raw:
|
291
|
+
if isinstance(dc_proxy, OdxLinkRef):
|
299
292
|
continue
|
300
|
-
|
293
|
+
dc_proxy._resolve_snrefs(context)
|
301
294
|
for request in self.requests:
|
302
|
-
request._resolve_snrefs(
|
295
|
+
request._resolve_snrefs(context)
|
303
296
|
for positive_response in self.positive_responses:
|
304
|
-
positive_response._resolve_snrefs(
|
297
|
+
positive_response._resolve_snrefs(context)
|
305
298
|
for negative_response in self.negative_responses:
|
306
|
-
negative_response._resolve_snrefs(
|
299
|
+
negative_response._resolve_snrefs(context)
|
307
300
|
for global_negative_response in self.global_negative_responses:
|
308
|
-
global_negative_response._resolve_snrefs(
|
301
|
+
global_negative_response._resolve_snrefs(context)
|
309
302
|
for state_chart in self.state_charts:
|
310
|
-
state_chart._resolve_snrefs(
|
303
|
+
state_chart._resolve_snrefs(context)
|
311
304
|
for additional_audience in self.additional_audiences:
|
312
|
-
additional_audience._resolve_snrefs(
|
305
|
+
additional_audience._resolve_snrefs(context)
|
306
|
+
for library in self.libraries:
|
307
|
+
library._resolve_snrefs(context)
|
308
|
+
for sub_component in self.sub_components:
|
309
|
+
sub_component._resolve_snrefs(context)
|
313
310
|
for sdg in self.sdgs:
|
314
|
-
sdg._resolve_snrefs(
|
315
|
-
for parent_ref in self.parent_refs:
|
316
|
-
parent_ref._resolve_snrefs(diag_layer)
|
317
|
-
for comparam in self.comparams:
|
318
|
-
comparam._resolve_snrefs(diag_layer)
|
319
|
-
|
320
|
-
@property
|
321
|
-
def comparam_spec(self) -> Optional[ComparamSpec]:
|
322
|
-
return self._comparam_spec
|
323
|
-
|
324
|
-
@property
|
325
|
-
def prot_stack(self) -> Optional[ProtStack]:
|
326
|
-
return self._prot_stack
|
311
|
+
sdg._resolve_snrefs(context)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from enum import Enum
|
3
|
+
from typing import Dict
|
4
|
+
|
5
|
+
|
6
|
+
class DiagLayerType(Enum):
|
7
|
+
PROTOCOL = "PROTOCOL"
|
8
|
+
FUNCTIONAL_GROUP = "FUNCTIONAL-GROUP"
|
9
|
+
BASE_VARIANT = "BASE-VARIANT"
|
10
|
+
ECU_VARIANT = "ECU-VARIANT"
|
11
|
+
ECU_SHARED_DATA = "ECU-SHARED-DATA"
|
12
|
+
|
13
|
+
@property
|
14
|
+
def inheritance_priority(self) -> int:
|
15
|
+
"""Return the inheritance priority of diag layers of the given type
|
16
|
+
|
17
|
+
ODX mandates that diagnostic layers can only inherit from
|
18
|
+
layers of lower priority...
|
19
|
+
|
20
|
+
"""
|
21
|
+
|
22
|
+
PRIORITY_OF_DIAG_LAYER_TYPE: Dict[DiagLayerType, int] = {
|
23
|
+
DiagLayerType.PROTOCOL:
|
24
|
+
1,
|
25
|
+
DiagLayerType.FUNCTIONAL_GROUP:
|
26
|
+
2,
|
27
|
+
DiagLayerType.BASE_VARIANT:
|
28
|
+
3,
|
29
|
+
DiagLayerType.ECU_VARIANT:
|
30
|
+
4,
|
31
|
+
|
32
|
+
# ECU shared data layers are a bit weird (see section
|
33
|
+
# 7.3.2.4.4 of the ASAM specification): they can be
|
34
|
+
# inherited from by any other layer but they will
|
35
|
+
# override any objects which are also provided by any of
|
36
|
+
# the other parent layers. tl;dr: When it comes to
|
37
|
+
# inheritance, they have the highest priority.
|
38
|
+
DiagLayerType.ECU_SHARED_DATA:
|
39
|
+
100,
|
40
|
+
}
|
41
|
+
|
42
|
+
return PRIORITY_OF_DIAG_LAYER_TYPE[self]
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from copy import deepcopy
|
3
|
+
from dataclasses import dataclass
|
4
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Union, cast
|
5
|
+
from xml.etree import ElementTree
|
6
|
+
|
7
|
+
from ..diagvariable import DiagVariable
|
8
|
+
from ..exceptions import odxassert
|
9
|
+
from ..nameditemlist import NamedItemList
|
10
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef
|
11
|
+
from ..snrefcontext import SnRefContext
|
12
|
+
from ..variablegroup import VariableGroup
|
13
|
+
from .diaglayer import DiagLayer
|
14
|
+
from .ecushareddataraw import EcuSharedDataRaw
|
15
|
+
|
16
|
+
if TYPE_CHECKING:
|
17
|
+
from .database import Database
|
18
|
+
|
19
|
+
|
20
|
+
@dataclass
|
21
|
+
class EcuSharedData(DiagLayer):
|
22
|
+
"""This is a diagnostic layer for data shared across others
|
23
|
+
"""
|
24
|
+
|
25
|
+
@property
|
26
|
+
def ecu_shared_data_raw(self) -> EcuSharedDataRaw:
|
27
|
+
return cast(EcuSharedDataRaw, self.diag_layer_raw)
|
28
|
+
|
29
|
+
@property
|
30
|
+
def diag_variables_raw(self) -> List[Union[OdxLinkRef, DiagVariable]]:
|
31
|
+
return self.ecu_shared_data_raw.diag_variables_raw
|
32
|
+
|
33
|
+
@property
|
34
|
+
def diag_variables(self) -> NamedItemList[DiagVariable]:
|
35
|
+
return self.ecu_shared_data_raw.diag_variables
|
36
|
+
|
37
|
+
@property
|
38
|
+
def variable_groups(self) -> NamedItemList[VariableGroup]:
|
39
|
+
return self.ecu_shared_data_raw.variable_groups
|
40
|
+
|
41
|
+
@staticmethod
|
42
|
+
def from_et(et_element: ElementTree.Element,
|
43
|
+
doc_frags: List[OdxDocFragment]) -> "EcuSharedData":
|
44
|
+
ecu_shared_data_raw = EcuSharedDataRaw.from_et(et_element, doc_frags)
|
45
|
+
|
46
|
+
return EcuSharedData(diag_layer_raw=ecu_shared_data_raw)
|
47
|
+
|
48
|
+
def __post_init__(self) -> None:
|
49
|
+
super().__post_init__()
|
50
|
+
|
51
|
+
odxassert(
|
52
|
+
isinstance(self.diag_layer_raw, EcuSharedDataRaw),
|
53
|
+
"The raw diagnostic layer passed to EcuSharedData "
|
54
|
+
"must be a EcuSharedDataRaw")
|
55
|
+
|
56
|
+
def _finalize_init(self, database: "Database", odxlinks: OdxLinkDatabase) -> None:
|
57
|
+
"""This method makes sure that all references in sub-objects
|
58
|
+
of the ECU shared data layer are resolved
|
59
|
+
|
60
|
+
In contrast to hierarchy element layers, ECU shared data
|
61
|
+
layers do not need to deal with inheritance...
|
62
|
+
|
63
|
+
"""
|
64
|
+
|
65
|
+
# this attribute may be removed later. it is currently
|
66
|
+
# required to properly deal with auxiliary files within the
|
67
|
+
# diagnostic layer.
|
68
|
+
self._database = database
|
69
|
+
|
70
|
+
#####
|
71
|
+
# resolve all SNREFs. TODO: We allow SNREFS to objects that
|
72
|
+
# were inherited by the diaglayer. This might not be allowed
|
73
|
+
# by the spec (So far, I haven't found any definitive
|
74
|
+
# statement...)
|
75
|
+
#####
|
76
|
+
context = SnRefContext(database=database)
|
77
|
+
context.diag_layer = self
|
78
|
+
self._resolve_snrefs(context)
|
79
|
+
context.diag_layer = None
|
80
|
+
|
81
|
+
def __deepcopy__(self, memo: Dict[int, Any]) -> Any:
|
82
|
+
"""Create a deep copy of the protocol layer
|
83
|
+
|
84
|
+
Note that the copied diagnostic layer is not fully
|
85
|
+
initialized, so `_finalize_init()` should to be called on it
|
86
|
+
before it can be used normally.
|
87
|
+
"""
|
88
|
+
|
89
|
+
result = super().__deepcopy__(memo)
|
90
|
+
|
91
|
+
# note that the self.ecu_shared_data_raw object is *not* copied at
|
92
|
+
# this place because the attribute points to the same object
|
93
|
+
# as self.diag_layer_raw.
|
94
|
+
result.ecu_shared_data_raw = deepcopy(self.ecu_shared_data_raw, memo)
|
95
|
+
|
96
|
+
return result
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import Any, Dict, List, Union
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from ..diagvariable import DiagVariable
|
7
|
+
from ..exceptions import odxraise
|
8
|
+
from ..nameditemlist import NamedItemList
|
9
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
10
|
+
from ..snrefcontext import SnRefContext
|
11
|
+
from ..utils import dataclass_fields_asdict
|
12
|
+
from ..variablegroup import VariableGroup
|
13
|
+
from .diaglayerraw import DiagLayerRaw
|
14
|
+
|
15
|
+
|
16
|
+
@dataclass
|
17
|
+
class EcuSharedDataRaw(DiagLayerRaw):
|
18
|
+
"""This is a diagnostic layer for data shared accross others
|
19
|
+
"""
|
20
|
+
|
21
|
+
diag_variables_raw: List[Union[DiagVariable, OdxLinkRef]]
|
22
|
+
variable_groups: NamedItemList[VariableGroup]
|
23
|
+
|
24
|
+
@property
|
25
|
+
def diag_variables(self) -> NamedItemList[DiagVariable]:
|
26
|
+
return self._diag_variables
|
27
|
+
|
28
|
+
@staticmethod
|
29
|
+
def from_et(et_element: ElementTree.Element,
|
30
|
+
doc_frags: List[OdxDocFragment]) -> "EcuSharedDataRaw":
|
31
|
+
# objects contained by diagnostic layers exibit an additional
|
32
|
+
# document fragment for the diag layer, so we use the document
|
33
|
+
# fragments of the odx id of the diag layer for IDs of
|
34
|
+
# contained objects.
|
35
|
+
dlr = DiagLayerRaw.from_et(et_element, doc_frags)
|
36
|
+
kwargs = dataclass_fields_asdict(dlr)
|
37
|
+
doc_frags = dlr.odx_id.doc_fragments
|
38
|
+
|
39
|
+
diag_variables_raw: List[Union[DiagVariable, OdxLinkRef]] = []
|
40
|
+
if (dv_elems := et_element.find("DIAG-VARIABLES")) is not None:
|
41
|
+
for dv_proxy_elem in dv_elems:
|
42
|
+
dv_proxy: Union[OdxLinkRef, DiagVariable]
|
43
|
+
if dv_proxy_elem.tag == "DIAG-VARIABLE-REF":
|
44
|
+
dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, doc_frags)
|
45
|
+
elif dv_proxy_elem.tag == "DIAG-VARIABLE":
|
46
|
+
dv_proxy = DiagVariable.from_et(dv_proxy_elem, doc_frags)
|
47
|
+
else:
|
48
|
+
odxraise()
|
49
|
+
|
50
|
+
diag_variables_raw.append(dv_proxy)
|
51
|
+
|
52
|
+
variable_groups = NamedItemList([
|
53
|
+
VariableGroup.from_et(vg_elem, doc_frags)
|
54
|
+
for vg_elem in et_element.iterfind("VARIABLE-GROUPS/VARIABLE-GROUP")
|
55
|
+
])
|
56
|
+
|
57
|
+
# Create DiagLayer
|
58
|
+
return EcuSharedDataRaw(
|
59
|
+
diag_variables_raw=diag_variables_raw, variable_groups=variable_groups, **kwargs)
|
60
|
+
|
61
|
+
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
62
|
+
result = super()._build_odxlinks()
|
63
|
+
for dv_proxy in self.diag_variables_raw:
|
64
|
+
if not isinstance(dv_proxy, OdxLinkRef):
|
65
|
+
result.update(dv_proxy._build_odxlinks())
|
66
|
+
|
67
|
+
return result
|
68
|
+
|
69
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
70
|
+
super()._resolve_odxlinks(odxlinks)
|
71
|
+
|
72
|
+
self._diag_variables: NamedItemList[DiagVariable] = NamedItemList()
|
73
|
+
for dv_proxy in self.diag_variables_raw:
|
74
|
+
if isinstance(dv_proxy, OdxLinkRef):
|
75
|
+
dv = odxlinks.resolve(dv_proxy, DiagVariable)
|
76
|
+
else:
|
77
|
+
dv_proxy._resolve_odxlinks(odxlinks)
|
78
|
+
dv = dv_proxy
|
79
|
+
|
80
|
+
self._diag_variables.append(dv)
|
81
|
+
|
82
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
83
|
+
super()._resolve_snrefs(context)
|
84
|
+
|
85
|
+
for dv_proxy in self.diag_variables_raw:
|
86
|
+
if not isinstance(dv_proxy, OdxLinkRef):
|
87
|
+
dv_proxy._resolve_snrefs(context)
|