odxtools 9.6.1__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.1.dist-info → odxtools-9.7.0.dist-info}/METADATA +1 -1
  61. {odxtools-9.6.1.dist-info → odxtools-9.7.0.dist-info}/RECORD +65 -39
  62. {odxtools-9.6.1.dist-info → odxtools-9.7.0.dist-info}/WHEEL +0 -0
  63. {odxtools-9.6.1.dist-info → odxtools-9.7.0.dist-info}/entry_points.txt +0 -0
  64. {odxtools-9.6.1.dist-info → odxtools-9.7.0.dist-info}/licenses/LICENSE +0 -0
  65. {odxtools-9.6.1.dist-info → odxtools-9.7.0.dist-info}/top_level.txt +0 -0
odxtools/diagcomm.py CHANGED
@@ -1,11 +1,11 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from enum import Enum
4
3
  from typing import TYPE_CHECKING, Any, Dict, List, Optional
5
4
  from xml.etree import ElementTree
6
5
 
7
6
  from .admindata import AdminData
8
7
  from .audience import Audience
8
+ from .diagclasstype import DiagClassType
9
9
  from .element import IdentifiableElement
10
10
  from .exceptions import odxraise, odxrequire
11
11
  from .functionalclass import FunctionalClass
@@ -13,6 +13,7 @@ from .nameditemlist import NamedItemList
13
13
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
14
14
  from .odxtypes import odxstr_to_bool
15
15
  from .preconditionstateref import PreConditionStateRef
16
+ from .relateddiagcommref import RelatedDiagCommRef
16
17
  from .snrefcontext import SnRefContext
17
18
  from .specialdatagroup import SpecialDataGroup
18
19
  from .state import State
@@ -24,30 +25,6 @@ if TYPE_CHECKING:
24
25
  from .diaglayers.protocol import Protocol
25
26
 
26
27
 
27
- class DiagClassType(Enum):
28
- STARTCOMM = "STARTCOMM"
29
- STOPCOMM = "STOPCOMM"
30
- VARIANTIDENTIFICATION = "VARIANTIDENTIFICATION"
31
- READ_DYN_DEFINED_MESSAGE = "READ-DYN-DEFINED-MESSAGE"
32
- DYN_DEF_MESSAGE = "DYN-DEF-MESSAGE"
33
- CLEAR_DYN_DEF_MESSAGE = "CLEAR-DYN-DEF-MESSAGE"
34
-
35
-
36
- @dataclass
37
- class RelatedDiagCommRef(OdxLinkRef):
38
- relation_type: str
39
-
40
- @staticmethod
41
- def from_et( # type: ignore[override]
42
- et_element: ElementTree.Element,
43
- doc_frags: List[OdxDocFragment]) -> "RelatedDiagCommRef":
44
- kwargs = dataclass_fields_asdict(odxrequire(OdxLinkRef.from_et(et_element, doc_frags)))
45
-
46
- relation_type = odxrequire(et_element.findtext("RELATION-TYPE"))
47
-
48
- return RelatedDiagCommRef(relation_type=relation_type, **kwargs)
49
-
50
-
51
28
  @dataclass
52
29
  class DiagComm(IdentifiableElement):
