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
@@ -28,11 +28,29 @@ class TableEntryParameter(Parameter):
|
|
28
28
|
target: RowFragment
|
29
29
|
table_row_ref: OdxLinkRef
|
30
30
|
|
31
|
+
@property
|
32
|
+
@override
|
33
|
+
def parameter_type(self) -> ParameterType:
|
34
|
+
return "TABLE-ENTRY"
|
35
|
+
|
36
|
+
@property
|
37
|
+
@override
|
38
|
+
def is_required(self) -> bool:
|
39
|
+
raise NotImplementedError("TableEntryParameter.is_required is not implemented yet.")
|
40
|
+
|
41
|
+
@property
|
42
|
+
@override
|
43
|
+
def is_settable(self) -> bool:
|
44
|
+
raise NotImplementedError("TableEntryParameter.is_settable is not implemented yet.")
|
45
|
+
|
46
|
+
@property
|
47
|
+
def table_row(self) -> "TableRow":
|
48
|
+
return self._table_row
|
49
|
+
|
31
50
|
@staticmethod
|
32
51
|
@override
|
33
52
|
def from_et(et_element: ElementTree.Element,
|
34
53
|
doc_frags: List[OdxDocFragment]) -> "TableEntryParameter":
|
35
|
-
|
36
54
|
kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
|
37
55
|
|
38
56
|
target_str = odxrequire(et_element.findtext("TARGET"))
|
@@ -54,30 +72,11 @@ class TableEntryParameter(Parameter):
|
|
54
72
|
else:
|
55
73
|
self._table_row = odxlinks.resolve(self.table_row_ref)
|
56
74
|
|
57
|
-
@property
|
58
|
-
@override
|
59
|
-
def parameter_type(self) -> ParameterType:
|
60
|
-
return "TABLE-ENTRY"
|
61
|
-
|
62
|
-
@property
|
63
|
-
@override
|
64
|
-
def is_required(self) -> bool:
|
65
|
-
raise NotImplementedError("TableEntryParameter.is_required is not implemented yet.")
|
66
|
-
|
67
|
-
@property
|
68
|
-
@override
|
69
|
-
def is_settable(self) -> bool:
|
70
|
-
raise NotImplementedError("TableEntryParameter.is_settable is not implemented yet.")
|
71
|
-
|
72
75
|
@override
|
73
76
|
def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
|
74
77
|
encode_state: EncodeState) -> None:
|
75
78
|
raise NotImplementedError("Encoding a TableEntryParameter is not implemented yet.")
|
76
79
|
|
77
|
-
@property
|
78
|
-
def table_row(self) -> "TableRow":
|
79
|
-
return self._table_row
|
80
|
-
|
81
80
|
@override
|
82
81
|
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
83
82
|
raise NotImplementedError("Decoding a TableEntryParameter is not implemented yet.")
|
@@ -38,7 +38,6 @@ class TableKeyParameter(Parameter):
|
|
38
38
|
@override
|
39
39
|
def from_et(et_element: ElementTree.Element,
|
40
40
|
doc_frags: List[OdxDocFragment]) -> "TableKeyParameter":
|
41
|
-
|
42
41
|
kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
|
43
42
|
|
44
43
|
odx_id = odxrequire(OdxLinkId.from_et(et_element, doc_frags))
|
@@ -201,7 +200,6 @@ class TableKeyParameter(Parameter):
|
|
201
200
|
encode_state.cursor_bit_position = 0
|
202
201
|
|
203
202
|
def encode_value_into_pdu(self, encode_state: EncodeState) -> None:
|
204
|
-
|
205
203
|
key_dop = self.table.key_dop
|
206
204
|
if key_dop is None:
|
207
205
|
odxraise(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any, Dict, List, Optional, cast
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from typing_extensions import override
|
@@ -15,13 +15,38 @@ from ..utils import dataclass_fields_asdict
|
|
15
15
|
from .parameter import Parameter, ParameterType
|
16
16
|
from .tablekeyparameter import TableKeyParameter
|
17
17
|
|
18
|
+
if TYPE_CHECKING:
|
19
|
+
from ..table import Table
|
20
|
+
|
18
21
|
|
19
22
|
@dataclass
|
20
23
|
class TableStructParameter(Parameter):
|
21
|
-
|
22
24
|
table_key_ref: Optional[OdxLinkRef]
|
23
25
|
table_key_snref: Optional[str]
|
24
26
|
|
27
|
+
@property
|
28
|
+
@override
|
29
|
+
def parameter_type(self) -> ParameterType:
|
30
|
+
return "TABLE-STRUCT"
|
31
|
+
|
32
|
+
@property
|
33
|
+
def table(self) -> "Table":
|
34
|
+
return self._table_key.table
|
35
|
+
|
36
|
+
@property
|
37
|
+
def table_key(self) -> TableKeyParameter:
|
38
|
+
return self._table_key
|
39
|
+
|
40
|
+
@property
|
41
|
+
@override
|
42
|
+
def is_required(self) -> bool:
|
43
|
+
return True
|
44
|
+
|
45
|
+
@property
|
46
|
+
@override
|
47
|
+
def is_settable(self) -> bool:
|
48
|
+
return True
|
49
|
+
|
25
50
|
@staticmethod
|
26
51
|
@override
|
27
52
|
def from_et(et_element: ElementTree.Element,
|
@@ -41,11 +66,6 @@ class TableStructParameter(Parameter):
|
|
41
66
|
if self.table_key_ref is None and self.table_key_snref is None:
|
42
67
|
odxraise("Either table_key_ref or table_key_snref must be defined.")
|
43
68
|
|
44
|
-
@property
|
45
|
-
@override
|
46
|
-
def parameter_type(self) -> ParameterType:
|
47
|
-
return "TABLE-STRUCT"
|
48
|
-
|
49
69
|
@override
|
50
70
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
51
71
|
return super()._build_odxlinks()
|
@@ -65,20 +85,6 @@ class TableStructParameter(Parameter):
|
|
65
85
|
self._table_key = resolve_snref(self.table_key_snref, odxrequire(context.parameters),
|
66
86
|
TableKeyParameter)
|
67
87
|
|
68
|
-
@property
|
69
|
-
def table_key(self) -> TableKeyParameter:
|
70
|
-
return self._table_key
|
71
|
-
|
72
|
-
@property
|
73
|
-
@override
|
74
|
-
def is_required(self) -> bool:
|
75
|
-
return True
|
76
|
-
|
77
|
-
@property
|
78
|
-
@override
|
79
|
-
def is_settable(self) -> bool:
|
80
|
-
return True
|
81
|
-
|
82
88
|
@override
|
83
89
|
def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
|
84
90
|
encode_state: EncodeState) -> None:
|
@@ -20,8 +20,24 @@ from .parameterwithdop import ParameterWithDOP
|
|
20
20
|
class ValueParameter(ParameterWithDOP):
|
21
21
|
physical_default_value_raw: Optional[str]
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
@property
|
24
|
+
@override
|
25
|
+
def parameter_type(self) -> ParameterType:
|
26
|
+
return "VALUE"
|
27
|
+
|
28
|
+
@property
|
29
|
+
def physical_default_value(self) -> Optional[AtomicOdxType]:
|
30
|
+
return self._physical_default_value
|
31
|
+
|
32
|
+
@property
|
33
|
+
@override
|
34
|
+
def is_required(self) -> bool:
|
35
|
+
return self._physical_default_value is None
|
36
|
+
|
37
|
+
@property
|
38
|
+
@override
|
39
|
+
def is_settable(self) -> bool:
|
40
|
+
return True
|
25
41
|
|
26
42
|
@staticmethod
|
27
43
|
@override
|
@@ -34,10 +50,8 @@ class ValueParameter(ParameterWithDOP):
|
|
34
50
|
|
35
51
|
return ValueParameter(physical_default_value_raw=physical_default_value_raw, **kwargs)
|
36
52
|
|
37
|
-
|
38
|
-
|
39
|
-
def parameter_type(self) -> ParameterType:
|
40
|
-
return "VALUE"
|
53
|
+
def __post_init__(self) -> None:
|
54
|
+
self._physical_default_value: Optional[AtomicOdxType] = None
|
41
55
|
|
42
56
|
@override
|
43
57
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
@@ -60,20 +74,6 @@ class ValueParameter(ParameterWithDOP):
|
|
60
74
|
self._physical_default_value = base_data_type.from_string(
|
61
75
|
self.physical_default_value_raw)
|
62
76
|
|
63
|
-
@property
|
64
|
-
def physical_default_value(self) -> Optional[AtomicOdxType]:
|
65
|
-
return self._physical_default_value
|
66
|
-
|
67
|
-
@property
|
68
|
-
@override
|
69
|
-
def is_required(self) -> bool:
|
70
|
-
return self._physical_default_value is None
|
71
|
-
|
72
|
-
@property
|
73
|
-
@override
|
74
|
-
def is_settable(self) -> bool:
|
75
|
-
return True
|
76
|
-
|
77
77
|
@override
|
78
78
|
def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
|
79
79
|
encode_state: EncodeState) -> None:
|
odxtools/parentref.py
CHANGED
@@ -37,6 +37,12 @@ class ParentRef:
|
|
37
37
|
"NOT-INHERITED-DIAG-COMM/"
|
38
38
|
"DIAG-COMM-SNREF")
|
39
39
|
]
|
40
|
+
not_inherited_variables = [
|
41
|
+
odxrequire(el.get("SHORT-NAME"))
|
42
|
+
for el in et_element.iterfind("NOT-INHERITED-VARIABLES/"
|
43
|
+
"NOT-INHERITED-VARIABLE/"
|
44
|
+
"DIAG-VARIABLE-SNREF")
|
45
|
+
]
|
40
46
|
not_inherited_dops = [
|
41
47
|
odxrequire(el.get("SHORT-NAME")) for el in et_element.iterfind("NOT-INHERITED-DOPS/"
|
42
48
|
"NOT-INHERITED-DOP/"
|
@@ -47,13 +53,6 @@ class ParentRef:
|
|
47
53
|
"NOT-INHERITED-TABLE/"
|
48
54
|
"TABLE-SNREF")
|
49
55
|
]
|
50
|
-
not_inherited_variables = [
|
51
|
-
odxrequire(el.get("SHORT-NAME"))
|
52
|
-
for el in et_element.iterfind("NOT-INHERITED-VARIABLES/"
|
53
|
-
"NOT-INHERITED-VARIABLE/"
|
54
|
-
"DIAG-VARIABLE-SNREF")
|
55
|
-
]
|
56
|
-
|
57
56
|
not_inherited_global_neg_responses = [
|
58
57
|
odxrequire(el.get("SHORT-NAME"))
|
59
58
|
for el in et_element.iterfind("NOT-INHERITED-GLOBAL-NEG-RESPONSES/"
|
odxtools/physicaldimension.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any, Dict, List
|
3
|
+
from typing import Any, Dict, List, Optional
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .element import IdentifiableElement
|
@@ -41,24 +41,24 @@ class PhysicalDimension(IdentifiableElement):
|
|
41
41
|
)
|
42
42
|
```
|
43
43
|
"""
|
44
|
-
length_exp: int
|
45
|
-
mass_exp: int
|
46
|
-
time_exp: int
|
47
|
-
current_exp: int
|
48
|
-
temperature_exp: int
|
49
|
-
molar_amount_exp: int
|
50
|
-
luminous_intensity_exp: int
|
44
|
+
length_exp: Optional[int]
|
45
|
+
mass_exp: Optional[int]
|
46
|
+
time_exp: Optional[int]
|
47
|
+
current_exp: Optional[int]
|
48
|
+
temperature_exp: Optional[int]
|
49
|
+
molar_amount_exp: Optional[int]
|
50
|
+
luminous_intensity_exp: Optional[int]
|
51
51
|
|
52
52
|
@staticmethod
|
53
53
|
def from_et(et_element: ElementTree.Element,
|
54
54
|
doc_frags: List[OdxDocFragment]) -> "PhysicalDimension":
|
55
55
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
56
56
|
|
57
|
-
def read_optional_int(element: ElementTree.Element, name: str) -> int:
|
58
|
-
if val_str := element.findtext(name):
|
57
|
+
def read_optional_int(element: ElementTree.Element, name: str) -> Optional[int]:
|
58
|
+
if (val_str := element.findtext(name)) is not None:
|
59
59
|
return int(val_str)
|
60
60
|
else:
|
61
|
-
return
|
61
|
+
return None
|
62
62
|
|
63
63
|
length_exp = read_optional_int(et_element, "LENGTH-EXP")
|
64
64
|
mass_exp = read_optional_int(et_element, "MASS-EXP")
|
odxtools/physicaltype.py
CHANGED
@@ -39,6 +39,11 @@ class PhysicalType:
|
|
39
39
|
PhysicalType(DataType.A_FLOAT64, precision=2)
|
40
40
|
"""
|
41
41
|
|
42
|
+
precision: Optional[int]
|
43
|
+
"""Number of digits after the decimal point to display to the user
|
44
|
+
The precision is only applicable if the base data type is A_FLOAT32 or A_FLOAT64.
|
45
|
+
"""
|
46
|
+
|
42
47
|
base_data_type: DataType
|
43
48
|
|
44
49
|
display_radix: Optional[Radix]
|
@@ -46,18 +51,11 @@ class PhysicalType:
|
|
46
51
|
The display radix is only applicable if the base data type is A_UINT32.
|
47
52
|
"""
|
48
53
|
|
49
|
-
precision: Optional[int]
|
50
|
-
"""Number of digits after the decimal point to display to the user
|
51
|
-
The precision is only applicable if the base data type is A_FLOAT32 or A_FLOAT64.
|
52
|
-
"""
|
53
|
-
|
54
|
-
def __post_init__(self) -> None:
|
55
|
-
self.base_data_type = DataType(self.base_data_type)
|
56
|
-
if self.display_radix is not None:
|
57
|
-
self.display_radix = Radix(self.display_radix)
|
58
|
-
|
59
54
|
@staticmethod
|
60
55
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "PhysicalType":
|
56
|
+
precision_str = et_element.findtext("PRECISION")
|
57
|
+
precision = int(precision_str) if precision_str is not None else None
|
58
|
+
|
61
59
|
base_data_type_str = et_element.get("BASE-DATA-TYPE")
|
62
60
|
if base_data_type_str not in DataType.__members__:
|
63
61
|
odxraise(f"Encountered unknown base data type '{base_data_type_str}'")
|
@@ -71,8 +69,5 @@ class PhysicalType:
|
|
71
69
|
else:
|
72
70
|
display_radix = None
|
73
71
|
|
74
|
-
precision_str = et_element.findtext("PRECISION")
|
75
|
-
precision = int(precision_str) if precision_str is not None else None
|
76
|
-
|
77
72
|
return PhysicalType(
|
78
|
-
base_data_type=base_data_type, display_radix=display_radix
|
73
|
+
precision=precision, base_data_type=base_data_type, display_radix=display_radix)
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from .exceptions import odxassert, odxrequire
|
7
|
+
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
8
|
+
from .odxtypes import ParameterValueDict
|
9
|
+
from .parameters.parameter import Parameter
|
10
|
+
from .snrefcontext import SnRefContext
|
11
|
+
from .state import State
|
12
|
+
from .statetransitionref import _check_applies
|
13
|
+
from .utils import dataclass_fields_asdict
|
14
|
+
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
from .statemachine import StateMachine
|
17
|
+
|
18
|
+
|
19
|
+
@dataclass
|
20
|
+
class PreConditionStateRef(OdxLinkRef):
|
21
|
+
"""
|
22
|
+
This class represents the PRE-CONDITION-STATE-REF XML tag.
|
23
|
+
"""
|
24
|
+
value: Optional[str]
|
25
|
+
|
26
|
+
in_param_if_snref: Optional[str]
|
27
|
+
in_param_if_snpathref: Optional[str]
|
28
|
+
|
29
|
+
@property
|
30
|
+
def state(self) -> "State":
|
31
|
+
return self._state
|
32
|
+
|
33
|
+
@staticmethod
|
34
|
+
def from_et( # type: ignore[override]
|
35
|
+
et_element: ElementTree.Element,
|
36
|
+
doc_frags: List[OdxDocFragment]) -> "PreConditionStateRef":
|
37
|
+
kwargs = dataclass_fields_asdict(OdxLinkRef.from_et(et_element, doc_frags))
|
38
|
+
|
39
|
+
value = et_element.findtext("VALUE")
|
40
|
+
|
41
|
+
in_param_if_snref = None
|
42
|
+
if (in_param_if_snref_elem := et_element.find("IN-PARAM-IF-SNREF")) is not None:
|
43
|
+
in_param_if_snref = odxrequire(in_param_if_snref_elem.get("SHORT-NAME"))
|
44
|
+
|
45
|
+
in_param_if_snpathref = None
|
46
|
+
if (in_param_if_snpathref_elem := et_element.find("IN-PARAM-IF-SNPATHREF")) is not None:
|
47
|
+
in_param_if_snpathref = odxrequire(in_param_if_snpathref_elem.get("SHORT-NAME-PATH"))
|
48
|
+
|
49
|
+
return PreConditionStateRef(
|
50
|
+
value=value,
|
51
|
+
in_param_if_snref=in_param_if_snref,
|
52
|
+
in_param_if_snpathref=in_param_if_snpathref,
|
53
|
+
**kwargs)
|
54
|
+
|
55
|
+
def __post_init__(self) -> None:
|
56
|
+
if self.value is not None:
|
57
|
+
odxassert(self.in_param_if_snref is not None or self.in_param_if_snref is not None,
|
58
|
+
"If VALUE is specified, a parameter must be referenced")
|
59
|
+
|
60
|
+
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
61
|
+
return {}
|
62
|
+
|
63
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
64
|
+
self._state = odxlinks.resolve(self, State)
|
65
|
+
|
66
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
67
|
+
pass
|
68
|
+
|
69
|
+
def applies(self, state_machine: "StateMachine", params: List[Parameter],
|
70
|
+
param_value_dict: ParameterValueDict) -> bool:
|
71
|
+
"""Given a state machine, evaluate whether the precondition is fulfilled or not
|
72
|
+
|
73
|
+
Note that the specification is unclear about what the
|
74
|
+
parameters are: It says "The optional VALUE together with the
|
75
|
+
also optional IN-PARAM-IF snref at STATE-TRANSITION-REF and
|
76
|
+
PRE-CONDITION-STATE-REF can be used if the STATE-TRANSITIONs
|
77
|
+
and pre-condition STATEs are dependent on the values of the
|
78
|
+
referenced PARAMs.", but it does not specify what the
|
79
|
+
"referenced PARAMs" are. For the state transition refs, let's
|
80
|
+
assume that they are the parameters of a positive response
|
81
|
+
received from the ECU, whilst we assume that they are the
|
82
|
+
parameters of the request for PRE-CONDITION-STATE-REFs.
|
83
|
+
"""
|
84
|
+
|
85
|
+
return _check_applies(self, state_machine, params, param_value_dict)
|
odxtools/progcode.py
CHANGED
@@ -31,7 +31,6 @@ class ProgCode:
|
|
31
31
|
@staticmethod
|
32
32
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ProgCode":
|
33
33
|
code_file = odxrequire(et_element.findtext("CODE-FILE"))
|
34
|
-
|
35
34
|
encryption = et_element.findtext("ENCRYPTION")
|
36
35
|
syntax = odxrequire(et_element.findtext("SYNTAX"))
|
37
36
|
revision = odxrequire(et_element.findtext("REVISION"))
|
@@ -44,9 +43,9 @@ class ProgCode:
|
|
44
43
|
|
45
44
|
return ProgCode(
|
46
45
|
code_file=code_file,
|
46
|
+
encryption=encryption,
|
47
47
|
syntax=syntax,
|
48
48
|
revision=revision,
|
49
|
-
encryption=encryption,
|
50
49
|
entrypoint=entrypoint,
|
51
50
|
library_refs=library_refs,
|
52
51
|
)
|
odxtools/protstack.py
CHANGED
@@ -19,6 +19,10 @@ class ProtStack(IdentifiableElement):
|
|
19
19
|
physical_link_type: str
|
20
20
|
comparam_subset_refs: List[OdxLinkRef]
|
21
21
|
|
22
|
+
@property
|
23
|
+
def comparam_subsets(self) -> NamedItemList[ComparamSubset]:
|
24
|
+
return self._comparam_subsets
|
25
|
+
|
22
26
|
@staticmethod
|
23
27
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ProtStack":
|
24
28
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
@@ -47,7 +51,3 @@ class ProtStack(IdentifiableElement):
|
|
47
51
|
|
48
52
|
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
49
53
|
pass
|
50
|
-
|
51
|
-
@property
|
52
|
-
def comparam_subsets(self) -> NamedItemList[ComparamSubset]:
|
53
|
-
return self._comparam_subsets
|
odxtools/relateddoc.py
CHANGED
@@ -11,20 +11,19 @@ from .xdoc import XDoc
|
|
11
11
|
|
12
12
|
@dataclass
|
13
13
|
class RelatedDoc:
|
14
|
-
description: Optional[Description]
|
15
14
|
xdoc: Optional[XDoc]
|
15
|
+
description: Optional[Description]
|
16
16
|
|
17
17
|
@staticmethod
|
18
18
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "RelatedDoc":
|
19
|
-
description = Description.from_et(et_element.find("DESC"), doc_frags)
|
20
|
-
|
21
19
|
xdoc: Optional[XDoc] = None
|
22
20
|
if (xdoc_elem := et_element.find("XDOC")) is not None:
|
23
21
|
xdoc = XDoc.from_et(xdoc_elem, doc_frags)
|
22
|
+
description = Description.from_et(et_element.find("DESC"), doc_frags)
|
24
23
|
|
25
24
|
return RelatedDoc(
|
26
|
-
description=description,
|
27
25
|
xdoc=xdoc,
|
26
|
+
description=description,
|
28
27
|
)
|
29
28
|
|
30
29
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
odxtools/scaleconstr.py
CHANGED
@@ -35,7 +35,6 @@ class ScaleConstr:
|
|
35
35
|
value_type: DataType) -> "ScaleConstr":
|
36
36
|
short_label = et_element.findtext("SHORT-LABEL")
|
37
37
|
description = Description.from_et(et_element.find("DESC"), doc_frags)
|
38
|
-
|
39
38
|
lower_limit = Limit.limit_from_et(
|
40
39
|
odxrequire(et_element.find("LOWER-LIMIT")), doc_frags, value_type=value_type)
|
41
40
|
upper_limit = Limit.limit_from_et(
|
odxtools/singleecujob.py
CHANGED
@@ -18,12 +18,16 @@ from .utils import dataclass_fields_asdict
|
|
18
18
|
class SingleEcuJob(DiagComm):
|
19
19
|
"""A single ECU job is a diagnostic communication primitive.
|
20
20
|
|
21
|
-
A single ECU job is more complex than a diagnostic service and is
|
22
|
-
In particular, the job is
|
21
|
+
A single ECU job is more complex than a diagnostic service and is
|
22
|
+
not provided natively by the ECU. In particular, the job is
|
23
|
+
defined in external programs which are referenced by the attribute
|
24
|
+
`.prog_codes`.
|
23
25
|
|
24
|
-
In contrast to "multiple ECU jobs", a single ECU job only
|
26
|
+
In contrast to "multiple ECU jobs", a single ECU job only involves
|
27
|
+
calls to services provided by a single ECU.
|
25
28
|
|
26
|
-
Single ECU jobs are defined in section 7.3.5.7 of the ASAM MCD-2
|
29
|
+
Single ECU jobs are defined in section 7.3.5.7 of the ASAM MCD-2
|
30
|
+
standard.
|
27
31
|
"""
|
28
32
|
|
29
33
|
prog_codes: List[ProgCode]
|
odxtools/specialdata.py
CHANGED
@@ -9,19 +9,11 @@ from .snrefcontext import SnRefContext
|
|
9
9
|
|
10
10
|
@dataclass
|
11
11
|
class SpecialData:
|
12
|
+
"""This corresponds to the SD XML tag"""
|
12
13
|
semantic_info: Optional[str] # the "SI" attribute
|
13
14
|
text_identifier: Optional[str] # the "TI" attribute, specifies the language used
|
14
15
|
value: str
|
15
16
|
|
16
|
-
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
17
|
-
return {}
|
18
|
-
|
19
|
-
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
20
|
-
pass
|
21
|
-
|
22
|
-
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
23
|
-
pass
|
24
|
-
|
25
17
|
@staticmethod
|
26
18
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "SpecialData":
|
27
19
|
semantic_info = et_element.get("SI")
|
@@ -30,3 +22,12 @@ class SpecialData:
|
|
30
22
|
|
31
23
|
return SpecialData(
|
32
24
|
semantic_info=semantic_info, text_identifier=text_identifier, value=value)
|
25
|
+
|
26
|
+
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
27
|
+
return {}
|
28
|
+
|
29
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
30
|
+
pass
|
31
|
+
|
32
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
33
|
+
pass
|
odxtools/specialdatagroup.py
CHANGED
@@ -11,6 +11,7 @@ from .specialdatagroupcaption import SpecialDataGroupCaption
|
|
11
11
|
|
12
12
|
@dataclass
|
13
13
|
class SpecialDataGroup:
|
14
|
+
"""This corresponds to the SDG XML tag"""
|
14
15
|
sdg_caption: Optional[SpecialDataGroupCaption]
|
15
16
|
sdg_caption_ref: Optional[OdxLinkRef]
|
16
17
|
values: List[Union["SpecialDataGroup", SpecialData]]
|
odxtools/standardlengthtype.py
CHANGED
@@ -10,8 +10,8 @@ from .diagcodedtype import DctType, DiagCodedType
|
|
10
10
|
from .encodestate import EncodeState
|
11
11
|
from .exceptions import odxassert, odxraise, odxrequire
|
12
12
|
from .odxlink import OdxDocFragment
|
13
|
-
from .odxtypes import AtomicOdxType, DataType, odxstr_to_bool
|
14
|
-
from .utils import
|
13
|
+
from .odxtypes import AtomicOdxType, BytesTypes, DataType, odxstr_to_bool
|
14
|
+
from .utils import dataclass_fields_asdict
|
15
15
|
|
16
16
|
|
17
17
|
@dataclass
|
@@ -21,6 +21,14 @@ class StandardLengthType(DiagCodedType):
|
|
21
21
|
bit_mask: Optional[int]
|
22
22
|
is_condensed_raw: Optional[bool]
|
23
23
|
|
24
|
+
@property
|
25
|
+
def dct_type(self) -> DctType:
|
26
|
+
return "STANDARD-LENGTH-TYPE"
|
27
|
+
|
28
|
+
@property
|
29
|
+
def is_condensed(self) -> bool:
|
30
|
+
return self.is_condensed_raw is True
|
31
|
+
|
24
32
|
@staticmethod
|
25
33
|
@override
|
26
34
|
def from_et(et_element: ElementTree.Element,
|
@@ -43,14 +51,6 @@ class StandardLengthType(DiagCodedType):
|
|
43
51
|
return StandardLengthType(
|
44
52
|
bit_length=bit_length, bit_mask=bit_mask, is_condensed_raw=is_condensed_raw, **kwargs)
|
45
53
|
|
46
|
-
@property
|
47
|
-
def dct_type(self) -> DctType:
|
48
|
-
return "STANDARD-LENGTH-TYPE"
|
49
|
-
|
50
|
-
@property
|
51
|
-
def is_condensed(self) -> bool:
|
52
|
-
return self.is_condensed_raw is True
|
53
|
-
|
54
54
|
def __post_init__(self) -> None:
|
55
55
|
if self.bit_mask is not None:
|
56
56
|
maskable_types = (DataType.A_UINT32, DataType.A_INT32, DataType.A_BYTEFIELD)
|
odxtools/statechart.py
CHANGED
@@ -30,6 +30,7 @@ class StateChart(IdentifiableElement):
|
|
30
30
|
@staticmethod
|
31
31
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "StateChart":
|
32
32
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
33
|
+
|
33
34
|
semantic: str = odxrequire(et_element.findtext("SEMANTIC"))
|
34
35
|
|
35
36
|
state_transitions = [
|
@@ -54,15 +55,18 @@ class StateChart(IdentifiableElement):
|
|
54
55
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
55
56
|
odxlinks = {self.odx_id: self}
|
56
57
|
|
57
|
-
for st in self.states:
|
58
|
-
odxlinks.update(st._build_odxlinks())
|
59
|
-
|
60
58
|
for strans in self.state_transitions:
|
61
59
|
odxlinks.update(strans._build_odxlinks())
|
62
60
|
|
61
|
+
for st in self.states:
|
62
|
+
odxlinks.update(st._build_odxlinks())
|
63
|
+
|
63
64
|
return odxlinks
|
64
65
|
|
65
66
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
67
|
+
for strans in self.state_transitions:
|
68
|
+
strans._resolve_odxlinks(odxlinks)
|
69
|
+
|
66
70
|
for st in self.states:
|
67
71
|
st._resolve_odxlinks(odxlinks)
|
68
72
|
|
@@ -77,10 +81,10 @@ class StateChart(IdentifiableElement):
|
|
77
81
|
# does that mean?
|
78
82
|
self._start_state = resolve_snref(self.start_state_snref, self.states, State)
|
79
83
|
|
80
|
-
for st in self.states:
|
81
|
-
st._resolve_snrefs(context)
|
82
|
-
|
83
84
|
for strans in self.state_transitions:
|
84
85
|
strans._resolve_snrefs(context)
|
85
86
|
|
87
|
+
for st in self.states:
|
88
|
+
st._resolve_snrefs(context)
|
89
|
+
|
86
90
|
context.state_chart = None
|