odxtools 9.5.0__py3-none-any.whl → 9.6.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.
Files changed (102) hide show
  1. odxtools/additionalaudience.py +2 -2
  2. odxtools/admindata.py +3 -0
  3. odxtools/audience.py +9 -13
  4. odxtools/basecomparam.py +1 -2
  5. odxtools/basevariantpattern.py +5 -5
  6. odxtools/basicstructure.py +34 -35
  7. odxtools/commrelation.py +2 -1
  8. odxtools/companydata.py +1 -2
  9. odxtools/companyspecificinfo.py +3 -0
  10. odxtools/comparam.py +16 -8
  11. odxtools/comparaminstance.py +12 -12
  12. odxtools/comparamspec.py +4 -3
  13. odxtools/comparamsubset.py +26 -24
  14. odxtools/compumethods/compuconst.py +4 -4
  15. odxtools/compumethods/limit.py +9 -9
  16. odxtools/compumethods/linearsegment.py +8 -8
  17. odxtools/dataobjectproperty.py +16 -18
  18. odxtools/description.py +4 -2
  19. odxtools/determinenumberofitems.py +4 -4
  20. odxtools/diagcodedtype.py +20 -20
  21. odxtools/diagcomm.py +61 -41
  22. odxtools/diagdatadictionaryspec.py +51 -55
  23. odxtools/diaglayercontainer.py +25 -25
  24. odxtools/diaglayers/diaglayerraw.py +26 -27
  25. odxtools/diagnostictroublecode.py +13 -10
  26. odxtools/diagservice.py +49 -51
  27. odxtools/diagvariable.py +10 -8
  28. odxtools/docrevision.py +5 -5
  29. odxtools/dtcdop.py +17 -17
  30. odxtools/dynamicendmarkerfield.py +8 -8
  31. odxtools/dynamiclengthfield.py +2 -0
  32. odxtools/dyndefinedspec.py +21 -8
  33. odxtools/encodestate.py +1 -2
  34. odxtools/endofpdufield.py +7 -9
  35. odxtools/environmentdatadescription.py +9 -20
  36. odxtools/field.py +21 -21
  37. odxtools/inputparam.py +15 -14
  38. odxtools/leadinglengthinfotype.py +4 -4
  39. odxtools/matchingparameter.py +2 -3
  40. odxtools/minmaxlengthtype.py +7 -7
  41. odxtools/multiplexer.py +38 -39
  42. odxtools/multiplexercase.py +3 -6
  43. odxtools/multiplexerdefaultcase.py +3 -6
  44. odxtools/multiplexerswitchkey.py +4 -4
  45. odxtools/negoutputparam.py +6 -9
  46. odxtools/odxlink.py +21 -5
  47. odxtools/odxtypes.py +4 -4
  48. odxtools/outputparam.py +9 -8
  49. odxtools/parameterinfo.py +1 -1
  50. odxtools/parameters/codedconstparameter.py +28 -27
  51. odxtools/parameters/dynamicparameter.py +9 -9
  52. odxtools/parameters/lengthkeyparameter.py +18 -18
  53. odxtools/parameters/matchingrequestparameter.py +15 -15
  54. odxtools/parameters/nrcconstparameter.py +32 -24
  55. odxtools/parameters/parameter.py +35 -37
  56. odxtools/parameters/parameterwithdop.py +6 -6
  57. odxtools/parameters/physicalconstantparameter.py +19 -20
  58. odxtools/parameters/reservedparameter.py +10 -11
  59. odxtools/parameters/systemparameter.py +10 -11
  60. odxtools/parameters/tableentryparameter.py +19 -20
  61. odxtools/parameters/tablekeyparameter.py +0 -2
  62. odxtools/parameters/tablestructparameter.py +27 -21
  63. odxtools/parameters/valueparameter.py +20 -20
  64. odxtools/parentref.py +6 -7
  65. odxtools/physicaldimension.py +11 -11
  66. odxtools/physicaltype.py +9 -14
  67. odxtools/preconditionstateref.py +85 -0
  68. odxtools/progcode.py +1 -2
  69. odxtools/protstack.py +4 -4
  70. odxtools/relateddoc.py +3 -4
  71. odxtools/scaleconstr.py +0 -1
  72. odxtools/singleecujob.py +8 -4
  73. odxtools/specialdata.py +10 -9
  74. odxtools/specialdatagroup.py +1 -0
  75. odxtools/standardlengthtype.py +10 -10
  76. odxtools/statechart.py +10 -6
  77. odxtools/statemachine.py +186 -0
  78. odxtools/statetransitionref.py +231 -0
  79. odxtools/structure.py +4 -4
  80. odxtools/subcomponent.py +72 -8
  81. odxtools/table.py +23 -13
  82. odxtools/tablerow.py +86 -69
  83. odxtools/teammember.py +4 -4
  84. odxtools/templates/macros/printCompanyData.xml.jinja2 +2 -2
  85. odxtools/templates/macros/printComparam.xml.jinja2 +3 -5
  86. odxtools/templates/macros/printDOP.xml.jinja2 +4 -1
  87. odxtools/templates/macros/printDiagComm.xml.jinja2 +6 -5
  88. odxtools/templates/macros/printParam.xml.jinja2 +5 -5
  89. odxtools/templates/macros/printPreConditionStateRef.xml.jinja2 +18 -0
  90. odxtools/templates/macros/printStateTransitionRef.xml.jinja2 +18 -0
  91. odxtools/templates/macros/printTable.xml.jinja2 +13 -9
  92. odxtools/text.py +35 -0
  93. odxtools/unit.py +1 -3
  94. odxtools/unitgroup.py +6 -8
  95. odxtools/utils.py +0 -4
  96. odxtools/version.py +2 -2
  97. {odxtools-9.5.0.dist-info → odxtools-9.6.1.dist-info}/METADATA +3 -2
  98. {odxtools-9.5.0.dist-info → odxtools-9.6.1.dist-info}/RECORD +102 -96
  99. {odxtools-9.5.0.dist-info → odxtools-9.6.1.dist-info}/WHEEL +1 -1
  100. {odxtools-9.5.0.dist-info → odxtools-9.6.1.dist-info}/entry_points.txt +0 -0
  101. {odxtools-9.5.0.dist-info → odxtools-9.6.1.dist-info/licenses}/LICENSE +0 -0
  102. {odxtools-9.5.0.dist-info → odxtools-9.6.1.dist-info}/top_level.txt +0 -0