53
30
  """Representation of a diagnostic communication object.
odxtools/diagservice.py CHANGED
@@ -1,9 +1,9 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from enum import Enum
4
3
  from typing import Any, Dict, List, Optional, Union, cast
5
4
  from xml.etree import ElementTree
6
5
 
6
+ from .addressing import Addressing
7
7
  from .comparaminstance import ComparamInstance
8
8
  from .diagcomm import DiagComm
9
9
  from .exceptions import DecodeError, DecodeMismatch, odxassert, odxraise, odxrequire
@@ -12,90 +12,14 @@ from .nameditemlist import NamedItemList
12
12
  from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
13
13
  from .odxtypes import ParameterValue, odxstr_to_bool
14
14
  from .parameters.parameter import Parameter
15
+ from .posresponsesuppressible import PosResponseSuppressible
15
16
  from .request import Request
16
17
  from .response import Response
17
18
  from .snrefcontext import SnRefContext
19
+ from .transmode import TransMode
18
20
  from .utils import dataclass_fields_asdict
19
21
 
20
22
 
21
- class Addressing(Enum):
22
- FUNCTIONAL = "FUNCTIONAL"
23
- PHYSICAL = "PHYSICAL"
24
- FUNCTIONAL_OR_PHYSICAL = "FUNCTIONAL-OR-PHYSICAL"
25
-
26
-
27
- class TransMode(Enum):
28
- SEND_ONLY = "SEND-ONLY"
29
- RECEIVE_ONLY = "RECEIVE-ONLY"
30
- SEND_AND_RECEIVE = "SEND-AND-RECEIVE"
31
- SEND_OR_RECEIVE = "SEND-OR-RECEIVE"
32
-
33
-
34
- # note that the spec has a typo here: it calls the corresponding
35
- # XML tag POS-RESPONSE-SUPPRESSABLE...
36
- @dataclass
37
- class PosResponseSuppressible:
38
- bit_mask: int
39
-
40
- coded_const_snref: Optional[str]
41
- coded_const_snpathref: Optional[str]
42
-
43
- value_snref: Optional[str]
44
- value_snpathref: Optional[str]
45
-
46
- phys_const_snref: Optional[str]
47
- phys_const_snpathref: Optional[str]
48
-
49
- table_key_snref: Optional[str]
50
- table_key_snpathref: Optional[str]
51
-
52
- @staticmethod
53
- def from_et(et_element: ElementTree.Element,
54
- doc_frags: List[OdxDocFragment]) -> "PosResponseSuppressible":
55
-
56
- bit_mask = int(odxrequire(et_element.findtext("BIT-MASK")))
57
-
58
- coded_const_snref = None
59
- if (cc_snref_elem := et_element.find("CODED-CONST-SNREF")) is not None:
60
- coded_const_snref = cc_snref_elem.attrib["SHORT-NAME"]
61
- coded_const_snpathref = None
62
- if (cc_snpathref_elem := et_element.find("CODED-CONST-SNPATHREF")) is not None:
63
- coded_const_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
64
-
65
- value_snref = None
66
- if (cc_snref_elem := et_element.find("VALUE-SNREF")) is not None:
67
- value_snref = cc_snref_elem.attrib["SHORT-NAME"]
68
- value_snpathref = None
69
- if (cc_snpathref_elem := et_element.find("VALUE-SNPATHREF")) is not None:
70
- value_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
71
-
72
- phys_const_snref = None
73
- if (cc_snref_elem := et_element.find("PHYS-CONST-SNREF")) is not None:
74
- phys_const_snref = cc_snref_elem.attrib["SHORT-NAME"]
75
- phys_const_snpathref = None
76
- if (cc_snpathref_elem := et_element.find("PHYS-CONST-SNPATHREF")) is not None:
77
- phys_const_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
78
-
79
- table_key_snref = None
80
- if (cc_snref_elem := et_element.find("TABLE-KEY-SNREF")) is not None:
81
- table_key_snref = cc_snref_elem.attrib["SHORT-NAME"]
82
- table_key_snpathref = None
83
- if (cc_snpathref_elem := et_element.find("TABLE-KEY-SNPATHREF")) is not None:
84
- table_key_snpathref = cc_snpathref_elem.attrib["SHORT-NAME-PATH"]
85
-
86
- return PosResponseSuppressible(
87
- bit_mask=bit_mask,
88
- coded_const_snref=coded_const_snref,
89
- coded_const_snpathref=coded_const_snpathref,
90
- value_snref=value_snref,
91
- value_snpathref=value_snpathref,
92
- phys_const_snref=phys_const_snref,
93
- phys_const_snpathref=phys_const_snpathref,
94
- table_key_snref=table_key_snref,
95
- table_key_snpathref=table_key_snpathref,
96
- )
97
-
98
-
99
23
  @dataclass
100
24
  class DiagService(DiagComm):
101
25
  """Representation of a diagnostic service description.
