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
@@ -0,0 +1,124 @@
|
|
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, HasDiagVariables
|
10
|
+
from ..dyndefinedspec import DynDefinedSpec
|
11
|
+
from ..ecuvariantpattern import EcuVariantPattern
|
12
|
+
from ..exceptions import odxassert
|
13
|
+
from ..nameditemlist import NamedItemList
|
14
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef
|
15
|
+
from ..parentref import ParentRef
|
16
|
+
from ..variablegroup import HasVariableGroups, VariableGroup
|
17
|
+
from .diaglayer import DiagLayer
|
18
|
+
from .ecuvariantraw import EcuVariantRaw
|
19
|
+
from .hierarchyelement import HierarchyElement
|
20
|
+
|
21
|
+
|
22
|
+
@dataclass
|
23
|
+
class EcuVariant(HierarchyElement):
|
24
|
+
|
25
|
+
@property
|
26
|
+
def ecu_variant_raw(self) -> EcuVariantRaw:
|
27
|
+
return cast(EcuVariantRaw, self.diag_layer_raw)
|
28
|
+
|
29
|
+
@property
|
30
|
+
def diag_variables_raw(self) -> List[Union[DiagVariable, OdxLinkRef]]:
|
31
|
+
return self.ecu_variant_raw.diag_variables_raw
|
32
|
+
|
33
|
+
@property
|
34
|
+
def dyn_defined_spec(self) -> Optional[DynDefinedSpec]:
|
35
|
+
return self.ecu_variant_raw.dyn_defined_spec
|
36
|
+
|
37
|
+
@property
|
38
|
+
def parent_refs(self) -> List[ParentRef]:
|
39
|
+
return self.ecu_variant_raw.parent_refs
|
40
|
+
|
41
|
+
@property
|
42
|
+
def ecu_variant_patterns(self) -> List[EcuVariantPattern]:
|
43
|
+
return self.ecu_variant_raw.ecu_variant_patterns
|
44
|
+
|
45
|
+
#######
|
46
|
+
# <properties subject to value inheritance>
|
47
|
+
#######
|
48
|
+
@property
|
49
|
+
def diag_variables(self) -> NamedItemList[DiagVariable]:
|
50
|
+
return self._diag_variables
|
51
|
+
|
52
|
+
@property
|
53
|
+
def variable_groups(self) -> NamedItemList[VariableGroup]:
|
54
|
+
return self._variable_groups
|
55
|
+
|
56
|
+
#######
|
57
|
+
# </properties subject to value inheritance>
|
58
|
+
#######
|
59
|
+
|
60
|
+
@staticmethod
|
61
|
+
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "EcuVariant":
|
62
|
+
ecu_variant_raw = EcuVariantRaw.from_et(et_element, doc_frags)
|
63
|
+
|
64
|
+
return EcuVariant(diag_layer_raw=ecu_variant_raw)
|
65
|
+
|
66
|
+
def __post_init__(self) -> None:
|
67
|
+
super().__post_init__()
|
68
|
+
|
69
|
+
odxassert(
|
70
|
+
isinstance(self.diag_layer_raw, EcuVariantRaw),
|
71
|
+
"The raw diagnostic layer passed to EcuVariant "
|
72
|
+
"must be a EcuVariantRaw")
|
73
|
+
|
74
|
+
def __deepcopy__(self, memo: Dict[int, Any]) -> Any:
|
75
|
+
"""Create a deep copy of the ECU variant
|
76
|
+
|
77
|
+
Note that the copied diagnostic layer is not fully
|
78
|
+
initialized, so `_finalize_init()` should to be called on it
|
79
|
+
before it can be used normally.
|
80
|
+
"""
|
81
|
+
|
82
|
+
result = super().__deepcopy__(memo)
|
83
|
+
|
84
|
+
# note that the self.ecu_variant_raw object is *not* copied at
|
85
|
+
# this place because the attribute points to the same object
|
86
|
+
# as self.diag_layer_raw.
|
87
|
+
result.ecu_variant_raw = deepcopy(self.ecu_variant_raw, memo)
|
88
|
+
|
89
|
+
return result
|
90
|
+
|
91
|
+
@override
|
92
|
+
def _compute_value_inheritance(self, odxlinks: OdxLinkDatabase) -> None:
|
93
|
+
super()._compute_value_inheritance(odxlinks)
|
94
|
+
|
95
|
+
self._diag_variables = NamedItemList(self._compute_available_diag_variables(odxlinks))
|
96
|
+
self._variable_groups = NamedItemList(self._compute_available_variable_groups(odxlinks))
|
97
|
+
|
98
|
+
def _compute_available_diag_variables(self,
|
99
|
+
odxlinks: OdxLinkDatabase) -> Iterable[DiagVariable]:
|
100
|
+
|
101
|
+
def get_local_objects_fn(dl: DiagLayer) -> Iterable[DiagVariable]:
|
102
|
+
if not isinstance(dl.diag_layer_raw, HasDiagVariables):
|
103
|
+
return []
|
104
|
+
|
105
|
+
return dl.diag_layer_raw.diag_variables
|
106
|
+
|
107
|
+
def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
|
108
|
+
return parent_ref.not_inherited_variables
|
109
|
+
|
110
|
+
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
111
|
+
|
112
|
+
def _compute_available_variable_groups(self,
|
113
|
+
odxlinks: OdxLinkDatabase) -> Iterable[VariableGroup]:
|
114
|
+
|
115
|
+
def get_local_objects_fn(dl: DiagLayer) -> Iterable[VariableGroup]:
|
116
|
+
if not isinstance(dl.diag_layer_raw, HasVariableGroups):
|
117
|
+
return []
|
118
|
+
|
119
|
+
return dl.diag_layer_raw.variable_groups
|
120
|
+
|
121
|
+
def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
|
122
|
+
return []
|
123
|
+
|
124
|
+
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
@@ -0,0 +1,129 @@
|
|
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 ..ecuvariantpattern import EcuVariantPattern
|
9
|
+
from ..exceptions import odxraise
|
10
|
+
from ..nameditemlist import NamedItemList
|
11
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
12
|
+
from ..parentref import ParentRef
|
13
|
+
from ..snrefcontext import SnRefContext
|
14
|
+
from ..utils import dataclass_fields_asdict
|
15
|
+
from ..variablegroup import VariableGroup
|
16
|
+
from .hierarchyelementraw import HierarchyElementRaw
|
17
|
+
|
18
|
+
|
19
|
+
@dataclass
|
20
|
+
class EcuVariantRaw(HierarchyElementRaw):
|
21
|
+
diag_variables_raw: List[Union[DiagVariable, OdxLinkRef]]
|
22
|
+
variable_groups: NamedItemList[VariableGroup]
|
23
|
+
ecu_variant_patterns: List[EcuVariantPattern]
|
24
|
+
dyn_defined_spec: Optional[DynDefinedSpec]
|
25
|
+
parent_refs: List[ParentRef]
|
26
|
+
|
27
|
+
@property
|
28
|
+
def diag_variables(self) -> NamedItemList[DiagVariable]:
|
29
|
+
return self._diag_variables
|
30
|
+
|
31
|
+
@staticmethod
|
32
|
+
def from_et(et_element: ElementTree.Element,
|
33
|
+
doc_frags: List[OdxDocFragment]) -> "EcuVariantRaw":
|
34
|
+
# objects contained by diagnostic layers exibit an additional
|
35
|
+
# document fragment for the diag layer, so we use the document
|
36
|
+
# fragments of the odx id of the diag layer for IDs of
|
37
|
+
# contained objects.
|
38
|
+
her = HierarchyElementRaw.from_et(et_element, doc_frags)
|
39
|
+
kwargs = dataclass_fields_asdict(her)
|
40
|
+
doc_frags = her.odx_id.doc_fragments
|
41
|
+
|
42
|
+
diag_variables_raw: List[Union[DiagVariable, OdxLinkRef]] = []
|
43
|
+
if (dv_elems := et_element.find("DIAG-VARIABLES")) is not None:
|
44
|
+
for dv_proxy_elem in dv_elems:
|
45
|
+
dv_proxy: Union[OdxLinkRef, DiagVariable]
|
46
|
+
if dv_proxy_elem.tag == "DIAG-VARIABLE-REF":
|
47
|
+
dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, doc_frags)
|
48
|
+
elif dv_proxy_elem.tag == "DIAG-VARIABLE":
|
49
|
+
dv_proxy = DiagVariable.from_et(dv_proxy_elem, doc_frags)
|
50
|
+
else:
|
51
|
+
odxraise()
|
52
|
+
|
53
|
+
diag_variables_raw.append(dv_proxy)
|
54
|
+
|
55
|
+
variable_groups = NamedItemList([
|
56
|
+
VariableGroup.from_et(vg_elem, doc_frags)
|
57
|
+
for vg_elem in et_element.iterfind("VARIABLE-GROUPS/VARIABLE-GROUP")
|
58
|
+
])
|
59
|
+
|
60
|
+
ecu_variant_patterns = None
|
61
|
+
ecu_variant_patterns = [
|
62
|
+
EcuVariantPattern.from_et(varpat_elem, doc_frags)
|
63
|
+
for varpat_elem in et_element.iterfind("ECU-VARIANT-PATTERNS/ECU-VARIANT-PATTERN")
|
64
|
+
]
|
65
|
+
|
66
|
+
dyn_defined_spec = None
|
67
|
+
if (dds_elem := et_element.find("DYN-DEFINED-SPEC")) is not None:
|
68
|
+
dyn_defined_spec = DynDefinedSpec.from_et(dds_elem, doc_frags)
|
69
|
+
|
70
|
+
parent_refs = [
|
71
|
+
ParentRef.from_et(pr_el, doc_frags)
|
72
|
+
for pr_el in et_element.iterfind("PARENT-REFS/PARENT-REF")
|
73
|
+
]
|
74
|
+
|
75
|
+
# Create DiagLayer
|
76
|
+
return EcuVariantRaw(
|
77
|
+
diag_variables_raw=diag_variables_raw,
|
78
|
+
variable_groups=variable_groups,
|
79
|
+
ecu_variant_patterns=ecu_variant_patterns,
|
80
|
+
dyn_defined_spec=dyn_defined_spec,
|
81
|
+
parent_refs=parent_refs,
|
82
|
+
**kwargs)
|
83
|
+
|
84
|
+
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
85
|
+
result = super()._build_odxlinks()
|
86
|
+
|
87
|
+
for dv_proxy in self.diag_variables_raw:
|
88
|
+
if not isinstance(dv_proxy, OdxLinkRef):
|
89
|
+
result.update(dv_proxy._build_odxlinks())
|
90
|
+
|
91
|
+
if self.dyn_defined_spec is not None:
|
92
|
+
result.update(self.dyn_defined_spec._build_odxlinks())
|
93
|
+
|
94
|
+
for parent_ref in self.parent_refs:
|
95
|
+
result.update(parent_ref._build_odxlinks())
|
96
|
+
|
97
|
+
return result
|
98
|
+
|
99
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
100
|
+
super()._resolve_odxlinks(odxlinks)
|
101
|
+
|
102
|
+
self._diag_variables: NamedItemList[DiagVariable] = NamedItemList()
|
103
|
+
for dv_proxy in self.diag_variables_raw:
|
104
|
+
if isinstance(dv_proxy, OdxLinkRef):
|
105
|
+
dv = odxlinks.resolve(dv_proxy, DiagVariable)
|
106
|
+
else:
|
107
|
+
dv_proxy._resolve_odxlinks(odxlinks)
|
108
|
+
dv = dv_proxy
|
109
|
+
|
110
|
+
self._diag_variables.append(dv)
|
111
|
+
|
112
|
+
if self.dyn_defined_spec is not None:
|
113
|
+
self.dyn_defined_spec._resolve_odxlinks(odxlinks)
|
114
|
+
|
115
|
+
for parent_ref in self.parent_refs:
|
116
|
+
parent_ref._resolve_odxlinks(odxlinks)
|
117
|
+
|
118
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
119
|
+
super()._resolve_snrefs(context)
|
120
|
+
|
121
|
+
for dv_proxy in self.diag_variables_raw:
|
122
|
+
if not isinstance(dv_proxy, OdxLinkRef):
|
123
|
+
dv_proxy._resolve_snrefs(context)
|
124
|
+
|
125
|
+
if self.dyn_defined_spec is not None:
|
126
|
+
self.dyn_defined_spec._resolve_snrefs(context)
|
127
|
+
|
128
|
+
for parent_ref in self.parent_refs:
|
129
|
+
parent_ref._resolve_snrefs(context)
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from copy import deepcopy
|
3
|
+
from dataclasses import dataclass
|
4
|
+
from typing import Any, Dict, Iterable, List, Union, cast
|
5
|
+
from xml.etree import ElementTree
|
6
|
+
|
7
|
+
from typing_extensions import override
|
8
|
+
|
9
|
+
from ..diagvariable import DiagVariable
|
10
|
+
from ..exceptions import odxassert
|
11
|
+
from ..nameditemlist import NamedItemList
|
12
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef
|
13
|
+
from ..parentref import ParentRef
|
14
|
+
from ..variablegroup import VariableGroup
|
15
|
+
from .diaglayer import DiagLayer
|
16
|
+
from .functionalgroupraw import FunctionalGroupRaw
|
17
|
+
from .hierarchyelement import HierarchyElement
|
18
|
+
|
19
|
+
|
20
|
+
@dataclass
|
21
|
+
class FunctionalGroup(HierarchyElement):
|
22
|
+
"""This is a diagnostic layer for functionality shared between multiple ECU variants
|
23
|
+
"""
|
24
|
+
|
25
|
+
@property
|
26
|
+
def functional_group_raw(self) -> FunctionalGroupRaw:
|
27
|
+
return cast(FunctionalGroupRaw, self.diag_layer_raw)
|
28
|
+
|
29
|
+
@property
|
30
|
+
def diag_variables_raw(self) -> List[Union[DiagVariable, OdxLinkRef]]:
|
31
|
+
return self.functional_group_raw.diag_variables_raw
|
32
|
+
|
33
|
+
@property
|
34
|
+
def diag_variables(self) -> NamedItemList[DiagVariable]:
|
35
|
+
return self._diag_variables
|
36
|
+
|
37
|
+
@property
|
38
|
+
def variable_groups(self) -> NamedItemList[VariableGroup]:
|
39
|
+
return self._variable_groups
|
40
|
+
|
41
|
+
@property
|
42
|
+
def parent_refs(self) -> List[ParentRef]:
|
43
|
+
return self.functional_group_raw.parent_refs
|
44
|
+
|
45
|
+
@staticmethod
|
46
|
+
def from_et(et_element: ElementTree.Element,
|
47
|
+
doc_frags: List[OdxDocFragment]) -> "FunctionalGroup":
|
48
|
+
functional_group_raw = FunctionalGroupRaw.from_et(et_element, doc_frags)
|
49
|
+
|
50
|
+
return FunctionalGroup(diag_layer_raw=functional_group_raw)
|
51
|
+
|
52
|
+
def __post_init__(self) -> None:
|
53
|
+
super().__post_init__()
|
54
|
+
|
55
|
+
odxassert(
|
56
|
+
isinstance(self.diag_layer_raw, FunctionalGroupRaw),
|
57
|
+
"The raw diagnostic layer passed to FunctionalGroup "
|
58
|
+
"must be a FunctionalGroupRaw")
|
59
|
+
|
60
|
+
@override
|
61
|
+
def _compute_value_inheritance(self, odxlinks: OdxLinkDatabase) -> None:
|
62
|
+
super()._compute_value_inheritance(odxlinks)
|
63
|
+
|
64
|
+
self._diag_variables = NamedItemList(self._compute_available_diag_variables(odxlinks))
|
65
|
+
self._variable_groups = NamedItemList(self._compute_available_variable_groups(odxlinks))
|
66
|
+
|
67
|
+
def _compute_available_diag_variables(self,
|
68
|
+
odxlinks: OdxLinkDatabase) -> Iterable[DiagVariable]:
|
69
|
+
|
70
|
+
def get_local_objects_fn(dl: DiagLayer) -> Iterable[DiagVariable]:
|
71
|
+
if not hasattr(dl.diag_layer_raw, "diag_variables"):
|
72
|
+
return []
|
73
|
+
|
74
|
+
return dl.diag_layer_raw.diag_variables # type: ignore[no-any-return]
|
75
|
+
|
76
|
+
def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
|
77
|
+
return parent_ref.not_inherited_variables
|
78
|
+
|
79
|
+
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
80
|
+
|
81
|
+
def _compute_available_variable_groups(self,
|
82
|
+
odxlinks: OdxLinkDatabase) -> Iterable[VariableGroup]:
|
83
|
+
|
84
|
+
def get_local_objects_fn(dl: DiagLayer) -> Iterable[VariableGroup]:
|
85
|
+
if not hasattr(dl.diag_layer_raw, "variable_groups"):
|
86
|
+
return []
|
87
|
+
|
88
|
+
return dl.diag_layer_raw.variable_groups # type: ignore[no-any-return]
|
89
|
+
|
90
|
+
def not_inherited_fn(parent_ref: ParentRef) -> List[str]:
|
91
|
+
return []
|
92
|
+
|
93
|
+
return self._compute_available_objects(get_local_objects_fn, not_inherited_fn)
|
94
|
+
|
95
|
+
def __deepcopy__(self, memo: Dict[int, Any]) -> Any:
|
96
|
+
"""Create a deep copy of the functional group layer
|
97
|
+
|
98
|
+
Note that the copied diagnostic layer is not fully
|
99
|
+
initialized, so `_finalize_init()` should to be called on it
|
100
|
+
before it can be used normally.
|
101
|
+
"""
|
102
|
+
|
103
|
+
result = super().__deepcopy__(memo)
|
104
|
+
|
105
|
+
# note that the self.functional_group_raw object is *not* copied at
|
106
|
+
# this place because the attribute points to the same object
|
107
|
+
# as self.diag_layer_raw.
|
108
|
+
result.functional_group_raw = deepcopy(self.functional_group_raw, memo)
|
109
|
+
|
110
|
+
return result
|
@@ -0,0 +1,106 @@
|
|
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 ..parentref import ParentRef
|
11
|
+
from ..snrefcontext import SnRefContext
|
12
|
+
from ..utils import dataclass_fields_asdict
|
13
|
+
from ..variablegroup import VariableGroup
|
14
|
+
from .hierarchyelementraw import HierarchyElementRaw
|
15
|
+
|
16
|
+
|
17
|
+
@dataclass
|
18
|
+
class FunctionalGroupRaw(HierarchyElementRaw):
|
19
|
+
"""This is a diagnostic layer for common functionality of an ECU
|
20
|
+
"""
|
21
|
+
|
22
|
+
diag_variables_raw: List[Union[DiagVariable, OdxLinkRef]]
|
23
|
+
variable_groups: NamedItemList[VariableGroup]
|
24
|
+
parent_refs: List[ParentRef]
|
25
|
+
|
26
|
+
@property
|
27
|
+
def diag_variables(self) -> NamedItemList[DiagVariable]:
|
28
|
+
return self._diag_variables
|
29
|
+
|
30
|
+
@staticmethod
|
31
|
+
def from_et(et_element: ElementTree.Element,
|
32
|
+
doc_frags: List[OdxDocFragment]) -> "FunctionalGroupRaw":
|
33
|
+
# objects contained by diagnostic layers exibit an additional
|
34
|
+
# document fragment for the diag layer, so we use the document
|
35
|
+
# fragments of the odx id of the diag layer for IDs of
|
36
|
+
# contained objects.
|
37
|
+
her = HierarchyElementRaw.from_et(et_element, doc_frags)
|
38
|
+
kwargs = dataclass_fields_asdict(her)
|
39
|
+
doc_frags = her.odx_id.doc_fragments
|
40
|
+
|
41
|
+
diag_variables_raw: List[Union[DiagVariable, OdxLinkRef]] = []
|
42
|
+
if (dv_elems := et_element.find("DIAG-VARIABLES")) is not None:
|
43
|
+
for dv_proxy_elem in dv_elems:
|
44
|
+
dv_proxy: Union[OdxLinkRef, DiagVariable]
|
45
|
+
if dv_proxy_elem.tag == "DIAG-VARIABLE-REF":
|
46
|
+
dv_proxy = OdxLinkRef.from_et(dv_proxy_elem, doc_frags)
|
47
|
+
elif dv_proxy_elem.tag == "DIAG-VARIABLE":
|
48
|
+
dv_proxy = DiagVariable.from_et(dv_proxy_elem, doc_frags)
|
49
|
+
else:
|
50
|
+
odxraise()
|
51
|
+
|
52
|
+
diag_variables_raw.append(dv_proxy)
|
53
|
+
|
54
|
+
variable_groups = NamedItemList([
|
55
|
+
VariableGroup.from_et(vg_elem, doc_frags)
|
56
|
+
for vg_elem in et_element.iterfind("VARIABLE-GROUPS/VARIABLE-GROUP")
|
57
|
+
])
|
58
|
+
|
59
|
+
parent_refs = [
|
60
|
+
ParentRef.from_et(pr_elem, doc_frags)
|
61
|
+
for pr_elem in et_element.iterfind("PARENT-REFS/PARENT-REF")
|
62
|
+
]
|
63
|
+
|
64
|
+
return FunctionalGroupRaw(
|
65
|
+
diag_variables_raw=diag_variables_raw,
|
66
|
+
variable_groups=variable_groups,
|
67
|
+
parent_refs=parent_refs,
|
68
|
+
**kwargs)
|
69
|
+
|
70
|
+
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
71
|
+
result = super()._build_odxlinks()
|
72
|
+
|
73
|
+
for dv_proxy in self.diag_variables_raw:
|
74
|
+
if not isinstance(dv_proxy, OdxLinkRef):
|
75
|
+
result.update(dv_proxy._build_odxlinks())
|
76
|
+
|
77
|
+
for parent_ref in self.parent_refs:
|
78
|
+
result.update(parent_ref._build_odxlinks())
|
79
|
+
|
80
|
+
return result
|
81
|
+
|
82
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
83
|
+
super()._resolve_odxlinks(odxlinks)
|
84
|
+
|
85
|
+
self._diag_variables: NamedItemList[DiagVariable] = NamedItemList()
|
86
|
+
for dv_proxy in self.diag_variables_raw:
|
87
|
+
if isinstance(dv_proxy, OdxLinkRef):
|
88
|
+
dv = odxlinks.resolve(dv_proxy, DiagVariable)
|
89
|
+
else:
|
90
|
+
dv_proxy._resolve_odxlinks(odxlinks)
|
91
|
+
dv = dv_proxy
|
92
|
+
|
93
|
+
self._diag_variables.append(dv)
|
94
|
+
|
95
|
+
for parent_ref in self.parent_refs:
|
96
|
+
parent_ref._resolve_odxlinks(odxlinks)
|
97
|
+
|
98
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
99
|
+
super()._resolve_snrefs(context)
|
100
|
+
|
101
|
+
for dv_proxy in self.diag_variables_raw:
|
102
|
+
if not isinstance(dv_proxy, OdxLinkRef):
|
103
|
+
dv_proxy._resolve_snrefs(context)
|
104
|
+
|
105
|
+
for parent_ref in self.parent_refs:
|
106
|
+
parent_ref._resolve_snrefs(context)
|