odxtools/odxtypes.py CHANGED
@@ -1,11 +1,10 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from enum import Enum
3
- from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, Optional, Tuple, Type, Union,
4
- overload)
3
+ from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, Optional, SupportsBytes, Tuple,
4
+ Type, Union, overload)
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from .exceptions import odxassert, odxraise, odxrequire
8
- from .utils import BytesTypes
9
8
 
10
9
  if TYPE_CHECKING:
11
10
  from odxtools.diagnostictroublecode import DiagnosticTroubleCode
@@ -17,7 +16,8 @@ def bytefield_to_bytearray(bytefield: str) -> bytearray:
17
16
  return bytearray([int(x, 16) for x in bytes_string])
18
17
 
19
18
 
20
- AtomicOdxType = Union[str, int, float, bytes]
19
+ BytesTypes = (bytearray, bytes, SupportsBytes)
20
+ AtomicOdxType = Union[str, int, float, bytearray, bytes]
21
21
 
22
22
  # dictionary mapping short names to a Parameter that needs to be
23
23
  # specified. Complex parameters (structures) may contain
odxtools/outputparam.py CHANGED
@@ -18,10 +18,19 @@ class OutputParam(IdentifiableElement):
18
18
  dop_base_ref: OdxLinkRef
19
19
  semantic: Optional[str]
20
20
 
21
+ @property
22
+ def dop(self) -> DopBase:
23
+ return self._dop
24
+
25
+ @deprecated(details="use .dop") # type: ignore[misc]
26
+ def dop_base(self) -> DopBase:
27
+ return self._dop
28
+
21
29
  @staticmethod
22
30
  def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "OutputParam":
23
31
 
24
32
  kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
33
+
25
34
  dop_base_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DOP-BASE-REF"), doc_frags))
26
35
  semantic = et_element.get("SEMANTIC")
27
36
 
@@ -35,11 +44,3 @@ class OutputParam(IdentifiableElement):
35
44
 
36
45
  def _resolve_snrefs(self, context: SnRefContext) -> None:
37
46
  pass