@@ -0,0 +1,45 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from typing import Any, Dict, List
4
+ from xml.etree import ElementTree
5
+
6
+ from .diagnostictroublecode import DiagnosticTroubleCode
7
+ from .dtcdop import DtcDop
8
+ from .element import NamedElement
9
+ from .exceptions import odxrequire
10
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
11
+ from .snrefcontext import SnRefContext
12
+ from .utils import dataclass_fields_asdict
13
+
14
+
15
+ @dataclass
16
+ class DtcConnector(NamedElement):
17
+ dtc_dop_ref: OdxLinkRef
18
+ dtc_snref: str
19
+
20
+ @property
21
+ def dtc_dop(self) -> DtcDop:
22
+ return self._dtc_dop
23
+
24
+ @property
25
+ def dtc(self) -> DiagnosticTroubleCode:
26
+ return self._dtc
27
+
28
+ @staticmethod
29
+ def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "DtcConnector":
30
+ kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
31
+
32
+ dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), doc_frags))
33
+ dtc_snref_el = odxrequire(et_element.find("DTC-SNREF"))
34
+ dtc_snref = odxrequire(dtc_snref_el.get("SHORT-NAME"))
35
+
36
+ return DtcConnector(dtc_dop_ref=dtc_dop_ref, dtc_snref=dtc_snref, **kwargs)
37
+
38
+ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
39
+ return {}
40
+
41
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
42
+ self._dtc_dop = odxlinks.resolve(self.dtc_dop_ref, DtcDop)
43
+
44
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
45
+ self._dtc = resolve_snref(self.dtc_snref, self._dtc_dop.dtcs, DiagnosticTroubleCode)
odxtools/dtcdop.py CHANGED
@@ -14,60 +14,15 @@ from .diagnostictroublecode import DiagnosticTroubleCode
14
14
  from .dopbase import DopBase
15
15
  from .encodestate import EncodeState
16
16
  from .exceptions import DecodeError, EncodeError, odxassert, odxraise, odxrequire
17
+ from .linkeddtcdop import LinkedDtcDop
17
18
  from .nameditemlist import NamedItemList
18
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
19
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef
19
20
  from .odxtypes import ParameterValue, odxstr_to_bool
20
21
  from .physicaltype import PhysicalType
21
22
  from .snrefcontext import SnRefContext
22
23
  from .utils import dataclass_fields_asdict
23
24
 
24
25
 
25
- @dataclass
26
- class LinkedDtcDop:
27
- not_inherited_dtc_snrefs: List[str]
28
- dtc_dop_ref: OdxLinkRef
29
-
30
- @property
31
- def not_inherited_dtcs(self) -> NamedItemList[DiagnosticTroubleCode]:
32
- return self._not_inherited_dtcs
33
-
34
- @property
35
- def dtc_dop(self) -> "DtcDop":
36
- return self._dtc_dop
37
-
38
- @property
39
- def short_name(self) -> str:
40
- return self._dtc_dop.short_name
41
-
42
- @staticmethod
43
- def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "LinkedDtcDop":
44
- not_inherited_dtc_snrefs = [
45
- odxrequire(el.get("SHORT-NAME"))
46
- for el in et_element.iterfind("NOT-INHERITED-DTC-SNREFS/"
47
- "NOT-INHERITED-DTC-SNREF")
48
- ]
49
-
50
- dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), doc_frags))
51
-
52
- return LinkedDtcDop(
53
- not_inherited_dtc_snrefs=not_inherited_dtc_snrefs, dtc_dop_ref=dtc_dop_ref)
54
-
55
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
56
- return {}
57
-
58
- def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
59
- self._dtc_dop = odxlinks.resolve(self.dtc_dop_ref, DtcDop)
60
-
61
- def _resolve_snrefs(self, context: SnRefContext) -> None:
62
- dtc_dop = self._dtc_dop
63
- not_inherited_dtcs = [
64
- resolve_snref(ni_snref, dtc_dop.dtcs, DiagnosticTroubleCode)
65
- for ni_snref in self.not_inherited_dtc_snrefs
66
- ]
67
-
68
- self._not_inherited_dtcs = NamedItemList(not_inherited_dtcs)
69
-
70
-
71
26
  @dataclass
