odxtools 6.6.1__py3-none-any.whl → 6.7.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odxtools/__init__.py +5 -5
- odxtools/basicstructure.py +7 -8
- odxtools/cli/_parser_utils.py +15 -0
- odxtools/cli/_print_utils.py +4 -3
- odxtools/cli/browse.py +19 -14
- odxtools/cli/compare.py +24 -16
- odxtools/cli/decode.py +2 -1
- odxtools/cli/dummy_sub_parser.py +3 -1
- odxtools/cli/find.py +2 -1
- odxtools/cli/list.py +2 -1
- odxtools/cli/main.py +1 -0
- odxtools/cli/snoop.py +4 -1
- odxtools/comparaminstance.py +7 -5
- odxtools/compumethods/compumethod.py +2 -4
- odxtools/compumethods/compuscale.py +45 -5
- odxtools/compumethods/createanycompumethod.py +28 -36
- odxtools/compumethods/limit.py +70 -36
- odxtools/compumethods/linearcompumethod.py +68 -59
- odxtools/compumethods/tabintpcompumethod.py +19 -8
- odxtools/compumethods/texttablecompumethod.py +32 -36
- odxtools/dataobjectproperty.py +13 -10
- odxtools/decodestate.py +6 -3
- odxtools/determinenumberofitems.py +1 -1
- odxtools/diagcodedtype.py +5 -4
- odxtools/diagdatadictionaryspec.py +108 -83
- odxtools/diaglayer.py +75 -35
- odxtools/diaglayertype.py +17 -5
- odxtools/diagservice.py +1 -1
- odxtools/dopbase.py +4 -2
- odxtools/dtcdop.py +7 -5
- odxtools/dynamiclengthfield.py +6 -5
- odxtools/endofpdufield.py +4 -4
- odxtools/environmentdatadescription.py +4 -2
- odxtools/inputparam.py +1 -1
- odxtools/internalconstr.py +14 -5
- odxtools/isotp_state_machine.py +14 -6
- odxtools/message.py +1 -1
- odxtools/multiplexer.py +18 -13
- odxtools/multiplexercase.py +27 -5
- odxtools/multiplexerswitchkey.py +1 -1
- odxtools/nameditemlist.py +7 -6
- odxtools/odxlink.py +2 -2
- odxtools/odxtypes.py +56 -3
- odxtools/outputparam.py +2 -2
- odxtools/parameterinfo.py +12 -5
- odxtools/parameters/codedconstparameter.py +33 -12
- odxtools/parameters/createanyparameter.py +19 -193
- odxtools/parameters/dynamicparameter.py +21 -1
- odxtools/parameters/lengthkeyparameter.py +28 -4
- odxtools/parameters/matchingrequestparameter.py +27 -9
- odxtools/parameters/nrcconstparameter.py +34 -11
- odxtools/parameters/parameter.py +58 -32
- odxtools/parameters/parameterwithdop.py +28 -15
- odxtools/parameters/physicalconstantparameter.py +28 -4
- odxtools/parameters/reservedparameter.py +32 -18
- odxtools/parameters/systemparameter.py +25 -2
- odxtools/parameters/tableentryparameter.py +45 -6
- odxtools/parameters/tablekeyparameter.py +43 -10
- odxtools/parameters/tablestructparameter.py +36 -14
- odxtools/parameters/valueparameter.py +24 -2
- odxtools/paramlengthinfotype.py +4 -1
- odxtools/parentref.py +4 -1
- odxtools/scaleconstr.py +11 -5
- odxtools/statetransition.py +1 -1
- odxtools/staticfield.py +101 -0
- odxtools/table.py +2 -1
- odxtools/tablerow.py +11 -4
- odxtools/templates/macros/printDOP.xml.jinja2 +30 -34
- odxtools/templates/macros/printMux.xml.jinja2 +3 -2
- odxtools/templates/macros/printParam.xml.jinja2 +9 -9
- odxtools/templates/macros/printStaticField.xml.jinja2 +15 -0
- odxtools/templates/macros/printVariant.xml.jinja2 +8 -0
- odxtools/uds.py +2 -2
- odxtools/version.py +2 -2
- odxtools/write_pdx_file.py +3 -3
- {odxtools-6.6.1.dist-info → odxtools-6.7.1.dist-info}/METADATA +28 -16
- {odxtools-6.6.1.dist-info → odxtools-6.7.1.dist-info}/RECORD +81 -79
- {odxtools-6.6.1.dist-info → odxtools-6.7.1.dist-info}/WHEEL +1 -1
- {odxtools-6.6.1.dist-info → odxtools-6.7.1.dist-info}/LICENSE +0 -0
- {odxtools-6.6.1.dist-info → odxtools-6.7.1.dist-info}/entry_points.txt +0 -0
- {odxtools-6.6.1.dist-info → odxtools-6.7.1.dist-info}/top_level.txt +0 -0
odxtools/parameters/parameter.py
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
import abc
|
3
2
|
from dataclasses import dataclass
|
4
3
|
from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional
|
4
|
+
from xml.etree import ElementTree
|
5
5
|
|
6
|
+
from typing_extensions import final, override
|
7
|
+
|
8
|
+
from ..createsdgs import create_sdgs_from_et
|
6
9
|
from ..decodestate import DecodeState
|
7
10
|
from ..element import NamedElement
|
8
11
|
from ..encodestate import EncodeState
|
9
|
-
from ..odxlink import OdxLinkDatabase, OdxLinkId
|
12
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
10
13
|
from ..odxtypes import ParameterValue
|
11
14
|
from ..specialdatagroup import SpecialDataGroup
|
15
|
+
from ..utils import dataclass_fields_asdict
|
12
16
|
|
13
17
|
if TYPE_CHECKING:
|
14
18
|
from ..diaglayer import DiagLayer
|
@@ -30,12 +34,42 @@ ParameterType = Literal[
|
|
30
34
|
|
31
35
|
|
32
36
|
@dataclass
|
33
|
-
class Parameter(NamedElement
|
37
|
+
class Parameter(NamedElement):
|
38
|
+
"""This class corresponds to POSITIONABLE-PARAM in the ODX
|
39
|
+
specification.
|
40
|
+
|
41
|
+
Be aware that, even though the ODX specification seems to make the
|
42
|
+
distinction of "positionable" and "normal" parameters, it does not
|
43
|
+
define any non-positionable parameter types.
|
44
|
+
|
45
|
+
"""
|
34
46
|
byte_position: Optional[int]
|
35
47
|
bit_position: Optional[int]
|
36
48
|
semantic: Optional[str]
|
37
49
|
sdgs: List[SpecialDataGroup]
|
38
50
|
|
51
|
+
@staticmethod
|
52
|
+
@override
|
53
|
+
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "Parameter":
|
54
|
+
|
55
|
+
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
56
|
+
|
57
|
+
semantic = et_element.get("SEMANTIC")
|
58
|
+
sdgs = create_sdgs_from_et(et_element.find("SDGS"), doc_frags)
|
59
|
+
|
60
|
+
byte_position_str = et_element.findtext("BYTE-POSITION")
|
61
|
+
bit_position_str = et_element.findtext("BIT-POSITION")
|
62
|
+
|
63
|
+
byte_position = int(byte_position_str) if byte_position_str is not None else None
|
64
|
+
bit_position = int(bit_position_str) if bit_position_str is not None else None
|
65
|
+
|
66
|
+
return Parameter(
|
67
|
+
byte_position=byte_position,
|
68
|
+
bit_position=bit_position,
|
69
|
+
semantic=semantic,
|
70
|
+
sdgs=sdgs,
|
71
|
+
**kwargs)
|
72
|
+
|
39
73
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
40
74
|
result = {}
|
41
75
|
|
@@ -53,9 +87,9 @@ class Parameter(NamedElement, abc.ABC):
|
|
53
87
|
sdg._resolve_snrefs(diag_layer)
|
54
88
|
|
55
89
|
@property
|
56
|
-
@abc.abstractmethod
|
57
90
|
def parameter_type(self) -> ParameterType:
|
58
|
-
|
91
|
+
raise NotImplementedError(
|
92
|
+
".parameter_type is not implemented by the concrete parameter class")
|
59
93
|
|
60
94
|
def get_static_bit_length(self) -> Optional[int]:
|
61
95
|
return None
|
@@ -70,7 +104,7 @@ class Parameter(NamedElement, abc.ABC):
|
|
70
104
|
specified.
|
71
105
|
|
72
106
|
"""
|
73
|
-
raise NotImplementedError
|
107
|
+
raise NotImplementedError(".is_required is not implemented by the concrete parameter class")
|
74
108
|
|
75
109
|
@property
|
76
110
|
def is_settable(self) -> bool:
|
@@ -81,44 +115,36 @@ class Parameter(NamedElement, abc.ABC):
|
|
81
115
|
have a default value are settable but not required to be
|
82
116
|
specified.
|
83
117
|
"""
|
84
|
-
raise NotImplementedError
|
118
|
+
raise NotImplementedError(".is_settable is not implemented by the concrete parameter class")
|
85
119
|
|
86
|
-
@abc.abstractmethod
|
87
120
|
def get_coded_value_as_bytes(self, encode_state: EncodeState) -> bytes:
|
88
121
|
"""Get the coded value of the parameter given the encode state.
|
89
122
|
Note that this method is called by `encode_into_pdu`.
|
90
123
|
"""
|
91
|
-
|
124
|
+
raise NotImplementedError(
|
125
|
+
".get_coded_value_as_bytes() is not implemented by the concrete parameter class")
|
92
126
|
|
93
|
-
@
|
127
|
+
@final
|
94
128
|
def decode_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
95
|
-
|
129
|
+
orig_cursor = decode_state.cursor_byte_position
|
130
|
+
if self.byte_position is not None:
|
131
|
+
decode_state.cursor_byte_position = decode_state.origin_byte_position + self.byte_position
|
96
132
|
|
97
|
-
|
98
|
-
at this byte position and the function parameter `default_byte_position` is ignored.
|
133
|
+
decode_state.cursor_bit_position = self.bit_position or 0
|
99
134
|
|
100
|
-
|
101
|
-
the bytes are extracted at the byte position given by the argument `default_byte_position`.
|
135
|
+
result = self._decode_positioned_from_pdu(decode_state)
|
102
136
|
|
103
|
-
|
104
|
-
|
137
|
+
decode_state.cursor_byte_position = max(decode_state.cursor_byte_position, orig_cursor)
|
138
|
+
decode_state.cursor_bit_position = 0
|
105
139
|
|
106
|
-
|
107
|
-
----------
|
108
|
-
decode_state : DecodeState
|
109
|
-
The decoding state containing
|
110
|
-
* the byte message to be decoded
|
111
|
-
* the parameter values that are already decoded
|
112
|
-
* the next byte position that is used iff the parameter does not specify a byte position
|
140
|
+
return result
|
113
141
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
"""
|
121
|
-
pass
|
142
|
+
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
143
|
+
"""Method which actually decodes the parameter
|
144
|
+
|
145
|
+
Its location is managed by `Parameter`."""
|
146
|
+
raise NotImplementedError(
|
147
|
+
"Required method '_decode_positioned_from_pdu()' not implemented by child class")
|
122
148
|
|
123
149
|
def encode_into_pdu(self, encode_state: EncodeState) -> bytes:
|
124
150
|
"""Encode the value of a parameter into a binary blob and return it
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import TYPE_CHECKING, Any, Dict, Optional
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from typing_extensions import override
|
4
7
|
|
5
8
|
from ..dataobjectproperty import DataObjectProperty
|
6
9
|
from ..decodestate import DecodeState
|
@@ -8,9 +11,10 @@ from ..dopbase import DopBase
|
|
8
11
|
from ..dtcdop import DtcDop
|
9
12
|
from ..encodestate import EncodeState
|
10
13
|
from ..exceptions import odxassert, odxrequire
|
11
|
-
from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
14
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
12
15
|
from ..odxtypes import ParameterValue
|
13
16
|
from ..physicaltype import PhysicalType
|
17
|
+
from ..utils import dataclass_fields_asdict
|
14
18
|
from .parameter import Parameter
|
15
19
|
|
16
20
|
if TYPE_CHECKING:
|
@@ -22,14 +26,30 @@ class ParameterWithDOP(Parameter):
|
|
22
26
|
dop_ref: Optional[OdxLinkRef]
|
23
27
|
dop_snref: Optional[str]
|
24
28
|
|
29
|
+
@staticmethod
|
30
|
+
@override
|
31
|
+
def from_et(et_element: ElementTree.Element,
|
32
|
+
doc_frags: List[OdxDocFragment]) -> "ParameterWithDOP":
|
33
|
+
|
34
|
+
kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
|
35
|
+
|
36
|
+
dop_ref = OdxLinkRef.from_et(et_element.find("DOP-REF"), doc_frags)
|
37
|
+
dop_snref = None
|
38
|
+
if (dop_snref_elem := et_element.find("DOP-SNREF")) is not None:
|
39
|
+
dop_snref = odxrequire(dop_snref_elem.get("SHORT-NAME"))
|
40
|
+
|
41
|
+
return ParameterWithDOP(dop_ref=dop_ref, dop_snref=dop_snref, **kwargs)
|
42
|
+
|
25
43
|
def __post_init__(self) -> None:
|
26
44
|
odxassert(self.dop_snref is not None or self.dop_ref is not None,
|
27
45
|
f"Param {self.short_name} without a DOP-(SN)REF should not exist!")
|
28
46
|
self._dop: Optional[DopBase] = None
|
29
47
|
|
48
|
+
@override
|
30
49
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
31
50
|
return super()._build_odxlinks()
|
32
51
|
|
52
|
+
@override
|
33
53
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
34
54
|
super()._resolve_odxlinks(odxlinks)
|
35
55
|
|
@@ -40,6 +60,7 @@ class ParameterWithDOP(Parameter):
|
|
40
60
|
# (e.g., static and dynamic fields)
|
41
61
|
self._dop = odxlinks.resolve_lenient(self.dop_ref)
|
42
62
|
|
63
|
+
@override
|
43
64
|
def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
|
44
65
|
super()._resolve_snrefs(diag_layer)
|
45
66
|
|
@@ -55,6 +76,7 @@ class ParameterWithDOP(Parameter):
|
|
55
76
|
self._dop, "Specifying a data object property is mandatory but it "
|
56
77
|
"could not be resolved")
|
57
78
|
|
79
|
+
@override
|
58
80
|
def get_static_bit_length(self) -> Optional[int]:
|
59
81
|
if self._dop is not None:
|
60
82
|
return self._dop.get_static_bit_length()
|
@@ -68,6 +90,7 @@ class ParameterWithDOP(Parameter):
|
|
68
90
|
else:
|
69
91
|
return None
|
70
92
|
|
93
|
+
@override
|
71
94
|
def get_coded_value_as_bytes(self, encode_state: EncodeState) -> bytes:
|
72
95
|
dop = odxrequire(self.dop, "Reference to DOP is not resolved")
|
73
96
|
physical_value = encode_state.parameter_values[self.short_name]
|
@@ -75,16 +98,6 @@ class ParameterWithDOP(Parameter):
|
|
75
98
|
return dop.convert_physical_to_bytes(
|
76
99
|
physical_value, encode_state, bit_position=bit_position_int)
|
77
100
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
decode_state.cursor_byte_position = decode_state.origin_byte_position + self.byte_position
|
82
|
-
|
83
|
-
decode_state.cursor_bit_position = self.bit_position or 0
|
84
|
-
|
85
|
-
# Use DOP to decode
|
86
|
-
phys_val = self.dop.decode_from_pdu(decode_state)
|
87
|
-
|
88
|
-
decode_state.cursor_byte_position = max(orig_cursor, decode_state.cursor_byte_position)
|
89
|
-
|
90
|
-
return phys_val
|
101
|
+
@override
|
102
|
+
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
103
|
+
return self.dop.decode_from_pdu(decode_state)
|
@@ -1,13 +1,17 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import TYPE_CHECKING, Any, Dict
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, List
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from typing_extensions import override
|
4
7
|
|
5
8
|
from ..dataobjectproperty import DataObjectProperty
|
6
9
|
from ..decodestate import DecodeState
|
7
10
|
from ..encodestate import EncodeState
|
8
11
|
from ..exceptions import DecodeError, odxraise, odxrequire
|
9
|
-
from ..odxlink import OdxLinkDatabase, OdxLinkId
|
12
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
10
13
|
from ..odxtypes import ParameterValue
|
14
|
+
from ..utils import dataclass_fields_asdict
|
11
15
|
from .parameter import ParameterType
|
12
16
|
from .parameterwithdop import ParameterWithDOP
|
13
17
|
|
@@ -20,16 +24,32 @@ class PhysicalConstantParameter(ParameterWithDOP):
|
|
20
24
|
|
21
25
|
physical_constant_value_raw: str
|
22
26
|
|
27
|
+
@staticmethod
|
28
|
+
@override
|
29
|
+
def from_et(et_element: ElementTree.Element,
|
30
|
+
doc_frags: List[OdxDocFragment]) -> "PhysicalConstantParameter":
|
31
|
+
|
32
|
+
kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, doc_frags))
|
33
|
+
|
34
|
+
physical_constant_value_raw = odxrequire(et_element.findtext("PHYS-CONSTANT-VALUE"))
|
35
|
+
|
36
|
+
return PhysicalConstantParameter(
|
37
|
+
physical_constant_value_raw=physical_constant_value_raw, **kwargs)
|
38
|
+
|
23
39
|
@property
|
40
|
+
@override
|
24
41
|
def parameter_type(self) -> ParameterType:
|
25
42
|
return "PHYS-CONST"
|
26
43
|
|
44
|
+
@override
|
27
45
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
28
46
|
return super()._build_odxlinks()
|
29
47
|
|
48
|
+
@override
|
30
49
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
31
50
|
super()._resolve_odxlinks(odxlinks)
|
32
51
|
|
52
|
+
@override
|
33
53
|
def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
|
34
54
|
super()._resolve_snrefs(diag_layer)
|
35
55
|
|
@@ -44,13 +64,16 @@ class PhysicalConstantParameter(ParameterWithDOP):
|
|
44
64
|
return self._physical_constant_value
|
45
65
|
|
46
66
|
@property
|
67
|
+
@override
|
47
68
|
def is_required(self) -> bool:
|
48
69
|
return False
|
49
70
|
|
50
71
|
@property
|
72
|
+
@override
|
51
73
|
def is_settable(self) -> bool:
|
52
74
|
return False
|
53
75
|
|
76
|
+
@override
|
54
77
|
def get_coded_value_as_bytes(self, encode_state: EncodeState) -> bytes:
|
55
78
|
dop = odxrequire(self.dop, "Reference to DOP is not resolved")
|
56
79
|
if (self.short_name in encode_state.parameter_values and
|
@@ -63,9 +86,10 @@ class PhysicalConstantParameter(ParameterWithDOP):
|
|
63
86
|
return dop.convert_physical_to_bytes(
|
64
87
|
self.physical_constant_value, encode_state, bit_position=bit_position_int)
|
65
88
|
|
66
|
-
|
89
|
+
@override
|
90
|
+
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
67
91
|
# Decode value
|
68
|
-
phys_val = super().
|
92
|
+
phys_val = super()._decode_positioned_from_pdu(decode_state)
|
69
93
|
|
70
94
|
# Check if decoded value matches expected value
|
71
95
|
if phys_val != self.physical_constant_value:
|
@@ -1,10 +1,16 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import
|
3
|
+
from typing import List, Optional
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from typing_extensions import override
|
4
7
|
|
5
8
|
from ..decodestate import DecodeState
|
6
9
|
from ..encodestate import EncodeState
|
7
|
-
from ..
|
10
|
+
from ..exceptions import odxrequire
|
11
|
+
from ..odxlink import OdxDocFragment
|
12
|
+
from ..odxtypes import DataType, ParameterValue
|
13
|
+
from ..utils import dataclass_fields_asdict
|
8
14
|
from .parameter import Parameter, ParameterType
|
9
15
|
|
10
16
|
|
@@ -12,35 +18,43 @@ from .parameter import Parameter, ParameterType
|
|
12
18
|
class ReservedParameter(Parameter):
|
13
19
|
bit_length: int
|
14
20
|
|
21
|
+
@staticmethod
|
22
|
+
@override
|
23
|
+
def from_et(et_element: ElementTree.Element,
|
24
|
+
doc_frags: List[OdxDocFragment]) -> "ReservedParameter":
|
25
|
+
|
26
|
+
kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
|
27
|
+
|
28
|
+
bit_length = int(odxrequire(et_element.findtext("BIT-LENGTH")))
|
29
|
+
|
30
|
+
return ReservedParameter(bit_length=bit_length, **kwargs)
|
31
|
+
|
15
32
|
@property
|
33
|
+
@override
|
16
34
|
def parameter_type(self) -> ParameterType:
|
17
35
|
return "RESERVED"
|
18
36
|
|
19
37
|
@property
|
38
|
+
@override
|
20
39
|
def is_required(self) -> bool:
|
21
40
|
return False
|
22
41
|
|
23
42
|
@property
|
43
|
+
@override
|
24
44
|
def is_settable(self) -> bool:
|
25
45
|
return False
|
26
46
|
|
47
|
+
@override
|
27
48
|
def get_static_bit_length(self) -> Optional[int]:
|
28
49
|
return self.bit_length
|
29
50
|
|
51
|
+
@override
|
30
52
|
def get_coded_value_as_bytes(self, encode_state: EncodeState) -> bytes:
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
decode_state.cursor_byte_position += ((self.bit_position or 0) + self.bit_length + 7) // 8
|
41
|
-
|
42
|
-
decode_state.cursor_byte_position = max(orig_cursor, decode_state.cursor_byte_position)
|
43
|
-
decode_state.cursor_bit_position = 0
|
44
|
-
|
45
|
-
# ignore the value of the parameter data
|
46
|
-
return cast(int, None)
|
53
|
+
return (0).to_bytes(((self.bit_position or 0) + self.bit_length + 7) // 8, "big")
|
54
|
+
|
55
|
+
@override
|
56
|
+
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
57
|
+
return decode_state.extract_atomic_value(
|
58
|
+
bit_length=self.bit_length,
|
59
|
+
base_data_type=DataType.A_UINT32,
|
60
|
+
is_highlow_byte_order=False)
|
@@ -1,9 +1,16 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
+
from typing import List
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from typing_extensions import override
|
3
7
|
|
4
8
|
from ..decodestate import DecodeState
|
5
9
|
from ..encodestate import EncodeState
|
10
|
+
from ..exceptions import odxrequire
|
11
|
+
from ..odxlink import OdxDocFragment
|
6
12
|
from ..odxtypes import ParameterValue
|
13
|
+
from ..utils import dataclass_fields_asdict
|
7
14
|
from .parameter import ParameterType
|
8
15
|
from .parameterwithdop import ParameterWithDOP
|
9
16
|
|
@@ -12,20 +19,36 @@ from .parameterwithdop import ParameterWithDOP
|
|
12
19
|
class SystemParameter(ParameterWithDOP):
|
13
20
|
sysparam: str
|
14
21
|
|
22
|
+
@staticmethod
|
23
|
+
@override
|
24
|
+
def from_et(et_element: ElementTree.Element,
|
25
|
+
doc_frags: List[OdxDocFragment]) -> "SystemParameter":
|
26
|
+
|
27
|
+
kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, doc_frags))
|
28
|
+
|
29
|
+
sysparam = odxrequire(et_element.findtext("SYSPARAM"))
|
30
|
+
|
31
|
+
return SystemParameter(sysparam=sysparam, **kwargs)
|
32
|
+
|
15
33
|
@property
|
34
|
+
@override
|
16
35
|
def parameter_type(self) -> ParameterType:
|
17
36
|
return "SYSTEM"
|
18
37
|
|
19
38
|
@property
|
39
|
+
@override
|
20
40
|
def is_required(self) -> bool:
|
21
41
|
raise NotImplementedError("SystemParameter.is_required is not implemented yet.")
|
22
42
|
|
23
43
|
@property
|
44
|
+
@override
|
24
45
|
def is_settable(self) -> bool:
|
25
46
|
raise NotImplementedError("SystemParameter.is_settable is not implemented yet.")
|
26
47
|
|
48
|
+
@override
|
27
49
|
def get_coded_value_as_bytes(self, encode_state: EncodeState) -> bytes:
|
28
50
|
raise NotImplementedError("Encoding a SystemParameter is not implemented yet.")
|
29
51
|
|
30
|
-
|
31
|
-
|
52
|
+
@override
|
53
|
+
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
54
|
+
raise NotImplementedError("Decoding SystemParameter is not implemented yet.")
|
@@ -1,32 +1,71 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
+
from typing import TYPE_CHECKING, List
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from typing_extensions import override
|
3
7
|
|
4
8
|
from ..decodestate import DecodeState
|
5
9
|
from ..encodestate import EncodeState
|
6
|
-
from ..
|
10
|
+
from ..exceptions import odxrequire
|
11
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef
|
7
12
|
from ..odxtypes import ParameterValue
|
13
|
+
from ..utils import dataclass_fields_asdict
|
8
14
|
from .parameter import Parameter, ParameterType
|
9
15
|
|
16
|
+
if TYPE_CHECKING:
|
17
|
+
from ..tablerow import TableRow
|
18
|
+
|
10
19
|
|
11
20
|
@dataclass
|
12
21
|
class TableEntryParameter(Parameter):
|
13
22
|
target: str
|
14
23
|
table_row_ref: OdxLinkRef
|
15
24
|
|
25
|
+
@staticmethod
|
26
|
+
@override
|
27
|
+
def from_et(et_element: ElementTree.Element,
|
28
|
+
doc_frags: List[OdxDocFragment]) -> "TableEntryParameter":
|
29
|
+
|
30
|
+
kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
|
31
|
+
|
32
|
+
target = odxrequire(et_element.findtext("TARGET"))
|
33
|
+
table_row_ref = odxrequire(OdxLinkRef.from_et(et_element.find("TABLE-ROW-REF"), doc_frags))
|
34
|
+
|
35
|
+
return TableEntryParameter(target=target, table_row_ref=table_row_ref, **kwargs)
|
36
|
+
|
37
|
+
@override
|
38
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
39
|
+
super()._resolve_odxlinks(odxlinks)
|
40
|
+
|
41
|
+
if TYPE_CHECKING:
|
42
|
+
self._table_row = odxlinks.resolve(self.table_row_ref, TableRow)
|
43
|
+
else:
|
44
|
+
self._table_row = odxlinks.resolve(self.table_row_ref)
|
45
|
+
|
16
46
|
@property
|
47
|
+
@override
|
17
48
|
def parameter_type(self) -> ParameterType:
|
18
49
|
return "TABLE-ENTRY"
|
19
50
|
|
20
51
|
@property
|
52
|
+
@override
|
21
53
|
def is_required(self) -> bool:
|
22
|
-
raise NotImplementedError("
|
54
|
+
raise NotImplementedError("TableEntryParameter.is_required is not implemented yet.")
|
23
55
|
|
24
56
|
@property
|
57
|
+
@override
|
25
58
|
def is_settable(self) -> bool:
|
26
|
-
raise NotImplementedError("
|
59
|
+
raise NotImplementedError("TableEntryParameter.is_settable is not implemented yet.")
|
27
60
|
|
61
|
+
@override
|
28
62
|
def get_coded_value_as_bytes(self, encode_state: EncodeState) -> bytes:
|
29
|
-
raise NotImplementedError("Encoding a
|
63
|
+
raise NotImplementedError("Encoding a TableEntryParameter is not implemented yet.")
|
64
|
+
|
65
|
+
@property
|
66
|
+
def table_row(self) -> "TableRow":
|
67
|
+
return self._table_row
|
30
68
|
|
31
|
-
|
32
|
-
|
69
|
+
@override
|
70
|
+
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
71
|
+
raise NotImplementedError("Decoding a TableEntryParameter is not implemented yet.")
|
@@ -1,12 +1,16 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import TYPE_CHECKING, Any, Dict, Optional
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from typing_extensions import override
|
4
7
|
|
5
8
|
from ..decodestate import DecodeState
|
6
9
|
from ..encodestate import EncodeState
|
7
10
|
from ..exceptions import DecodeError, EncodeError, odxraise, odxrequire
|
8
|
-
from ..odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
11
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
9
12
|
from ..odxtypes import ParameterValue
|
13
|
+
from ..utils import dataclass_fields_asdict
|
10
14
|
from .parameter import Parameter, ParameterType
|
11
15
|
|
12
16
|
if TYPE_CHECKING:
|
@@ -24,6 +28,33 @@ class TableKeyParameter(Parameter):
|
|
24
28
|
table_row_snref: Optional[str]
|
25
29
|
table_row_ref: Optional[OdxLinkRef]
|
26
30
|
|
31
|
+
@staticmethod
|
32
|
+
@override
|
33
|
+
def from_et(et_element: ElementTree.Element,
|
34
|
+
doc_frags: List[OdxDocFragment]) -> "TableKeyParameter":
|
35
|
+
|
36
|
+
kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
|
37
|
+
|
38
|
+
odx_id = odxrequire(OdxLinkId.from_et(et_element, doc_frags))
|
39
|
+
|
40
|
+
table_ref = OdxLinkRef.from_et(et_element.find("TABLE-REF"), doc_frags)
|
41
|
+
table_snref = None
|
42
|
+
if (table_snref_elem := et_element.find("TABLE-SNREF")) is not None:
|
43
|
+
table_snref = odxrequire(table_snref_elem.get("SHORT-NAME"))
|
44
|
+
|
45
|
+
table_row_ref = OdxLinkRef.from_et(et_element.find("TABLE-ROW-REF"), doc_frags)
|
46
|
+
table_row_snref = None
|
47
|
+
if (table_row_snref_elem := et_element.find("TABLE-ROW-SNREF")) is not None:
|
48
|
+
table_row_snref = odxrequire(table_row_snref_elem.get("SHORT-NAME"))
|
49
|
+
|
50
|
+
return TableKeyParameter(
|
51
|
+
odx_id=odx_id,
|
52
|
+
table_ref=table_ref,
|
53
|
+
table_snref=table_snref,
|
54
|
+
table_row_ref=table_row_ref,
|
55
|
+
table_row_snref=table_row_snref,
|
56
|
+
**kwargs)
|
57
|
+
|
27
58
|
def __post_init__(self) -> None:
|
28
59
|
self._table: "Table"
|
29
60
|
self._table_row: Optional["TableRow"] = None
|
@@ -32,9 +63,11 @@ class TableKeyParameter(Parameter):
|
|
32
63
|
odxraise("Either a table or a table row must be defined.")
|
33
64
|
|
34
65
|
@property
|
66
|
+
@override
|
35
67
|
def parameter_type(self) -> ParameterType:
|
36
68
|
return "TABLE-KEY"
|
37
69
|
|
70
|
+
@override
|
38
71
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
39
72
|
result = super()._build_odxlinks()
|
40
73
|
|
@@ -42,6 +75,7 @@ class TableKeyParameter(Parameter):
|
|
42
75
|
|
43
76
|
return result
|
44
77
|
|
78
|
+
@override
|
45
79
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
46
80
|
super()._resolve_odxlinks(odxlinks)
|
47
81
|
|
@@ -59,6 +93,7 @@ class TableKeyParameter(Parameter):
|
|
59
93
|
self._table_row = odxlinks.resolve(self.table_row_ref)
|
60
94
|
self._table = self._table_row.table
|
61
95
|
|
96
|
+
@override
|
62
97
|
def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
|
63
98
|
super()._resolve_snrefs(diag_layer)
|
64
99
|
|
@@ -86,15 +121,18 @@ class TableKeyParameter(Parameter):
|
|
86
121
|
return self._table_row
|
87
122
|
|
88
123
|
@property
|
124
|
+
@override
|
89
125
|
def is_required(self) -> bool:
|
90
126
|
# TABLE-KEY parameters can be implicitly determined from the
|
91
127
|
# corresponding TABLE-STRUCT
|
92
128
|
return False
|
93
129
|
|
94
130
|
@property
|
131
|
+
@override
|
95
132
|
def is_settable(self) -> bool:
|
96
133
|
return True
|
97
134
|
|
135
|
+
@override
|
98
136
|
def get_coded_value_as_bytes(self, encode_state: EncodeState) -> bytes:
|
99
137
|
tr_short_name = encode_state.parameter_values.get(self.short_name)
|
100
138
|
|
@@ -132,14 +170,12 @@ class TableKeyParameter(Parameter):
|
|
132
170
|
bit_position = 0 if self.bit_position is None else self.bit_position
|
133
171
|
return key_dop.convert_physical_to_bytes(tr.key, encode_state, bit_position=bit_position)
|
134
172
|
|
173
|
+
@override
|
135
174
|
def encode_into_pdu(self, encode_state: EncodeState) -> bytes:
|
136
175
|
return super().encode_into_pdu(encode_state)
|
137
176
|
|
138
|
-
|
139
|
-
|
140
|
-
if self.byte_position is not None:
|
141
|
-
decode_state.cursor_byte_position = decode_state.origin_byte_position + self.byte_position
|
142
|
-
|
177
|
+
@override
|
178
|
+
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
143
179
|
if self.table_row is not None:
|
144
180
|
# the table row to be used is statically specified -> no
|
145
181
|
# need to decode anything!
|
@@ -147,7 +183,6 @@ class TableKeyParameter(Parameter):
|
|
147
183
|
else:
|
148
184
|
# Use DOP to decode
|
149
185
|
key_dop = odxrequire(self.table.key_dop)
|
150
|
-
decode_state.cursor_bit_position = self.bit_position or 0
|
151
186
|
key_dop_val = key_dop.decode_from_pdu(decode_state)
|
152
187
|
|
153
188
|
table_row_candidates = [x for x in self.table.table_rows if x.key == key_dop_val]
|
@@ -162,6 +197,4 @@ class TableKeyParameter(Parameter):
|
|
162
197
|
# update the decode_state's table key
|
163
198
|
decode_state.table_keys[self.short_name] = table_row
|
164
199
|
|
165
|
-
decode_state.cursor_byte_position = max(decode_state.cursor_byte_position, orig_cursor)
|
166
|
-
|
167
200
|
return phys_val
|