odxtools 10.2.1__py3-none-any.whl → 10.3.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 (63) hide show
  1. odxtools/cli/browse.py +4 -2
  2. odxtools/cli/compare.py +3 -3
  3. odxtools/compositecodec.py +1 -1
  4. odxtools/configdata.py +70 -0
  5. odxtools/configdatadictionaryspec.py +57 -0
  6. odxtools/configiditem.py +18 -0
  7. odxtools/configitem.py +85 -0
  8. odxtools/configrecord.py +146 -0
  9. odxtools/database.py +21 -0
  10. odxtools/dataiditem.py +18 -0
  11. odxtools/datarecord.py +132 -0
  12. odxtools/decodestate.py +1 -1
  13. odxtools/diagcommdataconnector.py +61 -0
  14. odxtools/diaglayers/diaglayer.py +8 -6
  15. odxtools/diagservice.py +10 -10
  16. odxtools/ecuconfig.py +89 -0
  17. odxtools/encryptcompressmethod.py +16 -3
  18. odxtools/externflashdata.py +21 -2
  19. odxtools/flashdata.py +40 -2
  20. odxtools/identvalue.py +16 -3
  21. odxtools/internflashdata.py +4 -0
  22. odxtools/isotp_state_machine.py +11 -11
  23. odxtools/itemvalue.py +77 -0
  24. odxtools/nameditemlist.py +2 -2
  25. odxtools/optionitem.py +79 -0
  26. odxtools/parameters/codedconstparameter.py +2 -3
  27. odxtools/readdiagcommconnector.py +79 -0
  28. odxtools/readparamvalue.py +52 -0
  29. odxtools/request.py +3 -3
  30. odxtools/response.py +8 -4
  31. odxtools/statemachine.py +3 -2
  32. odxtools/systemitem.py +23 -0
  33. odxtools/templates/diag_layer_container.odx-d.xml.jinja2 +4 -0
  34. odxtools/templates/ecu_config.odx-e.xml.jinja2 +38 -0
  35. odxtools/templates/flash.odx-f.xml.jinja2 +2 -2
  36. odxtools/templates/macros/printAudience.xml.jinja2 +3 -3
  37. odxtools/templates/macros/printChecksum.xml.jinja2 +1 -1
  38. odxtools/templates/macros/printCompuMethod.xml.jinja2 +2 -2
  39. odxtools/templates/macros/printConfigData.xml.jinja2 +39 -0
  40. odxtools/templates/macros/printConfigDataDictionarySpec.xml.jinja2 +22 -0
  41. odxtools/templates/macros/printConfigItems.xml.jinja2 +66 -0
  42. odxtools/templates/macros/printConfigRecord.xml.jinja2 +73 -0
  43. odxtools/templates/macros/printDOP.xml.jinja2 +5 -6
  44. odxtools/templates/macros/printDataRecord.xml.jinja2 +35 -0
  45. odxtools/templates/macros/printDiagCommDataConnector.xml.jinja2 +66 -0
  46. odxtools/templates/macros/printExpectedIdent.xml.jinja2 +1 -1
  47. odxtools/templates/macros/printFlashdata.xml.jinja2 +2 -2
  48. odxtools/templates/macros/printItemValue.xml.jinja2 +31 -0
  49. odxtools/templates/macros/printOwnIdent.xml.jinja2 +1 -1
  50. odxtools/templates/macros/printSecurity.xml.jinja2 +4 -4
  51. odxtools/templates/macros/printSegment.xml.jinja2 +1 -1
  52. odxtools/validbasevariant.py +62 -0
  53. odxtools/validityfor.py +16 -3
  54. odxtools/variantmatcher.py +4 -4
  55. odxtools/version.py +2 -2
  56. odxtools/writediagcommconnector.py +77 -0
  57. odxtools/writepdxfile.py +15 -0
  58. {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/METADATA +2 -1
  59. {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/RECORD +63 -39
  60. {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/WHEEL +1 -1
  61. {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/entry_points.txt +0 -0
  62. {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/licenses/LICENSE +0 -0
  63. {odxtools-10.2.1.dist-info → odxtools-10.3.0.dist-info}/top_level.txt +0 -0
odxtools/optionitem.py ADDED
@@ -0,0 +1,79 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass, field
3
+ from typing import Any
4
+ from xml.etree import ElementTree
5
+
6
+ from .audience import Audience
7
+ from .configitem import ConfigItem
8
+ from .itemvalue import ItemValue
9
+ from .odxdoccontext import OdxDocContext
10
+ from .odxlink import OdxLinkDatabase, OdxLinkId
11
+ from .snrefcontext import SnRefContext
12
+ from .utils import dataclass_fields_asdict
13
+
14
+
15
+ @dataclass(kw_only=True)
16
+ class OptionItem(ConfigItem):
17
+ """This class represents a OPTION-ITEM."""
18
+
19
+ physical_default_value: str | None = None
20
+ item_values: list[ItemValue] = field(default_factory=list)
21
+ write_audience: Audience | None = None
22
+ read_audience: Audience | None = None
23
+
24
+ @staticmethod
25
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "OptionItem":
26
+ kwargs = dataclass_fields_asdict(ConfigItem.from_et(et_element, context))
27
+
28
+ physical_default_value = et_element.findtext("PHYSICAL-DEFAULT-VALUE")
29
+
30
+ item_values = [
31
+ ItemValue.from_et(el, context) for el in et_element.iterfind("ITEM-VALUES/ITEM-VALUE")
32
+ ]
33
+
34
+ write_audience = None
35
+ if (wa_elem := et_element.find("WRITE-AUDIENCE")) is not None:
36
+ write_audience = Audience.from_et(wa_elem, context)
37
+
38
+ read_audience = None
39
+ if (ra_elem := et_element.find("READ-AUDIENCE")) is not None:
40
+ read_audience = Audience.from_et(ra_elem, context)
41
+
42
+ return OptionItem(
43
+ physical_default_value=physical_default_value,
44
+ item_values=item_values,
45
+ write_audience=write_audience,
46
+ read_audience=read_audience,
47
+ **kwargs)
48
+
49
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
50
+ result = super()._build_odxlinks()
51
+
52
+ for item_value in self.item_values:
53
+ result.update(item_value._build_odxlinks())
54
+ if self.write_audience is not None:
55
+ result.update(self.write_audience._build_odxlinks())
56
+ if self.read_audience is not None:
57
+ result.update(self.read_audience._build_odxlinks())
58
+
59
+ return result
60
+
61
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
62
+ super()._resolve_odxlinks(odxlinks)
63
+
64
+ for item_value in self.item_values:
65
+ item_value._resolve_odxlinks(odxlinks)
66
+ if self.write_audience is not None:
67
+ self.write_audience._resolve_odxlinks(odxlinks)
68
+ if self.read_audience is not None:
69
+ self.read_audience._resolve_odxlinks(odxlinks)
70
+
71
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
72
+ super()._resolve_snrefs(context)
73
+
74
+ for item_value in self.item_values:
75
+ item_value._resolve_snrefs(context)
76
+ if self.write_audience is not None:
77
+ self.write_audience._resolve_snrefs(context)
78
+ if self.read_audience is not None:
79
+ self.read_audience._resolve_snrefs(context)
@@ -1,7 +1,7 @@
1
1
  # SPDX-License-Identifier: MIT
2
2
  import warnings
3
3
  from dataclasses import dataclass
4
- from typing import Any, cast
4
+ from typing import Any
5
5
  from xml.etree import ElementTree
6
6
 
7
7
  from typing_extensions import override
@@ -57,8 +57,7 @@ class CodedConstParameter(Parameter):
57
57
  coded_value_raw=coded_value_raw, diag_coded_type=diag_coded_type, **kwargs)
58
58
 
59
59
  def __post_init__(self) -> None:
60
- self._coded_value = cast(
61
- AtomicOdxType, self.diag_coded_type.base_data_type.from_string(self.coded_value_raw))
60
+ self._coded_value = self.diag_coded_type.base_data_type.from_string(self.coded_value_raw)
62
61
 
63
62
  @override
64
63
  def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
@@ -0,0 +1,79 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from typing import Any
4
+ from xml.etree import ElementTree
5
+
6
+ from .diagcomm import DiagComm
7
+ from .exceptions import odxrequire
8
+ from .odxdoccontext import OdxDocContext
9
+ from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef
10
+ from .readparamvalue import ReadParamValue
11
+ from .snrefcontext import SnRefContext
12
+
13
+
14
+ @dataclass(kw_only=True)
15
+ class ReadDiagCommConnector:
16
+ read_param_values: list[ReadParamValue]
17
+
18
+ # exactly one of the following attributes must be non-None
19
+ read_diag_comm_ref: OdxLinkRef | None = None
20
+ read_diag_comm_snref: str | None = None
21
+
22
+ # exactly one of the following attributes must be non-None
23
+ read_data_snref: str | None = None
24
+ read_data_snpathref: str | None = None
25
+
26
+ @property
27
+ def read_diag_comm(self) -> DiagComm | None:
28
+ return self._read_diag_comm
29
+
30
+ @staticmethod
31
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ReadDiagCommConnector":
32
+ read_param_values = [
33
+ ReadParamValue.from_et(el, context)
34
+ for el in et_element.iterfind("READ-PARAM-VALUES/READ-PARAM-VALUE")
35
+ ]
36
+
37
+ read_diag_comm_ref = OdxLinkRef.from_et(et_element.find("READ-DIAG-COMM-REF"), context)
38
+ read_diag_comm_snref = None
39
+ if (read_diag_comm_snref_elem := et_element.find("READ-DIAG-COMM-SNREF")) is not None:
40
+ read_diag_comm_snref = odxrequire(read_diag_comm_snref_elem.attrib.get("SHORT-NAME"))
41
+
42
+ read_data_snref = None
43
+ if (read_data_snref_elem := et_element.find("READ-DATA-SNREF")) is not None:
44
+ read_data_snref = odxrequire(read_data_snref_elem.attrib.get("SHORT-NAME"))
45
+
46
+ read_data_snpathref = None
47
+ if (read_data_snpathref_elem := et_element.find("READ-DATA-SNPATHREF")) is not None:
48
+ read_data_snpathref = odxrequire(read_data_snpathref_elem.attrib.get("SHORT-NAME-PATH"))
49
+
50
+ return ReadDiagCommConnector(
51
+ read_param_values=read_param_values,
52
+ read_diag_comm_ref=read_diag_comm_ref,
53
+ read_diag_comm_snref=read_diag_comm_snref,
54
+ read_data_snref=read_data_snref,
55
+ read_data_snpathref=read_data_snpathref,
56
+ )
57
+
58
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
59
+ odxlinks = {}
60
+
61
+ for rpv in self.read_param_values:
62
+ odxlinks.update(rpv._build_odxlinks())
63
+
64
+ return odxlinks
65
+
66
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
67
+ self._read_diag_comm = None
68
+ if self.read_diag_comm_ref is not None:
69
+ self._read_diag_comm = odxlinks.resolve(self.read_diag_comm_ref, DiagComm)
70
+
71
+ for rpv in self.read_param_values:
72
+ rpv._resolve_odxlinks(odxlinks)
73
+
74
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
75
+ # read_diag_comm_snref cannot be uniquely resolved ahead of
76
+ # time as it depends on the diag layer which is used
77
+
78
+ for rpv in self.read_param_values:
79
+ rpv._resolve_snrefs(context)
@@ -0,0 +1,52 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from typing import Any
4
+ from xml.etree import ElementTree
5
+
6
+ from .exceptions import odxrequire
7
+ from .odxdoccontext import OdxDocContext
8
+ from .odxlink import OdxLinkDatabase, OdxLinkId
9
+ from .snrefcontext import SnRefContext
10
+
11
+
12
+ @dataclass(kw_only=True)
13
+ class ReadParamValue:
14
+ phys_constant_value: str
15
+
16
+ # exactly one of the following attributes must be non-None
17
+ in_param_if_snref: str | None = None
18
+ in_param_if_snpathref: str | None = None
19
+
20
+ semantic: str
21
+
22
+ @staticmethod
23
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ReadParamValue":
24
+ phys_constant_value = odxrequire(et_element.findtext("PHYS-CONSTANT-VALUE"))
25
+
26
+ in_param_if_snref = None
27
+ if (in_param_if_snref_elem := et_element.find("IN-PARAM-IF-SNREF")) is not None:
28
+ in_param_if_snref = odxrequire(in_param_if_snref_elem.attrib.get("SHORT-NAME"))
29
+
30
+ in_param_if_snpathref = None
31
+ if (in_param_if_snpathref_elem := et_element.find("IN-PARAM-IF-SNPATHREF")) is not None:
32
+ in_param_if_snpathref = odxrequire(
33
+ in_param_if_snpathref_elem.attrib.get("SHORT-NAME-PATH"))
34
+
35
+ semantic = odxrequire(et_element.attrib.get("SEMANTIC"))
36
+
37
+ return ReadParamValue(
38
+ phys_constant_value=phys_constant_value,
39
+ in_param_if_snref=in_param_if_snref,
40
+ in_param_if_snpathref=in_param_if_snpathref,
41
+ semantic=semantic,
42
+ )
43
+
44
+ def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
45
+ odxlinks: dict[OdxLinkId, Any] = {}
46
+ return odxlinks
47
+
48
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
49
+ pass
50
+
51
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
52
+ pass
odxtools/request.py CHANGED
@@ -113,8 +113,8 @@ class Request(IdentifiableElement):
113
113
 
114
114
  return encode_state.coded_message
115
115
 
116
- def decode(self, message: bytes) -> ParameterValueDict:
117
- decode_state = DecodeState(coded_message=message)
116
+ def decode(self, message: bytes | bytearray) -> ParameterValueDict:
117
+ decode_state = DecodeState(coded_message=bytes(message))
118
118
  param_values = self.decode_from_pdu(decode_state)
119
119
 
120
120
  if not isinstance(param_values, dict):
@@ -129,5 +129,5 @@ class Request(IdentifiableElement):
129
129
  def decode_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
130
130
  return composite_codec_decode_from_pdu(self, decode_state)
131
131
 
132
- def coded_const_prefix(self, request_prefix: bytes = b'') -> bytes:
132
+ def coded_const_prefix(self, request_prefix: bytes = b'') -> bytearray:
133
133
  return composite_codec_get_coded_const_prefix(self, request_prefix)
odxtools/response.py CHANGED
@@ -109,14 +109,18 @@ class Response(IdentifiableElement):
109
109
  context.response = None
110
110
  context.parameters = None
111
111
 
112
- def encode(self, coded_request: bytes | None = None, **kwargs: ParameterValue) -> bytearray:
113
- encode_state = EncodeState(triggering_request=coded_request, is_end_of_pdu=True)
112
+ def encode(self,
113
+ coded_request: bytes | bytearray | None = None,
114
+ **kwargs: ParameterValue) -> bytearray:
115
+ encode_state = EncodeState(
116
+ triggering_request=bytes(coded_request) if coded_request is not None else None,
117
+ is_end_of_pdu=True)
114
118
 
115
119
  self.encode_into_pdu(physical_value=kwargs, encode_state=encode_state)
116
120
 
117
121
  return encode_state.coded_message
118
122
 
119
- def decode(self, message: bytes) -> ParameterValueDict:
123
+ def decode(self, message: bytes | bytearray) -> ParameterValueDict:
120
124
  decode_state = DecodeState(coded_message=message)
121
125
  param_values = self.decode_from_pdu(decode_state)
122
126
 
@@ -151,5 +155,5 @@ class Response(IdentifiableElement):
151
155
 
152
156
  print(parameter_info(self.free_parameters), end="")
153
157
 
154
- def coded_const_prefix(self, request_prefix: bytes = b'') -> bytes:
158
+ def coded_const_prefix(self, request_prefix: bytes = b'') -> bytearray:
155
159
  return composite_codec_get_coded_const_prefix(self, request_prefix)
odxtools/statemachine.py CHANGED
@@ -97,8 +97,9 @@ class StateMachine:
97
97
  self._state_chart = state_chart
98
98
  self._active_state = state_chart.start_state
99
99
 
100
- def execute(self, service: "DiagService", **service_params: Any
101
- ) -> Generator[bytes, bytes | bytearray | ParameterValueDict, None]:
100
+ def execute(
101
+ self, service: "DiagService", **service_params: Any
102
+ ) -> Generator[bytes | bytearray, bytes | bytearray | ParameterValueDict, None]:
102
103
  """Run a diagnostic service and update the state machine
103
104
  depending on the outcome.
104
105
 
odxtools/systemitem.py ADDED
@@ -0,0 +1,23 @@
1
+ # SPDX-License-Identifier: MIT
2
+ from dataclasses import dataclass
3
+ from xml.etree import ElementTree
4
+
5
+ from .configitem import ConfigItem
6
+ from .exceptions import odxrequire
7
+ from .odxdoccontext import OdxDocContext
8
+ from .utils import dataclass_fields_asdict
9
+
10
+
11
+ @dataclass(kw_only=True)
12
+ class SystemItem(ConfigItem):
13
+ """This class represents a SYSTEM-ITEM."""
14
+
15
+ sysparam: str
16
+
17
+ @staticmethod
18
+ def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "SystemItem":
19
+ kwargs = dataclass_fields_asdict(ConfigItem.from_et(et_element, context))
20
+
21
+ sysparam = odxrequire(et_element.attrib.get("SYSPARAM"))
22
+
23
+ return SystemItem(sysparam=sysparam, **kwargs)
@@ -1,6 +1,10 @@
1
1
  {#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
+ #
5
+ # This template writes an .odx-d file containing a diag layer container, i.e.,
6
+ # a collection of descriptions of the diagnostic interactions which are
7
+ # supported by variants of ECUs.
4
8
  -#}
5
9
  {%- import('macros/printOdxCategory.xml.jinja2') as poc %}
6
10
  {%- import('macros/printEcuSharedData.xml.jinja2') as pecusd -%}
@@ -0,0 +1,38 @@
1
+ {#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ #
5
+ # This template writes an .odx-e file containing an ECU-CONFIG description
6
+ # for variant coding.
7
+ -#}
8
+ {%- import('macros/printOdxCategory.xml.jinja2') as poc %}
9
+ {%- import('macros/printConfigData.xml.jinja2') as pcd %}
10
+ {%- import('macros/printConfigDataDictionarySpec.xml.jinja2') as pcdds %}
11
+ {%- import('macros/printAudience.xml.jinja2') as paud %}
12
+ {#- -#}
13
+
14
+ <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
15
+ <!-- Written using odxtools {{odxtools_version}} -->
16
+ <ODX MODEL-VERSION="2.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="odx.xsd">
17
+ {{- set_category_docfrag(ecu_config.short_name, "ECU-CONFIG") }}
18
+ <ECU-CONFIG {{- poc.printOdxCategoryAttribs(ecu_config) }}>
19
+ {{- poc.printOdxCategorySubtags(ecu_config)|indent(4) }}
20
+ {%- if ecu_config.config_datas %}
21
+ <CONFIG-DATAS>
22
+ {%- for config_data in ecu_config.config_datas %}
23
+ {{ pcd.printConfigData(config_data) | indent(6) }}
24
+ {%- endfor %}
25
+ </CONFIG-DATAS>
26
+ {%- endif %}
27
+ {%- if ecu_config.additional_audiences %}
28
+ <ADDITIONAL-AUDIENCES>
29
+ {%- for additional_audience in ecu_config.additional_audiences %}
30
+ {{ paud.printAdditionalAudience(additional_audience) | indent(6) }}
31
+ {%- endfor %}
32
+ </ADDITIONAL-AUDIENCES>
33
+ {%- endif %}
34
+ {%- if ecu_config.config_data_dictionary_spec %}
35
+ {{ pcdds.printConfigDataDictionarySpec(ecu_config.config_data_dictionary_spec) | indent(4) }}
36
+ {%- endif %}
37
+ </ECU-CONFIG>
38
+ </ODX>
@@ -2,8 +2,8 @@
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
4
  #
5
- # This template writes an .odx-cs file for a communication
6
- # parameter subset.
5
+ # This template writes an .odx-f file containing descriptions of firmware
6
+ # blobs that can be flashed to ECUs.
7
7
  -#}
8
8
  {%- import('macros/printOdxCategory.xml.jinja2') as poc %}
9
9
  {%- import('macros/printEcuMem.xml.jinja2') as pem %}
@@ -11,8 +11,8 @@
11
11
  </ADDITIONAL-AUDIENCE>
12
12
  {%- endmacro -%}
13
13
 
14
- {%- macro printAudience(audience) -%}
15
- <AUDIENCE {{-make_bool_xml_attrib("IS-SUPPLIER", audience.is_supplier_raw)}}
14
+ {%- macro printAudience(audience, tag_name="AUDIENCE") -%}
15
+ <{{tag_name}} {{-make_bool_xml_attrib("IS-SUPPLIER", audience.is_supplier_raw)}}
16
16
  {{-make_bool_xml_attrib("IS-DEVELOPMENT", audience.is_development_raw)}}
17
17
  {{-make_bool_xml_attrib("IS-MANUFACTURING", audience.is_manufacturing_raw)}}
18
18
  {{-make_bool_xml_attrib("IS-AFTERSALES", audience.is_aftersales_raw)}}
@@ -31,5 +31,5 @@
31
31
  {%- endfor %}
32
32
  </DISABLED-AUDIENCE-REFS>
33
33
  {%- endif%}
34
- </AUDIENCE>
34
+ </{{tag_name}}>
35
35
  {%- endmacro -%}
@@ -31,6 +31,6 @@
31
31
  {%- if checksum.checksum_result.value_type is not none %}
32
32
  {#- #} TYPE="{{ checksum.checksum_result.value_type.value }}"
33
33
  {%- endif %}
34
- {#- #}>{{checksum.checksum_result.value}}</CHECKSUM-RESULT>
34
+ {#- #}>{{checksum.checksum_result.value_raw}}</CHECKSUM-RESULT>
35
35
  </CHECKSUM>
36
36
  {%- endmacro -%}
@@ -110,7 +110,7 @@
110
110
  </PROG-CODE>
111
111
  {%- endmacro -%}
112
112
 
113
- {%- macro printCompuMethod(cm) -%}
113
+ {%- macro printCompuMethod(cm) %}
114
114
  <COMPU-METHOD>
115
115
  <CATEGORY>{{cm.category.value}}</CATEGORY>
116
116
  {%- if cm.compu_internal_to_phys is not none %}
@@ -144,4 +144,4 @@
144
144
  </COMPU-PHYS-TO-INTERNAL>
145
145
  {%- endif %}
146
146
  </COMPU-METHOD>
147
- {%- endmacro -%}
147
+ {%- endmacro %}
@@ -0,0 +1,39 @@
1
+ 1{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ -#}
5
+
6
+ {%- import('macros/printAdminData.xml.jinja2') as pad %}
7
+ {%- import('macros/printConfigRecord.xml.jinja2') as pcr %}
8
+ {%- import('macros/printElementId.xml.jinja2') as peid %}
9
+ {%- import('macros/printSpecialData.xml.jinja2') as psd %}
10
+
11
+ {%- macro printConfigData(config_data) -%}
12
+ <CONFIG-DATA>
13
+ {{peid.printElementIdSubtags(config_data)|indent(2) }}
14
+ {%- if config_data.valid_base_variants %}
15
+ <VALID-BASE-VARIANTS>
16
+ {%- for valid_base_variant in config_data.valid_base_variants %}
17
+ <VALID-BASE-VARIANT>
18
+ {%- if valid_base_variant.ecu_variant_snrefs %}
19
+ <ECU-VARIANT-SNREFS>
20
+ {%- for ecu_variant_snref in valid_base_variant.ecu_variant_snrefs %}
21
+ <ECU-VARIANT-SNREF SHORT-NAME="{{ecu_variant_snref}}" />
22
+ {%- endfor %}
23
+ </ECU-VARIANT-SNREFS>
24
+ {%- endif %}
25
+ <BASE-VARIANT-SNREF SHORT-NAME="{{valid_base_variant.base_variant_snref}}" />
26
+ </VALID-BASE-VARIANT>
27
+ {%- endfor %}
28
+ </VALID-BASE-VARIANTS>
29
+ {%- endif %}
30
+ {%- if config_data.config_records %}
31
+ <CONFIG-RECORDS>
32
+ {%- for config_record in config_data.config_records %}
33
+ {{ pcr.printConfigRecord(config_record) | indent(4) }}
34
+ {%- endfor %}
35
+ </CONFIG-RECORDS>
36
+ {%- endif %}
37
+ {{- psd.printSpecialDataGroups(config_data.sdgs)|indent(2, first=True) }}{#- #}
38
+ </CONFIG-DATA>
39
+ {%- endmacro -%}
@@ -0,0 +1,22 @@
1
+ {#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ -#}
5
+
6
+ {%- import('macros/printDOP.xml.jinja2') as pdop %}
7
+ {%- import('macros/printUnitSpec.xml.jinja2') as punit %}
8
+
9
+ {%- macro printConfigDataDictionarySpec(cdds) -%}
10
+ <CONFIG-DATA-DICTIONARY-SPEC>
11
+ {%- if cdds.data_object_props %}
12
+ <DATA-OBJECT-PROPS>
13
+ {%- for dop in cdds.data_object_props %}
14
+ {{- pdop.printDataObjectProp(dop)|indent(3) }}
15
+ {%- endfor %}
16
+ </DATA-OBJECT-PROPS>
17
+ {%- endif %}
18
+ {%- if cdds.unit_spec %}
19
+ {{ punit.printUnitSpec(cdds.unit_spec)|indent(2) }}
20
+ {%- endif %}
21
+ </CONFIG-DATA-DICTIONARY-SPEC>
22
+ {%- endmacro -%}
@@ -0,0 +1,66 @@
1
+ 1{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ -#}
5
+
6
+ {%- import('macros/printAudience.xml.jinja2') as paud %}
7
+ {%- import('macros/printElementId.xml.jinja2') as peid %}
8
+ {%- import('macros/printItemValue.xml.jinja2') as piv %}
9
+ {%- import('macros/printSpecialData.xml.jinja2') as psd %}
10
+
11
+ {%- macro printConfigItemSubtags(config_item) %}
12
+ {#-#}{{ peid.printElementIdSubtags(config_item) }}
13
+ {%- if config_item.byte_position is not none %}
14
+ <BYTE-POSITION>{{config_item.byte_position}}</BYTE-POSITION>
15
+ {%- endif %}
16
+ {%- if config_item.bit_position is not none %}
17
+ <BIT-POSITION>{{config_item.bit_position}}</BIT-POSITION>
18
+ {%- endif %}
19
+ {%- if config_item.data_object_prop_ref is not none %}
20
+ <DATA-OBJECT-PROP-REF {{ make_ref_attribs(config_item.data_object_prop_ref) }} />
21
+ {%- endif %}
22
+ {%- if config_item.data_object_prop_snref is not none %}
23
+ <DATA-OBJECT-PROP-SNREF SHORT-NAME="{{ config_item.data_object_prop_snref }}" />
24
+ {%- endif %}
25
+ {{- psd.printSpecialDataGroups(config_item.sdgs) }}
26
+ {%- endmacro %}
27
+
28
+ {%- macro printConfigIdItem(config_id_item) %}
29
+ <CONFIG-ID-ITEM>
30
+ {{ printConfigItemSubtags(config_id_item)|indent(2) }}
31
+ </CONFIG-ID-ITEM>
32
+ {%- endmacro %}
33
+
34
+ {%- macro printDataIdItem(data_id_item) %}
35
+ <DATA-ID-ITEM>
36
+ {{ printConfigItemSubtags(data_id_item)|indent(2) }}
37
+ </DATA-ID-ITEM>
38
+ {%- endmacro %}
39
+
40
+ {%- macro printOptionItem(option_item) %}
41
+ <OPTION-ITEM>
42
+ {{ printConfigItemSubtags(option_item)|indent(2) }}
43
+ {%- if option_item.physical_default_value is not none %}
44
+ <PHYSICAL-DEFAULT-VALUE>{{ option_item.physical_default_value|e }}</PHYSICAL-DEFAULT-VALUE>
45
+ {%- endif %}
46
+ {%- if option_item.item_values %}
47
+ <ITEM-VALUES>
48
+ {%- for item_value in option_item.item_values %}
49
+ {{ piv.printItemValue(item_value) }}
50
+ {%- endfor %}
51
+ </ITEM-VALUES>
52
+ {%- endif %}
53
+ {%- if option_item.write_audience is not none %}
54
+ {{ paud.printAudience(option_item.write_audience, "WRITE-AUDIENCE")}}
55
+ {%- endif %}
56
+ {%- if option_item.read_audience is not none %}
57
+ {{ paud.printAudience(option_item.read_audience, "READ-AUDIENCE")}}
58
+ {%- endif %}
59
+ </OPTION-ITEM>
60
+ {%- endmacro %}
61
+
62
+ {%- macro printSystemItem(system_item) %}
63
+ <SYSTEM-ITEM {{ make_xml_attrib("SYSPARAM", system_item.sysparam) }}>
64
+ {{ printConfigItemSubtags(system_item)|indent(2) }}
65
+ </SYSTEM-ITEM>
66
+ {%- endmacro %}
@@ -0,0 +1,73 @@
1
+ 1{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ -#}
5
+
6
+ {%- import('macros/printAdminData.xml.jinja2') as pad %}
7
+ {%- import('macros/printAudience.xml.jinja2') as paud %}
8
+ {%- import('macros/printDataRecord.xml.jinja2') as pdr %}
9
+ {%- import('macros/printDiagCommDataConnector.xml.jinja2') as pdcdc %}
10
+ {%- import('macros/printElementId.xml.jinja2') as peid %}
11
+ {%- import('macros/printConfigItems.xml.jinja2') as pcits %}
12
+ {%- import('macros/printSpecialData.xml.jinja2') as psd %}
13
+
14
+ {%- macro printConfigRecord(config_record) -%}
15
+ <CONFIG-RECORD>
16
+ {{peid.printElementIdSubtags(config_record)|indent(2) }}
17
+ {%- if config_record.config_id_item is not none %}
18
+ {{- pcits.printConfigIdItem(config_record.config_id_item)|indent(2)}}
19
+ {%- endif %}
20
+ {%- if config_record.data_items %}
21
+ <DATA-ITEMS>
22
+ {%- for data_item in config_record.data_items %}
23
+ {{ pcits.printDataItem(data_item) | indent(4) }}
24
+ {%- endfor %}
25
+ </DATA-ITEMS>
26
+ {%- endif %}
27
+ {%- if config_record.diag_comm_data_connectors %}
28
+ <DIAG-COMM-DATA-CONNECTORS>
29
+ {%- for connector in config_record.diag_comm_data_connectors %}
30
+ {{ pdcdc.printDiagCommDataConnector(connector) | indent(4) }}
31
+ {%- endfor %}
32
+ </DIAG-COMM-DATA-CONNECTORS>
33
+ {%- endif %}
34
+ {%- if config_record.config_id is not none %}
35
+ <CONFIG-ID
36
+ {%- if config_record.config_id.value_type is not none %}
37
+ {#- #} TYPE="{{ config_record.config_id.value_type.value }}"
38
+ {%- endif %}
39
+ {#- #}>{{config_record.config_id.value}}</CONFIG-ID>
40
+ {%- endif %}
41
+ {%- if config_record.data_records %}
42
+ <DATA-RECORDS>
43
+ {%- for data_record in config_record.data_records %}
44
+ {{ pdr.printDataRecord(data_record) | indent(4) }}
45
+ {%- endfor %}
46
+ </DATA-RECORDS>
47
+ {%- endif %}
48
+ {%- if config_record.audience is not none %}
49
+ {{ paud.printAudience(config_record.audience) | indent(2) }}
50
+ {%- endif %}
51
+ {%- if config_record.system_items %}
52
+ <SYSTEM-ITEMS>
53
+ {%- for system_item in config_record.system_items %}
54
+ {{- pcits.printSystemItem(system_item) | indent(4) }}
55
+ {%- endfor %}
56
+ </SYSTEM-ITEMS>
57
+ {%- endif %}
58
+ {%- if config_record.data_id_item is not none %}
59
+ {{- pcits.printDataIdItem(config_record.data_id_item)|indent(2)}}
60
+ {%- endif %}
61
+ {%- if config_record.option_items %}
62
+ <OPTION-ITEMS>
63
+ {%- for option_item in config_record.option_items %}
64
+ {{- pcits.printOptionItem(option_item) | indent(4) }}
65
+ {%- endfor %}
66
+ </OPTION-ITEMS>
67
+ {%- endif %}
68
+ {%- if config_record.default_data_record_snref is not none %}
69
+ <DEFAULT-DATA-RECORD-SNREF SHORT-NAME="{{config_record.default_data_record_snref}}" />
70
+ {%- endif %}
71
+ {{- psd.printSpecialDataGroups(config_record.sdgs)|indent(2, first=True) }}{#- #}
72
+ </CONFIG-RECORD>
73
+ {%- endmacro -%}
@@ -10,7 +10,7 @@
10
10
  {%- import('macros/printDescription.xml.jinja2') as pd %}
11
11
 
12
12
 
13
- {%- macro printDiagCodedType(dct) -%}
13
+ {%- macro printDiagCodedType(dct) %}
14
14
  <DIAG-CODED-TYPE {{-make_xml_attrib("BASE-DATA-TYPE", dct.base_data_type.value)}}
15
15
  {{-make_xml_attrib("BASE-TYPE-ENCODING", dct.base_type_encoding and dct.base_type_encoding.value)}}
16
16
  {{-make_bool_xml_attrib("IS-HIGHLOW-BYTE-ORDER", dct.is_highlow_byte_order_raw)}}
@@ -34,7 +34,7 @@
34
34
  <MIN-LENGTH>{{dct.min_length}}</MIN-LENGTH>
35
35
  {%- endif %}
36
36
  </DIAG-CODED-TYPE>
37
- {%- endmacro -%}
37
+ {%- endmacro %}
38
38
 
39
39
  {%- macro printPhysicalType(physical_type) %}
40
40
  {%- if physical_type.display_radix is not none %}
@@ -84,7 +84,6 @@
84
84
  {%- macro printDopBaseAttribs(dop) %}
85
85
  {{- make_xml_attrib("ID", dop.odx_id.local_id) }}
86
86
  {{- make_xml_attrib("OID", dop.oid) }}
87
- {#- -#}
88
87
  {%- endmacro %}
89
88
 
90
89
  {%- macro printDopBaseSubtags(dop) %}
@@ -92,8 +91,8 @@
92
91
  {%- if dop.admin_data %}
93
92
  {{ pad.printAdminData(dop.admin_data)|indent(1) }}
94
93
  {%- endif %}
95
- {{ psd.printSpecialDataGroups(dop.sdgs)|indent(1) }}
96
- {%- endmacro -%}
94
+ {{- psd.printSpecialDataGroups(dop.sdgs)|indent(1) }}
95
+ {%- endmacro %}
97
96
 
98
97
  {%- macro printComplexDopAttribs(st) %}
99
98
  {{- printDopBaseAttribs(st) }}
@@ -101,7 +100,7 @@
101
100
 
102
101
  {%- macro printComplexDopSubtags(st) %}
103
102
  {{- printDopBaseSubtags(st) }}
104
- {%- endmacro -%}
103
+ {%- endmacro %}
105
104
 
106
105
  {%- macro printDataObjectProp(dop) %}
107
106
  <DATA-OBJECT-PROP {{- printDopBaseAttribs(dop) }}>