odxtools 9.6.0__py3-none-any.whl → 9.7.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/addressing.py +8 -0
- odxtools/basecomparam.py +2 -15
- odxtools/basicstructure.py +4 -3
- odxtools/codec.py +1 -184
- odxtools/commrelation.py +1 -8
- odxtools/commrelationvaluetype.py +9 -0
- odxtools/compositecodec.py +191 -0
- odxtools/compumethods/compucategory.py +13 -0
- odxtools/compumethods/compucodecompumethod.py +2 -1
- odxtools/compumethods/compumethod.py +1 -12
- odxtools/compumethods/intervaltype.py +8 -0
- odxtools/compumethods/limit.py +1 -7
- odxtools/compumethods/linearcompumethod.py +2 -1
- odxtools/compumethods/ratfunccompumethod.py +2 -1
- odxtools/compumethods/scalelinearcompumethod.py +3 -2
- odxtools/compumethods/scaleratfunccompumethod.py +2 -1
- odxtools/compumethods/tabintpcompumethod.py +4 -2
- odxtools/compumethods/texttablecompumethod.py +2 -1
- odxtools/description.py +1 -17
- odxtools/diagclasstype.py +11 -0
- odxtools/diagcomm.py +2 -25
- odxtools/diagservice.py +3 -79
- odxtools/dtcconnector.py +45 -0
- odxtools/dtcdop.py +2 -47
- odxtools/dyndefinedspec.py +3 -155
- odxtools/dyniddefmodeinfo.py +161 -0
- odxtools/envdataconnector.py +49 -0
- odxtools/externalaccessmethod.py +23 -0
- odxtools/externaldoc.py +23 -0
- odxtools/linkeddtcdop.py +62 -0
- odxtools/minmaxlengthtype.py +1 -7
- odxtools/parameterinfo.py +1 -1
- odxtools/parameters/rowfragment.py +7 -0
- odxtools/parameters/tableentryparameter.py +1 -6
- odxtools/physicaltype.py +1 -8
- odxtools/posresponsesuppressible.py +73 -0
- odxtools/radix.py +9 -0
- odxtools/relateddiagcommref.py +23 -0
- odxtools/request.py +5 -3
- odxtools/response.py +5 -3
- odxtools/scaleconstr.py +1 -8
- odxtools/standardizationlevel.py +9 -0
- odxtools/standardlengthtype.py +2 -11
- odxtools/statetransition.py +1 -14
- odxtools/subcomponent.py +8 -241
- odxtools/subcomponentparamconnector.py +103 -0
- odxtools/subcomponentpattern.py +42 -0
- odxtools/table.py +3 -41
- odxtools/tablediagcommconnector.py +47 -0
- odxtools/tablerowconnector.py +46 -0
- odxtools/templates/macros/printService.xml.jinja2 +2 -1
- odxtools/termination.py +8 -0
- odxtools/transmode.py +9 -0
- odxtools/unitgroup.py +1 -6
- odxtools/unitgroupcategory.py +7 -0
- odxtools/usage.py +9 -0
- odxtools/utils.py +29 -0
- odxtools/validtype.py +9 -0
- odxtools/version.py +2 -2
- {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/METADATA +1 -1
- {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/RECORD +65 -39
- {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/WHEEL +0 -0
- {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/entry_points.txt +0 -0
- {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/licenses/LICENSE +0 -0
- {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/top_level.txt +0 -0
odxtools/externaldoc.py
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import List, Optional
|
3
|
+
from xml.etree import ElementTree
|
4
|
+
|
5
|
+
from .exceptions import odxrequire
|
6
|
+
from .odxlink import OdxDocFragment
|
7
|
+
|
8
|
+
|
9
|
+
@dataclass
|
10
|
+
class ExternalDoc:
|
11
|
+
description: Optional[str]
|
12
|
+
href: str
|
13
|
+
|
14
|
+
@staticmethod
|
15
|
+
def from_et(et_element: Optional[ElementTree.Element],
|
16
|
+
doc_frags: List[OdxDocFragment]) -> Optional["ExternalDoc"]:
|
17
|
+
if et_element is None:
|
18
|
+
return None
|
19
|
+
|
20
|
+
description = et_element.text
|
21
|
+
href = odxrequire(et_element.get("HREF"))
|
22
|
+
|
23
|
+
return ExternalDoc(description=description, href=href)
|
odxtools/linkeddtcdop.py
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, List
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from .diagnostictroublecode import DiagnosticTroubleCode
|
7
|
+
from .exceptions import odxrequire
|
8
|
+
from .nameditemlist import NamedItemList
|
9
|
+
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
|
10
|
+
from .snrefcontext import SnRefContext
|
11
|
+
|
12
|
+
if TYPE_CHECKING:
|
13
|
+
from .dtcdop import DtcDop
|
14
|
+
|
15
|
+
|
16
|
+
@dataclass
|
17
|
+
class LinkedDtcDop:
|
18
|
+
not_inherited_dtc_snrefs: List[str]
|
19
|
+
dtc_dop_ref: OdxLinkRef
|
20
|
+
|
21
|
+
@property
|
22
|
+
def not_inherited_dtcs(self) -> NamedItemList[DiagnosticTroubleCode]:
|
23
|
+
return self._not_inherited_dtcs
|
24
|
+
|
25
|
+
@property
|
26
|
+
def dtc_dop(self) -> "DtcDop":
|
27
|
+
return self._dtc_dop
|
28
|
+
|
29
|
+
@property
|
30
|
+
def short_name(self) -> str:
|
31
|
+
return self._dtc_dop.short_name
|
32
|
+
|
33
|
+
@staticmethod
|
34
|
+
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "LinkedDtcDop":
|
35
|
+
not_inherited_dtc_snrefs = [
|
36
|
+
odxrequire(el.get("SHORT-NAME"))
|
37
|
+
for el in et_element.iterfind("NOT-INHERITED-DTC-SNREFS/"
|
38
|
+
"NOT-INHERITED-DTC-SNREF")
|
39
|
+
]
|
40
|
+
|
41
|
+
dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), doc_frags))
|
42
|
+
|
43
|
+
return LinkedDtcDop(
|
44
|
+
not_inherited_dtc_snrefs=not_inherited_dtc_snrefs, dtc_dop_ref=dtc_dop_ref)
|
45
|
+
|
46
|
+
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
47
|
+
return {}
|
48
|
+
|
49
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
50
|
+
if TYPE_CHECKING:
|
51
|
+
self._dtc_dop = odxlinks.resolve(self.dtc_dop_ref, DtcDop)
|
52
|
+
else:
|
53
|
+
self._dtc_dop = odxlinks.resolve(self.dtc_dop_ref)
|
54
|
+
|
55
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
56
|
+
dtc_dop = self._dtc_dop
|
57
|
+
not_inherited_dtcs = [
|
58
|
+
resolve_snref(ni_snref, dtc_dop.dtcs, DiagnosticTroubleCode)
|
59
|
+
for ni_snref in self.not_inherited_dtc_snrefs
|
60
|
+
]
|
61
|
+
|
62
|
+
self._not_inherited_dtcs = NamedItemList(not_inherited_dtcs)
|
odxtools/minmaxlengthtype.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from enum import Enum
|
4
3
|
from typing import List, Optional, cast
|
5
4
|
from xml.etree import ElementTree
|
6
5
|
|
@@ -13,15 +12,10 @@ from .encoding import get_string_encoding
|
|
13
12
|
from .exceptions import DecodeError, EncodeError, odxassert, odxraise, odxrequire
|
14
13
|
from .odxlink import OdxDocFragment
|
15
14
|
from .odxtypes import AtomicOdxType, BytesTypes, DataType
|
15
|
+
from .termination import Termination
|
16
16
|
from .utils import dataclass_fields_asdict
|
17
17
|
|
18
18
|
|
19
|
-
class Termination(Enum):
|
20
|
-
END_OF_PDU = "END-OF-PDU"
|
21
|
-
ZERO = "ZERO"
|
22
|
-
HEX_FF = "HEX-FF"
|
23
|
-
|
24
|
-
|
25
19
|
@dataclass
|
26
20
|
class MinMaxLengthType(DiagCodedType):
|
27
21
|
max_length: Optional[int]
|
odxtools/parameterinfo.py
CHANGED
@@ -5,7 +5,7 @@ from typing import Iterable
|
|
5
5
|
|
6
6
|
from .compumethods.compucodecompumethod import CompuCodeCompuMethod
|
7
7
|
from .compumethods.identicalcompumethod import IdenticalCompuMethod
|
8
|
-
from .compumethods.
|
8
|
+
from .compumethods.intervaltype import IntervalType
|
9
9
|
from .compumethods.linearcompumethod import LinearCompuMethod
|
10
10
|
from .compumethods.linearsegment import LinearSegment
|
11
11
|
from .compumethods.ratfunccompumethod import RatFuncCompuMethod
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from enum import Enum
|
4
3
|
from typing import TYPE_CHECKING, List, Optional, cast
|
5
4
|
from xml.etree import ElementTree
|
6
5
|
|
@@ -13,16 +12,12 @@ from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef
|
|
13
12
|
from ..odxtypes import ParameterValue
|
14
13
|
from ..utils import dataclass_fields_asdict
|
15
14
|
from .parameter import Parameter, ParameterType
|
15
|
+
from .rowfragment import RowFragment
|
16
16
|
|
17
17
|
if TYPE_CHECKING:
|
18
18
|
from ..tablerow import TableRow
|
19
19
|
|
20
20
|
|
21
|
-
class RowFragment(Enum):
|
22
|
-
KEY = "KEY"
|
23
|
-
STRUCT = "STRUCT"
|
24
|
-
|
25
|
-
|
26
21
|
@dataclass
|
27
22
|
class TableEntryParameter(Parameter):
|
28
23
|
target: RowFragment
|
odxtools/physicaltype.py
CHANGED
@@ -1,19 +1,12 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from enum import IntEnum
|
4
3
|
from typing import List, Optional
|
5
4
|
from xml.etree import ElementTree
|
6
5
|
|
7
6
|
from .exceptions import odxraise
|
8
7
|
from .odxlink import OdxDocFragment
|
9
8
|
from .odxtypes import DataType
|
10
|
-
|
11
|
-
|
12
|
-
class Radix(IntEnum):
|
13
|
-
HEX = 16
|
14
|
-
DEC = 10
|
15
|
-
BIN = 2
|
16
|
-
OCT = 8
|
9
|
+
from .radix import Radix
|
17
10
|
|
18
11
|
|
19
12
|
@dataclass
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import List, Optional
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from .exceptions import odxrequire
|
7
|
+
from .odxlink import OdxDocFragment
|
8
|
+
from .utils import read_hex_binary
|
9
|
+
|
10
|
+
|
11
|
+
# note that the spec has a typo here: it calls the corresponding
|
12
|
+
# XML tag POS-RESPONSE-SUPPRESSABLE...
|
13
|
+
@dataclass
|
14
|
+
class PosResponseSuppressible:
|
15
|
+
bit_mask: int
|
16
|
+
|
17
|
+
coded_const_snref: Optional[str]
|
18
|
+
coded_const_snpathref: Optional[str]
|
19
|
+
|
20
|
+
value_snref: Optional[str]
|
21
|
+
value_snpathref: Optional[str]
|
22
|
+
|
23
|
+
phys_const_snref: Optional[str]
|
24
|
+
phys_const_snpathref: Optional[str]
|
25
|
+
|
26
|
+
table_key_snref: Optional[str]
|
27
|
+
table_key_snpathref: Optional[str]
|
28
|
+
|
29
|
+
@staticmethod
|
30
|
+
def from_et(et_element: ElementTree.Element,
|
31
|
+
doc_frags: List[OdxDocFragment]) -> "PosResponseSuppressible":
|
32
|
+
|
33
|
+
bit_mask = odxrequire(read_hex_binary(et_element.find("BIT-MASK")))
|
34
|
+
|
35
|
+
coded_const_snref = None
|
36
|
+
if (cc_snref_elem := et_element.find("CODED-CONST-SNREF")) is not None:
|
37
|
+
coded_const_snref = cc_snref_elem.attrib["SHORT-NAME"]
|
38
|
+
coded_const_snpathref = None
|
39
|
+
if (cc_snpathref_elem := et_element.find("CODED-CONST-SNPATHREF")) is not None:
|
40
|
+
coded_const_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
|
41
|
+
|
42
|
+
value_snref = None
|
43
|
+
if (cc_snref_elem := et_element.find("VALUE-SNREF")) is not None:
|
44
|
+
value_snref = cc_snref_elem.attrib["SHORT-NAME"]
|
45
|
+
value_snpathref = None
|
46
|
+
if (cc_snpathref_elem := et_element.find("VALUE-SNPATHREF")) is not None:
|
47
|
+
value_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
|
48
|
+
|
49
|
+
phys_const_snref = None
|
50
|
+
if (cc_snref_elem := et_element.find("PHYS-CONST-SNREF")) is not None:
|
51
|
+
phys_const_snref = cc_snref_elem.attrib["SHORT-NAME"]
|
52
|
+
phys_const_snpathref = None
|
53
|
+
if (cc_snpathref_elem := et_element.find("PHYS-CONST-SNPATHREF")) is not None:
|
54
|
+
phys_const_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
|
55
|
+
|
56
|
+
table_key_snref = None
|
57
|
+
if (cc_snref_elem := et_element.find("TABLE-KEY-SNREF")) is not None:
|
58
|
+
table_key_snref = cc_snref_elem.attrib["SHORT-NAME"]
|
59
|
+
table_key_snpathref = None
|
60
|
+
if (cc_snpathref_elem := et_element.find("TABLE-KEY-SNPATHREF")) is not None:
|
61
|
+
table_key_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
|
62
|
+
|
63
|
+
return PosResponseSuppressible(
|
64
|
+
bit_mask=bit_mask,
|
65
|
+
coded_const_snref=coded_const_snref,
|
66
|
+
coded_const_snpathref=coded_const_snpathref,
|
67
|
+
value_snref=value_snref,
|
68
|
+
value_snpathref=value_snpathref,
|
69
|
+
phys_const_snref=phys_const_snref,
|
70
|
+
phys_const_snpathref=phys_const_snpathref,
|
71
|
+
table_key_snref=table_key_snref,
|
72
|
+
table_key_snpathref=table_key_snpathref,
|
73
|
+
)
|
odxtools/radix.py
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import List
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from .exceptions import odxrequire
|
7
|
+
from .odxlink import OdxDocFragment, OdxLinkRef
|
8
|
+
from .utils import dataclass_fields_asdict
|
9
|
+
|
10
|
+
|
11
|
+
@dataclass
|
12
|
+
class RelatedDiagCommRef(OdxLinkRef):
|
13
|
+
relation_type: str
|
14
|
+
|
15
|
+
@staticmethod
|
16
|
+
def from_et( # type: ignore[override]
|
17
|
+
et_element: ElementTree.Element,
|
18
|
+
doc_frags: List[OdxDocFragment]) -> "RelatedDiagCommRef":
|
19
|
+
kwargs = dataclass_fields_asdict(odxrequire(OdxLinkRef.from_et(et_element, doc_frags)))
|
20
|
+
|
21
|
+
relation_type = odxrequire(et_element.findtext("RELATION-TYPE"))
|
22
|
+
|
23
|
+
return RelatedDiagCommRef(relation_type=relation_type, **kwargs)
|
odxtools/request.py
CHANGED
@@ -4,9 +4,11 @@ from typing import Any, Dict, List, Optional, cast
|
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .admindata import AdminData
|
7
|
-
from .
|
8
|
-
|
9
|
-
|
7
|
+
from .compositecodec import (composite_codec_decode_from_pdu, composite_codec_encode_into_pdu,
|
8
|
+
composite_codec_get_coded_const_prefix,
|
9
|
+
composite_codec_get_free_parameters,
|
10
|
+
composite_codec_get_required_parameters,
|
11
|
+
composite_codec_get_static_bit_length)
|
10
12
|
from .decodestate import DecodeState
|
11
13
|
from .element import IdentifiableElement
|
12
14
|
from .encodestate import EncodeState
|
odxtools/response.py
CHANGED
@@ -5,9 +5,11 @@ from typing import Any, Dict, List, Optional, cast
|
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from .admindata import AdminData
|
8
|
-
from .
|
9
|
-
|
10
|
-
|
8
|
+
from .compositecodec import (composite_codec_decode_from_pdu, composite_codec_encode_into_pdu,
|
9
|
+
composite_codec_get_coded_const_prefix,
|
10
|
+
composite_codec_get_free_parameters,
|
11
|
+
composite_codec_get_required_parameters,
|
12
|
+
composite_codec_get_static_bit_length)
|
11
13
|
from .decodestate import DecodeState
|
12
14
|
from .element import IdentifiableElement
|
13
15
|
from .encodestate import EncodeState
|
odxtools/scaleconstr.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from enum import Enum
|
4
3
|
from typing import List, Optional
|
5
4
|
from xml.etree import ElementTree
|
6
5
|
|
@@ -9,13 +8,7 @@ from .description import Description
|
|
9
8
|
from .exceptions import odxraise, odxrequire
|
10
9
|
from .odxlink import OdxDocFragment
|
11
10
|
from .odxtypes import DataType
|
12
|
-
|
13
|
-
|
14
|
-
class ValidType(Enum):
|
15
|
-
VALID = "VALID"
|
16
|
-
NOT_VALID = "NOT-VALID"
|
17
|
-
NOT_DEFINED = "NOT-DEFINED"
|
18
|
-
NOT_AVAILABLE = "NOT-AVAILABLE"
|
11
|
+
from .validtype import ValidType
|
19
12
|
|
20
13
|
|
21
14
|
@dataclass
|
odxtools/standardlengthtype.py
CHANGED
@@ -11,7 +11,7 @@ from .encodestate import EncodeState
|
|
11
11
|
from .exceptions import odxassert, odxraise, odxrequire
|
12
12
|
from .odxlink import OdxDocFragment
|
13
13
|
from .odxtypes import AtomicOdxType, BytesTypes, DataType, odxstr_to_bool
|
14
|
-
from .utils import dataclass_fields_asdict
|
14
|
+
from .utils import dataclass_fields_asdict, read_hex_binary
|
15
15
|
|
16
16
|
|
17
17
|
@dataclass
|
@@ -36,16 +36,7 @@ class StandardLengthType(DiagCodedType):
|
|
36
36
|
kwargs = dataclass_fields_asdict(DiagCodedType.from_et(et_element, doc_frags))
|
37
37
|
|
38
38
|
bit_length = int(odxrequire(et_element.findtext("BIT-LENGTH")))
|
39
|
-
bit_mask =
|
40
|
-
if (bit_mask_str := et_element.findtext("BIT-MASK")) is not None:
|
41
|
-
# The XSD uses the type xsd:hexBinary
|
42
|
-
# xsd:hexBinary allows for leading/trailing whitespace, empty strings, and it only allows an even
|
43
|
-
# number of hex digits, while some of the examples shown in the ODX specification exhibit an
|
44
|
-
# odd number of hex digits.
|
45
|
-
# This causes a validation paradox, so we try to be flexible
|
46
|
-
bit_mask_str = bit_mask_str.strip()
|
47
|
-
if len(bit_mask_str):
|
48
|
-
bit_mask = int(bit_mask_str, 16)
|
39
|
+
bit_mask = read_hex_binary(et_element.find("BIT-MASK"))
|
49
40
|
is_condensed_raw = odxstr_to_bool(et_element.get("IS-CONDENSED"))
|
50
41
|
|
51
42
|
return StandardLengthType(
|
odxtools/statetransition.py
CHANGED
@@ -5,26 +5,13 @@ from xml.etree import ElementTree
|
|
5
5
|
|
6
6
|
from .element import IdentifiableElement
|
7
7
|
from .exceptions import odxrequire
|
8
|
+
from .externalaccessmethod import ExternalAccessMethod
|
8
9
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, resolve_snref
|
9
10
|
from .snrefcontext import SnRefContext
|
10
11
|
from .state import State
|
11
12
|
from .utils import dataclass_fields_asdict
|
12
13
|
|
13
14
|
|
14
|
-
@dataclass
|
15
|
-
class ExternalAccessMethod(IdentifiableElement):
|
16
|
-
method: str
|
17
|
-
|
18
|
-
@staticmethod
|
19
|
-
def from_et(et_element: ElementTree.Element,
|
20
|
-
doc_frags: List[OdxDocFragment]) -> "ExternalAccessMethod":
|
21
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
22
|
-
|
23
|
-
method = odxrequire(et_element.findtext("METHOD"))
|
24
|
-
|
25
|
-
return ExternalAccessMethod(method=method, **kwargs)
|
26
|
-
|
27
|
-
|
28
15
|
@dataclass
|
29
16
|
class StateTransition(IdentifiableElement):
|
30
17
|
"""
|
odxtools/subcomponent.py
CHANGED
@@ -1,252 +1,19 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import
|
3
|
+
from typing import Any, Dict, List, Optional
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
|
-
from .
|
7
|
-
from .
|
8
|
-
from .
|
9
|
-
from .element import IdentifiableElement, NamedElement
|
10
|
-
from .environmentdata import EnvironmentData
|
11
|
-
from .environmentdatadescription import EnvironmentDataDescription
|
12
|
-
from .exceptions import odxassert, odxraise, odxrequire
|
6
|
+
from .dtcconnector import DtcConnector
|
7
|
+
from .element import IdentifiableElement
|
8
|
+
from .envdataconnector import EnvDataConnector
|
13
9
|
from .nameditemlist import NamedItemList
|
14
|
-
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
15
|
-
from .parameters.parameter import Parameter
|
10
|
+
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
16
11
|
from .snrefcontext import SnRefContext
|
17
|
-
from .
|
18
|
-
from .
|
12
|
+
from .subcomponentparamconnector import SubComponentParamConnector
|
13
|
+
from .subcomponentpattern import SubComponentPattern
|
14
|
+
from .tablerowconnector import TableRowConnector
|
19
15
|
from .utils import dataclass_fields_asdict
|
20
16
|
|
21
|
-
if TYPE_CHECKING:
|
22
|
-
from .matchingparameter import MatchingParameter
|
23
|
-
|
24
|
-
|
25
|
-
@dataclass
|
26
|
-
class SubComponentPattern:
|
27
|
-
matching_parameters: List["MatchingParameter"]
|
28
|
-
|
29
|
-
@staticmethod
|
30
|
-
def from_et(et_element: ElementTree.Element,
|
31
|
-
doc_frags: List[OdxDocFragment]) -> "SubComponentPattern":
|
32
|
-
from .matchingparameter import MatchingParameter
|
33
|
-
|
34
|
-
matching_parameters = [
|
35
|
-
MatchingParameter.from_et(el, doc_frags)
|
36
|
-
for el in et_element.iterfind("MATCHING-PARAMETERS/MATCHING-PARAMETER")
|
37
|
-
]
|
38
|
-
|
39
|
-
return SubComponentPattern(matching_parameters=matching_parameters)
|
40
|
-
|
41
|
-
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
42
|
-
result = {}
|
43
|
-
for mp in self.matching_parameters:
|
44
|
-
result.update(mp._build_odxlinks())
|
45
|
-
|
46
|
-
return result
|
47
|
-
|
48
|
-
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
49
|
-
for mp in self.matching_parameters:
|
50
|
-
mp._resolve_odxlinks(odxlinks)
|
51
|
-
|
52
|
-
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
53
|
-
for mp in self.matching_parameters:
|
54
|
-
mp._resolve_snrefs(context)
|
55
|
-
|
56
|
-
|
57
|
-
@dataclass
|
58
|
-
class SubComponentParamConnector(IdentifiableElement):
|
59
|
-
diag_comm_snref: str
|
60
|
-
|
61
|
-
# TODO: we currently only support SNREFs, not SNPATHREFs
|
62
|
-
out_param_if_refs: List[str]
|
63
|
-
in_param_if_refs: List[str]
|
64
|
-
|
65
|
-
@property
|
66
|
-
def service(self) -> DiagService:
|
67
|
-
return self._service
|
68
|
-
|
69
|
-
@property
|
70
|
-
def out_param_ifs(self) -> NamedItemList[Parameter]:
|
71
|
-
return self._out_param_ifs
|
72
|
-
|
73
|
-
@property
|
74
|
-
def in_param_ifs(self) -> NamedItemList[Parameter]:
|
75
|
-
return self._in_param_ifs
|
76
|
-
|
77
|
-
@staticmethod
|
78
|
-
def from_et(et_element: ElementTree.Element,
|
79
|
-
doc_frags: List[OdxDocFragment]) -> "SubComponentParamConnector":
|
80
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
81
|
-
|
82
|
-
diag_comm_snref = odxrequire(
|
83
|
-
odxrequire(et_element.find("DIAG-COMM-SNREF")).get("SHORT-NAME"))
|
84
|
-
|
85
|
-
out_param_if_refs = []
|
86
|
-
for elem in et_element.find("OUT-PARAM-IF-REFS") or []:
|
87
|
-
if elem.tag != "OUT-PARAM-IF-SNREF":
|
88
|
-
odxraise("Currently, only SNREFS are supported for OUT-PARAM-IF-REFS")
|
89
|
-
continue
|
90
|
-
else:
|
91
|
-
odxassert(elem.tag == "OUT-PARAM-IF-SNREF")
|
92
|
-
out_param_if_refs.append(odxrequire(elem.attrib.get("SHORT-NAME")))
|
93
|
-
|
94
|
-
in_param_if_refs = []
|
95
|
-
for elem in et_element.find("IN-PARAM-IF-REFS") or []:
|
96
|
-
if elem.tag != "IN-PARAM-IF-SNREF":
|
97
|
-
odxraise("Currently, only SNREFS are supported for IN-PARAM-IF-REFS")
|
98
|
-
continue
|
99
|
-
else:
|
100
|
-
odxassert(elem.tag == "IN-PARAM-IF-SNREF")
|
101
|
-
in_param_if_refs.append(odxrequire(elem.attrib.get("SHORT-NAME")))
|
102
|
-
|
103
|
-
return SubComponentParamConnector(
|
104
|
-
diag_comm_snref=diag_comm_snref,
|
105
|
-
out_param_if_refs=out_param_if_refs,
|
106
|
-
in_param_if_refs=in_param_if_refs,
|
107
|
-
**kwargs)
|
108
|
-
|
109
|
-
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
110
|
-
return {}
|
111
|
-
|
112
|
-
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
113
|
-
pass
|
114
|
-
|
115
|
-
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
116
|
-
service = resolve_snref(self.diag_comm_snref,
|
117
|
-
odxrequire(context.diag_layer).diag_comms, DiagService)
|
118
|
-
self._service = service
|
119
|
-
|
120
|
-
if self._service.request is not None:
|
121
|
-
odxraise()
|
122
|
-
return
|
123
|
-
if not self._service.positive_responses:
|
124
|
-
odxraise()
|
125
|
-
return
|
126
|
-
|
127
|
-
request = odxrequire(service.request)
|
128
|
-
in_param_ifs = []
|
129
|
-
for x in self.in_param_if_refs:
|
130
|
-
in_param_ifs.append(resolve_snref(x, request.parameters, Parameter))
|
131
|
-
|
132
|
-
# TODO: The output parameters are probably part of a response
|
133
|
-
# (?). If so, they cannot be resolved ahead of time because
|
134
|
-
# the service in question can have multiple responses
|
135
|
-
# associated with it and each of these has its own set of
|
136
|
-
# parameters. In the meantime, we simply use the first
|
137
|
-
# positive response specified.
|
138
|
-
response = service.positive_responses[0]
|
139
|
-
out_param_ifs = []
|
140
|
-
for x in self.out_param_if_refs:
|
141
|
-
out_param_ifs.append(resolve_snref(x, response.parameters, Parameter))
|
142
|
-
|
143
|
-
self._in_param_ifs = NamedItemList(in_param_ifs)
|
144
|
-
self._out_param_ifs = NamedItemList(out_param_ifs)
|
145
|
-
|
146
|
-
|
147
|
-
@dataclass
|
148
|
-
class TableRowConnector(NamedElement):
|
149
|
-
table_ref: OdxLinkRef
|
150
|
-
table_row_snref: str
|
151
|
-
|
152
|
-
@property
|
153
|
-
def table(self) -> Table:
|
154
|
-
return self._table
|
155
|
-
|
156
|
-
@property
|
157
|
-
def table_row(self) -> TableRow:
|
158
|
-
return self._table_row
|
159
|
-
|
160
|
-
@staticmethod
|
161
|
-
def from_et(et_element: ElementTree.Element,
|
162
|
-
doc_frags: List[OdxDocFragment]) -> "TableRowConnector":
|
163
|
-
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
164
|
-
|
165
|
-
table_ref = odxrequire(OdxLinkRef.from_et(et_element.find("TABLE-REF"), doc_frags))
|
166
|
-
table_row_snref_el = odxrequire(et_element.find("TABLE-ROW-SNREF"))
|
167
|
-
table_row_snref = odxrequire(table_row_snref_el.get("SHORT-NAME"))
|
168
|
-
|
169
|
-
return TableRowConnector(table_ref=table_ref, table_row_snref=table_row_snref, **kwargs)
|
170
|
-
|
171
|
-
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
172
|
-
return {}
|
173
|
-
|
174
|
-
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
175
|
-
self._table = odxlinks.resolve(self.table_ref, Table)
|
176
|
-
|
177
|
-
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
178
|
-
self._table_row = resolve_snref(self.table_row_snref, self._table.table_rows, TableRow)
|
179
|
-
|
180
|
-
|
181
|
-
@dataclass
|
182
|
-
class DtcConnector(NamedElement):
|
183
|
-
dtc_dop_ref: OdxLinkRef
|
184
|
-
dtc_snref: str
|
185
|
-
|
186
|
-
@property
|
187
|
-
def dtc_dop(self) -> DtcDop:
|
188
|
-
return self._dtc_dop
|
189
|
-
|
190
|
-
@property
|
191
|
-
def dtc(self) -> DiagnosticTroubleCode:
|
192
|
-
return self._dtc
|
193
|
-
|
194
|
-
@staticmethod
|
195
|
-
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "DtcConnector":
|
196
|
-
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
197
|
-
|
198
|
-
dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), doc_frags))
|
199
|
-
dtc_snref_el = odxrequire(et_element.find("DTC-SNREF"))
|
200
|
-
dtc_snref = odxrequire(dtc_snref_el.get("SHORT-NAME"))
|
201
|
-
|
202
|
-
return DtcConnector(dtc_dop_ref=dtc_dop_ref, dtc_snref=dtc_snref, **kwargs)
|
203
|
-
|
204
|
-
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
205
|
-
return {}
|
206
|
-
|
207
|
-
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
208
|
-
self._dtc_dop = odxlinks.resolve(self.dtc_dop_ref, DtcDop)
|
209
|
-
|
210
|
-
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
211
|
-
self._dtc = resolve_snref(self.dtc_snref, self._dtc_dop.dtcs, DiagnosticTroubleCode)
|
212
|
-
|
213
|
-
|
214
|
-
@dataclass
|
215
|
-
class EnvDataConnector(NamedElement):
|
216
|
-
env_data_desc_ref: OdxLinkRef
|
217
|
-
env_data_snref: str
|
218
|
-
|
219
|
-
@property
|
220
|
-
def env_data_desc(self) -> EnvironmentDataDescription:
|
221
|
-
return self._env_data_desc
|
222
|
-
|
223
|
-
@property
|
224
|
-
def env_data(self) -> EnvironmentData:
|
225
|
-
return self._env_data
|
226
|
-
|
227
|
-
@staticmethod
|
228
|
-
def from_et(et_element: ElementTree.Element,
|
229
|
-
doc_frags: List[OdxDocFragment]) -> "EnvDataConnector":
|
230
|
-
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
|
231
|
-
|
232
|
-
env_data_desc_ref = odxrequire(
|
233
|
-
OdxLinkRef.from_et(et_element.find("ENV-DATA-DESC-REF"), doc_frags))
|
234
|
-
env_data_snref_el = odxrequire(et_element.find("ENV-DATA-SNREF"))
|
235
|
-
env_data_snref = odxrequire(env_data_snref_el.get("SHORT-NAME"))
|
236
|
-
|
237
|
-
return EnvDataConnector(
|
238
|
-
env_data_desc_ref=env_data_desc_ref, env_data_snref=env_data_snref, **kwargs)
|
239
|
-
|
240
|
-
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
241
|
-
return {}
|
242
|
-
|
243
|
-
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
244
|
-
self._env_data_desc = odxlinks.resolve(self.env_data_desc_ref, EnvironmentDataDescription)
|
245
|
-
|
246
|
-
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
247
|
-
self._env_data = resolve_snref(self.env_data_snref, self._env_data_desc.env_datas,
|
248
|
-
EnvironmentData)
|
249
|
-
|
250
17
|
|
251
18
|
@dataclass
|
252
19
|
class SubComponent(IdentifiableElement):
|