odxtools 9.5.0__py3-none-any.whl → 9.6.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 +2 -2
- odxtools/admindata.py +3 -0
- odxtools/audience.py +9 -13
- odxtools/basecomparam.py +1 -2
- odxtools/basevariantpattern.py +5 -5
- odxtools/basicstructure.py +34 -35
- odxtools/commrelation.py +2 -1
- odxtools/companydata.py +1 -2
- odxtools/companyspecificinfo.py +3 -0
- odxtools/comparam.py +16 -8
- odxtools/comparaminstance.py +12 -12
- odxtools/comparamspec.py +4 -3
- odxtools/comparamsubset.py +26 -24
- odxtools/compumethods/compuconst.py +4 -4
- odxtools/compumethods/limit.py +9 -9
- odxtools/compumethods/linearsegment.py +8 -8
- odxtools/dataobjectproperty.py +16 -18
- odxtools/description.py +4 -2
- odxtools/determinenumberofitems.py +4 -4
- odxtools/diagcodedtype.py +20 -20
- odxtools/diagcomm.py +61 -41
- odxtools/diagdatadictionaryspec.py +51 -55
- odxtools/diaglayercontainer.py +25 -25
- odxtools/diaglayers/diaglayerraw.py +26 -27
- odxtools/diagnostictroublecode.py +13 -10
- odxtools/diagservice.py +48 -50
- odxtools/diagvariable.py +10 -8
- odxtools/docrevision.py +5 -5
- odxtools/dtcdop.py +17 -17
- odxtools/dynamicendmarkerfield.py +8 -8
- odxtools/dynamiclengthfield.py +2 -0
- odxtools/dyndefinedspec.py +21 -8
- odxtools/encodestate.py +1 -2
- odxtools/endofpdufield.py +7 -9
- odxtools/environmentdatadescription.py +9 -20
- odxtools/field.py +21 -21
- odxtools/inputparam.py +15 -14
- odxtools/leadinglengthinfotype.py +4 -4
- odxtools/matchingparameter.py +2 -3
- odxtools/minmaxlengthtype.py +7 -7
- odxtools/multiplexer.py +38 -39
- odxtools/multiplexercase.py +3 -6
- odxtools/multiplexerdefaultcase.py +3 -6
- odxtools/multiplexerswitchkey.py +4 -4
- odxtools/negoutputparam.py +6 -9
- odxtools/odxlink.py +21 -5
- odxtools/odxtypes.py +4 -4
- odxtools/outputparam.py +9 -8
- odxtools/parameterinfo.py +1 -1
- odxtools/parameters/codedconstparameter.py +28 -27
- odxtools/parameters/dynamicparameter.py +9 -9
- odxtools/parameters/lengthkeyparameter.py +18 -18
- odxtools/parameters/matchingrequestparameter.py +15 -15
- odxtools/parameters/nrcconstparameter.py +32 -24
- odxtools/parameters/parameter.py +35 -37
- odxtools/parameters/parameterwithdop.py +6 -6
- odxtools/parameters/physicalconstantparameter.py +19 -20
- odxtools/parameters/reservedparameter.py +10 -11
- odxtools/parameters/systemparameter.py +10 -11
- odxtools/parameters/tableentryparameter.py +19 -20
- odxtools/parameters/tablekeyparameter.py +0 -2
- odxtools/parameters/tablestructparameter.py +27 -21
- odxtools/parameters/valueparameter.py +20 -20
- odxtools/parentref.py +6 -7
- odxtools/physicaldimension.py +11 -11
- odxtools/physicaltype.py +9 -14
- odxtools/preconditionstateref.py +85 -0
- odxtools/progcode.py +1 -2
- odxtools/protstack.py +4 -4
- odxtools/relateddoc.py +3 -4
- odxtools/scaleconstr.py +0 -1
- odxtools/singleecujob.py +8 -4
- odxtools/specialdata.py +10 -9
- odxtools/specialdatagroup.py +1 -0
- odxtools/standardlengthtype.py +10 -10
- odxtools/statechart.py +10 -6
- odxtools/statemachine.py +186 -0
- odxtools/statetransitionref.py +231 -0
- odxtools/structure.py +4 -4
- odxtools/subcomponent.py +72 -8
- odxtools/table.py +23 -13
- odxtools/tablerow.py +86 -69
- odxtools/teammember.py +4 -4
- odxtools/templates/macros/printCompanyData.xml.jinja2 +2 -2
- odxtools/templates/macros/printComparam.xml.jinja2 +3 -5
- odxtools/templates/macros/printDOP.xml.jinja2 +4 -1
- odxtools/templates/macros/printDiagComm.xml.jinja2 +6 -5
- odxtools/templates/macros/printParam.xml.jinja2 +5 -5
- odxtools/templates/macros/printPreConditionStateRef.xml.jinja2 +18 -0
- odxtools/templates/macros/printStateTransitionRef.xml.jinja2 +18 -0
- odxtools/templates/macros/printTable.xml.jinja2 +13 -9
- odxtools/text.py +35 -0
- odxtools/unit.py +1 -3
- odxtools/unitgroup.py +6 -8
- odxtools/utils.py +0 -4
- odxtools/version.py +2 -2
- {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info}/METADATA +3 -2
- {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info}/RECORD +102 -96
- {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info}/WHEEL +1 -1
- {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info}/entry_points.txt +0 -0
- {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info/licenses}/LICENSE +0 -0
- {odxtools-9.5.0.dist-info → odxtools-9.6.0.dist-info}/top_level.txt +0 -0
odxtools/tablerow.py
CHANGED
@@ -5,7 +5,6 @@ from xml.etree import ElementTree
|
|
5
5
|
|
6
6
|
from .admindata import AdminData
|
7
7
|
from .audience import Audience
|
8
|
-
from .basicstructure import BasicStructure
|
9
8
|
from .dataobjectproperty import DataObjectProperty
|
10
9
|
from .dtcdop import DtcDop
|
11
10
|
from .element import IdentifiableElement
|
@@ -14,10 +13,11 @@ from .functionalclass import FunctionalClass
|
|
14
13
|
from .nameditemlist import NamedItemList
|
15
14
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
16
15
|
from .odxtypes import AtomicOdxType, odxstr_to_bool
|
16
|
+
from .preconditionstateref import PreConditionStateRef
|
17
17
|
from .snrefcontext import SnRefContext
|
18
18
|
from .specialdatagroup import SpecialDataGroup
|
19
|
-
from .
|
20
|
-
from .
|
19
|
+
from .statetransitionref import StateTransitionRef
|
20
|
+
from .structure import Structure
|
21
21
|
from .utils import dataclass_fields_asdict
|
22
22
|
|
23
23
|
if TYPE_CHECKING:
|
@@ -27,8 +27,8 @@ if TYPE_CHECKING:
|
|
27
27
|
@dataclass
|
28
28
|
class TableRow(IdentifiableElement):
|
29
29
|
"""This class represents a TABLE-ROW."""
|
30
|
-
key_raw: str
|
31
30
|
table_ref: OdxLinkRef
|
31
|
+
key_raw: str
|
32
32
|
|
33
33
|
# The spec mandates that either a structure or a non-complex DOP
|
34
34
|
# must be referenced here, i.e., exactly one of the four
|
@@ -41,8 +41,8 @@ class TableRow(IdentifiableElement):
|
|
41
41
|
sdgs: List[SpecialDataGroup]
|
42
42
|
audience: Optional[Audience]
|
43
43
|
functional_class_refs: List[OdxLinkRef]
|
44
|
-
state_transition_refs: List[
|
45
|
-
pre_condition_state_refs: List[
|
44
|
+
state_transition_refs: List[StateTransitionRef]
|
45
|
+
pre_condition_state_refs: List[PreConditionStateRef]
|
46
46
|
admin_data: Optional[AdminData]
|
47
47
|
|
48
48
|
is_executable_raw: Optional[bool]
|
@@ -51,16 +51,28 @@ class TableRow(IdentifiableElement):
|
|
51
51
|
is_final_raw: Optional[bool]
|
52
52
|
|
53
53
|
@property
|
54
|
-
def
|
55
|
-
return self.
|
54
|
+
def table(self) -> "Table":
|
55
|
+
return self._table
|
56
|
+
|
57
|
+
# the value of the key expressed in the type represented by the
|
58
|
+
# referenced DOP
|
59
|
+
@property
|
60
|
+
def key(self) -> Optional[AtomicOdxType]:
|
61
|
+
return self._key
|
62
|
+
|
63
|
+
@property
|
64
|
+
def dop(self) -> Optional[DataObjectProperty]:
|
65
|
+
"""The data object property object resolved by dop_ref."""
|
66
|
+
return self._dop
|
56
67
|
|
57
68
|
@property
|
58
|
-
def
|
59
|
-
|
69
|
+
def structure(self) -> Optional[Structure]:
|
70
|
+
"""The structure associated with this table row."""
|
71
|
+
return self._structure
|
60
72
|
|
61
73
|
@property
|
62
|
-
def
|
63
|
-
return self.
|
74
|
+
def functional_classes(self) -> NamedItemList[FunctionalClass]:
|
75
|
+
return self._functional_classes
|
64
76
|
|
65
77
|
@property
|
66
78
|
def is_executable(self) -> bool:
|
@@ -74,21 +86,6 @@ class TableRow(IdentifiableElement):
|
|
74
86
|
def is_final(self) -> bool:
|
75
87
|
return self.is_final_raw is True
|
76
88
|
|
77
|
-
def __post_init__(self) -> None:
|
78
|
-
self._structure: Optional[BasicStructure] = None
|
79
|
-
self._dop: Optional[DataObjectProperty] = None
|
80
|
-
|
81
|
-
n = sum([0 if x is None else 1 for x in (self.structure_ref, self.structure_snref)])
|
82
|
-
odxassert(
|
83
|
-
n <= 1,
|
84
|
-
f"Table row {self.short_name}: The structure can either be defined using ODXLINK or SNREF but not both."
|
85
|
-
)
|
86
|
-
n = sum([0 if x is None else 1 for x in (self.dop_ref, self.dop_snref)])
|
87
|
-
odxassert(
|
88
|
-
n <= 1,
|
89
|
-
f"Table row {self.short_name}: The dop can either be defined using ODXLINK or SNREF but not both."
|
90
|
-
)
|
91
|
-
|
92
89
|
@staticmethod
|
93
90
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> Any:
|
94
91
|
raise RuntimeError(
|
@@ -99,16 +96,19 @@ class TableRow(IdentifiableElement):
|
|
99
96
|
table_ref: OdxLinkRef) -> "TableRow":
|
100
97
|
"""Reads a TABLE-ROW."""
|
101
98
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
102
|
-
|
99
|
+
|
103
100
|
key_raw = odxrequire(et_element.findtext("KEY"))
|
104
|
-
|
105
|
-
structure_snref: Optional[str] = None
|
106
|
-
if (structure_snref_elem := et_element.find("STRUCTURE-SNREF")) is not None:
|
107
|
-
structure_snref = structure_snref_elem.attrib["SHORT-NAME"]
|
101
|
+
|
108
102
|
dop_ref = OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"), doc_frags)
|
109
103
|
dop_snref: Optional[str] = None
|
110
104
|
if (dop_snref_elem := et_element.find("DATA-OBJECT-PROP-SNREF")) is not None:
|
111
105
|
dop_snref = dop_snref_elem.attrib["SHORT-NAME"]
|
106
|
+
|
107
|
+
structure_ref = OdxLinkRef.from_et(et_element.find("STRUCTURE-REF"), doc_frags)
|
108
|
+
structure_snref: Optional[str] = None
|
109
|
+
if (structure_snref_elem := et_element.find("STRUCTURE-SNREF")) is not None:
|
110
|
+
structure_snref = structure_snref_elem.attrib["SHORT-NAME"]
|
111
|
+
|
112
112
|
sdgs = [
|
113
113
|
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
114
114
|
]
|
@@ -123,12 +123,12 @@ class TableRow(IdentifiableElement):
|
|
123
123
|
]
|
124
124
|
|
125
125
|
state_transition_refs = [
|
126
|
-
|
126
|
+
StateTransitionRef.from_et(el, doc_frags)
|
127
127
|
for el in et_element.iterfind("STATE-TRANSITION-REFS/STATE-TRANSITION-REF")
|
128
128
|
]
|
129
129
|
|
130
130
|
pre_condition_state_refs = [
|
131
|
-
|
131
|
+
PreConditionStateRef.from_et(el, doc_frags)
|
132
132
|
for el in et_element.iterfind("PRE-CONDITION-STATE-REFS/PRE-CONDITION-STATE-REF")
|
133
133
|
]
|
134
134
|
|
@@ -142,10 +142,10 @@ class TableRow(IdentifiableElement):
|
|
142
142
|
return TableRow(
|
143
143
|
table_ref=table_ref,
|
144
144
|
key_raw=key_raw,
|
145
|
-
structure_ref=structure_ref,
|
146
|
-
structure_snref=structure_snref,
|
147
145
|
dop_ref=dop_ref,
|
148
146
|
dop_snref=dop_snref,
|
147
|
+
structure_ref=structure_ref,
|
148
|
+
structure_snref=structure_snref,
|
149
149
|
sdgs=sdgs,
|
150
150
|
audience=audience,
|
151
151
|
functional_class_refs=functional_class_refs,
|
@@ -158,38 +158,66 @@ class TableRow(IdentifiableElement):
|
|
158
158
|
is_final_raw=is_final_raw,
|
159
159
|
**kwargs)
|
160
160
|
|
161
|
+
def __post_init__(self) -> None:
|
162
|
+
self._dop: Optional[DataObjectProperty] = None
|
163
|
+
self._structure: Optional[Structure] = None
|
164
|
+
|
165
|
+
n = sum([0 if x is None else 1 for x in (self.dop_ref, self.dop_snref)])
|
166
|
+
odxassert(
|
167
|
+
n <= 1,
|
168
|
+
f"Table row {self.short_name}: The dop can either be defined using ODXLINK or SNREF but not both."
|
169
|
+
)
|
170
|
+
|
171
|
+
n = sum([0 if x is None else 1 for x in (self.structure_ref, self.structure_snref)])
|
172
|
+
odxassert(
|
173
|
+
n <= 1,
|
174
|
+
f"Table row {self.short_name}: The structure can either be defined using ODXLINK or SNREF but not both."
|
175
|
+
)
|
176
|
+
|
161
177
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
162
178
|
result = {self.odx_id: self}
|
163
179
|
|
164
180
|
for sdg in self.sdgs:
|
165
181
|
result.update(sdg._build_odxlinks())
|
166
182
|
|
183
|
+
if self.audience is not None:
|
184
|
+
result.update(self.audience._build_odxlinks())
|
185
|
+
|
186
|
+
for st_ref in self.state_transition_refs:
|
187
|
+
result.update(st_ref._build_odxlinks())
|
188
|
+
|
189
|
+
for pc_ref in self.pre_condition_state_refs:
|
190
|
+
result.update(pc_ref._build_odxlinks())
|
191
|
+
|
167
192
|
return result
|
168
193
|
|
169
194
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
170
|
-
if self.structure_ref is not None:
|
171
|
-
self._structure = odxlinks.resolve(self.structure_ref, BasicStructure)
|
172
|
-
if self.dop_ref is not None:
|
173
|
-
self._dop = odxlinks.resolve(self.dop_ref)
|
174
|
-
if not isinstance(self._dop, (DataObjectProperty, DtcDop)):
|
175
|
-
odxraise("The DOP-REF of TABLE-ROWs must reference a simple DOP!")
|
176
|
-
|
177
195
|
if TYPE_CHECKING:
|
178
196
|
self._table = odxlinks.resolve(self.table_ref, Table)
|
179
197
|
else:
|
180
198
|
self._table = odxlinks.resolve(self.table_ref)
|
181
199
|
|
200
|
+
if self.dop_ref is not None:
|
201
|
+
self._dop = odxlinks.resolve(self.dop_ref)
|
202
|
+
if not isinstance(self._dop, (DataObjectProperty, DtcDop)):
|
203
|
+
odxraise("The DOP-REF of TABLE-ROWs must reference a simple DOP!")
|
204
|
+
if self.structure_ref is not None:
|
205
|
+
self._structure = odxlinks.resolve(self.structure_ref, Structure)
|
206
|
+
|
182
207
|
for sdg in self.sdgs:
|
183
208
|
sdg._resolve_odxlinks(odxlinks)
|
184
209
|
|
210
|
+
if self.audience is not None:
|
211
|
+
self.audience._resolve_odxlinks(odxlinks)
|
212
|
+
|
185
213
|
self._functional_classes = NamedItemList(
|
186
214
|
[odxlinks.resolve(fc_ref, FunctionalClass) for fc_ref in self.functional_class_refs])
|
187
215
|
|
188
|
-
self.
|
189
|
-
|
216
|
+
for st_ref in self.state_transition_refs:
|
217
|
+
st_ref._resolve_odxlinks(odxlinks)
|
190
218
|
|
191
|
-
self.
|
192
|
-
|
219
|
+
for pc_ref in self.pre_condition_state_refs:
|
220
|
+
pc_ref._resolve_odxlinks(odxlinks)
|
193
221
|
|
194
222
|
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
195
223
|
# convert the raw key into the proper internal
|
@@ -212,34 +240,23 @@ class TableRow(IdentifiableElement):
|
|
212
240
|
ddd_spec = odxrequire(context.diag_layer).diag_data_dictionary_spec
|
213
241
|
|
214
242
|
if self.structure_snref is not None:
|
215
|
-
self._structure = resolve_snref(self.structure_snref, ddd_spec.structures,
|
216
|
-
BasicStructure)
|
243
|
+
self._structure = resolve_snref(self.structure_snref, ddd_spec.structures, Structure)
|
217
244
|
if self.dop_snref is not None:
|
218
|
-
self._dop = resolve_snref(self.dop_snref, ddd_spec.data_object_props
|
219
|
-
|
245
|
+
self._dop = resolve_snref(self.dop_snref, ddd_spec.data_object_props)
|
246
|
+
if not isinstance(self._dop, (DataObjectProperty, DtcDop)):
|
247
|
+
odxraise("The DOP-SNREF of TABLE-ROWs must reference a simple DOP!")
|
248
|
+
|
249
|
+
if self.audience is not None:
|
250
|
+
self.audience._resolve_snrefs(context)
|
220
251
|
|
221
252
|
for sdg in self.sdgs:
|
222
253
|
sdg._resolve_snrefs(context)
|
223
254
|
|
224
|
-
|
225
|
-
|
226
|
-
return self._table
|
255
|
+
for st_ref in self.state_transition_refs:
|
256
|
+
st_ref._resolve_snrefs(context)
|
227
257
|
|
228
|
-
|
229
|
-
|
230
|
-
@property
|
231
|
-
def key(self) -> Optional[AtomicOdxType]:
|
232
|
-
return self._key
|
233
|
-
|
234
|
-
@property
|
235
|
-
def structure(self) -> Optional[BasicStructure]:
|
236
|
-
"""The structure associated with this table row."""
|
237
|
-
return self._structure
|
238
|
-
|
239
|
-
@property
|
240
|
-
def dop(self) -> Optional[DataObjectProperty]:
|
241
|
-
"""The data object property object resolved by dop_ref."""
|
242
|
-
return self._dop
|
258
|
+
for pc_ref in self.pre_condition_state_refs:
|
259
|
+
pc_ref._resolve_snrefs(context)
|
243
260
|
|
244
261
|
def __reduce__(self) -> Tuple[Any, ...]:
|
245
262
|
"""This ensures that the object can be correctly reconstructed during unpickling."""
|
odxtools/teammember.py
CHANGED
@@ -15,7 +15,7 @@ class TeamMember(IdentifiableElement):
|
|
15
15
|
roles: List[str]
|
16
16
|
department: Optional[str]
|
17
17
|
address: Optional[str]
|
18
|
-
|
18
|
+
zipcode: Optional[str] # the tag for this is "ZIP", but `zip` is a keyword in python
|
19
19
|
city: Optional[str]
|
20
20
|
phone: Optional[str]
|
21
21
|
fax: Optional[str]
|
@@ -24,11 +24,11 @@ class TeamMember(IdentifiableElement):
|
|
24
24
|
@staticmethod
|
25
25
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "TeamMember":
|
26
26
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
27
|
-
roles = [odxrequire(role_elem.text) for role_elem in et_element.iterfind("ROLES/ROLE")]
|
28
27
|
|
28
|
+
roles = [odxrequire(role_elem.text) for role_elem in et_element.iterfind("ROLES/ROLE")]
|
29
29
|
department = et_element.findtext("DEPARTMENT")
|
30
30
|
address = et_element.findtext("ADDRESS")
|
31
|
-
|
31
|
+
zipcode = et_element.findtext("ZIP")
|
32
32
|
city = et_element.findtext("CITY")
|
33
33
|
phone = et_element.findtext("PHONE")
|
34
34
|
fax = et_element.findtext("FAX")
|
@@ -38,7 +38,7 @@ class TeamMember(IdentifiableElement):
|
|
38
38
|
roles=roles,
|
39
39
|
department=department,
|
40
40
|
address=address,
|
41
|
-
|
41
|
+
zipcode=zipcode,
|
42
42
|
city=city,
|
43
43
|
phone=phone,
|
44
44
|
fax=fax,
|
@@ -35,8 +35,8 @@
|
|
35
35
|
{%- if team_member.address is not none %}
|
36
36
|
<ADDRESS>{{team_member.address|e}}</ADDRESS>
|
37
37
|
{%- endif %}
|
38
|
-
{%- if team_member.
|
39
|
-
<ZIP>{{team_member.
|
38
|
+
{%- if team_member.zipcode is not none %}
|
39
|
+
<ZIP>{{team_member.zipcode|e}}</ZIP>
|
40
40
|
{%- endif %}
|
41
41
|
{%- if team_member.city is not none %}
|
42
42
|
<CITY>{{team_member.city|e}}</CITY>
|
@@ -44,9 +44,7 @@
|
|
44
44
|
{{make_xml_attrib("DISPLAY-LEVEL", cp.display_level)}}{#- #}
|
45
45
|
CPUSAGE="{{cp.cpusage.value}}">
|
46
46
|
{{ peid.printElementIdSubtags(cp)|indent(1) }}
|
47
|
-
{
|
48
|
-
<PHYSICAL-DEFAULT-VALUE>{{cp.physical_default_value | e}}</PHYSICAL-DEFAULT-VALUE>
|
49
|
-
{%- endif %}
|
47
|
+
<PHYSICAL-DEFAULT-VALUE>{{cp.physical_default_value_raw}}</PHYSICAL-DEFAULT-VALUE>
|
50
48
|
<DATA-OBJECT-PROP-REF ID-REF="{{cp.dop_ref.ref_id}}" />
|
51
49
|
</COMPARAM>
|
52
50
|
{%- endmacro %}
|
@@ -55,9 +53,9 @@
|
|
55
53
|
<COMPLEX-COMPARAM {{-peid.printElementIdAttribs(cp)}}
|
56
54
|
PARAM-CLASS="{{cp.param_class}}"
|
57
55
|
CPTYPE="{{cp.cptype.value}}"
|
58
|
-
|
56
|
+
{{make_xml_attrib("DISPLAY-LEVEL", cp.display_level)}}{#- #}
|
59
57
|
CPUSAGE="{{cp.cpusage.value}}"
|
60
|
-
|
58
|
+
{{make_bool_xml_attrib("ALLOW-MULTIPLE-VALUES", cp.allow_multiple_values_raw)}}
|
61
59
|
{#- #}>
|
62
60
|
{{ peid.printElementIdSubtags(cp)|indent(1) }}
|
63
61
|
{%- for sub_cp in cp.subparams %}
|
@@ -17,6 +17,9 @@
|
|
17
17
|
{%- if dct.termination is defined %}
|
18
18
|
{{-make_xml_attrib("TERMINATION", dct.termination.value)}}
|
19
19
|
{%- endif %}
|
20
|
+
{%- if dct.is_condensed_raw is defined %}
|
21
|
+
{{-make_bool_xml_attrib("CONDENSED", dct.is_condensed_raw)}}
|
22
|
+
{%- endif %}
|
20
23
|
{#- #} xsi:type="{{dct.dct_type}}">
|
21
24
|
{%- if dct.dct_type in ("STANDARD-LENGTH-TYPE", "LEADING-LENGTH-INFO-TYPE") %}
|
22
25
|
<BIT-LENGTH>{{dct.bit_length}}</BIT-LENGTH>
|
@@ -136,7 +139,7 @@
|
|
136
139
|
{%- if dtc.display_trouble_code is not none %}
|
137
140
|
<DISPLAY-TROUBLE-CODE>{{dtc.display_trouble_code}}</DISPLAY-TROUBLE-CODE>
|
138
141
|
{%- endif %}
|
139
|
-
<TEXT>{{dtc.text|e}}</TEXT>
|
142
|
+
<TEXT {{- make_xml_attrib("TI", dtc.text.text_identifier) }}>{{dtc.text|e}}</TEXT>
|
140
143
|
{%- if not dtc.level is none %}
|
141
144
|
<LEVEL>{{dtc.level}}</LEVEL>
|
142
145
|
{%- endif %}
|
@@ -7,6 +7,8 @@
|
|
7
7
|
{%- import('macros/printAdminData.xml.jinja2') as pad %}
|
8
8
|
{%- import('macros/printAudience.xml.jinja2') as paud %}
|
9
9
|
{%- import('macros/printSpecialData.xml.jinja2') as psd %}
|
10
|
+
{%- import('macros/printPreConditionStateRef.xml.jinja2') as ppcsr %}
|
11
|
+
{%- import('macros/printStateTransitionRef.xml.jinja2') as pstr %}
|
10
12
|
|
11
13
|
{%- macro printDiagCommAttribs(dc) -%}
|
12
14
|
{{-peid.printElementIdAttribs(dc)}}
|
@@ -17,7 +19,6 @@
|
|
17
19
|
{{-make_bool_xml_attrib("IS-FINAL", dc.is_final_raw)}}
|
18
20
|
{%- endmacro -%}
|
19
21
|
|
20
|
-
|
21
22
|
{%- macro printDiagCommSubtags(dc) -%}
|
22
23
|
{{ peid.printElementIdSubtags(dc)|indent(1) }}
|
23
24
|
{%- if dc.admin_data %}
|
@@ -53,15 +54,15 @@
|
|
53
54
|
{%- if dc.pre_condition_state_refs %}
|
54
55
|
<PRE-CONDITION-STATE-REFS>
|
55
56
|
{%- for ps_ref in dc.pre_condition_state_refs %}
|
56
|
-
|
57
|
+
{{ ppcsr.printPreConditionStateRef(ps_ref)|indent(2) }}
|
57
58
|
{%- endfor %}
|
58
59
|
</PRE-CONDITION-STATE-REFS>
|
59
60
|
{%- endif%}
|
60
61
|
{%- if dc.state_transition_refs %}
|
61
62
|
<STATE-TRANSITION-REFS>
|
62
|
-
|
63
|
-
|
64
|
-
|
63
|
+
{%- for st_ref in dc.state_transition_refs %}
|
64
|
+
{{ pstr.printStateTransitionRef(st_ref)|indent(2) }}
|
65
|
+
{%- endfor %}
|
65
66
|
</STATE-TRANSITION-REFS>
|
66
67
|
{%- endif%}
|
67
68
|
{%- endmacro -%}
|
@@ -33,12 +33,12 @@
|
|
33
33
|
{%- if param.byte_length is defined and param.byte_length is not none %}
|
34
34
|
<BYTE-LENGTH>{{param.byte_length}}</BYTE-LENGTH>
|
35
35
|
{%- endif %}
|
36
|
-
{%- if param.
|
37
|
-
<CODED-VALUE>{{param.
|
38
|
-
{%- elif param.
|
36
|
+
{%- if param.coded_value_raw is defined %}
|
37
|
+
<CODED-VALUE>{{param.coded_value_raw}}</CODED-VALUE>
|
38
|
+
{%- elif param.coded_values_raw is defined %}
|
39
39
|
<CODED-VALUES>
|
40
|
-
{%- for
|
41
|
-
<CODED-VALUE>{{
|
40
|
+
{%- for coded_value_raw in param.coded_values_raw %}
|
41
|
+
<CODED-VALUE>{{coded_value_raw}}</CODED-VALUE>
|
42
42
|
{%- endfor %}
|
43
43
|
</CODED-VALUES>
|
44
44
|
{%- endif %}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
-#}
|
5
|
+
|
6
|
+
{%- macro printPreConditionStateRef(ps_ref) -%}
|
7
|
+
<PRE-CONDITION-STATE-REF ID-REF="{{ps_ref.ref_id}}">
|
8
|
+
{%- if ps_ref.value is not none %}
|
9
|
+
<VALUE>{{ ps_ref.value }}</VALUE>
|
10
|
+
{%- endif %}
|
11
|
+
{%- if ps_ref.in_param_if_snref is not none %}
|
12
|
+
<IN-PARAM-IF-SNREF SHORT-NAME="{{ ps_ref.in_param_if_snref }}" />
|
13
|
+
{%- endif %}
|
14
|
+
{%- if ps_ref.in_param_if_snpathref is not none %}
|
15
|
+
<IN-PARAM-IF-SNPATHREF SHORT-NAME-PATH="{{ ps_ref.in_param_if_snpathref }}" />
|
16
|
+
{%- endif %}
|
17
|
+
</PRE-CONDITION-STATE-REF>
|
18
|
+
{%- endmacro -%}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
-#}
|
5
|
+
|
6
|
+
{%- macro printStateTransitionRef(st_ref) -%}
|
7
|
+
<STATE-TRANSITION-REF ID-REF="{{st_ref.ref_id}}">
|
8
|
+
{%- if st_ref.value is not none %}
|
9
|
+
<VALUE>{{ st_ref.value }}</VALUE>
|
10
|
+
{%- endif %}
|
11
|
+
{%- if st_ref.in_param_if_snref is not none %}
|
12
|
+
<IN-PARAM-IF-SNREF SHORT-NAME="{{ st_ref.in_param_if_snref }}" />
|
13
|
+
{%- endif %}
|
14
|
+
{%- if st_ref.in_param_if_snpathref is not none %}
|
15
|
+
<IN-PARAM-IF-SNPATHREF SHORT-NAME-PATH="{{ st_ref.in_param_if_snpathref }}" />
|
16
|
+
{%- endif %}
|
17
|
+
</STATE-TRANSITION-REF>
|
18
|
+
{%- endmacro -%}
|
@@ -8,6 +8,8 @@
|
|
8
8
|
{%- import('macros/printDescription.xml.jinja2') as pd %}
|
9
9
|
{%- import('macros/printAdminData.xml.jinja2') as pad %}
|
10
10
|
{%- import('macros/printAudience.xml.jinja2') as paud %}
|
11
|
+
{%- import('macros/printPreConditionStateRef.xml.jinja2') as ppcsr %}
|
12
|
+
{%- import('macros/printStateTransitionRef.xml.jinja2') as pstr %}
|
11
13
|
|
12
14
|
{%- macro printTable(table) %}
|
13
15
|
<TABLE {{-peid.printElementIdAttribs(table)}}
|
@@ -20,18 +22,20 @@
|
|
20
22
|
{%- if hasattr(table_row, "key") %}
|
21
23
|
<TABLE-ROW {{-peid.printElementIdAttribs(table_row)}}
|
22
24
|
{{-make_xml_attrib("SEMANTIC", table_row.semantic)}}>
|
23
|
-
|
24
|
-
{%- if table_row.long_name %}
|
25
|
-
<LONG-NAME>{{table_row.long_name|e}}</LONG-NAME>
|
26
|
-
{%- endif %}
|
27
|
-
{{ pd.printDescription(table_row.description) }}
|
25
|
+
{{-peid.printElementIdSubtags(table_row)}}
|
28
26
|
<KEY>{{table_row.key|e}}</KEY>
|
29
|
-
{%- if table_row.dop_ref %}
|
27
|
+
{%- if table_row.dop_ref is not none %}
|
30
28
|
<DATA-OBJECT-PROP-REF ID-REF="{{ table_row.dop_ref.ref_id }}" />
|
31
29
|
{%- endif %}
|
32
|
-
{%- if table_row.
|
30
|
+
{%- if table_row.dop_snref is not none %}
|
31
|
+
<DATA-OBJECT-PROP-SNREF SHORT-NAME="{{ table_row.dop_snref }}" />
|
32
|
+
{%- endif %}
|
33
|
+
{%- if table_row.structure_ref is not none %}
|
33
34
|
<STRUCTURE-REF ID-REF="{{ table_row.structure_ref.ref_id }}" />
|
34
35
|
{%- endif %}
|
36
|
+
{%- if table_row.structure_snref is not none %}
|
37
|
+
<STRUCTURE-SNREF SHORT-NAME="{{ table_row.structure_snref }}" />
|
38
|
+
{%- endif %}
|
35
39
|
{{- psd.printSpecialDataGroups(table_row.sdgs)|indent(2, first=True) }}
|
36
40
|
{%- if table_row.audience is not none %}
|
37
41
|
{{ paud.printAudience(table_row.audience) | indent(2) }}
|
@@ -46,14 +50,14 @@
|
|
46
50
|
{%- if table_row.state_transition_refs %}
|
47
51
|
<STATE-TRANSITION-REFS>
|
48
52
|
{%- for st_ref in table_row.state_transition_refs %}
|
49
|
-
|
53
|
+
{{ pstr.printStateTransitionRef(st_ref)|indent(4) }}
|
50
54
|
{%- endfor %}
|
51
55
|
</STATE-TRANSITION-REFS>
|
52
56
|
{%- endif %}
|
53
57
|
{%- if table_row.pre_condition_state_refs %}
|
54
58
|
<PRE-CONDITION-STATE-REFS>
|
55
59
|
{%- for pcs_ref in table_row.pre_condition_state_refs %}
|
56
|
-
|
60
|
+
{{ ppcsr.printPreConditionStateRef(ps_ref)|indent(4) }}
|
57
61
|
{%- endfor %}
|
58
62
|
</PRE-CONDITION-STATE-REFS>
|
59
63
|
{%- endif %}
|
odxtools/text.py
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import List, Optional
|
3
|
+
from xml.etree import ElementTree
|
4
|
+
|
5
|
+
from .odxlink import OdxDocFragment
|
6
|
+
|
7
|
+
|
8
|
+
@dataclass
|
9
|
+
class Text:
|
10
|
+
text: str
|
11
|
+
text_identifier: Optional[str]
|
12
|
+
|
13
|
+
@staticmethod
|
14
|
+
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Text":
|
15
|
+
# Extract the contents of the tag as a string.
|
16
|
+
raw_string = et_element.text or ""
|
17
|
+
for e in et_element:
|
18
|
+
raw_string += ElementTree.tostring(e, encoding="unicode")
|
19
|
+
|
20
|
+
# remove white spaces at the beginning and at the end of all
|
21
|
+
# extracted lines
|
22
|
+
stripped_lines = [x.strip() for x in raw_string.split("\n")]
|
23
|
+
|
24
|
+
text = "\n".join(stripped_lines).strip()
|
25
|
+
|
26
|
+
text_identifier = et_element.get("TI")
|
27
|
+
|
28
|
+
return Text(text=text, text_identifier=text_identifier)
|
29
|
+
|
30
|
+
@staticmethod
|
31
|
+
def from_string(text: str) -> "Text":
|
32
|
+
return Text(text=text, text_identifier=None)
|
33
|
+
|
34
|
+
def __str__(self) -> str:
|
35
|
+
return self.text
|
odxtools/unit.py
CHANGED
@@ -61,9 +61,6 @@ class Unit(IdentifiableElement):
|
|
61
61
|
def physical_dimension(self) -> Optional[PhysicalDimension]:
|
62
62
|
return self._physical_dimension
|
63
63
|
|
64
|
-
def __post_init__(self) -> None:
|
65
|
-
self._physical_dimension: Optional[PhysicalDimension] = None
|
66
|
-
|
67
64
|
@staticmethod
|
68
65
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Unit":
|
69
66
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
@@ -92,6 +89,7 @@ class Unit(IdentifiableElement):
|
|
92
89
|
return {self.odx_id: self}
|
93
90
|
|
94
91
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
92
|
+
self._physical_dimension: Optional[PhysicalDimension] = None
|
95
93
|
if self.physical_dimension_ref:
|
96
94
|
self._physical_dimension = odxlinks.resolve(self.physical_dimension_ref,
|
97
95
|
PhysicalDimension)
|
odxtools/unitgroup.py
CHANGED
@@ -28,13 +28,14 @@ class UnitGroup(NamedElement):
|
|
28
28
|
unit_refs: List[OdxLinkRef]
|
29
29
|
oid: Optional[str]
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
@property
|
32
|
+
def units(self) -> NamedItemList[Unit]:
|
33
|
+
return self._units
|
33
34
|
|
34
35
|
@staticmethod
|
35
36
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "UnitGroup":
|
36
|
-
oid = et_element.get("OID")
|
37
37
|
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
38
|
+
|
38
39
|
category_str = odxrequire(et_element.findtext("CATEGORY"))
|
39
40
|
try:
|
40
41
|
category = UnitGroupCategory(category_str)
|
@@ -42,10 +43,11 @@ class UnitGroup(NamedElement):
|
|
42
43
|
category = cast(UnitGroupCategory, None)
|
43
44
|
odxraise(f"Encountered unknown unit group category '{category_str}'")
|
44
45
|
|
45
|
-
unit_refs
|
46
|
+
unit_refs = [
|
46
47
|
odxrequire(OdxLinkRef.from_et(el, doc_frags))
|
47
48
|
for el in et_element.iterfind("UNIT-REFS/UNIT-REF")
|
48
49
|
]
|
50
|
+
oid = et_element.get("OID")
|
49
51
|
|
50
52
|
return UnitGroup(category=category, unit_refs=unit_refs, oid=oid, **kwargs)
|
51
53
|
|
@@ -57,7 +59,3 @@ class UnitGroup(NamedElement):
|
|
57
59
|
|
58
60
|
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
59
61
|
pass
|
60
|
-
|
61
|
-
@property
|
62
|
-
def units(self) -> NamedItemList[Unit]:
|
63
|
-
return self._units
|
odxtools/utils.py
CHANGED
@@ -3,15 +3,11 @@ import dataclasses
|
|
3
3
|
import re
|
4
4
|
from typing import TYPE_CHECKING, Any, Dict, Optional
|
5
5
|
|
6
|
-
from typing_extensions import SupportsBytes
|
7
|
-
|
8
6
|
if TYPE_CHECKING:
|
9
7
|
from .database import Database
|
10
8
|
from .diaglayers.diaglayer import DiagLayer
|
11
9
|
from .snrefcontext import SnRefContext
|
12
10
|
|
13
|
-
BytesTypes = (bytearray, bytes, SupportsBytes)
|
14
|
-
|
15
11
|
|
16
12
|
def retarget_snrefs(database: "Database",
|
17
13
|
diag_layer: "DiagLayer",
|
odxtools/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: odxtools
|
3
|
-
Version: 9.
|
3
|
+
Version: 9.6.0
|
4
4
|
Summary: Utilities to work with the ODX standard for automotive diagnostics
|
5
5
|
Author-email: Katrin Bauer <katrin.bauer@mbition.io>, Andreas Lauser <andreas.lauser@mbition.io>, Ayoub Kaanich <kayoub5@live.com>
|
6
6
|
Maintainer-email: Andreas Lauser <andreas.lauser@mbition.io>, Ayoub Kaanich <kayoub5@live.com>
|
@@ -43,6 +43,7 @@ Provides-Extra: examples
|
|
43
43
|
Requires-Dist: can-isotp>=1.9; extra == "examples"
|
44
44
|
Provides-Extra: all
|
45
45
|
Requires-Dist: odxtools[browse-tool,examples,test]; extra == "all"
|
46
|
+
Dynamic: license-file
|
46
47
|
|
47
48
|
<!-- SPDX-License-Identifier: MIT -->
|
48
49
|
[](https://pypi.org/project/odxtools)
|