Skip to content

Commit 5cc2c95

Browse files
authored
Merge pull request #394 from andlaus/base_variant_patterns
Implement base variant patterns
2 parents 924c08e + 1040df0 commit 5cc2c95

21 files changed

+1560
-796
lines changed

examples/somersaultecu.py

+1
Original file line numberDiff line numberDiff line change
@@ -2419,6 +2419,7 @@ class SomersaultSID(IntEnum):
24192419
variable_groups=NamedItemList(),
24202420
libraries=NamedItemList(),
24212421
sub_components=NamedItemList(),
2422+
base_variant_pattern=None,
24222423
dyn_defined_spec=None)
24232424
somersault_base_variant = BaseVariant(diag_layer_raw=somersault_base_variant_raw)
24242425

odxtools/basevariantpattern.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# SPDX-License-Identifier: MIT
2+
from dataclasses import dataclass
3+
from typing import List, Union
4+
from xml.etree import ElementTree
5+
6+
from typing_extensions import override
7+
8+
from .exceptions import odxassert
9+
from .matchingbasevariantparameter import MatchingBaseVariantParameter
10+
from .matchingparameter import MatchingParameter
11+
from .odxlink import OdxDocFragment
12+
from .variantpattern import VariantPattern
13+
14+
15+
@dataclass
16+
class BaseVariantPattern(VariantPattern):
17+
"""Base variant patterns are variant patterns used to identify the
18+
base variant of an ECU.
19+
"""
20+
matching_base_variant_parameters: List[MatchingBaseVariantParameter]
21+
22+
@override
23+
def get_matching_parameters(
24+
self) -> Union[List[MatchingParameter], List[MatchingBaseVariantParameter]]:
25+
return self.matching_base_variant_parameters
26+
27+
@staticmethod
28+
def from_et(et_element: ElementTree.Element,
29+
doc_frags: List[OdxDocFragment]) -> "BaseVariantPattern":
30+
31+
matching_base_variant_parameters = [
32+
MatchingBaseVariantParameter.from_et(mbvp_el, doc_frags)
33+
for mbvp_el in et_element.iterfind("MATCHING-BASE-VARIANT-PARAMETERS/"
34+
"MATCHING-BASE-VARIANT-PARAMETER")
35+
]
36+
37+
odxassert(len(matching_base_variant_parameters) > 0) # required by ISO 22901-1 Figure 141
38+
return BaseVariantPattern(matching_base_variant_parameters=matching_base_variant_parameters)

odxtools/createecuvariantpatterns.py

-18
This file was deleted.

odxtools/diaglayers/basevariant.py

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from typing_extensions import override
88

9+
from ..basevariantpattern import BaseVariantPattern
910
from ..diagvariable import DiagVariable
1011
from ..dyndefinedspec import DynDefinedSpec
1112
from ..exceptions import odxassert
@@ -38,6 +39,10 @@ def diag_variables_raw(self) -> List[Union[DiagVariable, OdxLinkRef]]:
3839
def dyn_defined_spec(self) -> Optional[DynDefinedSpec]:
3940
return self.base_variant_raw.dyn_defined_spec
4041

42+
@property
43+
def base_variant_pattern(self) -> Optional[BaseVariantPattern]:
44+
return self.base_variant_raw.base_variant_pattern
45+
4146
@property
4247
def parent_refs(self) -> List[ParentRef]:
4348
return self.base_variant_raw.parent_refs

odxtools/diaglayers/basevariantraw.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from typing import Any, Dict, List, Optional, Union
44
from xml.etree import ElementTree
55

6+
from ..basevariantpattern import BaseVariantPattern
67
from ..diagvariable import DiagVariable
78
from ..dyndefinedspec import DynDefinedSpec
89
from ..exceptions import odxraise
@@ -23,7 +24,7 @@ class BaseVariantRaw(HierarchyElementRaw):
2324
diag_variables_raw: List[Union[DiagVariable, OdxLinkRef]]
2425
variable_groups: NamedItemList[VariableGroup]
2526
dyn_defined_spec: Optional[DynDefinedSpec]
26-
# TODO: base_variant_pattern: Optional[BaseVariantPattern]
27+
base_variant_pattern: Optional[BaseVariantPattern]
2728
parent_refs: List[ParentRef]
2829