72
27
  class DtcDop(DopBase):
73
28
  """A DOP describing a diagnostic trouble code"""
@@ -1,163 +1,11 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  from dataclasses import dataclass
3
- from typing import Any, Dict, List, Optional, Union
3
+ from typing import Any, Dict, List
4
4
  from xml.etree import ElementTree
5
5
 
6
- from .diagcomm import DiagClassType, DiagComm
7
- from .exceptions import odxassert, odxraise, odxrequire
8
- from .nameditemlist import NamedItemList
9
- from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
6
+ from .dyniddefmodeinfo import DynIdDefModeInfo
7
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
10
8
  from .snrefcontext import SnRefContext
11
- from .table import Table
12
-
13
-
14
- @dataclass
15
- class DynIdDefModeInfo:
16
- def_mode: str
17
-
18
- clear_dyn_def_message_ref: Optional[OdxLinkRef]
19
- clear_dyn_def_message_snref: Optional[str]
20
-
21
- read_dyn_def_message_ref: Optional[OdxLinkRef]
22
- read_dyn_def_message_snref: Optional[str]
23
-
24
- dyn_def_message_ref: Optional[OdxLinkRef]
25
- dyn_def_message_snref: Optional[str]
26
-
27
- supported_dyn_ids: List[bytes]
28
- selection_table_refs: List[Union[OdxLinkRef, str]]
29
-
30
- @property
31
- def clear_dyn_def_message(self) -> DiagComm:
32
- return self._clear_dyn_def_message
33
-
34
- @property
35
- def read_dyn_def_message(self) -> DiagComm:
36
- return self._read_dyn_def_message
37
-
38
- @property
39
- def dyn_def_message(self) -> DiagComm:
40
- return self._dyn_def_message
41
-
42
- @property
43
- def selection_tables(self) -> NamedItemList[Table]:
44
- return self._selection_tables
45
-
46
- @staticmethod
47
- def from_et(et_element: ElementTree.Element,
48
- doc_frags: List[OdxDocFragment]) -> "DynIdDefModeInfo":
49
- def_mode = odxrequire(et_element.findtext("DEF-MODE"))
50
-
51
- clear_dyn_def_message_ref = OdxLinkRef.from_et(
52
- et_element.find("CLEAR-DYN-DEF-MESSAGE-REF"), doc_frags)
53
- clear_dyn_def_message_snref = None
54
- if (snref_elem := et_element.find("CLEAR-DYN-DEF-MESSAGE-SNREF")) is not None:
55
- clear_dyn_def_message_snref = odxrequire(snref_elem.attrib.get("SHORT-NAME"))
56
-
57
- read_dyn_def_message_ref = OdxLinkRef.from_et(
58
- et_element.find("READ-DYN-DEF-MESSAGE-REF"), doc_frags)
59
- read_dyn_def_message_snref = None
60
- if (snref_elem := et_element.find("READ-DYN-DEF-MESSAGE-SNREF")) is not None:
61
- read_dyn_def_message_snref = odxrequire(snref_elem.attrib.get("SHORT-NAME"))
62
-
63
- dyn_def_message_ref = OdxLinkRef.from_et(et_element.find("DYN-DEF-MESSAGE-REF"), doc_frags)
64
- dyn_def_message_snref = None
65
- if (snref_elem := et_element.find("DYN-DEF-MESSAGE-SNREF")) is not None:
66
- dyn_def_message_snref = odxrequire(snref_elem.attrib.get("SHORT-NAME"))
67
-
68
- supported_dyn_ids = [
69
- bytes.fromhex(odxrequire(x.text))
70
- for x in et_element.iterfind("SUPPORTED-DYN-IDS/SUPPORTED-DYN-ID")
71
- ]
72
-
73
- selection_table_refs: List[Union[OdxLinkRef, str]] = []
74
- if (st_elems := et_element.find("SELECTION-TABLE-REFS")) is not None:
75
- for st_elem in st_elems:
76
- if st_elem.tag == "SELECTION-TABLE-REF":
77
- selection_table_refs.append(OdxLinkRef.from_et(st_elem, doc_frags))
78
- elif st_elem.tag == "SELECTION-TABLE-SNREF":
79
- selection_table_refs.append(odxrequire(st_elem.get("SHORT-NAME")))
80
- else:
81
- odxraise()
82
-
83
- return DynIdDefModeInfo(
84
- def_mode=def_mode,
85
- clear_dyn_def_message_ref=clear_dyn_def_message_ref,
86
- clear_dyn_def_message_snref=clear_dyn_def_message_snref,
87
- read_dyn_def_message_ref=read_dyn_def_message_ref,
88
- read_dyn_def_message_snref=read_dyn_def_message_snref,
89
- dyn_def_message_ref=dyn_def_message_ref,
90
- dyn_def_message_snref=dyn_def_message_snref,
91
- supported_dyn_ids=supported_dyn_ids,
92
- selection_table_refs=selection_table_refs,
93
- )
94
-
95
- def __post_init__(self) -> None:
96
- odxassert(
97
- self.clear_dyn_def_message_ref is not None or
98
- self.clear_dyn_def_message_snref is not None,
99
- "A CLEAR-DYN-DEF-MESSAGE must be specified")
100
- odxassert(
101
- self.read_dyn_def_message_ref is not None or
102
- self.read_dyn_def_message_snref is not None, "A READ-DYN-DEF-MESSAGE must be specified")
103
- odxassert(self.dyn_def_message_ref is not None or self.dyn_def_message_snref is not None,
104
- "A DYN-DEF-MESSAGE must be specified")
105
-
106
- def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
107
- result: Dict[OdxLinkId, Any] = {}
108
-
109
- return result
110
-
111
- def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
112
- if self.clear_dyn_def_message_ref is not None:
113
- self._clear_dyn_def_message = odxlinks.resolve(self.clear_dyn_def_message_ref, DiagComm)
114
-
115
- if self.read_dyn_def_message_ref is not None:
116
- self._read_dyn_def_message = odxlinks.resolve(self.read_dyn_def_message_ref, DiagComm)
117
-
118
- if self.dyn_def_message_ref is not None:
119
- self._dyn_def_message = odxlinks.resolve(self.dyn_def_message_ref, DiagComm)
120
-
121
- # resolve the selection tables that are referenced via ODXLINK
122
- self._selection_tables = NamedItemList[Table]()
123
- for x in self.selection_table_refs:
124
- if isinstance(x, OdxLinkRef):
125
- self._selection_tables.append(odxlinks.resolve(x, Table))
126
-
127
- def _resolve_snrefs(self, context: SnRefContext) -> None:
128
- diag_layer = odxrequire(context.diag_layer)
129
-
130
- if self.clear_dyn_def_message_snref is not None:
131
- self._clear_dyn_def_message = resolve_snref(self.clear_dyn_def_message_snref,
132
- diag_layer.diag_comms, DiagComm)
133
-
134
- if self.read_dyn_def_message_snref is not None:
135
- self._read_dyn_def_message = resolve_snref(self.read_dyn_def_message_snref,
136
- diag_layer.diag_comms, DiagComm)
137
-
138
- if self.dyn_def_message_snref is not None:
139
- self._dyn_def_message = resolve_snref(self.dyn_def_message_snref, diag_layer.diag_comms,
140
- DiagComm)
141
-
142
- if self._clear_dyn_def_message.diagnostic_class != DiagClassType.CLEAR_DYN_DEF_MESSAGE:
143
- odxraise(
144
- f"Diagnostic communication object of wrong type referenced: "
145
- f"({odxrequire(self._clear_dyn_def_message.diagnostic_class).value} instead of "
146
- f"CLEAR-DYN-DEF-MESSAGE)")
147
- if self._read_dyn_def_message.diagnostic_class != DiagClassType.READ_DYN_DEFINED_MESSAGE:
148
- odxraise(f"Diagnostic communication object of wrong type referenced: "
149
- f"({odxrequire(self._read_dyn_def_message.diagnostic_class).value} instead of "
150
- f"READ-DYN-DEFINED-MESSAGE)")
151
- if self._dyn_def_message.diagnostic_class != DiagClassType.DYN_DEF_MESSAGE:
152
- odxraise(f"Diagnostic communication object of wrong type referenced: "
153
- f"({odxrequire(self._dyn_def_message.diagnostic_class).value} instead of "
154
- f"DYN-DEF-MESSAGE)")
155
-
156
- # resolve the remaining selection tables that are referenced via SNREF
157
- ddd_spec = odxrequire(diag_layer.diag_data_dictionary_spec)
158
- for i, x in enumerate(self.selection_table_refs):
159
- if isinstance(x, str):
160
- self._selection_tables.insert(i, resolve_snref(x, ddd_spec.tables, Table))
161
9
 
