diff --git a/examples/somersaultecu.py b/examples/somersaultecu.py
index d2bd0fd3..536a5bbf 100755
--- a/examples/somersaultecu.py
+++ b/examples/somersaultecu.py
@@ -2144,6 +2144,7 @@ class SomersaultSID(IntEnum):
comparam_refs=somersault_comparam_refs,
libraries=NamedItemList(),
prot_stack_snref=None,
+ sub_components=NamedItemList(),
)
somersault_protocol = Protocol(diag_layer_raw=somersault_protocol_raw)
@@ -2182,6 +2183,7 @@ class SomersaultSID(IntEnum):
diag_variables_raw=[],
variable_groups=NamedItemList(),
libraries=NamedItemList(),
+ sub_components=NamedItemList(),
dyn_defined_spec=None)
somersault_base_variant = BaseVariant(diag_layer_raw=somersault_base_variant_raw)
@@ -2231,6 +2233,7 @@ class SomersaultSID(IntEnum):
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
somersault_lazy_ecu = EcuVariant(diag_layer_raw=somersault_lazy_ecu_raw)
@@ -2469,6 +2472,7 @@ class SomersaultSID(IntEnum):
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
somersault_assiduous_ecu = EcuVariant(diag_layer_raw=somersault_assiduous_ecu_raw)
diff --git a/odxtools/diaglayers/diaglayer.py b/odxtools/diaglayers/diaglayer.py
index caf5cfd1..2f3766fc 100644
--- a/odxtools/diaglayers/diaglayer.py
+++ b/odxtools/diaglayers/diaglayer.py
@@ -24,6 +24,7 @@
from ..singleecujob import SingleEcuJob
from ..snrefcontext import SnRefContext
from ..specialdatagroup import SpecialDataGroup
+from ..subcomponent import SubComponent
from ..unitgroup import UnitGroup
from .diaglayerraw import DiagLayerRaw
from .diaglayertype import DiagLayerType
@@ -261,9 +262,13 @@ def import_refs(self) -> List[OdxLinkRef]:
return self.diag_layer_raw.import_refs
@property
- def libraries(self) -> List[Library]:
+ def libraries(self) -> NamedItemList[Library]:
return self.diag_layer_raw.libraries
+ @property
+ def sub_components(self) -> NamedItemList[SubComponent]:
+ return self.diag_layer_raw.sub_components
+
@property
def sdgs(self) -> List[SpecialDataGroup]:
return self.diag_layer_raw.sdgs
diff --git a/odxtools/diaglayers/diaglayerraw.py b/odxtools/diaglayers/diaglayerraw.py
index f9d0e592..0d11aad7 100644
--- a/odxtools/diaglayers/diaglayerraw.py
+++ b/odxtools/diaglayers/diaglayerraw.py
@@ -22,6 +22,7 @@
from ..snrefcontext import SnRefContext
from ..specialdatagroup import SpecialDataGroup
from ..statechart import StateChart
+from ..subcomponent import SubComponent
from ..utils import dataclass_fields_asdict
from .diaglayertype import DiagLayerType
@@ -47,7 +48,7 @@ class DiagLayerRaw(IdentifiableElement):
import_refs: List[OdxLinkRef]
state_charts: NamedItemList[StateChart]
additional_audiences: NamedItemList[AdditionalAudience]
- # sub_components: List[DiagLayer] # TODO
+ sub_components: NamedItemList[SubComponent]
libraries: NamedItemList[Library]
sdgs: List[SpecialDataGroup]
@@ -154,6 +155,11 @@ def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) ->
Library.from_et(el, doc_frags) for el in et_element.iterfind("LIBRARYS/LIBRARY")
]
+ sub_components = [
+ SubComponent.from_et(el, doc_frags)
+ for el in et_element.iterfind("SUB-COMPONENTS/SUB-COMPONENT")
+ ]
+
sdgs = [
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
]
@@ -174,6 +180,7 @@ def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) ->
state_charts=NamedItemList(state_charts),
additional_audiences=NamedItemList(additional_audiences),
libraries=NamedItemList(libraries),
+ sub_components=NamedItemList(sub_components),
sdgs=sdgs,
**kwargs)
@@ -208,6 +215,8 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
odxlinks.update(additional_audience._build_odxlinks())
for library in self.libraries:
odxlinks.update(library._build_odxlinks())
+ for sub_comp in self.sub_components:
+ odxlinks.update(sub_comp._build_odxlinks())
for sdg in self.sdgs:
odxlinks.update(sdg._build_odxlinks())
@@ -262,6 +271,8 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
additional_audience._resolve_odxlinks(odxlinks)
for library in self.libraries:
library._resolve_odxlinks(odxlinks)
+ for sub_component in self.sub_components:
+ sub_component._resolve_odxlinks(odxlinks)
for sdg in self.sdgs:
sdg._resolve_odxlinks(odxlinks)
@@ -294,5 +305,7 @@ def _resolve_snrefs(self, context: SnRefContext) -> None:
additional_audience._resolve_snrefs(context)
for library in self.libraries:
library._resolve_snrefs(context)
+ for sub_component in self.sub_components:
+ sub_component._resolve_snrefs(context)
for sdg in self.sdgs:
sdg._resolve_snrefs(context)
diff --git a/odxtools/subcomponent.py b/odxtools/subcomponent.py
new file mode 100644
index 00000000..5fcd2d2c
--- /dev/null
+++ b/odxtools/subcomponent.py
@@ -0,0 +1,288 @@
+# SPDX-License-Identifier: MIT
+from dataclasses import dataclass
+from typing import Any, Dict, List, Optional
+from xml.etree import ElementTree
+
+from .diagnostictroublecode import DiagnosticTroubleCode
+from .diagservice import DiagService
+from .dtcdop import DtcDop
+from .element import IdentifiableElement, NamedElement
+from .environmentdata import EnvironmentData
+from .environmentdatadescription import EnvironmentDataDescription
+from .exceptions import odxraise, odxrequire
+from .matchingparameter import MatchingParameter
+from .nameditemlist import NamedItemList
+from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref
+from .parameters.parameter import Parameter
+from .snrefcontext import SnRefContext
+from .table import Table
+from .tablerow import TableRow
+from .utils import dataclass_fields_asdict
+
+
+@dataclass
+class SubComponentPattern:
+ matching_parameters: List[MatchingParameter]
+
+ @staticmethod
+ def from_et(et_element: ElementTree.Element,
+ doc_frags: List[OdxDocFragment]) -> "SubComponentPattern":
+
+ matching_parameters = [
+ MatchingParameter.from_et(el, doc_frags)
+ for el in et_element.iterfind("MATCHING-PARAMETERS/MATCHING-PARAMETER")
+ ]
+
+ return SubComponentPattern(matching_parameters=matching_parameters)
+
+
+@dataclass
+class SubComponentParamConnector(IdentifiableElement):
+ diag_comm_snref: str
+
+ # TODO: we currently only support SNREFs, not SNPATHREFs
+ out_param_if_refs: List[str]
+ in_param_if_refs: List[str]
+
+ @property
+ def service(self) -> DiagService:
+ return self._service
+
+ @property
+ def out_param_ifs(self) -> NamedItemList[Parameter]:
+ return self._out_param_ifs
+
+ @property
+ def in_param_ifs(self) -> NamedItemList[Parameter]:
+ return self._in_param_ifs
+
+ @staticmethod
+ def from_et(et_element: ElementTree.Element,
+ doc_frags: List[OdxDocFragment]) -> "SubComponentParamConnector":
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
+
+ diag_comm_snref = odxrequire(
+ odxrequire(et_element.find("DIAG-COMM-SNREF")).get("SHORT-NAME"))
+
+ out_param_if_refs = []
+ for elem in et_element.find("OUT-PARAM-IF-REFS") or []:
+ if elem.tag != "OUT-PARAM-IF-SNREF":
+ odxraise("Currently, only SNREFS are supported for OUT-PARAM-IF-REFS")
+ continue
+
+ out_param_if_refs.append(odxrequire(elem.get("SHORT-NAME")))
+
+ in_param_if_refs = []
+ for elem in et_element.find("IN-PARAM-IF-REFS") or []:
+ if elem.tag != "IN-PARAM-IF-SNREF":
+ odxraise("Currently, only SNREFS are supported for IN-PARAM-IF-REFS")
+ continue
+
+ in_param_if_refs.append(odxrequire(elem.get("SHORT-NAME")))
+
+ return SubComponentParamConnector(
+ diag_comm_snref=diag_comm_snref,
+ out_param_if_refs=out_param_if_refs,
+ in_param_if_refs=in_param_if_refs,
+ **kwargs)
+
+ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
+ return {}
+
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
+ pass
+
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
+ service = resolve_snref(self.diag_comm_snref,
+ odxrequire(context.diag_layer).diag_comms, DiagService)
+ self._service = service
+
+ if self._service.request is not None:
+ odxraise()
+ return
+ if not self._service.positive_responses:
+ odxraise()
+ return
+ request = odxrequire(service.request)
+ response = service.positive_responses[0]
+
+ in_param_ifs = []
+ for x in self.in_param_if_refs:
+ in_param_ifs.append(resolve_snref(x, request.parameters, Parameter))
+
+ out_param_ifs = []
+ for x in self.out_param_if_refs:
+ out_param_ifs.append(resolve_snref(x, response.parameters, Parameter))
+
+ self._in_param_ifs = NamedItemList(in_param_ifs)
+ self._out_param_ifs = NamedItemList(out_param_ifs)
+
+
+@dataclass
+class TableRowConnector(NamedElement):
+ table_ref: OdxLinkRef
+ table_row_snref: str
+
+ @property
+ def table(self) -> Table:
+ return self._table
+
+ @property
+ def table_row(self) -> TableRow:
+ return self._table_row
+
+ @staticmethod
+ def from_et(et_element: ElementTree.Element,
+ doc_frags: List[OdxDocFragment]) -> "TableRowConnector":
+ kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
+
+ table_ref = odxrequire(OdxLinkRef.from_et(et_element.find("TABLE-REF"), doc_frags))
+ table_row_snref_el = odxrequire(et_element.find("TABLE-ROW-SNREF"))
+ table_row_snref = odxrequire(table_row_snref_el.get("SHORT-NAME"))
+
+ return TableRowConnector(table_ref=table_ref, table_row_snref=table_row_snref, **kwargs)
+
+ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
+ return {}
+
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
+ self._table = odxlinks.resolve(self.table_ref, Table)
+
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
+ self._table_row = resolve_snref(self.table_row_snref, self._table.table_rows, TableRow)
+
+
+@dataclass
+class DtcConnector(NamedElement):
+ dtc_dop_ref: OdxLinkRef
+ dtc_snref: str
+
+ @property
+ def dtc_dop(self) -> DtcDop:
+ return self._dtc_dop
+
+ @property
+ def dtc(self) -> DiagnosticTroubleCode:
+ return self._dtc
+
+ @staticmethod
+ def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "DtcConnector":
+ kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
+
+ dtc_dop_ref = odxrequire(OdxLinkRef.from_et(et_element.find("DTC-DOP-REF"), doc_frags))
+ dtc_snref_el = odxrequire(et_element.find("DTC-SNREF"))
+ dtc_snref = odxrequire(dtc_snref_el.get("SHORT-NAME"))
+
+ return DtcConnector(dtc_dop_ref=dtc_dop_ref, dtc_snref=dtc_snref, **kwargs)
+
+ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
+ return {}
+
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
+ self._dtc_dop = odxlinks.resolve(self.dtc_dop_ref, DtcDop)
+
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
+ self._dtc = resolve_snref(self.dtc_snref, self._dtc_dop.dtcs, DiagnosticTroubleCode)
+
+
+@dataclass
+class EnvDataConnector(NamedElement):
+ env_data_desc_ref: OdxLinkRef
+ env_data_snref: str
+
+ @property
+ def env_data_desc(self) -> EnvironmentDataDescription:
+ return self._env_data_desc
+
+ @property
+ def env_data(self) -> EnvironmentData:
+ return self._env_data
+
+ @staticmethod
+ def from_et(et_element: ElementTree.Element,
+ doc_frags: List[OdxDocFragment]) -> "EnvDataConnector":
+ kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, doc_frags))
+
+ env_data_desc_ref = odxrequire(
+ OdxLinkRef.from_et(et_element.find("ENV-DATA-DESC-REF"), doc_frags))
+ env_data_snref_el = odxrequire(et_element.find("ENV-DATA-SNREF"))
+ env_data_snref = odxrequire(env_data_snref_el.get("SHORT-NAME"))
+
+ return EnvDataConnector(
+ env_data_desc_ref=env_data_desc_ref, env_data_snref=env_data_snref, **kwargs)
+
+ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
+ return {}
+
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
+ self._env_data_desc = odxlinks.resolve(self.env_data_desc_ref, EnvironmentDataDescription)
+
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
+ self._env_data = resolve_snref(self.env_data_snref, self._env_data_desc.env_datas,
+ EnvironmentData)
+
+
+@dataclass
+class SubComponent(IdentifiableElement):
+ """Sub-components describe collections of related diagnostic variables
+
+ Note that the communication paradigm via diagnostic variables is
+ somewhat uncommon. If your ECU does not define any, there's no
+ need for it to define sub-components.
+
+ """
+
+ #sub_component_patterns: NamedItemList[SubComponentPattern]
+ sub_component_param_connectors: NamedItemList[SubComponentParamConnector]
+ table_row_connectors: NamedItemList[TableRowConnector]
+ env_data_connectors: NamedItemList[EnvDataConnector]
+ dtc_connectors: NamedItemList[DtcConnector]
+
+ semantic: Optional[str]
+
+ @staticmethod
+ def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "SubComponent":
+ kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
+
+ semantic = et_element.get("SEMANTIC")
+
+ sub_component_param_connectors = [
+ SubComponentParamConnector.from_et(el, doc_frags) for el in et_element.iterfind(
+ "SUB-COMPONENT-PARAM-CONNECTORS/SUB-COMPONENT-PARAM-CONNECTOR")
+ ]
+ table_row_connectors = [
+ TableRowConnector.from_et(el, doc_frags)
+ for el in et_element.iterfind("TABLE-ROW-CONNECTORS/TABLE-ROW-CONNECTOR")
+ ]
+ env_data_connectors = [
+ EnvDataConnector.from_et(el, doc_frags)
+ for el in et_element.iterfind("ENV-DATA-CONNECTORS/ENV-DATA-CONNECTOR")
+ ]
+ dtc_connectors = [
+ DtcConnector.from_et(el, doc_frags)
+ for el in et_element.iterfind("DTC-CONNECTORS/DTC-CONNECTOR")
+ ]
+
+ return SubComponent(
+ semantic=semantic,
+ sub_component_param_connectors=NamedItemList(sub_component_param_connectors),
+ table_row_connectors=NamedItemList(table_row_connectors),
+ env_data_connectors=NamedItemList(env_data_connectors),
+ dtc_connectors=NamedItemList(dtc_connectors),
+ **kwargs)
+
+ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
+ result = {}
+
+ for dtc_conn in self.dtc_connectors:
+ result.update(dtc_conn._build_odxlinks())
+
+ return result
+
+ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
+ for dtc_conn in self.dtc_connectors:
+ dtc_conn._resolve_odxlinks(odxlinks)
+
+ def _resolve_snrefs(self, context: SnRefContext) -> None:
+ for dtc_conn in self.dtc_connectors:
+ dtc_conn._resolve_snrefs(context)
diff --git a/odxtools/templates/macros/printDiagLayer.xml.jinja2 b/odxtools/templates/macros/printDiagLayer.xml.jinja2
index 0697b9e6..7cb8c969 100644
--- a/odxtools/templates/macros/printDiagLayer.xml.jinja2
+++ b/odxtools/templates/macros/printDiagLayer.xml.jinja2
@@ -22,6 +22,7 @@
{%- import('macros/printResponse.xml.jinja2') as presp %}
{%- import('macros/printStateChart.xml.jinja2') as psc %}
{%- import('macros/printAudience.xml.jinja2') as paud %}
+{%- import('macros/printSubComponent.xml.jinja2') as psubcomp %}
{%- import('macros/printLibrary.xml.jinja2') as plib %}
{%- import('macros/printSpecialData.xml.jinja2') as psd %}
{%- import('macros/printEcuVariantPattern.xml.jinja2') as pvpat %}
@@ -203,6 +204,13 @@
{%- endfor %}
{%- endif %}
+{%- if dlr.sub_components %}
+
+ {%- for sc in dlr.sub_components %}
+ {{ psubcomp.printSubComponent(sc)|indent(2) }}
+ {%- endfor %}
+
+{%- endif %}
{%- if dlr.libraries %}
{%- for lib in dlr.libraries %}
diff --git a/odxtools/templates/macros/printSubComponent.xml.jinja2 b/odxtools/templates/macros/printSubComponent.xml.jinja2
new file mode 100644
index 00000000..9118f835
--- /dev/null
+++ b/odxtools/templates/macros/printSubComponent.xml.jinja2
@@ -0,0 +1,104 @@
+{#- -*- mode: sgml; tab-width: 1; indent-tabs-mode: nil -*-
+#
+# SPDX-License-Identifier: MIT
+-#}
+
+{%- import('macros/printElementId.xml.jinja2') as peid %}
+{%- import('macros/printEcuVariantPattern.xml.jinja2') as pevp %}
+
+{%- macro printSubComponentPattern(pat) %}
+
+
+ {%- for mp in pat.matching_parameters %}
+ {{ pvp.printMatchingParameter(mp)|indent(4) }}
+ {%- endfor %}
+
+
+{%- endmacro %}
+
+{%- macro printSubComponentParamConnector(conn) %}
+
+ {{ peid.printElementIdSubtags(conn)|indent(2) }}
+
+ {%- if conn.out_param_if_refs %}
+
+ {%- for snref in conn.out_param_if_refs %}
+
+ {%- endfor %}
+
+ {%- endif %}
+ {%- if conn.in_param_if_refs %}
+
+ {%- for snref in conn.in_param_if_refs %}
+
+ {%- endfor %}
+
+ {%- endif %}
+
+{%- endmacro %}
+
+{%- macro printTableRowConnector(conn) %}
+
+ {{ peid.printElementIdSubtags(conn)|indent(2) }}
+
+
+
+{%- endmacro %}
+
+{%- macro printEnvDataConnector(conn) %}
+
+ {{ peid.printElementIdSubtags(conn)|indent(2) }}
+
+
+
+{%- endmacro %}
+
+{%- macro printDtcConnector(conn) %}
+
+ {{ peid.printElementIdSubtags(conn)|indent(2) }}
+
+
+
+{%- endmacro %}
+
+{%- macro printSubComponent(sc) %}
+
+ {{ peid.printElementIdSubtags(sc)|indent(2) }}
+ {%- if sc.sub_component_patterns %}
+
+ {%- for scp in sc.sub_component_patterns %}
+ {{ printSubComponentPattern(scp)|indent(4) }}
+ {%- endfor %}
+
+ {%- endif %}
+ {%- if sc.sub_component_param_connectors %}
+
+ {%- for conn in sc.sub_component_param_connectors %}
+ {{ printSubComponentParamConnector(conn)|indent(4) }}
+ {%- endfor %}
+
+ {%- endif %}
+ {%- if sc.table_row_connectors %}
+
+ {%- for conn in sc.table_row_connectors %}
+ {{ printTableRowConnector(conn)|indent(4) }}
+ {%- endfor %}
+
+ {%- endif %}
+ {%- if sc.env_data_connectors %}
+
+ {%- for conn in sc.env_data_connectors %}
+ {{ printEnvDataConnector(conn)|indent(4) }}
+ {%- endfor %}
+
+ {%- endif %}
+ {%- if sc.dtc_connectors %}
+
+ {%- for conn in sc.dtc_connectors %}
+ {{ printDtcConnector(conn)|indent(4) }}
+ {%- endfor %}
+
+ {%- endif %}
+
+{%- endmacro %}
diff --git a/tests/test_decoding.py b/tests/test_decoding.py
index c2a5b23f..c48a2b1e 100644
--- a/tests/test_decoding.py
+++ b/tests/test_decoding.py
@@ -238,6 +238,7 @@ def test_prefix_tree_construction(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
db = Database()
@@ -364,6 +365,7 @@ def test_decode_request_coded_const(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
@@ -562,6 +564,7 @@ def test_decode_nrc_const(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = BaseVariant(diag_layer_raw=base_variant_raw)
db = Database()
@@ -719,6 +722,7 @@ def test_decode_request_coded_const_undefined_byte_position(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
db = Database()
@@ -938,6 +942,7 @@ def test_decode_request_structure(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
@@ -1158,6 +1163,7 @@ def test_static_field_coding(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
@@ -1511,6 +1517,7 @@ def test_dynamic_endmarker_field_coding(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
@@ -1797,6 +1804,7 @@ def test_dynamic_length_field_coding(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
@@ -2040,6 +2048,7 @@ def test_decode_request_end_of_pdu_field(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
@@ -2229,6 +2238,7 @@ def test_decode_request_linear_compu_method(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
@@ -2428,6 +2438,7 @@ def test_decode_response(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
diff --git a/tests/test_diag_coded_types.py b/tests/test_diag_coded_types.py
index 36c19e9a..83d56156 100644
--- a/tests/test_diag_coded_types.py
+++ b/tests/test_diag_coded_types.py
@@ -301,6 +301,7 @@ def test_end_to_end(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
@@ -636,6 +637,7 @@ def test_end_to_end(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
@@ -981,6 +983,7 @@ def test_end_to_end(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
diff --git a/tests/test_ecu_variant_matching.py b/tests/test_ecu_variant_matching.py
index ae72f9c5..b4b1748a 100644
--- a/tests/test_ecu_variant_matching.py
+++ b/tests/test_ecu_variant_matching.py
@@ -227,6 +227,7 @@ def ecu_variant_1(
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
result = EcuVariant(diag_layer_raw=raw_layer)
odxlinks.update(result._build_odxlinks())
@@ -269,6 +270,7 @@ def ecu_variant_2(
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
result = EcuVariant(diag_layer_raw=raw_layer)
odxlinks.update(result._build_odxlinks())
@@ -312,6 +314,7 @@ def ecu_variant_3(
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
result = EcuVariant(diag_layer_raw=raw_layer)
odxlinks.update(result._build_odxlinks())
diff --git a/tests/test_encoding.py b/tests/test_encoding.py
index c3e9f936..709d38f5 100644
--- a/tests/test_encoding.py
+++ b/tests/test_encoding.py
@@ -398,6 +398,7 @@ def test_encode_nrc_const(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
diff --git a/tests/test_singleecujob.py b/tests/test_singleecujob.py
index 1a962c38..e24c589e 100644
--- a/tests/test_singleecujob.py
+++ b/tests/test_singleecujob.py
@@ -478,6 +478,7 @@ def test_resolve_odxlinks(self) -> None:
entrypoint="i_am_great")
]),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
ecu_variant = EcuVariant(diag_layer_raw=ecu_variant_raw)
odxlinks = OdxLinkDatabase()
diff --git a/tests/test_unit_spec.py b/tests/test_unit_spec.py
index f057aa5b..7464d565 100644
--- a/tests/test_unit_spec.py
+++ b/tests/test_unit_spec.py
@@ -214,6 +214,7 @@ def test_resolve_odxlinks(self) -> None:
variable_groups=NamedItemList(),
libraries=NamedItemList(),
dyn_defined_spec=None,
+ sub_components=NamedItemList(),
)
dl = EcuVariant(diag_layer_raw=dl_raw)
odxlinks = OdxLinkDatabase()