odxtools 9.7.0__py3-none-any.whl → 10.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odxtools/additionalaudience.py +7 -7
- odxtools/admindata.py +14 -13
- odxtools/audience.py +17 -17
- odxtools/basecomparam.py +9 -8
- odxtools/basevariantpattern.py +9 -10
- odxtools/basicstructure.py +15 -15
- odxtools/cli/_print_utils.py +34 -22
- odxtools/cli/browse.py +8 -8
- odxtools/cli/compare.py +24 -24
- odxtools/cli/decode.py +3 -4
- odxtools/cli/find.py +4 -5
- odxtools/cli/list.py +6 -6
- odxtools/cli/main.py +2 -2
- odxtools/cli/snoop.py +3 -3
- odxtools/codec.py +3 -3
- odxtools/commrelation.py +18 -17
- odxtools/companydata.py +13 -13
- odxtools/companydocinfo.py +15 -17
- odxtools/companyrevisioninfo.py +9 -9
- odxtools/companyspecificinfo.py +11 -13
- odxtools/comparam.py +8 -7
- odxtools/comparaminstance.py +14 -14
- odxtools/comparamspec.py +10 -11
- odxtools/comparamsubset.py +17 -25
- odxtools/complexcomparam.py +14 -14
- odxtools/complexdop.py +1 -1
- odxtools/compositecodec.py +8 -8
- odxtools/compumethods/compucodecompumethod.py +7 -7
- odxtools/compumethods/compuconst.py +5 -6
- odxtools/compumethods/compudefaultvalue.py +2 -3
- odxtools/compumethods/compuinternaltophys.py +13 -12
- odxtools/compumethods/compumethod.py +10 -9
- odxtools/compumethods/compuphystointernal.py +13 -12
- odxtools/compumethods/compurationalcoeffs.py +7 -7
- odxtools/compumethods/compuscale.py +15 -16
- odxtools/compumethods/createanycompumethod.py +12 -13
- odxtools/compumethods/identicalcompumethod.py +4 -5
- odxtools/compumethods/limit.py +14 -14
- odxtools/compumethods/linearcompumethod.py +5 -5
- odxtools/compumethods/linearsegment.py +10 -11
- odxtools/compumethods/ratfunccompumethod.py +6 -6
- odxtools/compumethods/ratfuncsegment.py +7 -8
- odxtools/compumethods/scalelinearcompumethod.py +9 -9
- odxtools/compumethods/scaleratfunccompumethod.py +7 -7
- odxtools/compumethods/tabintpcompumethod.py +10 -13
- odxtools/compumethods/texttablecompumethod.py +6 -6
- odxtools/createanycomparam.py +5 -7
- odxtools/createanydiagcodedtype.py +7 -8
- odxtools/database.py +34 -31
- odxtools/dataobjectproperty.py +19 -20
- odxtools/decodestate.py +5 -5
- odxtools/description.py +9 -9
- odxtools/determinenumberofitems.py +8 -7
- odxtools/diagcodedtype.py +10 -10
- odxtools/diagcomm.py +29 -30
- odxtools/diagdatadictionaryspec.py +36 -36
- odxtools/diaglayercontainer.py +35 -34
- odxtools/diaglayers/basevariant.py +14 -12
- odxtools/diaglayers/basevariantraw.py +22 -23
- odxtools/diaglayers/diaglayer.py +24 -22
- odxtools/diaglayers/diaglayerraw.py +43 -52
- odxtools/diaglayers/diaglayertype.py +1 -2
- odxtools/diaglayers/ecushareddata.py +9 -9
- odxtools/diaglayers/ecushareddataraw.py +15 -16
- odxtools/diaglayers/ecuvariant.py +15 -13
- odxtools/diaglayers/ecuvariantraw.py +21 -22
- odxtools/diaglayers/functionalgroup.py +12 -11
- odxtools/diaglayers/functionalgroupraw.py +17 -18
- odxtools/diaglayers/hierarchyelement.py +48 -54
- odxtools/diaglayers/hierarchyelementraw.py +10 -11
- odxtools/diaglayers/protocol.py +7 -7
- odxtools/diaglayers/protocolraw.py +13 -14
- odxtools/diagnostictroublecode.py +15 -17
- odxtools/diagservice.py +28 -27
- odxtools/diagvariable.py +24 -25
- odxtools/docrevision.py +18 -17
- odxtools/dopbase.py +13 -14
- odxtools/dtcconnector.py +8 -7
- odxtools/dtcdop.py +24 -20
- odxtools/dynamicendmarkerfield.py +10 -9
- odxtools/dynamiclengthfield.py +10 -9
- odxtools/dyndefinedspec.py +10 -10
- odxtools/dynenddopref.py +9 -9
- odxtools/dyniddefmodeinfo.py +21 -21
- odxtools/ecuvariantpattern.py +8 -10
- odxtools/element.py +12 -13
- odxtools/encodestate.py +11 -11
- odxtools/encoding.py +2 -3
- odxtools/endofpdufield.py +9 -10
- odxtools/envdataconnector.py +8 -8
- odxtools/environmentdata.py +7 -9
- odxtools/environmentdatadescription.py +18 -17
- odxtools/exceptions.py +5 -5
- odxtools/externalaccessmethod.py +4 -6
- odxtools/externaldoc.py +6 -6
- odxtools/field.py +15 -15
- odxtools/functionalclass.py +9 -9
- odxtools/inputparam.py +11 -10
- odxtools/internalconstr.py +10 -11
- odxtools/isotp_state_machine.py +12 -11
- odxtools/leadinglengthinfotype.py +4 -6
- odxtools/library.py +9 -8
- odxtools/linkeddtcdop.py +9 -8
- odxtools/loadfile.py +5 -6
- odxtools/matchingbasevariantparameter.py +5 -6
- odxtools/matchingparameter.py +10 -10
- odxtools/message.py +1 -1
- odxtools/minmaxlengthtype.py +6 -7
- odxtools/modification.py +7 -6
- odxtools/multiplexer.py +54 -18
- odxtools/multiplexercase.py +13 -13
- odxtools/multiplexerdefaultcase.py +11 -10
- odxtools/multiplexerswitchkey.py +8 -8
- odxtools/nameditemlist.py +13 -13
- odxtools/negoutputparam.py +8 -8
- odxtools/obd.py +1 -2
- odxtools/odxcategory.py +14 -26
- odxtools/odxdoccontext.py +16 -0
- odxtools/odxlink.py +23 -25
- odxtools/odxtypes.py +18 -15
- odxtools/outputparam.py +9 -8
- odxtools/parameterinfo.py +1 -1
- odxtools/parameters/codedconstparameter.py +10 -10
- odxtools/parameters/createanyparameter.py +15 -16
- odxtools/parameters/dynamicparameter.py +5 -7
- odxtools/parameters/lengthkeyparameter.py +10 -10
- odxtools/parameters/matchingrequestparameter.py +6 -7
- odxtools/parameters/nrcconstparameter.py +13 -13
- odxtools/parameters/parameter.py +17 -18
- odxtools/parameters/parameterwithdop.py +13 -13
- odxtools/parameters/physicalconstantparameter.py +8 -7
- odxtools/parameters/reservedparameter.py +6 -8
- odxtools/parameters/systemparameter.py +5 -7
- odxtools/parameters/tableentryparameter.py +8 -8
- odxtools/parameters/tablekeyparameter.py +17 -17
- odxtools/parameters/tablestructparameter.py +11 -11
- odxtools/parameters/valueparameter.py +11 -11
- odxtools/paramlengthinfotype.py +10 -9
- odxtools/parentref.py +15 -13
- odxtools/physicaldimension.py +15 -15
- odxtools/physicaltype.py +5 -6
- odxtools/posresponsesuppressible.py +11 -12
- odxtools/preconditionstateref.py +11 -11
- odxtools/progcode.py +11 -10
- odxtools/protstack.py +10 -9
- odxtools/relateddiagcommref.py +5 -6
- odxtools/relateddoc.py +11 -10
- odxtools/request.py +18 -19
- odxtools/response.py +19 -20
- odxtools/scaleconstr.py +8 -9
- odxtools/servicebinner.py +5 -5
- odxtools/singleecujob.py +16 -15
- odxtools/snrefcontext.py +3 -3
- odxtools/specialdata.py +8 -7
- odxtools/specialdatagroup.py +17 -17
- odxtools/specialdatagroupcaption.py +7 -6
- odxtools/standardlengthtype.py +14 -22
- odxtools/state.py +7 -6
- odxtools/statechart.py +12 -11
- odxtools/statemachine.py +4 -3
- odxtools/statetransition.py +9 -9
- odxtools/statetransitionref.py +19 -19
- odxtools/staticfield.py +9 -7
- odxtools/structure.py +5 -6
- odxtools/subcomponent.py +20 -18
- odxtools/subcomponentparamconnector.py +10 -9
- odxtools/subcomponentpattern.py +9 -9
- odxtools/swvariable.py +6 -7
- odxtools/table.py +25 -26
- odxtools/tablediagcommconnector.py +9 -8
- odxtools/tablerow.py +64 -43
- odxtools/tablerowconnector.py +8 -8
- odxtools/teammember.py +16 -15
- odxtools/templates/macros/printParentRef.xml.jinja2 +3 -1
- odxtools/text.py +4 -5
- odxtools/uds.py +2 -3
- odxtools/unit.py +14 -13
- odxtools/unitgroup.py +11 -10
- odxtools/unitspec.py +18 -19
- odxtools/utils.py +3 -3
- odxtools/variablegroup.py +5 -6
- odxtools/variantmatcher.py +10 -10
- odxtools/variantpattern.py +5 -6
- odxtools/version.py +2 -2
- odxtools/writepdxfile.py +5 -24
- odxtools/xdoc.py +13 -12
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/METADATA +4 -5
- odxtools-10.1.0.dist-info/RECORD +265 -0
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/WHEEL +1 -1
- odxtools-9.7.0.dist-info/RECORD +0 -264
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/entry_points.txt +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/licenses/LICENSE +0 -0
- {odxtools-9.7.0.dist-info → odxtools-10.1.0.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,12 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import IdentifiableElement
|
7
7
|
from .exceptions import odxrequire
|
8
|
-
from .
|
8
|
+
from .odxdoccontext import OdxDocContext
|
9
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
9
10
|
from .odxtypes import odxstr_to_bool
|
10
11
|
from .snrefcontext import SnRefContext
|
11
12
|
from .specialdatagroup import SpecialDataGroup
|
@@ -13,34 +14,31 @@ from .text import Text
|
|
13
14
|
from .utils import dataclass_fields_asdict
|
14
15
|
|
15
16
|
|
16
|
-
@dataclass
|
17
|
+
@dataclass(kw_only=True)
|
17
18
|
class DiagnosticTroubleCode(IdentifiableElement):
|
18
19
|
trouble_code: int
|
19
|
-
display_trouble_code:
|
20
|
+
display_trouble_code: str | None = None
|
20
21
|
text: Text
|
21
|
-
level:
|
22
|
-
sdgs:
|
22
|
+
level: int | None = None
|
23
|
+
sdgs: list[SpecialDataGroup] = field(default_factory=list)
|
23
24
|
|
24
|
-
is_temporary_raw:
|
25
|
+
is_temporary_raw: bool | None = None
|
25
26
|
|
26
27
|
@property
|
27
28
|
def is_temporary(self) -> bool:
|
28
29
|
return self.is_temporary_raw is True
|
29
30
|
|
30
31
|
@staticmethod
|
31
|
-
def from_et(et_element: ElementTree.Element,
|
32
|
-
|
33
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
32
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DiagnosticTroubleCode":
|
33
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
34
34
|
|
35
35
|
trouble_code = int(odxrequire(et_element.findtext("TROUBLE-CODE")))
|
36
36
|
display_trouble_code = et_element.findtext("DISPLAY-TROUBLE-CODE")
|
37
|
-
text = Text.from_et(odxrequire(et_element.find("TEXT")),
|
37
|
+
text = Text.from_et(odxrequire(et_element.find("TEXT")), context)
|
38
38
|
level = None
|
39
39
|
if (level_str := et_element.findtext("LEVEL")) is not None:
|
40
40
|
level = int(level_str)
|
41
|
-
sdgs = [
|
42
|
-
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
43
|
-
]
|
41
|
+
sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
|
44
42
|
|
45
43
|
is_temporary_raw = odxstr_to_bool(et_element.attrib.get("IS-TEMPORARY"))
|
46
44
|
|
@@ -53,8 +51,8 @@ class DiagnosticTroubleCode(IdentifiableElement):
|
|
53
51
|
is_temporary_raw=is_temporary_raw,
|
54
52
|
**kwargs)
|
55
53
|
|
56
|
-
def _build_odxlinks(self) ->
|
57
|
-
result:
|
54
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
55
|
+
result: dict[OdxLinkId, Any] = {}
|
58
56
|
|
59
57
|
result[self.odx_id] = self
|
60
58
|
|
odxtools/diagservice.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import Any,
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import Any, cast
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .addressing import Addressing
|
@@ -9,7 +9,8 @@ from .diagcomm import DiagComm
|
|
9
9
|
from .exceptions import DecodeError, DecodeMismatch, odxassert, odxraise, odxrequire
|
10
10
|
from .message import Message
|
11
11
|
from .nameditemlist import NamedItemList
|
12
|
-
from .
|
12
|
+
from .odxdoccontext import OdxDocContext
|
13
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
13
14
|
from .odxtypes import ParameterValue, odxstr_to_bool
|
14
15
|
from .parameters.parameter import Parameter
|
15
16
|
from .posresponsesuppressible import PosResponseSuppressible
|
@@ -20,28 +21,28 @@ from .transmode import TransMode
|
|
20
21
|
from .utils import dataclass_fields_asdict
|
21
22
|
|
22
23
|
|
23
|
-
@dataclass
|
24
|
+
@dataclass(kw_only=True)
|
24
25
|
class DiagService(DiagComm):
|
25
26
|
"""Representation of a diagnostic service description.
|
26
27
|
"""
|
27
28
|
|
28
|
-
comparam_refs:
|
29
|
+
comparam_refs: list[ComparamInstance] = field(default_factory=list)
|
29
30
|
request_ref: OdxLinkRef
|
30
|
-
pos_response_refs:
|
31
|
-
neg_response_refs:
|
32
|
-
pos_response_suppressible:
|
31
|
+
pos_response_refs: list[OdxLinkRef] = field(default_factory=list)
|
32
|
+
neg_response_refs: list[OdxLinkRef] = field(default_factory=list)
|
33
|
+
pos_response_suppressible: PosResponseSuppressible | None = None
|
33
34
|
|
34
|
-
is_cyclic_raw:
|
35
|
-
is_multiple_raw:
|
36
|
-
addressing_raw:
|
37
|
-
transmission_mode_raw:
|
35
|
+
is_cyclic_raw: bool | None = None
|
36
|
+
is_multiple_raw: bool | None = None
|
37
|
+
addressing_raw: Addressing | None = None
|
38
|
+
transmission_mode_raw: TransMode | None = None
|
38
39
|
|
39
40
|
@property
|
40
41
|
def comparams(self) -> NamedItemList[ComparamInstance]:
|
41
42
|
return self._comparams
|
42
43
|
|
43
44
|
@property
|
44
|
-
def request(self) ->
|
45
|
+
def request(self) -> Request | None:
|
45
46
|
return self._request
|
46
47
|
|
47
48
|
@property
|
@@ -69,42 +70,42 @@ class DiagService(DiagComm):
|
|
69
70
|
return self.transmission_mode_raw or TransMode.SEND_AND_RECEIVE
|
70
71
|
|
71
72
|
@property
|
72
|
-
def free_parameters(self) ->
|
73
|
+
def free_parameters(self) -> list[Parameter]:
|
73
74
|
"""Return the list of parameters which can be freely specified by
|
74
75
|
the user when encoding the service's request.
|
75
76
|
"""
|
76
77
|
return self.request.free_parameters if self.request is not None else []
|
77
78
|
|
78
79
|
@staticmethod
|
79
|
-
def from_et(et_element: ElementTree.Element,
|
80
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DiagService":
|
80
81
|
|
81
|
-
kwargs = dataclass_fields_asdict(DiagComm.from_et(et_element,
|
82
|
+
kwargs = dataclass_fields_asdict(DiagComm.from_et(et_element, context))
|
82
83
|
|
83
84
|
comparam_refs = [
|
84
|
-
ComparamInstance.from_et(el,
|
85
|
+
ComparamInstance.from_et(el, context)
|
85
86
|
for el in et_element.iterfind("COMPARAM-REFS/COMPARAM-REF")
|
86
87
|
]
|
87
88
|
|
88
|
-
request_ref = odxrequire(OdxLinkRef.from_et(et_element.find("REQUEST-REF"),
|
89
|
+
request_ref = odxrequire(OdxLinkRef.from_et(et_element.find("REQUEST-REF"), context))
|
89
90
|
|
90
91
|
pos_response_refs = [
|
91
|
-
odxrequire(OdxLinkRef.from_et(el,
|
92
|
+
odxrequire(OdxLinkRef.from_et(el, context))
|
92
93
|
for el in et_element.iterfind("POS-RESPONSE-REFS/POS-RESPONSE-REF")
|
93
94
|
]
|
94
95
|
|
95
96
|
neg_response_refs = [
|
96
|
-
odxrequire(OdxLinkRef.from_et(el,
|
97
|
+
odxrequire(OdxLinkRef.from_et(el, context))
|
97
98
|
for el in et_element.iterfind("NEG-RESPONSE-REFS/NEG-RESPONSE-REF")
|
98
99
|
]
|
99
100
|
|
100
101
|
pos_response_suppressible = None
|
101
102
|
if (prs_elem := et_element.find("POS-RESPONSE-SUPPRESSABLE")) is not None:
|
102
|
-
pos_response_suppressible = PosResponseSuppressible.from_et(prs_elem,
|
103
|
+
pos_response_suppressible = PosResponseSuppressible.from_et(prs_elem, context)
|
103
104
|
|
104
105
|
is_cyclic_raw = odxstr_to_bool(et_element.get("IS-CYCLIC"))
|
105
106
|
is_multiple_raw = odxstr_to_bool(et_element.get("IS-MULTIPLE"))
|
106
107
|
|
107
|
-
addressing_raw:
|
108
|
+
addressing_raw: Addressing | None = None
|
108
109
|
if (addressing_raw_str := et_element.get("ADDRESSING")) is not None:
|
109
110
|
try:
|
110
111
|
addressing_raw = Addressing(addressing_raw_str)
|
@@ -112,7 +113,7 @@ class DiagService(DiagComm):
|
|
112
113
|
addressing_raw = cast(Addressing, None)
|
113
114
|
odxraise(f"Encountered unknown addressing type '{addressing_raw_str}'")
|
114
115
|
|
115
|
-
transmission_mode_raw:
|
116
|
+
transmission_mode_raw: TransMode | None = None
|
116
117
|
if (transmission_mode_raw_str := et_element.get("TRANSMISSION-MODE")) is not None:
|
117
118
|
try:
|
118
119
|
transmission_mode_raw = TransMode(transmission_mode_raw_str)
|
@@ -132,7 +133,7 @@ class DiagService(DiagComm):
|
|
132
133
|
transmission_mode_raw=transmission_mode_raw,
|
133
134
|
**kwargs)
|
134
135
|
|
135
|
-
def _build_odxlinks(self) ->
|
136
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
136
137
|
result = super()._build_odxlinks()
|
137
138
|
|
138
139
|
for cpr in self.comparam_refs:
|
@@ -180,20 +181,20 @@ class DiagService(DiagComm):
|
|
180
181
|
|
181
182
|
def decode_message(self, raw_message: bytes) -> Message:
|
182
183
|
request_prefix = b''
|
183
|
-
candidate_coding_objects:
|
184
|
+
candidate_coding_objects: list[Request | Response] = [
|
184
185
|
*self.positive_responses, *self.negative_responses
|
185
186
|
]
|
186
187
|
if self.request is not None:
|
187
188
|
request_prefix = self.request.coded_const_prefix()
|
188
189
|
candidate_coding_objects.append(self.request)
|
189
190
|
|
190
|
-
coding_objects:
|
191
|
+
coding_objects: list[Request | Response] = []
|
191
192
|
for candidate_coding_object in candidate_coding_objects:
|
192
193
|
prefix = candidate_coding_object.coded_const_prefix(request_prefix=request_prefix)
|
193
194
|
if len(raw_message) >= len(prefix) and prefix == raw_message[:len(prefix)]:
|
194
195
|
coding_objects.append(candidate_coding_object)
|
195
196
|
|
196
|
-
result_list:
|
197
|
+
result_list: list[Message] = []
|
197
198
|
for coding_object in coding_objects:
|
198
199
|
try:
|
199
200
|
result_list.append(
|
odxtools/diagvariable.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import typing
|
3
|
-
from dataclasses import dataclass
|
4
|
-
from typing import Any,
|
3
|
+
from dataclasses import dataclass, field
|
4
|
+
from typing import Any, runtime_checkable
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from .admindata import AdminData
|
@@ -9,7 +9,8 @@ from .commrelation import CommRelation
|
|
9
9
|
from .element import IdentifiableElement
|
10
10
|
from .exceptions import odxrequire
|
11
11
|
from .nameditemlist import NamedItemList
|
12
|
-
from .
|
12
|
+
from .odxdoccontext import OdxDocContext
|
13
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
13
14
|
from .odxtypes import odxstr_to_bool
|
14
15
|
from .snrefcontext import SnRefContext
|
15
16
|
from .specialdatagroup import SpecialDataGroup
|
@@ -28,37 +29,37 @@ class HasDiagVariables(typing.Protocol):
|
|
28
29
|
...
|
29
30
|
|
30
31
|
|
31
|
-
@dataclass
|
32
|
+
@dataclass(kw_only=True)
|
32
33
|
class DiagVariable(IdentifiableElement):
|
33
34
|
"""Representation of a diagnostic variable
|
34
35
|
"""
|
35
36
|
|
36
|
-
admin_data:
|
37
|
-
variable_group_ref:
|
38
|
-
sw_variables:
|
37
|
+
admin_data: AdminData | None = None
|
38
|
+
variable_group_ref: OdxLinkRef | None = None
|
39
|
+
sw_variables: list[SwVariable] = field(default_factory=list)
|
39
40
|
|
40
41
|
# a diag variable must specify either COMM-RELATIONS or a
|
41
42
|
# reference to a table row
|
42
|
-
comm_relations:
|
43
|
+
comm_relations: list[CommRelation] = field(default_factory=list)
|
43
44
|
|
44
45
|
# these are nested inside the SNREF-TO-TABLEROW tag
|
45
|
-
table_snref:
|
46
|
-
table_row_snref:
|
46
|
+
table_snref: str | None = None
|
47
|
+
table_row_snref: str | None = None
|
47
48
|
|
48
|
-
sdgs:
|
49
|
+
sdgs: list[SpecialDataGroup] = field(default_factory=list)
|
49
50
|
|
50
|
-
is_read_before_write_raw:
|
51
|
+
is_read_before_write_raw: bool | None = None
|
51
52
|
|
52
53
|
@property
|
53
|
-
def table(self) ->
|
54
|
+
def table(self) -> Table | None:
|
54
55
|
return self._table
|
55
56
|
|
56
57
|
@property
|
57
|
-
def table_row(self) ->
|
58
|
+
def table_row(self) -> TableRow | None:
|
58
59
|
return self._table_row
|
59
60
|
|
60
61
|
@property
|
61
|
-
def variable_group(self) ->
|
62
|
+
def variable_group(self) -> VariableGroup | None:
|
62
63
|
return self._variable_group
|
63
64
|
|
64
65
|
@property
|
@@ -66,17 +67,17 @@ class DiagVariable(IdentifiableElement):
|
|
66
67
|
return self.is_read_before_write_raw is True
|
67
68
|
|
68
69
|
@staticmethod
|
69
|
-
def from_et(et_element: ElementTree.Element,
|
70
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
70
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DiagVariable":
|
71
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
71
72
|
|
72
|
-
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"),
|
73
|
-
variable_group_ref = OdxLinkRef.from_et(et_element.find("VARIABLE-GROUP-REF"),
|
73
|
+
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), context)
|
74
|
+
variable_group_ref = OdxLinkRef.from_et(et_element.find("VARIABLE-GROUP-REF"), context)
|
74
75
|
sw_variables = NamedItemList([
|
75
|
-
SwVariable.from_et(swv_elem,
|
76
|
+
SwVariable.from_et(swv_elem, context)
|
76
77
|
for swv_elem in et_element.iterfind("SW-VARIABLES/SW-VARIABLE")
|
77
78
|
])
|
78
79
|
comm_relations = [
|
79
|
-
CommRelation.from_et(cr_elem,
|
80
|
+
CommRelation.from_et(cr_elem, context)
|
80
81
|
for cr_elem in et_element.iterfind("COMM-RELATIONS/COMM-RELATION")
|
81
82
|
]
|
82
83
|
|
@@ -89,9 +90,7 @@ class DiagVariable(IdentifiableElement):
|
|
89
90
|
table_row_snref_elem = odxrequire(snref_to_tablerow_elem.find("TABLE-ROW-SNREF"))
|
90
91
|
table_row_snref = odxrequire(table_row_snref_elem.attrib.get("SHORT-NAME"))
|
91
92
|
|
92
|
-
sdgs = [
|
93
|
-
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
94
|
-
]
|
93
|
+
sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
|
95
94
|
|
96
95
|
is_read_before_write_raw = odxstr_to_bool(et_element.get("IS-READ-BEFORE-WRITE"))
|
97
96
|
|
@@ -106,7 +105,7 @@ class DiagVariable(IdentifiableElement):
|
|
106
105
|
is_read_before_write_raw=is_read_before_write_raw,
|
107
106
|
**kwargs)
|
108
107
|
|
109
|
-
def _build_odxlinks(self) ->
|
108
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
110
109
|
result = {self.odx_id: self}
|
111
110
|
|
112
111
|
if self.admin_data is not None:
|
odxtools/docrevision.py
CHANGED
@@ -1,51 +1,52 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .companyrevisioninfo import CompanyRevisionInfo
|
7
7
|
from .exceptions import odxrequire
|
8
8
|
from .modification import Modification
|
9
|
-
from .
|
9
|
+
from .odxdoccontext import OdxDocContext
|
10
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
10
11
|
from .snrefcontext import SnRefContext
|
11
12
|
from .teammember import TeamMember
|
12
13
|
|
13
14
|
|
14
|
-
@dataclass
|
15
|
+
@dataclass(kw_only=True)
|
15
16
|
class DocRevision:
|
16
17
|
"""
|
17
18
|
Representation of a single revision of the relevant object.
|
18
19
|
"""
|
19
20
|
|
20
|
-
team_member_ref:
|
21
|
-
revision_label:
|
22
|
-
state:
|
21
|
+
team_member_ref: OdxLinkRef | None = None
|
22
|
+
revision_label: str | None = None
|
23
|
+
state: str | None = None
|
23
24
|
date: str
|
24
|
-
tool:
|
25
|
-
company_revision_infos:
|
26
|
-
modifications:
|
25
|
+
tool: str | None = None
|
26
|
+
company_revision_infos: list[CompanyRevisionInfo] = field(default_factory=list)
|
27
|
+
modifications: list[Modification] = field(default_factory=list)
|
27
28
|
|
28
29
|
@property
|
29
|
-
def team_member(self) ->
|
30
|
+
def team_member(self) -> TeamMember | None:
|
30
31
|
return self._team_member
|
31
32
|
|
32
33
|
@staticmethod
|
33
|
-
def from_et(et_element: ElementTree.Element,
|
34
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DocRevision":
|
34
35
|
|
35
|
-
team_member_ref = OdxLinkRef.from_et(et_element.find("TEAM-MEMBER-REF"),
|
36
|
+
team_member_ref = OdxLinkRef.from_et(et_element.find("TEAM-MEMBER-REF"), context)
|
36
37
|
revision_label = et_element.findtext("REVISION-LABEL")
|
37
38
|
state = et_element.findtext("STATE")
|
38
39
|
date = odxrequire(et_element.findtext("DATE"))
|
39
40
|
tool = et_element.findtext("TOOL")
|
40
41
|
|
41
42
|
company_revision_infos = [
|
42
|
-
CompanyRevisionInfo.from_et(cri_elem,
|
43
|
+
CompanyRevisionInfo.from_et(cri_elem, context)
|
43
44
|
for cri_elem in et_element.iterfind("COMPANY-REVISION-INFOS/"
|
44
45
|
"COMPANY-REVISION-INFO")
|
45
46
|
]
|
46
47
|
|
47
48
|
modifications = [
|
48
|
-
Modification.from_et(mod_elem,
|
49
|
+
Modification.from_et(mod_elem, context)
|
49
50
|
for mod_elem in et_element.iterfind("MODIFICATIONS/MODIFICATION")
|
50
51
|
]
|
51
52
|
|
@@ -59,11 +60,11 @@ class DocRevision:
|
|
59
60
|
modifications=modifications,
|
60
61
|
)
|
61
62
|
|
62
|
-
def _build_odxlinks(self) ->
|
63
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
63
64
|
return {}
|
64
65
|
|
65
66
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
66
|
-
self._team_member:
|
67
|
+
self._team_member: TeamMember | None = None
|
67
68
|
if self.team_member_ref is not None:
|
68
69
|
self._team_member = odxlinks.resolve(self.team_member_ref, TeamMember)
|
69
70
|
|
odxtools/dopbase.py
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .admindata import AdminData
|
7
7
|
from .decodestate import DecodeState
|
8
8
|
from .element import IdentifiableElement
|
9
9
|
from .encodestate import EncodeState
|
10
|
-
from .
|
10
|
+
from .odxdoccontext import OdxDocContext
|
11
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId
|
11
12
|
from .odxtypes import ParameterValue
|
12
13
|
from .snrefcontext import SnRefContext
|
13
14
|
from .specialdatagroup import SpecialDataGroup
|
14
15
|
from .utils import dataclass_fields_asdict
|
15
16
|
|
16
17
|
|
17
|
-
@dataclass
|
18
|
+
@dataclass(kw_only=True)
|
18
19
|
class DopBase(IdentifiableElement):
|
19
20
|
"""Base class for all (simple and complex) data object properties.
|
20
21
|
|
@@ -24,25 +25,23 @@ class DopBase(IdentifiableElement):
|
|
24
25
|
|
25
26
|
"""
|
26
27
|
|
27
|
-
admin_data:
|
28
|
-
sdgs:
|
28
|
+
admin_data: AdminData | None = None
|
29
|
+
sdgs: list[SpecialDataGroup] = field(default_factory=list)
|
29
30
|
|
30
31
|
@staticmethod
|
31
|
-
def from_et(et_element: ElementTree.Element,
|
32
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DopBase":
|
32
33
|
|
33
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element,
|
34
|
+
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, context))
|
34
35
|
|
35
36
|
admin_data = None
|
36
37
|
if (admin_data_elem := et_element.find("ADMIN-DATA")) is not None:
|
37
|
-
admin_data = AdminData.from_et(admin_data_elem,
|
38
|
+
admin_data = AdminData.from_et(admin_data_elem, context)
|
38
39
|
|
39
|
-
sdgs = [
|
40
|
-
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
41
|
-
]
|
40
|
+
sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")]
|
42
41
|
|
43
42
|
return DopBase(admin_data=admin_data, sdgs=sdgs, **kwargs)
|
44
43
|
|
45
|
-
def _build_odxlinks(self) ->
|
44
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
46
45
|
result = {self.odx_id: self}
|
47
46
|
|
48
47
|
for sdg in self.sdgs:
|
@@ -58,7 +57,7 @@ class DopBase(IdentifiableElement):
|
|
58
57
|
for sdg in self.sdgs:
|
59
58
|
sdg._resolve_snrefs(context)
|
60
59
|
|
61
|
-
def get_static_bit_length(self) ->
|
60
|
+
def get_static_bit_length(self) -> int | None:
|
62
61
|
return None
|
63
62
|
|
64
63
|
def is_valid_physical_value(self, physical_value: ParameterValue) -> bool:
|
odxtools/dtcconnector.py
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .diagnostictroublecode import DiagnosticTroubleCode
|
7
7
|
from .dtcdop import DtcDop
|
8
8
|
from .element import NamedElement
|
9
9
|
from .exceptions import odxrequire
|
10
|
-
from .
|
10
|
+
from .odxdoccontext import OdxDocContext
|
11
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
11
12
|
from .snrefcontext import SnRefContext
|
12
13
|
from .utils import dataclass_fields_asdict
|
13
14
|
|
14
15
|
|
15
|
-
@dataclass
|
16
|
+
@dataclass(kw_only=True)
|
16
17
|
class DtcConnector(NamedElement):
|
17
18
|
dtc_dop_ref: OdxLinkRef
|
18
19
|
dtc_snref: str
|
@@ -26,16 +27,16 @@ class DtcConnector(NamedElement):
|
|
26
27
|
return self._dtc
|
27
28
|
|
28
29
|
@staticmethod
|
29
|
-
def from_et(et_element: ElementTree.Element,
|
30
|
-
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element,
|
30
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DtcConnector":
|
31
|
+
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context))
|
31
32
|
|
32
|
-
dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"),
|
33
|
+
dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), context))
|
33
34
|
dtc_snref_el = odxrequire(et_element.find("DTC-SNREF"))
|
34
35
|
dtc_snref = odxrequire(dtc_snref_el.get("SHORT-NAME"))
|
35
36
|
|
36
37
|
return DtcConnector(dtc_dop_ref=dtc_dop_ref, dtc_snref=dtc_snref, **kwargs)
|
37
38
|
|
38
|
-
def _build_odxlinks(self) ->
|
39
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
39
40
|
return {}
|
40
41
|
|
41
42
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/dtcdop.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
from dataclasses import dataclass
|
3
|
-
from typing import Any,
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from typing import Any, cast
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from typing_extensions import override
|
@@ -16,23 +16,24 @@ from .encodestate import EncodeState
|
|
16
16
|
from .exceptions import DecodeError, EncodeError, odxassert, odxraise, odxrequire
|
17
17
|
from .linkeddtcdop import LinkedDtcDop
|
18
18
|
from .nameditemlist import NamedItemList
|
19
|
-
from .
|
19
|
+
from .odxdoccontext import OdxDocContext
|
20
|
+
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
20
21
|
from .odxtypes import ParameterValue, odxstr_to_bool
|
21
22
|
from .physicaltype import PhysicalType
|
22
23
|
from .snrefcontext import SnRefContext
|
23
24
|
from .utils import dataclass_fields_asdict
|
24
25
|
|
25
26
|
|
26
|
-
@dataclass
|
27
|
+
@dataclass(kw_only=True)
|
27
28
|
class DtcDop(DopBase):
|
28
29
|
"""A DOP describing a diagnostic trouble code"""
|
29
30
|
|
30
31
|
diag_coded_type: DiagCodedType
|
31
32
|
physical_type: PhysicalType
|
32
33
|
compu_method: CompuMethod
|
33
|
-
dtcs_raw:
|
34
|
-
linked_dtc_dops_raw:
|
35
|
-
is_visible_raw:
|
34
|
+
dtcs_raw: list[DiagnosticTroubleCode | OdxLinkRef] = field(default_factory=list)
|
35
|
+
linked_dtc_dops_raw: list[LinkedDtcDop] = field(default_factory=list)
|
36
|
+
is_visible_raw: bool | None = None
|
36
37
|
|
37
38
|
@property
|
38
39
|
def dtcs(self) -> NamedItemList[DiagnosticTroubleCode]:
|
@@ -47,30 +48,29 @@ class DtcDop(DopBase):
|
|
47
48
|
return self.is_visible_raw is True
|
48
49
|
|
49
50
|
@staticmethod
|
50
|
-
def from_et(et_element: ElementTree.Element,
|
51
|
+
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "DtcDop":
|
51
52
|
"""Reads a DTC-DOP."""
|
52
|
-
kwargs = dataclass_fields_asdict(DopBase.from_et(et_element,
|
53
|
+
kwargs = dataclass_fields_asdict(DopBase.from_et(et_element, context))
|
53
54
|
|
54
55
|
diag_coded_type = create_any_diag_coded_type_from_et(
|
55
|
-
odxrequire(et_element.find("DIAG-CODED-TYPE")),
|
56
|
-
physical_type = PhysicalType.from_et(
|
57
|
-
odxrequire(et_element.find("PHYSICAL-TYPE")), doc_frags)
|
56
|
+
odxrequire(et_element.find("DIAG-CODED-TYPE")), context)
|
57
|
+
physical_type = PhysicalType.from_et(odxrequire(et_element.find("PHYSICAL-TYPE")), context)
|
58
58
|
compu_method = create_any_compu_method_from_et(
|
59
59
|
odxrequire(et_element.find("COMPU-METHOD")),
|
60
|
-
|
60
|
+
context,
|
61
61
|
internal_type=diag_coded_type.base_data_type,
|
62
62
|
physical_type=physical_type.base_data_type,
|
63
63
|
)
|
64
|
-
dtcs_raw:
|
64
|
+
dtcs_raw: list[DiagnosticTroubleCode | OdxLinkRef] = []
|
65
65
|
if (dtcs_elem := et_element.find("DTCS")) is not None:
|
66
66
|
for dtc_proxy_elem in dtcs_elem:
|
67
67
|
if dtc_proxy_elem.tag == "DTC":
|
68
|
-
dtcs_raw.append(DiagnosticTroubleCode.from_et(dtc_proxy_elem,
|
68
|
+
dtcs_raw.append(DiagnosticTroubleCode.from_et(dtc_proxy_elem, context))
|
69
69
|
elif dtc_proxy_elem.tag == "DTC-REF":
|
70
|
-
dtcs_raw.append(OdxLinkRef.from_et(dtc_proxy_elem,
|
70
|
+
dtcs_raw.append(OdxLinkRef.from_et(dtc_proxy_elem, context))
|
71
71
|
|
72
72
|
linked_dtc_dops_raw = [
|
73
|
-
LinkedDtcDop.from_et(dtc_ref_elem,
|
73
|
+
LinkedDtcDop.from_et(dtc_ref_elem, context)
|
74
74
|
for dtc_ref_elem in et_element.iterfind("LINKED-DTC-DOPS/"
|
75
75
|
"LINKED-DTC-DOP")
|
76
76
|
]
|
@@ -155,7 +155,7 @@ class DtcDop(DopBase):
|
|
155
155
|
return cast(int, None)
|
156
156
|
|
157
157
|
@override
|
158
|
-
def encode_into_pdu(self, physical_value:
|
158
|
+
def encode_into_pdu(self, physical_value: ParameterValue | None,
|
159
159
|
encode_state: EncodeState) -> None:
|
160
160
|
if physical_value is None:
|
161
161
|
odxraise(f"No DTC specified", EncodeError)
|
@@ -163,7 +163,11 @@ class DtcDop(DopBase):
|
|
163
163
|
|
164
164
|
trouble_code = self.convert_to_numerical_trouble_code(physical_value)
|
165
165
|
|
166
|
-
|
166
|
+
if not isinstance(trouble_code, int):
|
167
|
+
odxraise()
|
168
|
+
internal_trouble_code = self.compu_method.convert_physical_to_internal(trouble_code)
|
169
|
+
if not isinstance(internal_trouble_code, int):
|
170
|
+
odxraise()
|
167
171
|
|
168
172
|
found = False
|
169
173
|
for dtc in self.dtcs:
|
@@ -178,7 +182,7 @@ class DtcDop(DopBase):
|
|
178
182
|
|
179
183
|
self.diag_coded_type.encode_into_pdu(internal_trouble_code, encode_state)
|
180
184
|
|
181
|
-
def _build_odxlinks(self) ->
|
185
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
182
186
|
odxlinks = super()._build_odxlinks()
|
183
187
|
|
184
188
|
odxlinks.update(self.compu_method._build_odxlinks())
|