38
-
39
- @property
40
- def dop(self) -> DopBase:
41
- return self._dop
42
-
43
- @deprecated(details="use .dop") # type: ignore[misc]
44
- def dop_base(self) -> DopBase:
45
- return self._dop
odxtools/parameterinfo.py CHANGED
@@ -73,7 +73,7 @@ def parameter_info(param_list: Iterable[Parameter], quoted_names: bool = False)
73
73
  of = StringIO()
74
74
  for param in param_list:
75
75
  if isinstance(param, CodedConstParameter):
76
- of.write(f"{q}{param.short_name}{q}: const = {param._coded_value_str}\n")
76
+ of.write(f"{q}{param.short_name}{q}: const = {param.coded_value_raw}\n")
77
77
  continue
78
78
  elif isinstance(param, MatchingRequestParameter):
79
79
  of.write(f"{q}{param.short_name}{q}: <matches request>\n")
@@ -1,7 +1,7 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import warnings
3
3
  from dataclasses import dataclass
4
- from typing import Any, Dict, List, Optional
4
+ from typing import Any, Dict, List, Optional, cast
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from typing_extensions import override
@@ -20,8 +20,27 @@ from .parameter import Parameter, ParameterType
20
20
  @dataclass
21
21
  class CodedConstParameter(Parameter):
22
22
 
23
+ coded_value_raw: str
23
24
  diag_coded_type: DiagCodedType
24
- coded_value: AtomicOdxType
25
+
26
+ @property
27
+ @override
28
+ def parameter_type(self) -> ParameterType:
29
+ return "CODED-CONST"
30
+
31
+ @property
32
+ @override
33
+ def is_required(self) -> bool:
34
+ return False
35
+
36
+ @property
37
+ @override
38
+ def is_settable(self) -> bool:
39
+ return False
40
+
41
+ @property
42
+ def coded_value(self) -> AtomicOdxType:
43
+ return self._coded_value
25
44
 
26
45
  @staticmethod
27
46
  @override
@@ -30,18 +49,16 @@ class CodedConstParameter(Parameter):
30
49
 
31
50
  kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
32
51
 
52
+ coded_value_raw = odxrequire(et_element.findtext("CODED-VALUE"))
33
53
  dct_elem = odxrequire(et_element.find("DIAG-CODED-TYPE"))
34
54
  diag_coded_type = create_any_diag_coded_type_from_et(dct_elem, doc_frags)
35
- coded_value = diag_coded_type.base_data_type.from_string(
36
- odxrequire(et_element.findtext("CODED-VALUE")))
37
55
 
38
56
  return CodedConstParameter(
39
- diag_coded_type=diag_coded_type, coded_value=coded_value, **kwargs)
57
+ coded_value_raw=coded_value_raw, diag_coded_type=diag_coded_type, **kwargs)
40
58
 
41
- @property
42
- @override
43
- def parameter_type(self) -> ParameterType:
44
- return "CODED-CONST"
59
+ def __post_init__(self) -> None:
60
+ self._coded_value = cast(
61
+ AtomicOdxType, self.diag_coded_type.base_data_type.from_string(self.coded_value_raw))
45
62
 
46
63
  @override
47
64
  def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
@@ -59,16 +76,6 @@ class CodedConstParameter(Parameter):
59
76
  def internal_data_type(self) -> DataType:
60
77
  return self.diag_coded_type.base_data_type
61
78
 
62
- @property
63
- @override
64
- def is_required(self) -> bool:
65
- return False
66
-
67
- @property
68
- @override
69
- def is_settable(self) -> bool:
70
- return False
71
-
72
79
  @override
73
80
  def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
74
81
  encode_state: EncodeState) -> None:
@@ -91,7 +98,7 @@ class CodedConstParameter(Parameter):
91
98
  warnings.warn(
92
99
  f"Coded constant parameter does not match! "
93
100
  f"The parameter {self.short_name} expected coded "
94
- f"value {str(self._coded_value_str)} but got {str(coded_val)} "
101
+ f"value {str(self.coded_value)} but got {str(coded_val)} "
95
102
  f"at byte position {decode_state.cursor_byte_position} "
96
103
  f"in coded message {decode_state.coded_message.hex()}.",
97
104
  DecodeError,
@@ -100,12 +107,6 @@ class CodedConstParameter(Parameter):
100
107
 
101
108
  return coded_val
102
109
 
103
- @property
104
- def _coded_value_str(self) -> str:
105
- if isinstance(self.coded_value, bytes):
106
- return self.coded_value.hex()
107
- return str(self.coded_value)
108
-
109
110
  def get_description_of_valid_values(self) -> str:
110
111
  """return a human-understandable description of valid physical values"""
111
- return f"Constant internal value: {self._coded_value_str}"
112
+ return f"Constant internal value: {str(self.coded_value)}"
@@ -16,15 +16,6 @@ from .parameter import Parameter, ParameterType
16
16
  @dataclass
17
17
  class DynamicParameter(Parameter):
18
18
 
19
- @staticmethod
20
- @override
21
- def from_et(et_element: ElementTree.Element,
22
- doc_frags: List[OdxDocFragment]) -> "DynamicParameter":
23
-
24
- kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
25
-
26
- return DynamicParameter(**kwargs)
27
-
28
19
  @property
29
20
  @override
30
21
  def parameter_type(self) -> ParameterType:
@@ -40,6 +31,15 @@ class DynamicParameter(Parameter):
40
31
  def is_settable(self) -> bool:
41
32
  raise NotImplementedError(".is_settable for a DynamicParameter")
42
33
 
34
+ @staticmethod
35
+ @override
36
+ def from_et(et_element: ElementTree.Element,
37
+ doc_frags: List[OdxDocFragment]) -> "DynamicParameter":
38
+
39
+ kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
40
+
41
+ return DynamicParameter(**kwargs)
42
+
43
43
  @override
44
44
  def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
45
45
  encode_state: EncodeState) -> None:
@@ -28,6 +28,24 @@ class LengthKeyParameter(ParameterWithDOP):
28
28
 
29
29
  odx_id: OdxLinkId
30
30
 
31
+ @property
32
+ @override
33
+ def parameter_type(self) -> ParameterType:
34
+ return "LENGTH-KEY"
35
+
36
+ @property
37
+ @override
38
+ def is_required(self) -> bool:
39
+ return False
40
+
41
+ @property
42
+ @override
43
+ def is_settable(self) -> bool:
44
+ # length keys can be explicitly set, but they do not need to
45
+ # be because they can be implicitly determined by the length
46
+ # of the corresponding field
47
+ return True
48
+
31
49
  @staticmethod
32
50
  @override