162
10
 
163
11
  @dataclass
@@ -0,0 +1,161 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from typing import Any, Dict, List, Optional, Union
4
+ from xml.etree import ElementTree
5
+
6
+ from .diagclasstype import DiagClassType
7
+ from .diagcomm import DiagComm
8
+ from .exceptions import odxassert, odxraise, odxrequire
9
+ from .nameditemlist import NamedItemList
10
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
11
+ from .snrefcontext import SnRefContext
12
+ from .table import Table
13
+
14
+
15
+ @dataclass
16
+ class DynIdDefModeInfo:
17
+ def_mode: str
18
+
19
+ clear_dyn_def_message_ref: Optional[OdxLinkRef]
20
+ clear_dyn_def_message_snref: Optional[str]
21
+
22
+ read_dyn_def_message_ref: Optional[OdxLinkRef]
23
+ read_dyn_def_message_snref: Optional[str]
24
+
25
+ dyn_def_message_ref: Optional[OdxLinkRef]
26
+ dyn_def_message_snref: Optional[str]
27
+
28
+ supported_dyn_ids: List[bytes]
29
+ selection_table_refs: List[Union[OdxLinkRef, str]]
30
+
31
+ @property
32
+ def clear_dyn_def_message(self) -> DiagComm:
33
+ return self._clear_dyn_def_message
34
+
35
+ @property
36
+ def read_dyn_def_message(self) -> DiagComm:
37
+ return self._read_dyn_def_message
38
+
39
+ @property
40
+ def dyn_def_message(self) -> DiagComm:
41
+ return self._dyn_def_message
42
+
43
+ @property
44
+ def selection_tables(self) -> NamedItemList[Table]:
45
+ return self._selection_tables
46
+
47
+ @staticmethod
48
+ def from_et(et_element: ElementTree.Element,
49
+ doc_frags: List[OdxDocFragment]) -> "DynIdDefModeInfo":
50
+ def_mode = odxrequire(et_element.findtext("DEF-MODE"))
51
+
52
+ clear_dyn_def_message_ref = OdxLinkRef.from_et(
53
+ et_element.find("CLEAR-DYN-DEF-MESSAGE-REF"), doc_frags)
54
+ clear_dyn_def_message_snref = None
55
+ if (snref_elem := et_element.find("CLEAR-DYN-DEF-MESSAGE-SNREF")) is not None:
56
+ clear_dyn_def_message_snref = odxrequire(snref_elem.attrib.get("SHORT-NAME"))
57
+
58
+ read_dyn_def_message_ref = OdxLinkRef.from_et(
59
+ et_element.find("READ-DYN-DEF-MESSAGE-REF"), doc_frags)
60
+ read_dyn_def_message_snref = None
61
+ if (snref_elem := et_element.find("READ-DYN-DEF-MESSAGE-SNREF")) is not None:
62
+ read_dyn_def_message_snref = odxrequire(snref_elem.attrib.get("SHORT-NAME"))
63
+
64
+ dyn_def_message_ref = OdxLinkRef.from_et(et_element.find("DYN-DEF-MESSAGE-REF"), doc_frags)
65
+ dyn_def_message_snref = None
66
+ if (snref_elem := et_element.find("DYN-DEF-MESSAGE-SNREF")) is not None:
67
+ dyn_def_message_snref = odxrequire(snref_elem.attrib.get("SHORT-NAME"))
68
+
69
+ supported_dyn_ids = [
70
+ bytes.fromhex(odxrequire(x.text))
71
+ for x in et_element.iterfind("SUPPORTED-DYN-IDS/SUPPORTED-DYN-ID")
72
+ ]
73
+
74
+ selection_table_refs: List[Union[OdxLinkRef, str]] = []
75
+ if (st_elems := et_element.find("SELECTION-TABLE-REFS")) is not None:
76
+ for st_elem in st_elems:
77
+ if st_elem.tag == "SELECTION-TABLE-REF":
78
+ selection_table_refs.append(OdxLinkRef.from_et(st_elem, doc_frags))
79
+ elif st_elem.tag == "SELECTION-TABLE-SNREF":
80
+ selection_table_refs.append(odxrequire(st_elem.get("SHORT-NAME")))
81
+ else:
82
+ odxraise()
83
+
84
+ return DynIdDefModeInfo(
85
+ def_mode=def_mode,
86
+ clear_dyn_def_message_ref=clear_dyn_def_message_ref,
87
+ clear_dyn_def_message_snref=clear_dyn_def_message_snref,
88
+ read_dyn_def_message_ref=read_dyn_def_message_ref,
89
+ read_dyn_def_message_snref=read_dyn_def_message_snref,
90
+ dyn_def_message_ref=dyn_def_message_ref,
91
+ dyn_def_message_snref=dyn_def_message_snref,
92
+ supported_dyn_ids=supported_dyn_ids,
93
+ selection_table_refs=selection_table_refs,
94
+ )
95
+
96
+ def __post_init__(self) -> None:
97
+ odxassert(
98
+ self.clear_dyn_def_message_ref is not None or
99
+ self.clear_dyn_def_message_snref is not None,
100
+ "A CLEAR-DYN-DEF-MESSAGE must be specified")
101
+ odxassert(
102
+ self.read_dyn_def_message_ref is not None or
103
+ self.read_dyn_def_message_snref is not None, "A READ-DYN-DEF-MESSAGE must be specified")
104
+ odxassert(self.dyn_def_message_ref is not None or self.dyn_def_message_snref is not None,
105
+ "A DYN-DEF-MESSAGE must be specified")
106
+
107
+ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
108
+ result: Dict[OdxLinkId, Any] = {}
109
+
110
+ return result
111
+
112
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
113
+ if self.clear_dyn_def_message_ref is not None:
114
+ self._clear_dyn_def_message = odxlinks.resolve(self.clear_dyn_def_message_ref, DiagComm)
115
+
116
+ if self.read_dyn_def_message_ref is not None:
117
+ self._read_dyn_def_message = odxlinks.resolve(self.read_dyn_def_message_ref, DiagComm)
118
+
119
+ if self.dyn_def_message_ref is not None:
120
+ self._dyn_def_message = odxlinks.resolve(self.dyn_def_message_ref, DiagComm)
121
+
122
+ # resolve the selection tables that are referenced via ODXLINK
123
+ self._selection_tables = NamedItemList[Table]()
124
+ for x in self.selection_table_refs:
125
+ if isinstance(x, OdxLinkRef):
126
+ self._selection_tables.append(odxlinks.resolve(x, Table))
127
+
128
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
129
+ diag_layer = odxrequire(context.diag_layer)
130
+
131
+ if self.clear_dyn_def_message_snref is not None:
132
+ self._clear_dyn_def_message = resolve_snref(self.clear_dyn_def_message_snref,
133
+ diag_layer.diag_comms, DiagComm)
134
+
135
+ if self.read_dyn_def_message_snref is not None:
136
+ self._read_dyn_def_message = resolve_snref(self.read_dyn_def_message_snref,
137
+ diag_layer.diag_comms, DiagComm)
138
+
139
+ if self.dyn_def_message_snref is not None:
140
+ self._dyn_def_message = resolve_snref(self.dyn_def_message_snref, diag_layer.diag_comms,
141
+ DiagComm)
142
+
143
+ if self._clear_dyn_def_message.diagnostic_class != DiagClassType.CLEAR_DYN_DEF_MESSAGE:
144
+ odxraise(
145
+ f"Diagnostic communication object of wrong type referenced: "
146
+ f"({odxrequire(self._clear_dyn_def_message.diagnostic_class).value} instead of "
147
+ f"CLEAR-DYN-DEF-MESSAGE)")
148
+ if self._read_dyn_def_message.diagnostic_class != DiagClassType.READ_DYN_DEFINED_MESSAGE:
149
+ odxraise(f"Diagnostic communication object of wrong type referenced: "
150
+ f"({odxrequire(self._read_dyn_def_message.diagnostic_class).value} instead of "
151
+ f"READ-DYN-DEFINED-MESSAGE)")
152
+ if self._dyn_def_message.diagnostic_class != DiagClassType.DYN_DEF_MESSAGE:
153
+ odxraise(f"Diagnostic communication object of wrong type referenced: "
154
+ f"({odxrequire(self._dyn_def_message.diagnostic_class).value} instead of "
155
+ f"DYN-DEF-MESSAGE)")
156
+
157
+ # resolve the remaining selection tables that are referenced via SNREF
158
+ ddd_spec = odxrequire(diag_layer.diag_data_dictionary_spec)
159
+ for i, x in enumerate(self.selection_table_refs):
160
+ if isinstance(x, str):
161
+ self._selection_tables.insert(i, resolve_snref(x, ddd_spec.tables, Table))
@@ -0,0 +1,49 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from typing import Any, Dict, List
4
+ from xml.etree import ElementTree
5
+
6
+ from .element import NamedElement
7
+ from .environmentdata import EnvironmentData
8
+ from .environmentdatadescription import EnvironmentDataDescription
9
+ from .exceptions import odxrequire
10
+ from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
11
+ from .snrefcontext import SnRefContext
12
+ from .utils import dataclass_fields_asdict
13
+
14
+
15
+ @dataclass
16
+ class EnvDataConnector(NamedElement):
17
+ env_data_desc_ref: OdxLinkRef
18
+ env_data_snref: str
19
+
20
+ @property
21
+ def env_data_desc(self) -> EnvironmentDataDescription:
22
+ return self._env_data_desc
23
+
24
+ @property
25
+ def env_data(self) -> EnvironmentData:
26
+ return self._env_data
27
+
28
+ @staticmethod
29
+ def from_et(et_element: ElementTree.Element,
30
+ doc_frags: List[OdxDocFragment]) -> "EnvDataConnector":
31
+ kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
32
+
33
+ env_data_desc_ref = odxrequire(
34
+ OdxLinkRef.from_et(et_element.find("ENV-DATA-DESC-REF"), doc_frags))
35
+ env_data_snref_el = odxrequire(et_element.find("ENV-DATA-SNREF"))
36
+ env_data_snref = odxrequire(env_data_snref_el.get("SHORT-NAME"))
37
+
38
+ return EnvDataConnector(
39
+ env_data_desc_ref=env_data_desc_ref, env_data_snref=env_data_snref, **kwargs)
40
+
41
+ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
42
+ return {}
43
+
44
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
45
+ self._env_data_desc = odxlinks.resolve(self.env_data_desc_ref, EnvironmentDataDescription)
46
+
47
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
48
+ self._env_data = resolve_snref(self.env_data_snref, self._env_data_desc.env_datas,
49
+ EnvironmentData)
@@ -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 .element import IdentifiableElement
7
+ from .exceptions import odxrequire
8
+ from .odxlink import OdxDocFragment
9
+ from .utils import dataclass_fields_asdict
10
+
11
+
12
+ @dataclass
13
+ class ExternalAccessMethod(IdentifiableElement):
14
+ method: str
15
+
16
+ @staticmethod
17
+ def from_et(et_element: ElementTree.Element,
18
+ doc_frags: List[OdxDocFragment]) -> "ExternalAccessMethod":
19
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
20
+
21
+ method = odxrequire(et_element.findtext("METHOD"))
22
+
23
+ return ExternalAccessMethod(method=method, **kwargs)