odxtools 9.4.1__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 +38 -0
- 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/basevariant.py +5 -0
- odxtools/diaglayers/basevariantraw.py +7 -1
- odxtools/diaglayers/diaglayerraw.py +26 -27
- odxtools/diaglayers/ecuvariant.py +16 -0
- 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/ecuvariantpattern.py +20 -9
- odxtools/encodestate.py +3 -3
- 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/matchingbasevariantparameter.py +38 -0
- odxtools/matchingparameter.py +108 -28
- odxtools/minmaxlengthtype.py +6 -6
- 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 +7 -6
- 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 +18 -18
- odxtools/statechart.py +10 -6
- odxtools/statemachine.py +186 -0
- odxtools/statetransitionref.py +231 -0
- odxtools/structure.py +4 -4
- odxtools/subcomponent.py +78 -11
- odxtools/table.py +23 -13
- odxtools/tablerow.py +86 -69
- odxtools/teammember.py +4 -4
- odxtools/templates/macros/printBaseVariant.xml.jinja2 +4 -9
- odxtools/templates/macros/printBaseVariantPattern.xml.jinja2 +32 -0
- 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/printEcuVariantPattern.xml.jinja2 +7 -6
- 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/variantmatcher.py +209 -0
- odxtools/variantpattern.py +38 -0
- odxtools/version.py +2 -2
- {odxtools-9.4.1.dist-info → odxtools-9.6.0.dist-info}/METADATA +3 -2
- {odxtools-9.4.1.dist-info → odxtools-9.6.0.dist-info}/RECORD +111 -102
- {odxtools-9.4.1.dist-info → odxtools-9.6.0.dist-info}/WHEEL +1 -1
- odxtools/createecuvariantpatterns.py +0 -18
- odxtools/ecuvariantmatcher.py +0 -171
- {odxtools-9.4.1.dist-info → odxtools-9.6.0.dist-info}/entry_points.txt +0 -0
- {odxtools-9.4.1.dist-info → odxtools-9.6.0.dist-info/licenses}/LICENSE +0 -0
- {odxtools-9.4.1.dist-info → odxtools-9.6.0.dist-info}/top_level.txt +0 -0
odxtools/dataobjectproperty.py
CHANGED
@@ -13,7 +13,7 @@ from .encodestate import EncodeState
|
|
13
13
|
from .exceptions import EncodeError, odxraise, odxrequire
|
14
14
|
from .internalconstr import InternalConstr
|
15
15
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
|
16
|
-
from .odxtypes import AtomicOdxType, ParameterValue
|
16
|
+
from .odxtypes import AtomicOdxType, BytesTypes, ParameterValue
|
17
17
|
from .physicaltype import PhysicalType
|
18
18
|
from .snrefcontext import SnRefContext
|
19
19
|
from .unit import Unit
|
@@ -28,21 +28,26 @@ class DataObjectProperty(DopBase):
|
|
28
28
|
name would thus be SimpleDataObjectProp...
|
29
29
|
"""
|
30
30
|
|
31
|
+
#: Conversion from the physical to the internal representation and vice-versa.
|
32
|
+
compu_method: CompuMethod
|
33
|
+
|
31
34
|
#: The type used to represent a value internally
|
32
35
|
diag_coded_type: DiagCodedType
|
33
36
|
|
34
37
|
#: The type of the value in the physical world
|
35
38
|
physical_type: PhysicalType
|
36
39
|
|
37
|
-
|
38
|
-
compu_method: CompuMethod
|
40
|
+
internal_constr: Optional[InternalConstr]
|
39
41
|
|
40
42
|
#: The unit associated with physical values (e.g. 'm/s^2')
|
41
43
|
unit_ref: Optional[OdxLinkRef]
|
42
44
|
|
43
|
-
internal_constr: Optional[InternalConstr]
|
44
45
|
physical_constr: Optional[InternalConstr]
|
45
46
|
|
47
|
+
@property
|
48
|
+
def unit(self) -> Optional[Unit]:
|
49
|
+
return self._unit
|
50
|
+
|
46
51
|
@staticmethod
|
47
52
|
def from_et(et_element: ElementTree.Element,
|
48
53
|
doc_frags: List[OdxDocFragment]) -> "DataObjectProperty":
|
@@ -51,7 +56,6 @@ class DataObjectProperty(DopBase):
|
|
51
56
|
|
52
57
|
diag_coded_type = create_any_diag_coded_type_from_et(
|
53
58
|
odxrequire(et_element.find("DIAG-CODED-TYPE")), doc_frags)
|
54
|
-
|
55
59
|
physical_type = PhysicalType.from_et(
|
56
60
|
odxrequire(et_element.find("PHYSICAL-TYPE")), doc_frags)
|
57
61
|
compu_method = create_any_compu_method_from_et(
|
@@ -60,39 +64,37 @@ class DataObjectProperty(DopBase):
|
|
60
64
|
internal_type=diag_coded_type.base_data_type,
|
61
65
|
physical_type=physical_type.base_data_type,
|
62
66
|
)
|
63
|
-
unit_ref = OdxLinkRef.from_et(et_element.find("UNIT-REF"), doc_frags)
|
64
|
-
|
65
67
|
internal_constr = None
|
66
68
|
if (internal_constr_elem := et_element.find("INTERNAL-CONSTR")) is not None:
|
67
69
|
internal_constr = InternalConstr.constr_from_et(
|
68
70
|
internal_constr_elem, doc_frags, value_type=diag_coded_type.base_data_type)
|
69
|
-
|
71
|
+
unit_ref = OdxLinkRef.from_et(et_element.find("UNIT-REF"), doc_frags)
|
70
72
|
physical_constr = None
|
71
73
|
if (physical_constr_elem := et_element.find("PHYS-CONSTR")) is not None:
|
72
74
|
physical_constr = InternalConstr.constr_from_et(
|
73
75
|
physical_constr_elem, doc_frags, value_type=physical_type.base_data_type)
|
74
76
|
|
75
77
|
return DataObjectProperty(
|
78
|
+
compu_method=compu_method,
|
76
79
|
diag_coded_type=diag_coded_type,
|
77
80
|
physical_type=physical_type,
|
78
|
-
compu_method=compu_method,
|
79
|
-
unit_ref=unit_ref,
|
80
81
|
internal_constr=internal_constr,
|
82
|
+
unit_ref=unit_ref,
|
81
83
|
physical_constr=physical_constr,
|
82
84
|
**kwargs)
|
83
85
|
|
84
86
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
85
87
|
result = super()._build_odxlinks()
|
86
|
-
result.update(self.diag_coded_type._build_odxlinks())
|
87
88
|
result.update(self.compu_method._build_odxlinks())
|
89
|
+
result.update(self.diag_coded_type._build_odxlinks())
|
88
90
|
return result
|
89
91
|
|
90
92
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
91
93
|
"""Resolves the reference to the unit"""
|
92
94
|
super()._resolve_odxlinks(odxlinks)
|
93
95
|
|
94
|
-
self.diag_coded_type._resolve_odxlinks(odxlinks)
|
95
96
|
self.compu_method._resolve_odxlinks(odxlinks)
|
97
|
+
self.diag_coded_type._resolve_odxlinks(odxlinks)
|
96
98
|
|
97
99
|
self._unit: Optional[Unit] = None
|
98
100
|
if self.unit_ref:
|
@@ -101,12 +103,8 @@ class DataObjectProperty(DopBase):
|
|
101
103
|
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
102
104
|
super()._resolve_snrefs(context)
|
103
105
|
|
104
|
-
self.diag_coded_type._resolve_snrefs(context)
|
105
106
|
self.compu_method._resolve_snrefs(context)
|
106
|
-
|
107
|
-
@property
|
108
|
-
def unit(self) -> Optional[Unit]:
|
109
|
-
return self._unit
|
107
|
+
self.diag_coded_type._resolve_snrefs(context)
|
110
108
|
|
111
109
|
def get_static_bit_length(self) -> Optional[int]:
|
112
110
|
return self.diag_coded_type.get_static_bit_length()
|
@@ -120,7 +118,7 @@ class DataObjectProperty(DopBase):
|
|
120
118
|
f"The value {repr(physical_value)} of type {type(physical_value).__name__}"
|
121
119
|
f" is not a valid.")
|
122
120
|
|
123
|
-
if not isinstance(physical_value, (int, float, str,
|
121
|
+
if not isinstance(physical_value, (int, float, str, BytesTypes)):
|
124
122
|
odxraise(f"Invalid type '{type(physical_value).__name__}' for physical value. "
|
125
123
|
f"(Expect atomic type!)")
|
126
124
|
internal_value = self.compu_method.convert_physical_to_internal(physical_value)
|
odxtools/description.py
CHANGED
@@ -27,6 +27,7 @@ class ExternalDoc:
|
|
27
27
|
class Description:
|
28
28
|
text: str
|
29
29
|
external_docs: List[ExternalDoc]
|
30
|
+
|
30
31
|
text_identifier: Optional[str]
|
31
32
|
|
32
33
|
@staticmethod
|
@@ -48,12 +49,13 @@ class Description:
|
|
48
49
|
|
49
50
|
text = "\n".join(stripped_lines).strip()
|
50
51
|
|
51
|
-
text_identifier = et_element.get("TI")
|
52
|
-
|
53
52
|
external_docs = \
|
54
53
|
[
|
55
54
|
odxrequire(ExternalDoc.from_et(ed, doc_frags)) for ed in et_element.iterfind("EXTERNAL-DOCS/EXTERNAL-DOC")
|
56
55
|
]
|
56
|
+
|
57
|
+
text_identifier = et_element.attrib.get("TI")
|
58
|
+
|
57
59
|
return Description(text=text, text_identifier=text_identifier, external_docs=external_docs)
|
58
60
|
|
59
61
|
@staticmethod
|
@@ -18,6 +18,10 @@ class DetermineNumberOfItems:
|
|
18
18
|
bit_position: Optional[int]
|
19
19
|
dop_ref: OdxLinkRef
|
20
20
|
|
21
|
+
@property
|
22
|
+
def dop(self) -> DataObjectProperty:
|
23
|
+
return self._dop
|
24
|
+
|
21
25
|
@staticmethod
|
22
26
|
def from_et(et_element: ElementTree.Element,
|
23
27
|
doc_frags: List[OdxDocFragment]) -> "DetermineNumberOfItems":
|
@@ -40,7 +44,3 @@ class DetermineNumberOfItems:
|
|
40
44
|
|
41
45
|
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
42
46
|
pass
|
43
|
-
|
44
|
-
@property
|
45
|
-
def dop(self) -> DataObjectProperty:
|
46
|
-
return self._dop
|
odxtools/diagcodedtype.py
CHANGED
@@ -22,21 +22,24 @@ DctType = Literal[
|
|
22
22
|
|
23
23
|
@dataclass
|
24
24
|
class DiagCodedType:
|
25
|
-
|
26
|
-
base_data_type: DataType
|
27
25
|
base_type_encoding: Optional[Encoding]
|
26
|
+
base_data_type: DataType
|
27
|
+
|
28
28
|
is_highlow_byte_order_raw: Optional[bool]
|
29
29
|
|
30
|
+
@property
|
31
|
+
def dct_type(self) -> DctType:
|
32
|
+
odxraise(f"Class {type(self).__name__} does not override required method "
|
33
|
+
f"dct_type()", NotImplementedError)
|
34
|
+
return cast(DctType, None)
|
35
|
+
|
36
|
+
@property
|
37
|
+
def is_highlow_byte_order(self) -> bool:
|
38
|
+
return self.is_highlow_byte_order_raw in [None, True]
|
39
|
+
|
30
40
|
@staticmethod
|
31
41
|
def from_et(et_element: ElementTree.Element,
|
32
42
|
doc_frags: List[OdxDocFragment]) -> "DiagCodedType":
|
33
|
-
base_data_type_str = odxrequire(et_element.get("BASE-DATA-TYPE"))
|
34
|
-
try:
|
35
|
-
base_data_type = DataType(base_data_type_str)
|
36
|
-
except ValueError:
|
37
|
-
odxraise(f"Unknown base data type {base_data_type_str}")
|
38
|
-
base_data_type = cast(DataType, None)
|
39
|
-
|
40
43
|
base_type_encoding = None
|
41
44
|
if (base_type_encoding_str := et_element.get("BASE-TYPE-ENCODING")) is not None:
|
42
45
|
try:
|
@@ -44,11 +47,18 @@ class DiagCodedType:
|
|
44
47
|
except ValueError:
|
45
48
|
odxraise(f"Encountered unknown BASE-TYPE-ENCODING '{base_type_encoding_str}'")
|
46
49
|
|
50
|
+
base_data_type_str = odxrequire(et_element.get("BASE-DATA-TYPE"))
|
51
|
+
try:
|
52
|
+
base_data_type = DataType(base_data_type_str)
|
53
|
+
except ValueError:
|
54
|
+
odxraise(f"Unknown base data type {base_data_type_str}")
|
55
|
+
base_data_type = cast(DataType, None)
|
56
|
+
|
47
57
|
is_highlow_byte_order_raw = odxstr_to_bool(et_element.get("IS-HIGHLOW-BYTE-ORDER"))
|
48
58
|
|
49
59
|
return DiagCodedType(
|
50
|
-
base_data_type=base_data_type,
|
51
60
|
base_type_encoding=base_type_encoding,
|
61
|
+
base_data_type=base_data_type,
|
52
62
|
is_highlow_byte_order_raw=is_highlow_byte_order_raw)
|
53
63
|
|
54
64
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]: # noqa: B027
|
@@ -65,16 +75,6 @@ class DiagCodedType:
|
|
65
75
|
def get_static_bit_length(self) -> Optional[int]:
|
66
76
|
return None
|
67
77
|
|
68
|
-
@property
|
69
|
-
def dct_type(self) -> DctType:
|
70
|
-
odxraise(f"Class {type(self).__name__} does not override required method "
|
71
|
-
f"dct_type()", NotImplementedError)
|
72
|
-
return cast(DctType, None)
|
73
|
-
|
74
|
-
@property
|
75
|
-
def is_highlow_byte_order(self) -> bool:
|
76
|
-
return self.is_highlow_byte_order_raw in [None, True]
|
77
|
-
|
78
78
|
def _minimal_byte_length_of(self, internal_value: Union[bytes, str]) -> int:
|
79
79
|
"""Helper method to get the minimal byte length.
|
80
80
|
(needed for LeadingLength- and MinMaxLengthType)
|
odxtools/diagcomm.py
CHANGED
@@ -12,10 +12,12 @@ from .functionalclass import FunctionalClass
|
|
12
12
|
from .nameditemlist import NamedItemList
|
13
13
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
14
14
|
from .odxtypes import odxstr_to_bool
|
15
|
+
from .preconditionstateref import PreConditionStateRef
|
15
16
|
from .snrefcontext import SnRefContext
|
16
17
|
from .specialdatagroup import SpecialDataGroup
|
17
18
|
from .state import State
|
18
19
|
from .statetransition import StateTransition
|
20
|
+
from .statetransitionref import StateTransitionRef
|
19
21
|
from .utils import dataclass_fields_asdict
|
20
22
|
|
21
23
|
if TYPE_CHECKING:
|
@@ -61,8 +63,8 @@ class DiagComm(IdentifiableElement):
|
|
61
63
|
audience: Optional[Audience]
|
62
64
|
protocol_snrefs: List[str]
|
63
65
|
related_diag_comm_refs: List[RelatedDiagCommRef]
|
64
|
-
pre_condition_state_refs: List[
|
65
|
-
state_transition_refs: List[
|
66
|
+
pre_condition_state_refs: List[PreConditionStateRef]
|
67
|
+
state_transition_refs: List[StateTransitionRef]
|
66
68
|
|
67
69
|
# attributes
|
68
70
|
semantic: Optional[str]
|
@@ -71,6 +73,38 @@ class DiagComm(IdentifiableElement):
|
|
71
73
|
is_executable_raw: Optional[bool]
|
72
74
|
is_final_raw: Optional[bool]
|
73
75
|
|
76
|
+
@property
|
77
|
+
def functional_classes(self) -> NamedItemList[FunctionalClass]:
|
78
|
+
return self._functional_classes
|
79
|
+
|
80
|
+
@property
|
81
|
+
def protocols(self) -> NamedItemList["Protocol"]:
|
82
|
+
return self._protocols
|
83
|
+
|
84
|
+
@property
|
85
|
+
def related_diag_comms(self) -> NamedItemList["DiagComm"]:
|
86
|
+
return self._related_diag_comms
|
87
|
+
|
88
|
+
@property
|
89
|
+
def pre_condition_states(self) -> NamedItemList[State]:
|
90
|
+
return self._pre_condition_states
|
91
|
+
|
92
|
+
@property
|
93
|
+
def state_transitions(self) -> NamedItemList[StateTransition]:
|
94
|
+
return self._state_transitions
|
95
|
+
|
96
|
+
@property
|
97
|
+
def is_mandatory(self) -> bool:
|
98
|
+
return self.is_mandatory_raw is True
|
99
|
+
|
100
|
+
@property
|
101
|
+
def is_executable(self) -> bool:
|
102
|
+
return self.is_executable_raw in (None, True)
|
103
|
+
|
104
|
+
@property
|
105
|
+
def is_final(self) -> bool:
|
106
|
+
return self.is_final_raw is True
|
107
|
+
|
74
108
|
@staticmethod
|
75
109
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "DiagComm":
|
76
110
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
@@ -100,27 +134,27 @@ class DiagComm(IdentifiableElement):
|
|
100
134
|
]
|
101
135
|
|
102
136
|
pre_condition_state_refs = [
|
103
|
-
|
137
|
+
PreConditionStateRef.from_et(el, doc_frags)
|
104
138
|
for el in et_element.iterfind("PRE-CONDITION-STATE-REFS/PRE-CONDITION-STATE-REF")
|
105
139
|
]
|
106
140
|
|
107
141
|
state_transition_refs = [
|
108
|
-
|
142
|
+
StateTransitionRef.from_et(el, doc_frags)
|
109
143
|
for el in et_element.iterfind("STATE-TRANSITION-REFS/STATE-TRANSITION-REF")
|
110
144
|
]
|
111
145
|
|
112
|
-
semantic = et_element.get("SEMANTIC")
|
146
|
+
semantic = et_element.attrib.get("SEMANTIC")
|
113
147
|
|
114
148
|
diagnostic_class: Optional[DiagClassType] = None
|
115
|
-
if (diagnostic_class_str := et_element.get("DIAGNOSTIC-CLASS")) is not None:
|
149
|
+
if (diagnostic_class_str := et_element.attrib.get("DIAGNOSTIC-CLASS")) is not None:
|
116
150
|
try:
|
117
151
|
diagnostic_class = DiagClassType(diagnostic_class_str)
|
118
152
|
except ValueError:
|
119
153
|
odxraise(f"Encountered unknown diagnostic class type '{diagnostic_class_str}'")
|
120
154
|
|
121
|
-
is_mandatory_raw = odxstr_to_bool(et_element.get("IS-MANDATORY"))
|
122
|
-
is_executable_raw = odxstr_to_bool(et_element.get("IS-EXECUTABLE"))
|
123
|
-
is_final_raw = odxstr_to_bool(et_element.get("IS-FINAL"))
|
155
|
+
is_mandatory_raw = odxstr_to_bool(et_element.attrib.get("IS-MANDATORY"))
|
156
|
+
is_executable_raw = odxstr_to_bool(et_element.attrib.get("IS-EXECUTABLE"))
|
157
|
+
is_final_raw = odxstr_to_bool(et_element.attrib.get("IS-FINAL"))
|
124
158
|
|
125
159
|
return DiagComm(
|
126
160
|
admin_data=admin_data,
|
@@ -138,38 +172,6 @@ class DiagComm(IdentifiableElement):
|
|
138
172
|
is_final_raw=is_final_raw,
|
139
173
|
**kwargs)
|
140
174
|
|
141
|
-
@property
|
142
|
-
def functional_classes(self) -> NamedItemList[FunctionalClass]:
|
143
|
-
return self._functional_classes
|
144
|
-
|
145
|
-
@property
|
146
|
-
def protocols(self) -> NamedItemList["Protocol"]:
|
147
|
-
return self._protocols
|
148
|
-
|
149
|
-
@property
|
150
|
-
def related_diag_comms(self) -> NamedItemList["DiagComm"]:
|
151
|
-
return self._related_diag_comms
|
152
|
-
|
153
|
-
@property
|
154
|
-
def pre_condition_states(self) -> NamedItemList[State]:
|
155
|
-
return self._pre_condition_states
|
156
|
-
|
157
|
-
@property
|
158
|
-
def state_transitions(self) -> NamedItemList[StateTransition]:
|
159
|
-
return self._state_transitions
|
160
|
-
|
161
|
-
@property
|
162
|
-
def is_mandatory(self) -> bool:
|
163
|
-
return self.is_mandatory_raw is True
|
164
|
-
|
165
|
-
@property
|
166
|
-
def is_executable(self) -> bool:
|
167
|
-
return self.is_executable_raw in (None, True)
|
168
|
-
|
169
|
-
@property
|
170
|
-
def is_final(self) -> bool:
|
171
|
-
return self.is_final_raw is True
|
172
|
-
|
173
175
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
174
176
|
result = {self.odx_id: self}
|
175
177
|
|
@@ -182,6 +184,12 @@ class DiagComm(IdentifiableElement):
|
|
182
184
|
if self.audience is not None:
|
183
185
|
result.update(self.audience._build_odxlinks())
|
184
186
|
|
187
|
+
for pc_ref in self.pre_condition_state_refs:
|
188
|
+
result.update(pc_ref._build_odxlinks())
|
189
|
+
|
190
|
+
for st_ref in self.state_transition_refs:
|
191
|
+
result.update(st_ref._build_odxlinks())
|
192
|
+
|
185
193
|
return result
|
186
194
|
|
187
195
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
@@ -194,6 +202,12 @@ class DiagComm(IdentifiableElement):
|
|
194
202
|
for sdg in self.sdgs:
|
195
203
|
sdg._resolve_odxlinks(odxlinks)
|
196
204
|
|
205
|
+
for pc_ref in self.pre_condition_state_refs:
|
206
|
+
pc_ref._resolve_odxlinks(odxlinks)
|
207
|
+
|
208
|
+
for st_ref in self.state_transition_refs:
|
209
|
+
st_ref._resolve_odxlinks(odxlinks)
|
210
|
+
|
197
211
|
self._related_diag_comms = NamedItemList(
|
198
212
|
[odxlinks.resolve(dc_ref, DiagComm) for dc_ref in self.related_diag_comm_refs])
|
199
213
|
self._functional_classes = NamedItemList(
|
@@ -213,6 +227,12 @@ class DiagComm(IdentifiableElement):
|
|
213
227
|
for sdg in self.sdgs:
|
214
228
|
sdg._resolve_snrefs(context)
|
215
229
|
|
230
|
+
for pc_ref in self.pre_condition_state_refs:
|
231
|
+
pc_ref._resolve_snrefs(context)
|
232
|
+
|
233
|
+
for st_ref in self.state_transition_refs:
|
234
|
+
st_ref._resolve_snrefs(context)
|
235
|
+
|
216
236
|
if TYPE_CHECKING:
|
217
237
|
diag_layer = odxrequire(context.diag_layer)
|
218
238
|
self._protocols = NamedItemList([
|
@@ -5,7 +5,6 @@ from typing import Any, Dict, List, Optional
|
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from .admindata import AdminData
|
8
|
-
from .basicstructure import BasicStructure
|
9
8
|
from .dataobjectproperty import DataObjectProperty
|
10
9
|
from .dopbase import DopBase
|
11
10
|
from .dtcdop import DtcDop
|
@@ -14,7 +13,6 @@ from .dynamiclengthfield import DynamicLengthField
|
|
14
13
|
from .endofpdufield import EndOfPduField
|
15
14
|
from .environmentdata import EnvironmentData
|
16
15
|
from .environmentdatadescription import EnvironmentDataDescription
|
17
|
-
from .exceptions import odxraise
|
18
16
|
from .multiplexer import Multiplexer
|
19
17
|
from .nameditemlist import NamedItemList
|
20
18
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
@@ -32,7 +30,7 @@ class DiagDataDictionarySpec:
|
|
32
30
|
dtc_dops: NamedItemList[DtcDop]
|
33
31
|
env_data_descs: NamedItemList[EnvironmentDataDescription]
|
34
32
|
data_object_props: NamedItemList[DataObjectProperty]
|
35
|
-
structures: NamedItemList[
|
33
|
+
structures: NamedItemList[Structure]
|
36
34
|
static_fields: NamedItemList[StaticField]
|
37
35
|
dynamic_length_fields: NamedItemList[DynamicLengthField]
|
38
36
|
dynamic_endmarker_fields: NamedItemList[DynamicEndmarkerField]
|
@@ -43,21 +41,6 @@ class DiagDataDictionarySpec:
|
|
43
41
|
tables: NamedItemList[Table]
|
44
42
|
sdgs: List[SpecialDataGroup]
|
45
43
|
|
46
|
-
def __post_init__(self) -> None:
|
47
|
-
self._all_data_object_properties: NamedItemList[DopBase] = NamedItemList(
|
48
|
-
chain(
|
49
|
-
self.dtc_dops,
|
50
|
-
self.env_data_descs,
|
51
|
-
self.data_object_props,
|
52
|
-
self.structures,
|
53
|
-
self.static_fields,
|
54
|
-
self.dynamic_length_fields,
|
55
|
-
self.dynamic_endmarker_fields,
|
56
|
-
self.end_of_pdu_fields,
|
57
|
-
self.muxs,
|
58
|
-
self.env_datas,
|
59
|
-
))
|
60
|
-
|
61
44
|
@staticmethod
|
62
45
|
def from_et(et_element: ElementTree.Element,
|
63
46
|
doc_frags: List[OdxDocFragment]) -> "DiagDataDictionarySpec":
|
@@ -65,72 +48,70 @@ class DiagDataDictionarySpec:
|
|
65
48
|
if (admin_data_elem := et_element.find("ADMIN-DATA")) is not None:
|
66
49
|
admin_data = AdminData.from_et(admin_data_elem, doc_frags)
|
67
50
|
|
68
|
-
dtc_dops = [
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
odxraise()
|
73
|
-
dtc_dops.append(dtc_dop)
|
51
|
+
dtc_dops = NamedItemList([
|
52
|
+
DtcDop.from_et(dtc_dop_elem, doc_frags)
|
53
|
+
for dtc_dop_elem in et_element.iterfind("DTC-DOPS/DTC-DOP")
|
54
|
+
])
|
74
55
|
|
75
|
-
env_data_descs = [
|
56
|
+
env_data_descs = NamedItemList([
|
76
57
|
EnvironmentDataDescription.from_et(env_data_desc_element, doc_frags)
|
77
58
|
for env_data_desc_element in et_element.iterfind("ENV-DATA-DESCS/ENV-DATA-DESC")
|
78
|
-
]
|
59
|
+
])
|
79
60
|
|
80
|
-
data_object_props = [
|
61
|
+
data_object_props = NamedItemList([
|
81
62
|
DataObjectProperty.from_et(dop_element, doc_frags)
|
82
63
|
for dop_element in et_element.iterfind("DATA-OBJECT-PROPS/DATA-OBJECT-PROP")
|
83
|
-
]
|
64
|
+
])
|
84
65
|
|
85
|
-
structures = [
|
66
|
+
structures = NamedItemList([
|
86
67
|
Structure.from_et(structure_element, doc_frags)
|
87
68
|
for structure_element in et_element.iterfind("STRUCTURES/STRUCTURE")
|
88
|
-
]
|
69
|
+
])
|
89
70
|
|
90
|
-
static_fields = [
|
71
|
+
static_fields = NamedItemList([
|
91
72
|
StaticField.from_et(dl_element, doc_frags)
|
92
73
|
for dl_element in et_element.iterfind("STATIC-FIELDS/STATIC-FIELD")
|
93
|
-
]
|
74
|
+
])
|
94
75
|
|
95
|
-
dynamic_length_fields = [
|
76
|
+
dynamic_length_fields = NamedItemList([
|
96
77
|
DynamicLengthField.from_et(dl_element, doc_frags)
|
97
78
|
for dl_element in et_element.iterfind("DYNAMIC-LENGTH-FIELDS/DYNAMIC-LENGTH-FIELD")
|
98
|
-
]
|
79
|
+
])
|
99
80
|
|
100
|
-
dynamic_endmarker_fields = [
|
81
|
+
dynamic_endmarker_fields = NamedItemList([
|
101
82
|
DynamicEndmarkerField.from_et(dl_element, doc_frags) for dl_element in
|
102
83
|
et_element.iterfind("DYNAMIC-ENDMARKER-FIELDS/DYNAMIC-ENDMARKER-FIELD")
|
103
|
-
]
|
84
|
+
])
|
104
85
|
|
105
|
-
end_of_pdu_fields = [
|
86
|
+
end_of_pdu_fields = NamedItemList([
|
106
87
|
EndOfPduField.from_et(eofp_element, doc_frags)
|
107
88
|
for eofp_element in et_element.iterfind("END-OF-PDU-FIELDS/END-OF-PDU-FIELD")
|
108
|
-
]
|
89
|
+
])
|
109
90
|
|
110
|
-
muxs = [
|
91
|
+
muxs = NamedItemList([
|
111
92
|
Multiplexer.from_et(mux_element, doc_frags)
|
112
93
|
for mux_element in et_element.iterfind("MUXS/MUX")
|
113
|
-
]
|
94
|
+
])
|
114
95
|
|
115
96
|
env_data_elements = chain(
|
116
97
|
et_element.iterfind("ENV-DATAS/ENV-DATA"),
|
117
98
|
# ODX 2.0.0 says ENV-DATA-DESC could contain a list of ENV-DATAS
|
118
99
|
et_element.iterfind("ENV-DATA-DESCS/ENV-DATA-DESC/ENV-DATAS/ENV-DATA"),
|
119
100
|
)
|
120
|
-
env_datas = [
|
101
|
+
env_datas = NamedItemList([
|
121
102
|
EnvironmentData.from_et(env_data_element, doc_frags)
|
122
103
|
for env_data_element in env_data_elements
|
123
|
-
]
|
104
|
+
])
|
124
105
|
|
125
106
|
if (spec_elem := et_element.find("UNIT-SPEC")) is not None:
|
126
107
|
unit_spec = UnitSpec.from_et(spec_elem, doc_frags)
|
127
108
|
else:
|
128
109
|
unit_spec = None
|
129
110
|
|
130
|
-
tables = [
|
111
|
+
tables = NamedItemList([
|
131
112
|
Table.from_et(table_element, doc_frags)
|
132
113
|
for table_element in et_element.iterfind("TABLES/TABLE")
|
133
|
-
]
|
114
|
+
])
|
134
115
|
|
135
116
|
sdgs = [
|
136
117
|
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
|
@@ -138,21 +119,36 @@ class DiagDataDictionarySpec:
|
|
138
119
|
|
139
120
|
return DiagDataDictionarySpec(
|
140
121
|
admin_data=admin_data,
|
141
|
-
dtc_dops=
|
142
|
-
env_data_descs=
|
143
|
-
data_object_props=
|
144
|
-
structures=
|
145
|
-
static_fields=
|
146
|
-
dynamic_length_fields=
|
147
|
-
dynamic_endmarker_fields=
|
148
|
-
end_of_pdu_fields=
|
149
|
-
muxs=
|
150
|
-
env_datas=
|
122
|
+
dtc_dops=dtc_dops,
|
123
|
+
env_data_descs=env_data_descs,
|
124
|
+
data_object_props=data_object_props,
|
125
|
+
structures=structures,
|
126
|
+
static_fields=static_fields,
|
127
|
+
dynamic_length_fields=dynamic_length_fields,
|
128
|
+
dynamic_endmarker_fields=dynamic_endmarker_fields,
|
129
|
+
end_of_pdu_fields=end_of_pdu_fields,
|
130
|
+
muxs=muxs,
|
131
|
+
env_datas=env_datas,
|
151
132
|
unit_spec=unit_spec,
|
152
|
-
tables=
|
133
|
+
tables=tables,
|
153
134
|
sdgs=sdgs,
|
154
135
|
)
|
155
136
|
|
137
|
+
def __post_init__(self) -> None:
|
138
|
+
self._all_data_object_properties: NamedItemList[DopBase] = NamedItemList(
|
139
|
+
chain(
|
140
|
+
self.dtc_dops,
|
141
|
+
self.env_data_descs,
|
142
|
+
self.data_object_props,
|
143
|
+
self.structures,
|
144
|
+
self.static_fields,
|
145
|
+
self.dynamic_length_fields,
|
146
|
+
self.dynamic_endmarker_fields,
|
147
|
+
self.end_of_pdu_fields,
|
148
|
+
self.muxs,
|
149
|
+
self.env_datas,
|
150
|
+
))
|
151
|
+
|
156
152
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
157
153
|
# note that DataDictionarySpec objects do not exhibit an ODXLINK id.
|
158
154
|
odxlinks = {}
|