-
Notifications
You must be signed in to change notification settings - Fork 93
Implement the ECU-CONFIG category #428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
bf267bd
243783d
ea1766a
83c036d
b15c00f
b7f38e7
b5e6635
aa5e9ec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# SPDX-License-Identifier: MIT | ||
from dataclasses import dataclass, field | ||
from typing import Any | ||
from xml.etree import ElementTree | ||
|
||
from .configrecord import ConfigRecord | ||
from .element import NamedElement | ||
from .nameditemlist import NamedItemList | ||
from .odxdoccontext import OdxDocContext | ||
from .odxlink import OdxLinkDatabase, OdxLinkId | ||
from .snrefcontext import SnRefContext | ||
from .specialdatagroup import SpecialDataGroup | ||
from .utils import dataclass_fields_asdict | ||
from .validbasevariant import ValidBaseVariant | ||
|
||
|
||
@dataclass(kw_only=True) | ||
class ConfigData(NamedElement): | ||
"""This class represents a CONFIG-DATA.""" | ||
valid_base_variants: list[ValidBaseVariant] | ||
config_records: NamedItemList[ConfigRecord] | ||
sdgs: list[SpecialDataGroup] = field(default_factory=list) | ||
|
||
@staticmethod | ||
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ConfigData": | ||
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context)) | ||
|
||
valid_base_variants = [ | ||
ValidBaseVariant.from_et(vbv_elem, context) | ||
for vbv_elem in et_element.iterfind("VALID-BASE-VARIANTS/VALID-BASE-VARIANT") | ||
] | ||
config_records = NamedItemList([ | ||
ConfigRecord.from_et(cr_elem, context) | ||
for cr_elem in et_element.iterfind("CONFIG-RECORDS/CONFIG-RECORD") | ||
]) | ||
sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")] | ||
|
||
return ConfigData( | ||
valid_base_variants=valid_base_variants, | ||
config_records=config_records, | ||
sdgs=sdgs, | ||
**kwargs) | ||
|
||
def _build_odxlinks(self) -> dict[OdxLinkId, Any]: | ||
result = {} | ||
|
||
for valid_base_variant in self.valid_base_variants: | ||
result.update(valid_base_variant._build_odxlinks()) | ||
for config_record in self.config_records: | ||
result.update(config_record._build_odxlinks()) | ||
for sdg in self.sdgs: | ||
result.update(sdg._build_odxlinks()) | ||
|
||
return result | ||
|
||
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: | ||
for valid_base_variant in self.valid_base_variants: | ||
valid_base_variant._resolve_odxlinks(odxlinks) | ||
for config_record in self.config_records: | ||
config_record._resolve_odxlinks(odxlinks) | ||
for sdg in self.sdgs: | ||
sdg._resolve_odxlinks(odxlinks) | ||
|
||
def _resolve_snrefs(self, context: SnRefContext) -> None: | ||
for valid_base_variant in self.valid_base_variants: | ||
valid_base_variant._resolve_snrefs(context) | ||
for config_record in self.config_records: | ||
config_record._resolve_snrefs(context) | ||
for sdg in self.sdgs: | ||
sdg._resolve_snrefs(context) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# SPDX-License-Identifier: MIT | ||
from dataclasses import dataclass, field | ||
from typing import Any | ||
from xml.etree import ElementTree | ||
|
||
from .dataobjectproperty import DataObjectProperty | ||
from .nameditemlist import NamedItemList | ||
from .odxdoccontext import OdxDocContext | ||
from .odxlink import OdxLinkDatabase, OdxLinkId | ||
from .snrefcontext import SnRefContext | ||
from .unitspec import UnitSpec | ||
|
||
|
||
@dataclass(kw_only=True) | ||
class ConfigDataDictionarySpec: | ||
data_object_props: NamedItemList[DataObjectProperty] = field(default_factory=NamedItemList) | ||
unit_spec: UnitSpec | None = None | ||
|
||
@staticmethod | ||
def from_et(et_element: ElementTree.Element, | ||
context: OdxDocContext) -> "ConfigDataDictionarySpec": | ||
data_object_props = NamedItemList([ | ||
DataObjectProperty.from_et(dop_element, context) | ||
for dop_element in et_element.iterfind("DATA-OBJECT-PROPS/DATA-OBJECT-PROP") | ||
]) | ||
|
||
if (spec_elem := et_element.find("UNIT-SPEC")) is not None: | ||
unit_spec = UnitSpec.from_et(spec_elem, context) | ||
else: | ||
unit_spec = None | ||
|
||
return ConfigDataDictionarySpec( | ||
data_object_props=data_object_props, | ||
unit_spec=unit_spec, | ||
) | ||
|
||
def _build_odxlinks(self) -> dict[OdxLinkId, Any]: | ||
odxlinks = {} | ||
|
||
for data_object_prop in self.data_object_props: | ||
odxlinks.update(data_object_prop._build_odxlinks()) | ||
if self.unit_spec is not None: | ||
odxlinks.update(self.unit_spec._build_odxlinks()) | ||
|
||
return odxlinks | ||
|
||
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: | ||
for data_object_prop in self.data_object_props: | ||
data_object_prop._resolve_odxlinks(odxlinks) | ||
if self.unit_spec is not None: | ||
self.unit_spec._resolve_odxlinks(odxlinks) | ||
|
||
def _resolve_snrefs(self, context: SnRefContext) -> None: | ||
for data_object_prop in self.data_object_props: | ||
data_object_prop._resolve_snrefs(context) | ||
if self.unit_spec is not None: | ||
self.unit_spec._resolve_snrefs(context) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# SPDX-License-Identifier: MIT | ||
from dataclasses import dataclass | ||
from xml.etree import ElementTree | ||
|
||
from .configitem import ConfigItem | ||
from .odxdoccontext import OdxDocContext | ||
from .utils import dataclass_fields_asdict | ||
|
||
|
||
@dataclass(kw_only=True) | ||
class ConfigIdItem(ConfigItem): | ||
"""This class represents a CONFIG-ID-ITEM.""" | ||
|
||
@staticmethod | ||
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ConfigIdItem": | ||
kwargs = dataclass_fields_asdict(ConfigItem.from_et(et_element, context)) | ||
|
||
return ConfigIdItem(**kwargs) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# SPDX-License-Identifier: MIT | ||
from dataclasses import dataclass, field | ||
from typing import Any | ||
from xml.etree import ElementTree | ||
|
||
from .dopbase import DopBase | ||
from .element import NamedElement | ||
from .exceptions import odxrequire | ||
from .odxdoccontext import OdxDocContext | ||
from .odxlink import OdxLinkDatabase, OdxLinkId, OdxLinkRef, resolve_snref | ||
from .snrefcontext import SnRefContext | ||
from .specialdatagroup import SpecialDataGroup | ||
from .utils import dataclass_fields_asdict | ||
|
||
|
||
@dataclass(kw_only=True) | ||
class ConfigItem(NamedElement): | ||
"""This class represents a CONFIG-ITEM. | ||
|
||
CONFIG-ITEM is the base class for CONFIG-ID-ITEM, DATA-ID-ITEM, | ||
OPTION-ITEM, and SYSTEM-ITEM. | ||
""" | ||
byte_position: int | None = None | ||
bit_position: int | None = None | ||
|
||
# according to the spec exactly one of the following two | ||
# attributes is not None...x | ||
data_object_prop_ref: OdxLinkRef | None = None | ||
data_object_prop_snref: str | None = None | ||
sdgs: list[SpecialDataGroup] = field(default_factory=list) | ||
|
||
@property | ||
def data_object_prop(self) -> DopBase: | ||
return self._data_object_prop | ||
|
||
@staticmethod | ||
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ConfigItem": | ||
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context)) | ||
|
||
byte_position = None | ||
if (byte_pos_elem := et_element.findtext("BYTE-POSITION")) is not None: | ||
byte_position = int(byte_pos_elem) | ||
|
||
bit_position = None | ||
if (bit_pos_elem := et_element.findtext("BIT-POSITION")) is not None: | ||
bit_position = int(bit_pos_elem) | ||
|
||
data_object_prop_ref = OdxLinkRef.from_et(et_element.find("DATA-OBJECT-PROP-REF"), context) | ||
data_object_prop_snref = None | ||
if (data_object_prop_snref_elem := et_element.find("DATA-OBJECT-PROP-SNREF")) is not None: | ||
data_object_prop_snref = odxrequire( | ||
data_object_prop_snref_elem.attrib.get("SHORT-NAME")) | ||
sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")] | ||
|
||
return ConfigItem( | ||
byte_position=byte_position, | ||
bit_position=bit_position, | ||
data_object_prop_ref=data_object_prop_ref, | ||
data_object_prop_snref=data_object_prop_snref, | ||
sdgs=sdgs, | ||
**kwargs) | ||
|
||
def _build_odxlinks(self) -> dict[OdxLinkId, Any]: | ||
result = {} | ||
|
||
for sdg in self.sdgs: | ||
result.update(sdg._build_odxlinks()) | ||
|
||
return result | ||
|
||
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: | ||
if self.data_object_prop_ref is not None: | ||
self._data_object_prop = odxlinks.resolve(self.data_object_prop_ref, DopBase) | ||
|
||
for sdg in self.sdgs: | ||
sdg._resolve_odxlinks(odxlinks) | ||
|
||
def _resolve_snrefs(self, context: SnRefContext) -> None: | ||
if self.data_object_prop_snref is not None: | ||
ddds = odxrequire(context.diag_layer).diag_data_dictionary_spec | ||
self._data_object_prop = resolve_snref(self.data_object_prop_snref, | ||
ddds.all_data_object_properties, DopBase) | ||
|
||
for sdg in self.sdgs: | ||
sdg._resolve_snrefs(context) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# SPDX-License-Identifier: MIT | ||
from dataclasses import dataclass, field | ||
from typing import Any | ||
from xml.etree import ElementTree | ||
|
||
from .audience import Audience | ||
from .configiditem import ConfigIdItem | ||
from .dataiditem import DataIdItem | ||
from .datarecord import DataRecord | ||
from .diagcommdataconnector import DiagCommDataConnector | ||
from .element import NamedElement | ||
from .exceptions import odxrequire | ||
from .identvalue import IdentValue | ||
from .nameditemlist import NamedItemList | ||
from .odxdoccontext import OdxDocContext | ||
from .odxlink import OdxLinkDatabase, OdxLinkId | ||
from .optionitem import OptionItem | ||
from .snrefcontext import SnRefContext | ||
from .specialdatagroup import SpecialDataGroup | ||
from .systemitem import SystemItem | ||
from .utils import dataclass_fields_asdict | ||
|
||
|
||
@dataclass(kw_only=True) | ||
class ConfigRecord(NamedElement): | ||
"""This class represents a CONFIG-RECORD.""" | ||
config_id_item: ConfigIdItem | None = None | ||
diag_comm_data_connectors: list[DiagCommDataConnector] = field(default_factory=list) | ||
config_id: IdentValue | None = None | ||
data_records: NamedItemList[DataRecord] = field(default_factory=NamedItemList) | ||
audience: Audience | None = None | ||
system_items: NamedItemList[SystemItem] = field(default_factory=NamedItemList) | ||
data_id_item: DataIdItem | None = None | ||
option_items: NamedItemList[OptionItem] = field(default_factory=NamedItemList) | ||
default_data_record_snref: str | None = None | ||
sdgs: list[SpecialDataGroup] = field(default_factory=list) | ||
|
||
@staticmethod | ||
def from_et(et_element: ElementTree.Element, context: OdxDocContext) -> "ConfigRecord": | ||
kwargs = dataclass_fields_asdict(NamedElement.from_et(et_element, context)) | ||
|
||
config_id_item = None | ||
if (cid_elem := et_element.find("CONFIG-ID-ITEM")) is not None: | ||
config_id_item = ConfigIdItem.from_et(cid_elem, context) | ||
diag_comm_data_connectors = [ | ||
DiagCommDataConnector.from_et(dcdc_elem, context) for dcdc_elem in et_element.iterfind( | ||
"DIAG-COMM-DATA-CONNECTORS/DIAG-COMM-DATA-CONNECTOR") | ||
] | ||
config_id = None | ||
if (cid_elem := et_element.find("CONFIG-ID")) is not None: | ||
config_id = IdentValue.from_et(cid_elem, context) | ||
data_records = NamedItemList([ | ||
DataRecord.from_et(dr_elem, context) | ||
for dr_elem in et_element.iterfind("DATA-RECORDS/DATA-RECORD") | ||
]) | ||
audience = None | ||
if (aud_elem := et_element.find("AUDIENCE")) is not None: | ||
audience = Audience.from_et(aud_elem, context) | ||
system_items = NamedItemList([ | ||
SystemItem.from_et(si_elem, context) | ||
for si_elem in et_element.iterfind("SYSTEM-ITEMS/SYSTEM-ITEM") | ||
]) | ||
data_id_item = None | ||
if (dii_elem := et_element.find("DATA-ID-ITEM")) is not None: | ||
data_id_item = DataIdItem.from_et(dii_elem, context) | ||
option_items = NamedItemList([ | ||
OptionItem.from_et(si_elem, context) | ||
for si_elem in et_element.iterfind("OPTION-ITEMS/OPTION-ITEM") | ||
]) | ||
default_data_record_snref = None | ||
if (default_data_record_snref_elem := | ||
et_element.find("DEFAULT-DATA-RECORD-SNREF")) is not None: | ||
default_data_record_snref = odxrequire( | ||
default_data_record_snref_elem.attrib.get("SHORT-NAME")) | ||
sdgs = [SpecialDataGroup.from_et(sdge, context) for sdge in et_element.iterfind("SDGS/SDG")] | ||
|
||
return ConfigRecord( | ||
config_id_item=config_id_item, | ||
diag_comm_data_connectors=diag_comm_data_connectors, | ||
config_id=config_id, | ||
data_records=data_records, | ||
audience=audience, | ||
system_items=system_items, | ||
data_id_item=data_id_item, | ||
option_items=option_items, | ||
default_data_record_snref=default_data_record_snref, | ||
sdgs=sdgs, | ||
**kwargs) | ||
|
||
def _build_odxlinks(self) -> dict[OdxLinkId, Any]: | ||
result = {} | ||
|
||
if self.config_id_item is not None: | ||
result.update(self.config_id_item._build_odxlinks()) | ||
for diag_comm_data_connector in self.diag_comm_data_connectors: | ||
result.update(diag_comm_data_connector._build_odxlinks()) | ||
for data_record in self.data_records: | ||
result.update(data_record._build_odxlinks()) | ||
if self.audience is not None: | ||
result.update(self.audience._build_odxlinks()) | ||
for system_item in self.system_items: | ||
result.update(system_item._build_odxlinks()) | ||
if self.data_id_item is not None: | ||
result.update(self.data_id_item._build_odxlinks()) | ||
for option_item in self.option_items: | ||
result.update(option_item._build_odxlinks()) | ||
for sdg in self.sdgs: | ||
result.update(sdg._build_odxlinks()) | ||
|
||
return result | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit off topic, but maybe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess the "leafs" of |
||
|
||
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None: | ||
if self.config_id_item is not None: | ||
self.config_id_item._resolve_odxlinks(odxlinks) | ||
for diag_comm_data_connector in self.diag_comm_data_connectors: | ||
diag_comm_data_connector._resolve_odxlinks(odxlinks) | ||
for data_record in self.data_records: | ||
data_record._resolve_odxlinks(odxlinks) | ||
if self.audience is not None: | ||
self.audience._resolve_odxlinks(odxlinks) | ||
for system_item in self.system_items: | ||
system_item._resolve_odxlinks(odxlinks) | ||
if self.data_id_item is not None: | ||
self.data_id_item._resolve_odxlinks(odxlinks) | ||
for option_item in self.option_items: | ||
option_item._resolve_odxlinks(odxlinks) | ||
for sdg in self.sdgs: | ||
sdg._resolve_odxlinks(odxlinks) | ||
|
||
def _resolve_snrefs(self, context: SnRefContext) -> None: | ||
if self.config_id_item is not None: | ||
self.config_id_item._resolve_snrefs(context) | ||
for diag_comm_data_connector in self.diag_comm_data_connectors: | ||
diag_comm_data_connector._resolve_snrefs(context) | ||
for data_record in self.data_records: | ||
data_record._resolve_snrefs(context) | ||
if self.audience is not None: | ||
self.audience._resolve_snrefs(context) | ||
for system_item in self.system_items: | ||
system_item._resolve_snrefs(context) | ||
if self.data_id_item is not None: | ||
self.data_id_item._resolve_snrefs(context) | ||
for option_item in self.option_items: | ||
option_item._resolve_snrefs(context) | ||
for sdg in self.sdgs: | ||
sdg._resolve_snrefs(context) |
Uh oh!
There was an error while loading. Please reload this page.