33
51
  def from_et(et_element: ElementTree.Element,
@@ -39,11 +57,6 @@ class LengthKeyParameter(ParameterWithDOP):
39
57
 
40
58
  return LengthKeyParameter(odx_id=odx_id, **kwargs)
41
59
 
42
- @property
43
- @override
44
- def parameter_type(self) -> ParameterType:
45
- return "LENGTH-KEY"
46
-
47
60
  @override
48
61
  def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
49
62
  result = super()._build_odxlinks()
@@ -52,19 +65,6 @@ class LengthKeyParameter(ParameterWithDOP):
52
65
 
53
66
  return result
54
67
 
55
- @property
56
- @override
57
- def is_required(self) -> bool:
58
- return False
59
-
60
- @property
61
- @override
62
- def is_settable(self) -> bool:
63
- # length keys can be explicitly set, but they do not need to
64
- # be because they can be implicitly determined by the length
65
- # of the corresponding field
66
- return True
67
-
68
68
  @override
69
69
  @final
70
70
  def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
@@ -19,6 +19,21 @@ class MatchingRequestParameter(Parameter):
19
19
  request_byte_position: int
20
20
  byte_length: int
21
21
 
22
+ @property
23
+ @override
24
+ def parameter_type(self) -> ParameterType:
25
+ return "MATCHING-REQUEST-PARAM"
26
+
27
+ @property
28
+ @override
29
+ def is_required(self) -> bool:
30
+ return False
31
+
32
+ @property
33
+ @override
34
+ def is_settable(self) -> bool:
35
+ return False
36
+
22
37
  @staticmethod
23
38
  @override
24
39
  def from_et(et_element: ElementTree.Element,
@@ -32,25 +47,10 @@ class MatchingRequestParameter(Parameter):
32
47
  return MatchingRequestParameter(
33
48
  request_byte_position=request_byte_position, byte_length=byte_length, **kwargs)
34
49
 
35
- @property
36
- @override
37
- def parameter_type(self) -> ParameterType:
38
- return "MATCHING-REQUEST-PARAM"
39
-
40
50
  @override
41
51
  def get_static_bit_length(self) -> Optional[int]:
42
52
  return 8 * self.byte_length
43
53
 
44
- @property
45
- @override
46
- def is_required(self) -> bool:
47
- return False
48
-
49
- @property
50
- @override
51
- def is_settable(self) -> bool:
52
- return False
53
-
54
54
  @override
55
55
  def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
56
56
  encode_state: EncodeState) -> None:
@@ -34,8 +34,31 @@ class NrcConstParameter(Parameter):
34
34
 
35
35
  """
36
36
 
37
+ coded_values_raw: List[str]
37
38
  diag_coded_type: DiagCodedType
38
- coded_values: List[AtomicOdxType]
39
+
40
+ @property
41
+ @override
42
+ def parameter_type(self) -> ParameterType:
43
+ return "NRC-CONST"
44
+
45
+ @property
46
+ @override
47
+ def is_required(self) -> bool:
48
+ return False
49
+
50
+ @property
51
+ @override
52
+ def is_settable(self) -> bool:
53
+ return False
54
+
55
+ @property
56
+ def internal_data_type(self) -> DataType:
57
+ return self.diag_coded_type.base_data_type
58
+
59
+ @property
60
+ def coded_values(self) -> List[AtomicOdxType]:
61
+ return self._coded_values
39
62
 
40
63
  @staticmethod
41
64
  @override
@@ -44,20 +67,19 @@ class NrcConstParameter(Parameter):
44
67
 
45
68
  kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
46
69
 
70
+ coded_values_raw = [
71
+ odxrequire(x.text) for x in et_element.iterfind("CODED-VALUES/CODED-VALUE")
72
+ ]
47
73
  dct_elem = odxrequire(et_element.find("DIAG-CODED-TYPE"))
48
74
  diag_coded_type = create_any_diag_coded_type_from_et(dct_elem, doc_frags)
49
- coded_values = [
50
- diag_coded_type.base_data_type.from_string(odxrequire(val.text))
51
- for val in et_element.iterfind("CODED-VALUES/CODED-VALUE")
52
- ]
53
75
 
54
76
  return NrcConstParameter(
55
- diag_coded_type=diag_coded_type, coded_values=coded_values, **kwargs)
77
+ coded_values_raw=coded_values_raw, diag_coded_type=diag_coded_type, **kwargs)
56
78
 
57
- @property
58
- @override
59
- def parameter_type(self) -> ParameterType:
60
- return "NRC-CONST"
79
+ def __post_init__(self) -> None:
80
+ self._coded_values = [
81
+ self.diag_coded_type.base_data_type.from_string(val) for val in self.coded_values_raw
82
+ ]
61
83
 
62
84
  @override
63
85
  def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
@@ -71,20 +93,6 @@ class NrcConstParameter(Parameter):
71
93
  def get_static_bit_length(self) -> Optional[int]:
72
94
  return self.diag_coded_type.get_static_bit_length()
73
95
 
74
- @property
75
- def internal_data_type(self) -> DataType:
76
- return self.diag_coded_type.base_data_type
77
-
78
- @property
79
- @override
80
- def is_required(self) -> bool:
81
- return False
82
-
83
- @property
84
- @override
85
- def is_settable(self) -> bool:
86
- return False
87
-
88
96
  @override
89
97
  def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
90
98
  encode_state: EncodeState) -> None:
@@ -42,11 +42,39 @@ class Parameter(NamedElement):
42
42
  non-positionable parameter types.
43
43
 
44
44
  """
45
+ sdgs: List[SpecialDataGroup]
46
+ semantic: Optional[str]
45
47
  oid: Optional[str]
46
48
  byte_position: Optional[int]
47
49
  bit_position: Optional[int]
48
- semantic: Optional[str]
49
- sdgs: List[SpecialDataGroup]
50
+
51
+ @property
52
+ def parameter_type(self) -> ParameterType:
53
+ raise NotImplementedError(
54
+ ".parameter_type is not implemented by the concrete parameter class")
55
+
56
+ @property
57
+ def is_required(self) -> bool:
58
+ """True if the parameter must be explicitly specified when
59
+ encoding a message.
60
+
61
+ Required parameters are always settable, and parameters which
62
+ have a default value are settable but not required to be
63
+ specified.
64
+
65
+ """
66
+ raise NotImplementedError(".is_required is not implemented by the concrete parameter class")
67
+
68
+ @property
69
+ def is_settable(self) -> bool:
70
+ """True if the parameter can be specified when encoding a
71
+ message.
72
+
73
+ Required parameters are always settable, and parameters which
74
+ have a default value are settable but not required to be
75
+ specified.
76
+ """
77
+ raise NotImplementedError(".is_settable is not implemented by the concrete parameter class")
50
78
 
51
79
  @staticmethod
52
80
  @override
@@ -54,24 +82,22 @@ class Parameter(NamedElement):
54
82
 
55
83
  kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
56
84
 
57
- oid = et_element.get("OID")
58
- semantic = et_element.get("SEMANTIC")
59
85
  sdgs = [
60
86
  SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
61
87
  ]
62
-
88
+ semantic = et_element.attrib.get("SEMANTIC")
89
+ oid = et_element.attrib.get("OID")
63
90
  byte_position_str = et_element.findtext("BYTE-POSITION")
64
- bit_position_str = et_element.findtext("BIT-POSITION")
65
-
66
91
  byte_position = int(byte_position_str) if byte_position_str is not None else None
92
+ bit_position_str = et_element.findtext("BIT-POSITION")
67
93
  bit_position = int(bit_position_str) if bit_position_str is not None else None
68
94
 
69
95
  return Parameter(
96
+ sdgs=sdgs,
97
+ semantic=semantic,
70
98
  oid=oid,
71
99
  byte_position=byte_position,
72
100
  bit_position=bit_position,
73
- semantic=semantic,
74
- sdgs=sdgs,
75
101
  **kwargs)
76
102
 
77
103
  def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
@@ -90,37 +116,9 @@ class Parameter(NamedElement):
90
116
  for sdg in self.sdgs:
91
117
  sdg._resolve_snrefs(context)
92
118
 
93
- @property
94
- def parameter_type(self) -> ParameterType:
95
- raise NotImplementedError(
96
- ".parameter_type is not implemented by the concrete parameter class")
97
-
98
119
  def get_static_bit_length(self) -> Optional[int]:
99
120
  return None
100
121
 
101
- @property
102
- def is_required(self) -> bool:
103
- """True if the parameter must be explicitly specified when
104
- encoding a message.
105
-
106
- Required parameters are always settable, and parameters which
107
- have a default value are settable but not required to be
108
- specified.
109
-
110
- """
111
- raise NotImplementedError(".is_required is not implemented by the concrete parameter class")
112
-
113
- @property
114
- def is_settable(self) -> bool:
115
- """True if the parameter can be specified when encoding a
116
- message.
117
-
118
- Required parameters are always settable, and parameters which
119
- have a default value are settable but not required to be
120
- specified.
121
- """
122
- raise NotImplementedError(".is_settable is not implemented by the concrete parameter class")
123
-
124
122
  @final
125
123
  def encode_into_pdu(self, physical_value: Optional[ParameterValue],
126
124
  encode_state: EncodeState) -> None:
@@ -24,6 +24,12 @@ class ParameterWithDOP(Parameter):
24
24
  dop_ref: Optional[OdxLinkRef]
25
25
  dop_snref: Optional[str]
26
26
 
27
+ @property
28
+ def dop(self) -> DopBase:
29
+ """This is usually a DataObjectProperty or a Structure object"""
30
+
31
+ return self._dop
32
+
27
33
  @staticmethod
28
34
  @override
29
35
  def from_et(et_element: ElementTree.Element,
@@ -63,12 +69,6 @@ class ParameterWithDOP(Parameter):
63
69
  ddds = odxrequire(context.diag_layer).diag_data_dictionary_spec
64
70
  self._dop = resolve_snref(self.dop_snref, ddds.all_data_object_properties, DopBase)
65
71
 
66
- @property
67
- def dop(self) -> DopBase:
68
- """This is usually a DataObjectProperty or a Structure object"""
69
-
70
- return self._dop
71
-
72
72
  @override
73
73
  def get_static_bit_length(self) -> Optional[int]:
74
74
  if self._dop is not None:
@@ -19,9 +19,27 @@ from .parameterwithdop import ParameterWithDOP
19
19
 
20
20
  @dataclass
21
21
  class PhysicalConstantParameter(ParameterWithDOP):
22
-
23
22
  physical_constant_value_raw: str
24
23
 
24
+ @property
25
+ @override
26
+ def parameter_type(self) -> ParameterType:
27
+ return "PHYS-CONST"
28
+
29
+ @property
30
+ @override
31
+ def is_required(self) -> bool:
32
+ return False
33
+
34
+ @property
35
+ @override
36
+ def is_settable(self) -> bool:
37
+ return False
38
+
39
+ @property
40
+ def physical_constant_value(self) -> ParameterValue:
41
+ return self._physical_constant_value
42
+
25
43
  @staticmethod
26
44
  @override
27
45
  def from_et(et_element: ElementTree.Element,
@@ -34,11 +52,6 @@ class PhysicalConstantParameter(ParameterWithDOP):
34
52
  return PhysicalConstantParameter(
35
53
  physical_constant_value_raw=physical_constant_value_raw, **kwargs)
36
54
 
37
- @property
38
- @override
39
- def parameter_type(self) -> ParameterType:
40
- return "PHYS-CONST"
41
-
42
55
  @override
43
56
  def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
44
57
  return super()._build_odxlinks()
@@ -58,20 +71,6 @@ class PhysicalConstantParameter(ParameterWithDOP):
58
71
  base_data_type = dop.physical_type.base_data_type
59
72
  self._physical_constant_value = base_data_type.from_string(self.physical_constant_value_raw)
60
73
 
61
- @property
62
- def physical_constant_value(self) -> ParameterValue:
63
- return self._physical_constant_value
64
-
65
- @property
66
- @override
67
- def is_required(self) -> bool:
68
- return False
69
-
70
- @property
71
- @override
72
- def is_settable(self) -> bool:
73
- return False
74
-
75
74
  @override
76
75
  def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
77
76
  encode_state: EncodeState) -> None:
@@ -18,17 +18,6 @@ from .parameter import Parameter, ParameterType
18
18
  class ReservedParameter(Parameter):
19
19
  bit_length: int
20
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
-
32
21
  @property
33
22
  @override
34
23
  def parameter_type(self) -> ParameterType:
@@ -44,6 +33,16 @@ class ReservedParameter(Parameter):
44
33
  def is_settable(self) -> bool:
45
34
  return False
46
35
 
36
+ @staticmethod
37
+ @override
38
+ def from_et(et_element: ElementTree.Element,
39
+ doc_frags: List[OdxDocFragment]) -> "ReservedParameter":
40
+ kwargs = dataclass_fields_asdict(Parameter.from_et(et_element, doc_frags))
41
+
42
+ bit_length = int(odxrequire(et_element.findtext("BIT-LENGTH")))
43
+
44
+ return ReservedParameter(bit_length=bit_length, **kwargs)
45
+
47
46
  @override
48
47
  def get_static_bit_length(self) -> Optional[int]:
49
48
  return self.bit_length
@@ -29,17 +29,6 @@ PREDEFINED_SYSPARAM_VALUES = [
29
29
  class SystemParameter(ParameterWithDOP):
30
30
  sysparam: str
31
31
 
32
- @staticmethod
33
- @override
34
- def from_et(et_element: ElementTree.Element,
35
- doc_frags: List[OdxDocFragment]) -> "SystemParameter":
36
-
37
- kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, doc_frags))
38
-
39
- sysparam = odxrequire(et_element.get("SYSPARAM"))
40
-
41
- return SystemParameter(sysparam=sysparam, **kwargs)
42
-
43
32
  @property
44
33
  @override
45
34
  def parameter_type(self) -> ParameterType:
@@ -58,6 +47,16 @@ class SystemParameter(ParameterWithDOP):
58
47
  def is_settable(self) -> bool:
59
48
  return True
60
49
 
50
+ @staticmethod
51
+ @override
52
+ def from_et(et_element: ElementTree.Element,
53
+ doc_frags: List[OdxDocFragment]) -> "SystemParameter":
54
+ kwargs = dataclass_fields_asdict(ParameterWithDOP.from_et(et_element, doc_frags))
55
+
56
+ sysparam = odxrequire(et_element.get("SYSPARAM"))
57
+
58
+ return SystemParameter(sysparam=sysparam, **kwargs)
59
+
61
60
  @override
62
61
  def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
63
62
  encode_state: EncodeState) -> None: