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,63 +1,82 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
3
|
from itertools import chain
|
4
|
-
from typing import
|
4
|
+
from typing import Any, Dict, List, Optional
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
|
+
from .admindata import AdminData
|
7
8
|
from .basicstructure import BasicStructure
|
8
|
-
from .createsdgs import create_sdgs_from_et
|
9
9
|
from .dataobjectproperty import DataObjectProperty
|
10
10
|
from .dopbase import DopBase
|
11
11
|
from .dtcdop import DtcDop
|
12
|
+
from .dynamicendmarkerfield import DynamicEndmarkerField
|
12
13
|
from .dynamiclengthfield import DynamicLengthField
|
13
14
|
from .endofpdufield import EndOfPduField
|
14
15
|
from .environmentdata import EnvironmentData
|
15
16
|
from .environmentdatadescription import EnvironmentDataDescription
|
16
17
|
from .exceptions import odxraise
|
17
|
-
from .globals import logger
|
18
18
|
from .multiplexer import Multiplexer
|
19
19
|
from .nameditemlist import NamedItemList
|
20
20
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
21
|
+
from .snrefcontext import SnRefContext
|
21
22
|
from .specialdatagroup import SpecialDataGroup
|
23
|
+
from .staticfield import StaticField
|
22
24
|
from .structure import Structure
|
23
25
|
from .table import Table
|
24
26
|
from .unitspec import UnitSpec
|
25
27
|
|
26
|
-
if TYPE_CHECKING:
|
27
|
-
from .diaglayer import DiagLayer
|
28
|
-
|
29
28
|
|
30
29
|
@dataclass
|
31
30
|
class DiagDataDictionarySpec:
|
31
|
+
admin_data: Optional[AdminData]
|
32
32
|
dtc_dops: NamedItemList[DtcDop]
|
33
|
+
env_data_descs: NamedItemList[EnvironmentDataDescription]
|
33
34
|
data_object_props: NamedItemList[DataObjectProperty]
|
34
35
|
structures: NamedItemList[BasicStructure]
|
35
|
-
|
36
|
+
static_fields: NamedItemList[StaticField]
|
36
37
|
dynamic_length_fields: NamedItemList[DynamicLengthField]
|
37
|
-
|
38
|
-
|
39
|
-
env_datas: NamedItemList[EnvironmentData]
|
38
|
+
dynamic_endmarker_fields: NamedItemList[DynamicEndmarkerField]
|
39
|
+
end_of_pdu_fields: NamedItemList[EndOfPduField]
|
40
40
|
muxs: NamedItemList[Multiplexer]
|
41
|
+
env_datas: NamedItemList[EnvironmentData]
|
41
42
|
unit_spec: Optional[UnitSpec]
|
43
|
+
tables: NamedItemList[Table]
|
42
44
|
sdgs: List[SpecialDataGroup]
|
43
45
|
|
44
46
|
def __post_init__(self) -> None:
|
45
47
|
self._all_data_object_properties: NamedItemList[DopBase] = NamedItemList(
|
46
48
|
chain(
|
47
49
|
self.dtc_dops,
|
50
|
+
self.env_data_descs,
|
48
51
|
self.data_object_props,
|
49
52
|
self.structures,
|
50
|
-
self.
|
53
|
+
self.static_fields,
|
51
54
|
self.dynamic_length_fields,
|
52
|
-
self.
|
53
|
-
self.
|
55
|
+
self.dynamic_endmarker_fields,
|
56
|
+
self.end_of_pdu_fields,
|
54
57
|
self.muxs,
|
58
|
+
self.env_datas,
|
55
59
|
))
|
56
60
|
|
57
61
|
@staticmethod
|
58
62
|
def from_et(et_element: ElementTree.Element,
|
59
63
|
doc_frags: List[OdxDocFragment]) -> "DiagDataDictionarySpec":
|
60
|
-
|
64
|
+
admin_data = None
|
65
|
+
if (admin_data_elem := et_element.find("ADMIN-DATA")) is not None:
|
66
|
+
admin_data = AdminData.from_et(admin_data_elem, doc_frags)
|
67
|
+
|
68
|
+
dtc_dops = []
|
69
|
+
for dtc_dop_elem in et_element.iterfind("DTC-DOPS/DTC-DOP"):
|
70
|
+
dtc_dop = DtcDop.from_et(dtc_dop_elem, doc_frags)
|
71
|
+
if not isinstance(dtc_dop, DtcDop):
|
72
|
+
odxraise()
|
73
|
+
dtc_dops.append(dtc_dop)
|
74
|
+
|
75
|
+
env_data_descs = [
|
76
|
+
EnvironmentDataDescription.from_et(env_data_desc_element, doc_frags)
|
77
|
+
for env_data_desc_element in et_element.iterfind("ENV-DATA-DESCS/ENV-DATA-DESC")
|
78
|
+
]
|
79
|
+
|
61
80
|
data_object_props = [
|
62
81
|
DataObjectProperty.from_et(dop_element, doc_frags)
|
63
82
|
for dop_element in et_element.iterfind("DATA-OBJECT-PROPS/DATA-OBJECT-PROP")
|
@@ -68,9 +87,9 @@ class DiagDataDictionarySpec:
|
|
68
87
|
for structure_element in et_element.iterfind("STRUCTURES/STRUCTURE")
|
69
88
|
]
|
70
89
|
|
71
|
-
|
72
|
-
|
73
|
-
for
|
90
|
+
static_fields = [
|
91
|
+
StaticField.from_et(dl_element, doc_frags)
|
92
|
+
for dl_element in et_element.iterfind("STATIC-FIELDS/STATIC-FIELD")
|
74
93
|
]
|
75
94
|
|
76
95
|
dynamic_length_fields = [
|
@@ -78,21 +97,19 @@ class DiagDataDictionarySpec:
|
|
78
97
|
for dl_element in et_element.iterfind("DYNAMIC-LENGTH-FIELDS/DYNAMIC-LENGTH-FIELD")
|
79
98
|
]
|
80
99
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
odxraise()
|
86
|
-
dtc_dops.append(dtc_dop)
|
100
|
+
dynamic_endmarker_fields = [
|
101
|
+
DynamicEndmarkerField.from_et(dl_element, doc_frags) for dl_element in
|
102
|
+
et_element.iterfind("DYNAMIC-ENDMARKER-FIELDS/DYNAMIC-ENDMARKER-FIELD")
|
103
|
+
]
|
87
104
|
|
88
|
-
|
89
|
-
|
90
|
-
for
|
105
|
+
end_of_pdu_fields = [
|
106
|
+
EndOfPduField.from_et(eofp_element, doc_frags)
|
107
|
+
for eofp_element in et_element.iterfind("END-OF-PDU-FIELDS/END-OF-PDU-FIELD")
|
91
108
|
]
|
92
109
|
|
93
|
-
|
94
|
-
|
95
|
-
for
|
110
|
+
muxs = [
|
111
|
+
Multiplexer.from_et(mux_element, doc_frags)
|
112
|
+
for mux_element in et_element.iterfind("MUXS/MUX")
|
96
113
|
]
|
97
114
|
|
98
115
|
env_data_elements = chain(
|
@@ -105,42 +122,34 @@ class DiagDataDictionarySpec:
|
|
105
122
|
for env_data_element in env_data_elements
|
106
123
|
]
|
107
124
|
|
108
|
-
muxs = [
|
109
|
-
Multiplexer.from_et(mux_element, doc_frags)
|
110
|
-
for mux_element in et_element.iterfind("MUXS/MUX")
|
111
|
-
]
|
112
|
-
|
113
125
|
if (spec_elem := et_element.find("UNIT-SPEC")) is not None:
|
114
126
|
unit_spec = UnitSpec.from_et(spec_elem, doc_frags)
|
115
127
|
else:
|
116
128
|
unit_spec = None
|
117
129
|
|
118
|
-
|
119
|
-
|
120
|
-
("
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
]:
|
127
|
-
num = len(list(et_element.iterfind(path)))
|
128
|
-
if num > 0:
|
129
|
-
logger.info(f"Not implemented: Did not parse {num} {name}.")
|
130
|
-
|
131
|
-
sdgs = create_sdgs_from_et(et_element.find("SDGS"), doc_frags)
|
130
|
+
tables = [
|
131
|
+
Table.from_et(table_element, doc_frags)
|
132
|
+
for table_element in et_element.iterfind("TABLES/TABLE")
|
133
|
+
]
|
134
|
+
|
135
|
+
sdgs = [
|
136
|
+
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
137
|
+
]
|
132
138
|
|
133
139
|
return DiagDataDictionarySpec(
|
140
|
+
admin_data=admin_data,
|
141
|
+
dtc_dops=NamedItemList(dtc_dops),
|
142
|
+
env_data_descs=NamedItemList(env_data_descs),
|
134
143
|
data_object_props=NamedItemList(data_object_props),
|
135
144
|
structures=NamedItemList(structures),
|
136
|
-
|
145
|
+
static_fields=NamedItemList(static_fields),
|
137
146
|
dynamic_length_fields=NamedItemList(dynamic_length_fields),
|
138
|
-
|
147
|
+
dynamic_endmarker_fields=NamedItemList(dynamic_endmarker_fields),
|
148
|
+
end_of_pdu_fields=NamedItemList(end_of_pdu_fields),
|
149
|
+
muxs=NamedItemList(muxs),
|
150
|
+
env_datas=NamedItemList(env_datas),
|
139
151
|
unit_spec=unit_spec,
|
140
152
|
tables=NamedItemList(tables),
|
141
|
-
env_data_descs=NamedItemList(env_data_descs),
|
142
|
-
env_datas=NamedItemList(env_datas),
|
143
|
-
muxs=NamedItemList(muxs),
|
144
153
|
sdgs=sdgs,
|
145
154
|
)
|
146
155
|
|
@@ -148,81 +157,96 @@ class DiagDataDictionarySpec:
|
|
148
157
|
# note that DataDictionarySpec objects do not exhibit an ODXLINK id.
|
149
158
|
odxlinks = {}
|
150
159
|
|
151
|
-
|
152
|
-
odxlinks.update(
|
160
|
+
if self.admin_data is not None:
|
161
|
+
odxlinks.update(self.admin_data._build_odxlinks())
|
153
162
|
for dtc_dop in self.dtc_dops:
|
154
163
|
odxlinks.update(dtc_dop._build_odxlinks())
|
155
164
|
for env_data_desc in self.env_data_descs:
|
156
165
|
odxlinks.update(env_data_desc._build_odxlinks())
|
157
|
-
for
|
158
|
-
odxlinks.update(
|
159
|
-
for mux in self.muxs:
|
160
|
-
odxlinks.update(mux._build_odxlinks())
|
161
|
-
for sdg in self.sdgs:
|
162
|
-
odxlinks.update(sdg._build_odxlinks())
|
166
|
+
for data_object_prop in self.data_object_props:
|
167
|
+
odxlinks.update(data_object_prop._build_odxlinks())
|
163
168
|
for structure in self.structures:
|
164
169
|
odxlinks.update(structure._build_odxlinks())
|
170
|
+
for static_field in self.static_fields:
|
171
|
+
odxlinks.update(static_field._build_odxlinks())
|
165
172
|
for dynamic_length_field in self.dynamic_length_fields:
|
166
173
|
odxlinks.update(dynamic_length_field._build_odxlinks())
|
174
|
+
for dynamic_endmarker_field in self.dynamic_endmarker_fields:
|
175
|
+
odxlinks.update(dynamic_endmarker_field._build_odxlinks())
|
167
176
|
for end_of_pdu_field in self.end_of_pdu_fields:
|
168
177
|
odxlinks.update(end_of_pdu_field._build_odxlinks())
|
169
|
-
for
|
170
|
-
odxlinks.update(
|
171
|
-
|
178
|
+
for mux in self.muxs:
|
179
|
+
odxlinks.update(mux._build_odxlinks())
|
180
|
+
for env_data in self.env_datas:
|
181
|
+
odxlinks.update(env_data._build_odxlinks())
|
172
182
|
if self.unit_spec is not None:
|
173
183
|
odxlinks.update(self.unit_spec._build_odxlinks())
|
184
|
+
for table in self.tables:
|
185
|
+
odxlinks.update(table._build_odxlinks())
|
186
|
+
for sdg in self.sdgs:
|
187
|
+
odxlinks.update(sdg._build_odxlinks())
|
174
188
|
|
175
189
|
return odxlinks
|
176
190
|
|
177
191
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
178
|
-
|
179
|
-
|
192
|
+
if self.admin_data is not None:
|
193
|
+
self.admin_data._resolve_odxlinks(odxlinks)
|
180
194
|
for dtc_dop in self.dtc_dops:
|
181
195
|
dtc_dop._resolve_odxlinks(odxlinks)
|
196
|
+
for env_data_desc in self.env_data_descs:
|
197
|
+
env_data_desc._resolve_odxlinks(odxlinks)
|
198
|
+
for data_object_prop in self.data_object_props:
|
199
|
+
data_object_prop._resolve_odxlinks(odxlinks)
|
200
|
+
for structure in self.structures:
|
201
|
+
structure._resolve_odxlinks(odxlinks)
|
202
|
+
for static_field in self.static_fields:
|
203
|
+
static_field._resolve_odxlinks(odxlinks)
|
182
204
|
for dynamic_length_field in self.dynamic_length_fields:
|
183
205
|
dynamic_length_field._resolve_odxlinks(odxlinks)
|
206
|
+
for dynamic_endmarker_field in self.dynamic_endmarker_fields:
|
207
|
+
dynamic_endmarker_field._resolve_odxlinks(odxlinks)
|
184
208
|
for end_of_pdu_field in self.end_of_pdu_fields:
|
185
209
|
end_of_pdu_field._resolve_odxlinks(odxlinks)
|
186
|
-
for env_data_desc in self.env_data_descs:
|
187
|
-
env_data_desc._resolve_odxlinks(odxlinks)
|
188
|
-
for env_data in self.env_datas:
|
189
|
-
env_data._resolve_odxlinks(odxlinks)
|
190
210
|
for mux in self.muxs:
|
191
211
|
mux._resolve_odxlinks(odxlinks)
|
192
|
-
for
|
193
|
-
|
194
|
-
for structure in self.structures:
|
195
|
-
structure._resolve_odxlinks(odxlinks)
|
196
|
-
for table in self.tables:
|
197
|
-
table._resolve_odxlinks(odxlinks)
|
198
|
-
|
212
|
+
for env_data in self.env_datas:
|
213
|
+
env_data._resolve_odxlinks(odxlinks)
|
199
214
|
if self.unit_spec is not None:
|
200
215
|
self.unit_spec._resolve_odxlinks(odxlinks)
|
216
|
+
for table in self.tables:
|
217
|
+
table._resolve_odxlinks(odxlinks)
|
218
|
+
for sdg in self.sdgs:
|
219
|
+
sdg._resolve_odxlinks(odxlinks)
|
201
220
|
|
202
|
-
def _resolve_snrefs(self,
|
203
|
-
|
204
|
-
|
221
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
222
|
+
if self.admin_data is not None:
|
223
|
+
self.admin_data._resolve_snrefs(context)
|
205
224
|
for dtc_dop in self.dtc_dops:
|
206
|
-
dtc_dop._resolve_snrefs(
|
225
|
+
dtc_dop._resolve_snrefs(context)
|
226
|
+
for env_data_desc in self.env_data_descs:
|
227
|
+
env_data_desc._resolve_snrefs(context)
|
228
|
+
for data_object_prop in self.data_object_props:
|
229
|
+
data_object_prop._resolve_snrefs(context)
|
230
|
+
for structure in self.structures:
|
231
|
+
structure._resolve_snrefs(context)
|
232
|
+
for static_field in self.static_fields:
|
233
|
+
static_field._resolve_snrefs(context)
|
207
234
|
for dynamic_length_field in self.dynamic_length_fields:
|
208
|
-
dynamic_length_field._resolve_snrefs(
|
235
|
+
dynamic_length_field._resolve_snrefs(context)
|
236
|
+
for dynamic_endmarker_field in self.dynamic_endmarker_fields:
|
237
|
+
dynamic_endmarker_field._resolve_snrefs(context)
|
209
238
|
for end_of_pdu_field in self.end_of_pdu_fields:
|
210
|
-
end_of_pdu_field._resolve_snrefs(
|
211
|
-
for env_data_desc in self.env_data_descs:
|
212
|
-
env_data_desc._resolve_snrefs(diag_layer)
|
213
|
-
for env_data in self.env_datas:
|
214
|
-
env_data._resolve_snrefs(diag_layer)
|
239
|
+
end_of_pdu_field._resolve_snrefs(context)
|
215
240
|
for mux in self.muxs:
|
216
|
-
mux._resolve_snrefs(
|
217
|
-
for
|
218
|
-
|
219
|
-
for structure in self.structures:
|
220
|
-
structure._resolve_snrefs(diag_layer)
|
221
|
-
for table in self.tables:
|
222
|
-
table._resolve_snrefs(diag_layer)
|
223
|
-
|
241
|
+
mux._resolve_snrefs(context)
|
242
|
+
for env_data in self.env_datas:
|
243
|
+
env_data._resolve_snrefs(context)
|
224
244
|
if self.unit_spec is not None:
|
225
|
-
self.unit_spec._resolve_snrefs(
|
245
|
+
self.unit_spec._resolve_snrefs(context)
|
246
|
+
for table in self.tables:
|
247
|
+
table._resolve_snrefs(context)
|
248
|
+
for sdg in self.sdgs:
|
249
|
+
sdg._resolve_snrefs(context)
|
226
250
|
|
227
251
|
@property
|
228
252
|
def all_data_object_properties(self) -> NamedItemList[DopBase]:
|
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)
|