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.
Files changed (65) hide show
  1. odxtools/addressing.py +8 -0
  2. odxtools/basecomparam.py +2 -15
  3. odxtools/basicstructure.py +4 -3
  4. odxtools/codec.py +1 -184
  5. odxtools/commrelation.py +1 -8
  6. odxtools/commrelationvaluetype.py +9 -0
  7. odxtools/compositecodec.py +191 -0
  8. odxtools/compumethods/compucategory.py +13 -0
  9. odxtools/compumethods/compucodecompumethod.py +2 -1
  10. odxtools/compumethods/compumethod.py +1 -12
  11. odxtools/compumethods/intervaltype.py +8 -0
  12. odxtools/compumethods/limit.py +1 -7
  13. odxtools/compumethods/linearcompumethod.py +2 -1
  14. odxtools/compumethods/ratfunccompumethod.py +2 -1
  15. odxtools/compumethods/scalelinearcompumethod.py +3 -2
  16. odxtools/compumethods/scaleratfunccompumethod.py +2 -1
  17. odxtools/compumethods/tabintpcompumethod.py +4 -2
  18. odxtools/compumethods/texttablecompumethod.py +2 -1
  19. odxtools/description.py +1 -17
  20. odxtools/diagclasstype.py +11 -0
  21. odxtools/diagcomm.py +2 -25
  22. odxtools/diagservice.py +3 -79
  23. odxtools/dtcconnector.py +45 -0
  24. odxtools/dtcdop.py +2 -47
  25. odxtools/dyndefinedspec.py +3 -155
  26. odxtools/dyniddefmodeinfo.py +161 -0
  27. odxtools/envdataconnector.py +49 -0
  28. odxtools/externalaccessmethod.py +23 -0
  29. odxtools/externaldoc.py +23 -0
  30. odxtools/linkeddtcdop.py +62 -0
  31. odxtools/minmaxlengthtype.py +1 -7
  32. odxtools/parameterinfo.py +1 -1
  33. odxtools/parameters/rowfragment.py +7 -0
  34. odxtools/parameters/tableentryparameter.py +1 -6
  35. odxtools/physicaltype.py +1 -8
  36. odxtools/posresponsesuppressible.py +73 -0
  37. odxtools/radix.py +9 -0
  38. odxtools/relateddiagcommref.py +23 -0
  39. odxtools/request.py +5 -3
  40. odxtools/response.py +5 -3
  41. odxtools/scaleconstr.py +1 -8
  42. odxtools/standardizationlevel.py +9 -0
  43. odxtools/standardlengthtype.py +2 -11
  44. odxtools/statetransition.py +1 -14
  45. odxtools/subcomponent.py +8 -241
  46. odxtools/subcomponentparamconnector.py +103 -0
  47. odxtools/subcomponentpattern.py +42 -0
  48. odxtools/table.py +3 -41
  49. odxtools/tablediagcommconnector.py +47 -0
  50. odxtools/tablerowconnector.py +46 -0
  51. odxtools/templates/macros/printService.xml.jinja2 +2 -1
  52. odxtools/termination.py +8 -0
  53. odxtools/transmode.py +9 -0
  54. odxtools/unitgroup.py +1 -6
  55. odxtools/unitgroupcategory.py +7 -0
  56. odxtools/usage.py +9 -0
  57. odxtools/utils.py +29 -0
  58. odxtools/validtype.py +9 -0
  59. odxtools/version.py +2 -2
  60. {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/METADATA +1 -1
  61. {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/RECORD +65 -39
  62. {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/WHEEL +0 -0
  63. {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/entry_points.txt +0 -0
  64. {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/licenses/LICENSE +0 -0
  65. {odxtools-9.6.0.dist-info → odxtools-9.7.0.dist-info}/top_level.txt +0 -0
@@ -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)
@@ -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)
@@ -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.limit import IntervalType
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
@@ -0,0 +1,7 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from enum import Enum
3
+
4
+
5
+ class RowFragment(Enum):
6
+ KEY = "KEY"
7
+ STRUCT = "STRUCT"
@@ -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,9 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from enum import IntEnum
3
+
4
+
5
+ class Radix(IntEnum):
6
+ HEX = 16
7
+ DEC = 10
8
+ BIN = 2
9
+ OCT = 8
@@ -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 .codec import (composite_codec_decode_from_pdu, composite_codec_encode_into_pdu,
8
- composite_codec_get_coded_const_prefix, composite_codec_get_free_parameters,
9
- composite_codec_get_required_parameters, composite_codec_get_static_bit_length)
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 .codec import (composite_codec_decode_from_pdu, composite_codec_encode_into_pdu,
9
- composite_codec_get_coded_const_prefix, composite_codec_get_free_parameters,
10
- composite_codec_get_required_parameters, composite_codec_get_static_bit_length)
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
@@ -0,0 +1,9 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from enum import Enum
3
+
4
+
5
+ class StandardizationLevel(Enum):
6
+ STANDARD = "STANDARD"
7
+ OEM_SPECIFIC = "OEM-SPECIFIC"
8
+ OPTIONAL = "OPTIONAL"
9
+ OEM_OPTIONAL = "OEM-OPTIONAL"
@@ -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 = None
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(
@@ -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 TYPE_CHECKING, Any, Dict, List, Optional
3
+ from typing import Any, Dict, List, Optional
4
4
  from xml.etree import ElementTree
5
5
 
6
- from .diagnostictroublecode import DiagnosticTroubleCode
7
- from .diagservice import DiagService
8
- from .dtcdop import DtcDop
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, OdxLinkRef, resolve_snref
15
- from .parameters.parameter import Parameter
10
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
16
11
  from .snrefcontext import SnRefContext
17
- from .table import Table
18
- from .tablerow import TableRow
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):