2930
@property
@@ -63,6 +64,10 @@ def from_et(et_element: ElementTree.Element,
6364
if (dds_elem := et_element.find("DYN-DEFINED-SPEC")) is not None:
6465
dyn_defined_spec = DynDefinedSpec.from_et(dds_elem, doc_frags)
6566

67+
base_variant_pattern = None
68+
if (bvp_elem := et_element.find("BASE-VARIANT-PATTERN")) is not None:
69+
base_variant_pattern = BaseVariantPattern.from_et(bvp_elem, doc_frags)
70+
6671
parent_refs = [
6772
ParentRef.from_et(pr_elem, doc_frags)
6873
for pr_elem in et_element.iterfind("PARENT-REFS/PARENT-REF")
@@ -72,6 +77,7 @@ def from_et(et_element: ElementTree.Element,
7277
diag_variables_raw=diag_variables_raw,
7378
variable_groups=variable_groups,
7479
dyn_defined_spec=dyn_defined_spec,
80+
base_variant_pattern=base_variant_pattern,
7581
parent_refs=parent_refs,
7682
**kwargs)
7783

odxtools/diaglayers/ecuvariant.py

+16
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkRef
1515
from ..parentref import ParentRef
1616
from ..variablegroup import HasVariableGroups, VariableGroup
17+
from .basevariant import BaseVariant
1718
from .diaglayer import DiagLayer
1819
from .ecuvariantraw import EcuVariantRaw
1920
from .hierarchyelement import HierarchyElement
@@ -38,6 +39,21 @@ def dyn_defined_spec(self) -> Optional[DynDefinedSpec]:
3839
def parent_refs(self) -> List[ParentRef]:
3940
return self.ecu_variant_raw.parent_refs
4041

42+
@property
43+
def base_variant(self) -> Optional[BaseVariant]:
44+
"""Return the base variant for the ECU variant
45+
46+
The ODX specification allows at a single base variant for each
47+
ECU variant, cf checker rule 50 of appendix B.2 of the
48+
specification document.
49+
50+
"""
51+
for pr in self.ecu_variant_raw.parent_refs:
52+
if isinstance(pr.layer, BaseVariant):
53+
return pr.layer
54+
55+
return None
56+
4157
@property
4258
def ecu_variant_patterns(self) -> List[EcuVariantPattern]:
4359
return self.ecu_variant_raw.ecu_variant_patterns

odxtools/ecuvariantmatcher.py

-171
This file was deleted.

odxtools/ecuvariantpattern.py

+20-9
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,38 @@
11
# SPDX-License-Identifier: MIT
22
from dataclasses import dataclass
3-
from typing import List
3+
from typing import List, Union
44
from xml.etree import ElementTree
55

6-
from .exceptions import odxassert, odxrequire
6+
from typing_extensions import override
7+
8+
from .exceptions import odxassert
9+
from .matchingbasevariantparameter import MatchingBaseVariantParameter
710
from .matchingparameter import MatchingParameter
811
from .odxlink import OdxDocFragment
12+
from .variantpattern import VariantPattern
913

1014

1115
@dataclass
12-
class EcuVariantPattern:
16+
class EcuVariantPattern(VariantPattern):
17+
"""ECU variant patterns are variant patterns used to identify the
18+
concrete variant of an ECU.
19+
"""
1320
matching_parameters: List[MatchingParameter]
1421

22+
@override
23+
def get_matching_parameters(
24+
self) -> Union[List[MatchingParameter], List[MatchingBaseVariantParameter]]:
25+
return self.matching_parameters
26+
1527
@staticmethod
1628
def from_et(et_element: ElementTree.Element,
1729
doc_frags: List[OdxDocFragment]) -> "EcuVariantPattern":
1830

19-
mp_collection_el = odxrequire(et_element.find("MATCHING-PARAMETERS"))
20-
21-
matching_params = [
31+
matching_parameters = [
2232
MatchingParameter.from_et(mp_el, doc_frags)
23-
for mp_el in mp_collection_el.iterfind("MATCHING-PARAMETER")
33+
for mp_el in et_element.iterfind("MATCHING-PARAMETERS/"
34+
"MATCHING-PARAMETER")
2435
]
2536

26-
odxassert(len(matching_params) > 0) # required by ISO 22901-1 Figure 141
27-
return EcuVariantPattern(matching_params)
37+
odxassert(len(matching_parameters) > 0) # required by ISO 22901-1 Figure 141
38+
return EcuVariantPattern(matching_parameters=matching_parameters)

0 commit comments

Comments
 (0)