odxtools 6.6.1__py3-none-any.whl → 9.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.
- odxtools/__init__.py +7 -5
- odxtools/additionalaudience.py +3 -5
- odxtools/admindata.py +5 -7
- odxtools/audience.py +10 -13
- odxtools/basecomparam.py +3 -5
- odxtools/basicstructure.py +55 -241
- odxtools/cli/_parser_utils.py +16 -1
- odxtools/cli/_print_utils.py +169 -134
- odxtools/cli/browse.py +127 -103
- odxtools/cli/compare.py +114 -87
- odxtools/cli/decode.py +2 -1
- odxtools/cli/dummy_sub_parser.py +3 -1
- odxtools/cli/find.py +2 -1
- odxtools/cli/list.py +26 -16
- odxtools/cli/main.py +1 -0
- odxtools/cli/snoop.py +32 -6
- odxtools/codec.py +211 -0
- odxtools/commrelation.py +122 -0
- odxtools/companydata.py +5 -7
- odxtools/companydocinfo.py +7 -8
- odxtools/companyrevisioninfo.py +3 -5
- odxtools/companyspecificinfo.py +8 -9
- odxtools/comparam.py +4 -6
- odxtools/comparaminstance.py +14 -14
- odxtools/comparamspec.py +16 -54
- odxtools/comparamsubset.py +22 -62
- odxtools/complexcomparam.py +5 -7
- odxtools/compumethods/compucodecompumethod.py +63 -0
- odxtools/compumethods/compuconst.py +31 -0
- odxtools/compumethods/compudefaultvalue.py +27 -0
- odxtools/compumethods/compuinternaltophys.py +56 -0
- odxtools/compumethods/compuinversevalue.py +7 -0
- odxtools/compumethods/compumethod.py +94 -15
- odxtools/compumethods/compuphystointernal.py +56 -0
- odxtools/compumethods/compurationalcoeffs.py +20 -9
- odxtools/compumethods/compuscale.py +67 -32
- odxtools/compumethods/createanycompumethod.py +31 -172
- odxtools/compumethods/identicalcompumethod.py +31 -6
- odxtools/compumethods/limit.py +70 -36
- odxtools/compumethods/linearcompumethod.py +70 -181
- odxtools/compumethods/linearsegment.py +190 -0
- odxtools/compumethods/ratfunccompumethod.py +106 -0
- odxtools/compumethods/ratfuncsegment.py +87 -0
- odxtools/compumethods/scalelinearcompumethod.py +132 -26
- odxtools/compumethods/scaleratfunccompumethod.py +113 -0
- odxtools/compumethods/tabintpcompumethod.py +123 -92
- odxtools/compumethods/texttablecompumethod.py +117 -57
- odxtools/createanydiagcodedtype.py +10 -67
- odxtools/database.py +167 -87
- odxtools/dataobjectproperty.py +25 -32
- odxtools/decodestate.py +14 -17
- odxtools/description.py +47 -0
- odxtools/determinenumberofitems.py +4 -5
- odxtools/diagcodedtype.py +37 -106
- odxtools/diagcomm.py +24 -12
- odxtools/diagdatadictionaryspec.py +120 -96
- odxtools/diaglayercontainer.py +46 -54
- odxtools/diaglayers/basevariant.py +128 -0
- odxtools/diaglayers/basevariantraw.py +123 -0
- odxtools/diaglayers/diaglayer.py +432 -0
- odxtools/{diaglayerraw.py → diaglayers/diaglayerraw.py} +105 -120
- odxtools/diaglayers/diaglayertype.py +42 -0
- odxtools/diaglayers/ecushareddata.py +96 -0
- odxtools/diaglayers/ecushareddataraw.py +87 -0
- odxtools/diaglayers/ecuvariant.py +124 -0
- odxtools/diaglayers/ecuvariantraw.py +129 -0
- odxtools/diaglayers/functionalgroup.py +110 -0
- odxtools/diaglayers/functionalgroupraw.py +106 -0
- odxtools/{diaglayer.py → diaglayers/hierarchyelement.py} +273 -472
- odxtools/diaglayers/hierarchyelementraw.py +58 -0
- odxtools/diaglayers/protocol.py +64 -0
- odxtools/diaglayers/protocolraw.py +91 -0
- odxtools/diagnostictroublecode.py +8 -9
- odxtools/diagservice.py +57 -44
- odxtools/diagvariable.py +113 -0
- odxtools/docrevision.py +5 -7
- odxtools/dopbase.py +15 -15
- odxtools/dtcdop.py +170 -50
- odxtools/dynamicendmarkerfield.py +134 -0
- odxtools/dynamiclengthfield.py +47 -42
- odxtools/dyndefinedspec.py +177 -0
- odxtools/dynenddopref.py +38 -0
- odxtools/ecuvariantmatcher.py +6 -7
- odxtools/element.py +13 -15
- odxtools/encodestate.py +199 -22
- odxtools/endofpdufield.py +31 -18
- odxtools/environmentdata.py +8 -1
- odxtools/environmentdatadescription.py +198 -36
- odxtools/exceptions.py +11 -2
- odxtools/field.py +10 -10
- odxtools/functionalclass.py +3 -5
- odxtools/inputparam.py +3 -12
- odxtools/internalconstr.py +14 -5
- odxtools/isotp_state_machine.py +14 -6
- odxtools/leadinglengthinfotype.py +37 -18
- odxtools/library.py +66 -0
- odxtools/loadfile.py +64 -0
- odxtools/matchingparameter.py +3 -3
- odxtools/message.py +0 -7
- odxtools/minmaxlengthtype.py +61 -33
- odxtools/modification.py +3 -5
- odxtools/multiplexer.py +135 -75
- odxtools/multiplexercase.py +39 -18
- odxtools/multiplexerdefaultcase.py +15 -12
- odxtools/multiplexerswitchkey.py +4 -5
- odxtools/nameditemlist.py +33 -8
- odxtools/negoutputparam.py +3 -5
- odxtools/odxcategory.py +83 -0
- odxtools/odxlink.py +62 -53
- odxtools/odxtypes.py +93 -8
- odxtools/outputparam.py +5 -16
- odxtools/parameterinfo.py +219 -61
- odxtools/parameters/codedconstparameter.py +45 -32
- odxtools/parameters/createanyparameter.py +19 -193
- odxtools/parameters/dynamicparameter.py +25 -4
- odxtools/parameters/lengthkeyparameter.py +83 -25
- odxtools/parameters/matchingrequestparameter.py +48 -18
- odxtools/parameters/nrcconstparameter.py +76 -54
- odxtools/parameters/parameter.py +97 -73
- odxtools/parameters/parameterwithdop.py +41 -38
- odxtools/parameters/physicalconstantparameter.py +41 -20
- odxtools/parameters/reservedparameter.py +36 -18
- odxtools/parameters/systemparameter.py +74 -7
- odxtools/parameters/tableentryparameter.py +47 -7
- odxtools/parameters/tablekeyparameter.py +142 -55
- odxtools/parameters/tablestructparameter.py +79 -58
- odxtools/parameters/valueparameter.py +39 -21
- odxtools/paramlengthinfotype.py +56 -33
- odxtools/parentref.py +20 -3
- odxtools/physicaldimension.py +3 -8
- odxtools/progcode.py +26 -11
- odxtools/protstack.py +3 -5
- odxtools/py.typed +0 -0
- odxtools/relateddoc.py +7 -9
- odxtools/request.py +120 -10
- odxtools/response.py +123 -23
- odxtools/scaleconstr.py +14 -8
- odxtools/servicebinner.py +1 -1
- odxtools/singleecujob.py +12 -10
- odxtools/snrefcontext.py +29 -0
- odxtools/specialdata.py +3 -5
- odxtools/specialdatagroup.py +7 -9
- odxtools/specialdatagroupcaption.py +3 -6
- odxtools/standardlengthtype.py +80 -14
- odxtools/state.py +3 -5
- odxtools/statechart.py +13 -19
- odxtools/statetransition.py +8 -18
- odxtools/staticfield.py +107 -0
- odxtools/subcomponent.py +288 -0
- odxtools/swvariable.py +21 -0
- odxtools/table.py +9 -9
- odxtools/tablerow.py +30 -15
- odxtools/teammember.py +3 -5
- odxtools/templates/comparam-spec.odx-c.xml.jinja2 +4 -24
- odxtools/templates/comparam-subset.odx-cs.xml.jinja2 +5 -26
- odxtools/templates/diag_layer_container.odx-d.xml.jinja2 +15 -31
- odxtools/templates/{index.xml.xml.jinja2 → index.xml.jinja2} +1 -1
- odxtools/templates/macros/printAudience.xml.jinja2 +1 -1
- odxtools/templates/macros/printBaseVariant.xml.jinja2 +53 -0
- odxtools/templates/macros/printCompanyData.xml.jinja2 +4 -7
- odxtools/templates/macros/printComparam.xml.jinja2 +6 -4
- odxtools/templates/macros/printComparamRef.xml.jinja2 +5 -12
- odxtools/templates/macros/printCompuMethod.xml.jinja2 +147 -0
- odxtools/templates/macros/printDOP.xml.jinja2 +27 -137
- odxtools/templates/macros/printDescription.xml.jinja2 +18 -0
- odxtools/templates/macros/printDiagComm.xml.jinja2 +1 -1
- odxtools/templates/macros/printDiagLayer.xml.jinja2 +222 -0
- odxtools/templates/macros/printDiagVariable.xml.jinja2 +66 -0
- odxtools/templates/macros/printDynDefinedSpec.xml.jinja2 +48 -0
- odxtools/templates/macros/printDynamicEndmarkerField.xml.jinja2 +16 -0
- odxtools/templates/macros/printDynamicLengthField.xml.jinja2 +1 -1
- odxtools/templates/macros/printEcuSharedData.xml.jinja2 +30 -0
- odxtools/templates/macros/printEcuVariant.xml.jinja2 +53 -0
- odxtools/templates/macros/printEcuVariantPattern.xml.jinja2 +1 -1
- odxtools/templates/macros/printElementId.xml.jinja2 +8 -3
- odxtools/templates/macros/printEndOfPdu.xml.jinja2 +1 -1
- odxtools/templates/macros/printEnvDataDesc.xml.jinja2 +1 -1
- odxtools/templates/macros/printFunctionalClass.xml.jinja2 +1 -1
- odxtools/templates/macros/printFunctionalGroup.xml.jinja2 +40 -0
- odxtools/templates/macros/printHierarchyElement.xml.jinja2 +24 -0
- odxtools/templates/macros/printLibrary.xml.jinja2 +21 -0
- odxtools/templates/macros/printMux.xml.jinja2 +5 -3
- odxtools/templates/macros/printOdxCategory.xml.jinja2 +28 -0
- odxtools/templates/macros/printParam.xml.jinja2 +18 -19
- odxtools/templates/macros/printProtStack.xml.jinja2 +1 -1
- odxtools/templates/macros/printProtocol.xml.jinja2 +30 -0
- odxtools/templates/macros/printRequest.xml.jinja2 +1 -1
- odxtools/templates/macros/printResponse.xml.jinja2 +1 -1
- odxtools/templates/macros/printService.xml.jinja2 +3 -2
- odxtools/templates/macros/printSingleEcuJob.xml.jinja2 +5 -26
- odxtools/templates/macros/printSpecialData.xml.jinja2 +1 -1
- odxtools/templates/macros/printState.xml.jinja2 +1 -1
- odxtools/templates/macros/printStateChart.xml.jinja2 +1 -1
- odxtools/templates/macros/printStateTransition.xml.jinja2 +1 -1
- odxtools/templates/macros/printStaticField.xml.jinja2 +15 -0
- odxtools/templates/macros/printStructure.xml.jinja2 +1 -1
- odxtools/templates/macros/printSubComponent.xml.jinja2 +104 -0
- odxtools/templates/macros/printTable.xml.jinja2 +4 -5
- odxtools/templates/macros/printUnitSpec.xml.jinja2 +3 -5
- odxtools/uds.py +2 -10
- odxtools/unit.py +4 -8
- odxtools/unitgroup.py +3 -5
- odxtools/unitspec.py +17 -17
- odxtools/utils.py +38 -20
- odxtools/variablegroup.py +32 -0
- odxtools/version.py +2 -2
- odxtools/{write_pdx_file.py → writepdxfile.py} +22 -12
- odxtools/xdoc.py +3 -5
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/METADATA +44 -33
- odxtools-9.3.0.dist-info/RECORD +228 -0
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/WHEEL +1 -1
- odxtools/createcompanydatas.py +0 -17
- odxtools/createsdgs.py +0 -19
- odxtools/diaglayertype.py +0 -30
- odxtools/load_file.py +0 -13
- odxtools/load_odx_d_file.py +0 -6
- odxtools/load_pdx_file.py +0 -8
- odxtools/templates/macros/printVariant.xml.jinja2 +0 -208
- odxtools-6.6.1.dist-info/RECORD +0 -180
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/LICENSE +0 -0
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/entry_points.txt +0 -0
- {odxtools-6.6.1.dist-info → odxtools-9.3.0.dist-info}/top_level.txt +0 -0
odxtools/comparamspec.py
CHANGED
@@ -1,66 +1,39 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import TYPE_CHECKING, Any, Dict, List
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, List
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
|
-
from .admindata import AdminData
|
7
|
-
from .companydata import CompanyData
|
8
|
-
from .createcompanydatas import create_company_datas_from_et
|
9
|
-
from .createsdgs import create_sdgs_from_et
|
10
|
-
from .element import IdentifiableElement
|
11
|
-
from .exceptions import odxrequire
|
12
6
|
from .nameditemlist import NamedItemList
|
7
|
+
from .odxcategory import OdxCategory
|
13
8
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
14
9
|
from .protstack import ProtStack
|
15
|
-
from .
|
10
|
+
from .snrefcontext import SnRefContext
|
16
11
|
from .utils import dataclass_fields_asdict
|
17
12
|
|
18
13
|
if TYPE_CHECKING:
|
19
|
-
from .
|
14
|
+
from .database import Database
|
20
15
|
|
21
16
|
|
22
17
|
@dataclass
|
23
|
-
class ComparamSpec(
|
24
|
-
admin_data: Optional[AdminData]
|
25
|
-
company_datas: NamedItemList[CompanyData]
|
26
|
-
sdgs: List[SpecialDataGroup]
|
18
|
+
class ComparamSpec(OdxCategory):
|
27
19
|
prot_stacks: NamedItemList[ProtStack]
|
28
20
|
|
29
21
|
@staticmethod
|
30
22
|
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ComparamSpec":
|
31
23
|
|
32
|
-
|
33
|
-
doc_frags =
|
34
|
-
kwargs = dataclass_fields_asdict(
|
24
|
+
cat = OdxCategory.category_from_et(et_element, doc_frags, doc_type="COMPARAM-SPEC")
|
25
|
+
doc_frags = cat.odx_id.doc_fragments
|
26
|
+
kwargs = dataclass_fields_asdict(cat)
|
35
27
|
|
36
|
-
admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
|
37
|
-
company_datas = create_company_datas_from_et(et_element.find("COMPANY-DATAS"), doc_frags)
|
38
|
-
sdgs = create_sdgs_from_et(et_element.find("SDGS"), doc_frags)
|
39
28
|
prot_stacks = NamedItemList([
|
40
29
|
ProtStack.from_et(dl_element, doc_frags)
|
41
30
|
for dl_element in et_element.iterfind("PROT-STACKS/PROT-STACK")
|
42
31
|
])
|
43
32
|
|
44
|
-
return ComparamSpec(
|
45
|
-
admin_data=admin_data,
|
46
|
-
company_datas=company_datas,
|
47
|
-
sdgs=sdgs,
|
48
|
-
prot_stacks=prot_stacks,
|
49
|
-
**kwargs)
|
33
|
+
return ComparamSpec(prot_stacks=prot_stacks, **kwargs)
|
50
34
|
|
51
35
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
52
|
-
odxlinks
|
53
|
-
if self.odx_id is not None:
|
54
|
-
odxlinks[self.odx_id] = self
|
55
|
-
|
56
|
-
if self.admin_data is not None:
|
57
|
-
odxlinks.update(self.admin_data._build_odxlinks())
|
58
|
-
|
59
|
-
for cd in self.company_datas:
|
60
|
-
odxlinks.update(cd._build_odxlinks())
|
61
|
-
|
62
|
-
for sdg in self.sdgs:
|
63
|
-
odxlinks.update(sdg._build_odxlinks())
|
36
|
+
odxlinks = super()._build_odxlinks()
|
64
37
|
|
65
38
|
for ps in self.prot_stacks:
|
66
39
|
odxlinks.update(ps._build_odxlinks())
|
@@ -68,27 +41,16 @@ class ComparamSpec(IdentifiableElement):
|
|
68
41
|
return odxlinks
|
69
42
|
|
70
43
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
71
|
-
|
72
|
-
self.admin_data._resolve_odxlinks(odxlinks)
|
73
|
-
|
74
|
-
for cd in self.company_datas:
|
75
|
-
cd._resolve_odxlinks(odxlinks)
|
76
|
-
|
77
|
-
for sdg in self.sdgs:
|
78
|
-
sdg._resolve_odxlinks(odxlinks)
|
44
|
+
super()._resolve_odxlinks(odxlinks)
|
79
45
|
|
80
46
|
for ps in self.prot_stacks:
|
81
47
|
ps._resolve_odxlinks(odxlinks)
|
82
48
|
|
83
|
-
def
|
84
|
-
|
85
|
-
self.admin_data._resolve_snrefs(diag_layer)
|
86
|
-
|
87
|
-
for cd in self.company_datas:
|
88
|
-
cd._resolve_snrefs(diag_layer)
|
49
|
+
def _finalize_init(self, database: "Database", odxlinks: OdxLinkDatabase) -> None:
|
50
|
+
super()._finalize_init(database, odxlinks)
|
89
51
|
|
90
|
-
|
91
|
-
|
52
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
53
|
+
super()._resolve_snrefs(context)
|
92
54
|
|
93
55
|
for ps in self.prot_stacks:
|
94
|
-
ps._resolve_snrefs(
|
56
|
+
ps._resolve_snrefs(context)
|
odxtools/comparamsubset.py
CHANGED
@@ -3,49 +3,39 @@ from dataclasses import dataclass
|
|
3
3
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
|
-
from .admindata import AdminData
|
7
|
-
from .companydata import CompanyData
|
8
6
|
from .comparam import Comparam
|
9
7
|
from .complexcomparam import ComplexComparam
|
10
|
-
from .createcompanydatas import create_company_datas_from_et
|
11
|
-
from .createsdgs import create_sdgs_from_et
|
12
8
|
from .dataobjectproperty import DataObjectProperty
|
13
|
-
from .element import IdentifiableElement
|
14
|
-
from .exceptions import odxrequire
|
15
9
|
from .nameditemlist import NamedItemList
|
10
|
+
from .odxcategory import OdxCategory
|
16
11
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
17
|
-
from .
|
12
|
+
from .snrefcontext import SnRefContext
|
18
13
|
from .unitspec import UnitSpec
|
19
14
|
from .utils import dataclass_fields_asdict
|
20
15
|
|
21
16
|
if TYPE_CHECKING:
|
22
|
-
from .
|
17
|
+
from .database import Database
|
23
18
|
|
24
19
|
|
25
20
|
@dataclass
|
26
|
-
class ComparamSubset(
|
27
|
-
# mandatory in ODX 2.2, but non
|
21
|
+
class ComparamSubset(OdxCategory):
|
22
|
+
# mandatory in ODX 2.2, but non-existent in ODX 2.0
|
28
23
|
category: Optional[str]
|
29
|
-
|
24
|
+
|
30
25
|
comparams: NamedItemList[Comparam]
|
31
26
|
complex_comparams: NamedItemList[ComplexComparam]
|
27
|
+
data_object_props: NamedItemList[DataObjectProperty]
|
32
28
|
unit_spec: Optional[UnitSpec]
|
33
|
-
admin_data: Optional[AdminData]
|
34
|
-
company_datas: NamedItemList[CompanyData]
|
35
|
-
sdgs: List[SpecialDataGroup]
|
36
29
|
|
37
30
|
@staticmethod
|
38
31
|
def from_et(et_element: ElementTree.Element,
|
39
32
|
doc_frags: List[OdxDocFragment]) -> "ComparamSubset":
|
40
33
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
doc_frags = [OdxDocFragment(short_name, str(et_element.tag))]
|
45
|
-
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
34
|
+
cat = OdxCategory.category_from_et(et_element, doc_frags, doc_type="COMPARAM-SUBSET")
|
35
|
+
doc_frags = cat.odx_id.doc_fragments
|
36
|
+
kwargs = dataclass_fields_asdict(cat)
|
46
37
|
|
47
|
-
|
48
|
-
company_datas = create_company_datas_from_et(et_element.find("COMPANY-DATAS"), doc_frags)
|
38
|
+
category = et_element.get("CATEGORY")
|
49
39
|
|
50
40
|
data_object_props = NamedItemList([
|
51
41
|
DataObjectProperty.from_et(el, doc_frags)
|
@@ -62,23 +52,16 @@ class ComparamSubset(IdentifiableElement):
|
|
62
52
|
else:
|
63
53
|
unit_spec = None
|
64
54
|
|
65
|
-
sdgs = create_sdgs_from_et(et_element.find("SDGS"), doc_frags)
|
66
|
-
|
67
55
|
return ComparamSubset(
|
68
56
|
category=category,
|
69
|
-
admin_data=admin_data,
|
70
|
-
company_datas=company_datas,
|
71
57
|
data_object_props=data_object_props,
|
72
58
|
comparams=comparams,
|
73
59
|
complex_comparams=complex_comparams,
|
74
60
|
unit_spec=unit_spec,
|
75
|
-
sdgs=sdgs,
|
76
61
|
**kwargs)
|
77
62
|
|
78
63
|
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
79
|
-
odxlinks
|
80
|
-
if self.odx_id is not None:
|
81
|
-
odxlinks[self.odx_id] = self
|
64
|
+
odxlinks = super()._build_odxlinks()
|
82
65
|
|
83
66
|
for dop in self.data_object_props:
|
84
67
|
odxlinks[dop.odx_id] = dop
|
@@ -92,19 +75,11 @@ class ComparamSubset(IdentifiableElement):
|
|
92
75
|
if self.unit_spec:
|
93
76
|
odxlinks.update(self.unit_spec._build_odxlinks())
|
94
77
|
|
95
|
-
if self.admin_data is not None:
|
96
|
-
odxlinks.update(self.admin_data._build_odxlinks())
|
97
|
-
|
98
|
-
if self.company_datas is not None:
|
99
|
-
for cd in self.company_datas:
|
100
|
-
odxlinks.update(cd._build_odxlinks())
|
101
|
-
|
102
|
-
for sdg in self.sdgs:
|
103
|
-
odxlinks.update(sdg._build_odxlinks())
|
104
|
-
|
105
78
|
return odxlinks
|
106
79
|
|
107
80
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
81
|
+
super()._resolve_odxlinks(odxlinks)
|
82
|
+
|
108
83
|
for dop in self.data_object_props:
|
109
84
|
dop._resolve_odxlinks(odxlinks)
|
110
85
|
|
@@ -117,35 +92,20 @@ class ComparamSubset(IdentifiableElement):
|
|
117
92
|
if self.unit_spec:
|
118
93
|
self.unit_spec._resolve_odxlinks(odxlinks)
|
119
94
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
if self.company_datas is not None:
|
124
|
-
for cd in self.company_datas:
|
125
|
-
cd._resolve_odxlinks(odxlinks)
|
95
|
+
def _finalize_init(self, database: "Database", odxlinks: OdxLinkDatabase) -> None:
|
96
|
+
super()._finalize_init(database, odxlinks)
|
126
97
|
|
127
|
-
|
128
|
-
|
98
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
99
|
+
super()._resolve_snrefs(context)
|
129
100
|
|
130
|
-
def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
|
131
101
|
for dop in self.data_object_props:
|
132
|
-
dop._resolve_snrefs(
|
102
|
+
dop._resolve_snrefs(context)
|
133
103
|
|
134
104
|
for comparam in self.comparams:
|
135
|
-
comparam._resolve_snrefs(
|
105
|
+
comparam._resolve_snrefs(context)
|
136
106
|
|
137
107
|
for ccomparam in self.complex_comparams:
|
138
|
-
ccomparam._resolve_snrefs(
|
108
|
+
ccomparam._resolve_snrefs(context)
|
139
109
|
|
140
110
|
if self.unit_spec:
|
141
|
-
self.unit_spec._resolve_snrefs(
|
142
|
-
|
143
|
-
if self.admin_data is not None:
|
144
|
-
self.admin_data._resolve_snrefs(diag_layer)
|
145
|
-
|
146
|
-
if self.company_datas is not None:
|
147
|
-
for cd in self.company_datas:
|
148
|
-
cd._resolve_snrefs(diag_layer)
|
149
|
-
|
150
|
-
for sdg in self.sdgs:
|
151
|
-
sdg._resolve_snrefs(diag_layer)
|
111
|
+
self.unit_spec._resolve_snrefs(context)
|
odxtools/complexcomparam.py
CHANGED
@@ -1,17 +1,15 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import
|
3
|
+
from typing import Any, Dict, List, Optional, Union
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .basecomparam import BaseComparam
|
7
7
|
from .nameditemlist import NamedItemList
|
8
8
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
9
9
|
from .odxtypes import odxstr_to_bool
|
10
|
+
from .snrefcontext import SnRefContext
|
10
11
|
from .utils import dataclass_fields_asdict
|
11
12
|
|
12
|
-
if TYPE_CHECKING:
|
13
|
-
from .diaglayer import DiagLayer
|
14
|
-
|
15
13
|
ComplexValue = List[Union[str, "ComplexValue"]]
|
16
14
|
|
17
15
|
|
@@ -93,7 +91,7 @@ class ComplexComparam(BaseComparam):
|
|
93
91
|
for subparam in self.subparams:
|
94
92
|
subparam._resolve_odxlinks(odxlinks)
|
95
93
|
|
96
|
-
def _resolve_snrefs(self,
|
97
|
-
super()._resolve_snrefs(
|
94
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
95
|
+
super()._resolve_snrefs(context)
|
98
96
|
for subparam in self.subparams:
|
99
|
-
subparam._resolve_snrefs(
|
97
|
+
subparam._resolve_snrefs(context)
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import List, Optional, cast
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from ..exceptions import DecodeError, EncodeError, odxassert, odxraise
|
7
|
+
from ..odxlink import OdxDocFragment
|
8
|
+
from ..odxtypes import AtomicOdxType, DataType
|
9
|
+
from ..progcode import ProgCode
|
10
|
+
from ..utils import dataclass_fields_asdict
|
11
|
+
from .compumethod import CompuCategory, CompuMethod
|
12
|
+
|
13
|
+
|
14
|
+
@dataclass
|
15
|
+
class CompuCodeCompuMethod(CompuMethod):
|
16
|
+
"""A compu method specifies the tranfer functions using Java bytecode
|
17
|
+
|
18
|
+
For details, refer to ASAM specification MCD-2 D (ODX), section 7.3.6.6.9.
|
19
|
+
"""
|
20
|
+
|
21
|
+
@property
|
22
|
+
def internal_to_phys_code(self) -> Optional[ProgCode]:
|
23
|
+
if self.compu_internal_to_phys is None:
|
24
|
+
return None
|
25
|
+
|
26
|
+
return self.compu_internal_to_phys.prog_code
|
27
|
+
|
28
|
+
@property
|
29
|
+
def phys_to_internal_code(self) -> Optional[ProgCode]:
|
30
|
+
if self.compu_phys_to_internal is None:
|
31
|
+
return None
|
32
|
+
|
33
|
+
return self.compu_phys_to_internal.prog_code
|
34
|
+
|
35
|
+
@staticmethod
|
36
|
+
def compu_method_from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment], *,
|
37
|
+
internal_type: DataType,
|
38
|
+
physical_type: DataType) -> "CompuCodeCompuMethod":
|
39
|
+
cm = CompuMethod.compu_method_from_et(
|
40
|
+
et_element, doc_frags, internal_type=internal_type, physical_type=physical_type)
|
41
|
+
kwargs = dataclass_fields_asdict(cm)
|
42
|
+
|
43
|
+
return CompuCodeCompuMethod(**kwargs)
|
44
|
+
|
45
|
+
def __post_init__(self) -> None:
|
46
|
+
odxassert(self.category == CompuCategory.COMPUCODE,
|
47
|
+
"CompuCodeCompuMethod must exhibit COMPUCODE category")
|
48
|
+
|
49
|
+
def convert_internal_to_physical(self, internal_value: AtomicOdxType) -> AtomicOdxType:
|
50
|
+
odxraise(r"CompuCodeCompuMethod cannot be executed by odxtools", DecodeError)
|
51
|
+
return cast(AtomicOdxType, None)
|
52
|
+
|
53
|
+
def convert_physical_to_internal(self, physical_value: AtomicOdxType) -> AtomicOdxType:
|
54
|
+
odxraise(r"CompuCodeCompuMethod cannot be executed by odxtools", EncodeError)
|
55
|
+
return cast(AtomicOdxType, None)
|
56
|
+
|
57
|
+
def is_valid_physical_value(self, physical_value: AtomicOdxType) -> bool:
|
58
|
+
# CompuCodeCompuMethod cannot be executed by odxtools
|
59
|
+
return False
|
60
|
+
|
61
|
+
def is_valid_internal_value(self, internal_value: AtomicOdxType) -> bool:
|
62
|
+
# CompuCodeCompuMethod cannot be executed by odxtools
|
63
|
+
return False
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import Optional
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from ..odxtypes import AtomicOdxType, DataType
|
7
|
+
|
8
|
+
|
9
|
+
@dataclass
|
10
|
+
class CompuConst:
|
11
|
+
v: Optional[str]
|
12
|
+
vt: Optional[str]
|
13
|
+
|
14
|
+
data_type: DataType
|
15
|
+
|
16
|
+
@staticmethod
|
17
|
+
def compuvalue_from_et(et_element: ElementTree.Element, *, data_type: DataType) -> "CompuConst":
|
18
|
+
|
19
|
+
v = et_element.findtext("V")
|
20
|
+
vt = et_element.findtext("VT")
|
21
|
+
|
22
|
+
return CompuConst(v=v, vt=vt, data_type=data_type)
|
23
|
+
|
24
|
+
def __post_init__(self) -> None:
|
25
|
+
self._value: Optional[AtomicOdxType] = self.vt
|
26
|
+
if self.v is not None:
|
27
|
+
self._value = self.data_type.from_string(self.v)
|
28
|
+
|
29
|
+
@property
|
30
|
+
def value(self) -> Optional[AtomicOdxType]:
|
31
|
+
return self._value
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import Optional
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from ..odxtypes import DataType
|
7
|
+
from ..utils import dataclass_fields_asdict
|
8
|
+
from .compuconst import CompuConst
|
9
|
+
from .compuinversevalue import CompuInverseValue
|
10
|
+
|
11
|
+
|
12
|
+
@dataclass
|
13
|
+
class CompuDefaultValue(CompuConst):
|
14
|
+
compu_inverse_value: Optional[CompuInverseValue]
|
15
|
+
|
16
|
+
@staticmethod
|
17
|
+
def compuvalue_from_et(et_element: ElementTree.Element, *,
|
18
|
+
data_type: DataType) -> "CompuDefaultValue":
|
19
|
+
kwargs = dataclass_fields_asdict(
|
20
|
+
CompuConst.compuvalue_from_et(et_element, data_type=data_type))
|
21
|
+
|
22
|
+
compu_inverse_value = None
|
23
|
+
if (civ_elem := et_element.find("COMPU-INVERSE-VALUE")) is not None:
|
24
|
+
compu_inverse_value = CompuInverseValue.compuvalue_from_et(
|
25
|
+
civ_elem, data_type=data_type)
|
26
|
+
|
27
|
+
return CompuDefaultValue(**kwargs, compu_inverse_value=compu_inverse_value)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import Any, Dict, List, Optional
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
7
|
+
from ..odxtypes import DataType
|
8
|
+
from ..progcode import ProgCode
|
9
|
+
from ..snrefcontext import SnRefContext
|
10
|
+
from .compudefaultvalue import CompuDefaultValue
|
11
|
+
from .compuscale import CompuScale
|
12
|
+
|
13
|
+
|
14
|
+
@dataclass
|
15
|
+
class CompuInternalToPhys:
|
16
|
+
compu_scales: List[CompuScale]
|
17
|
+
prog_code: Optional[ProgCode]
|
18
|
+
compu_default_value: Optional[CompuDefaultValue]
|
19
|
+
|
20
|
+
@staticmethod
|
21
|
+
def compu_internal_to_phys_from_et(et_element: ElementTree.Element,
|
22
|
+
doc_frags: List[OdxDocFragment], *, internal_type: DataType,
|
23
|
+
physical_type: DataType) -> "CompuInternalToPhys":
|
24
|
+
compu_scales = [
|
25
|
+
CompuScale.compuscale_from_et(
|
26
|
+
cse, doc_frags, domain_type=internal_type, range_type=physical_type)
|
27
|
+
for cse in et_element.iterfind("COMPU-SCALES/COMPU-SCALE")
|
28
|
+
]
|
29
|
+
|
30
|
+
prog_code = None
|
31
|
+
if (pce := et_element.find("PROG-CODE")) is not None:
|
32
|
+
prog_code = ProgCode.from_et(pce, doc_frags)
|
33
|
+
|
34
|
+
compu_default_value = None
|
35
|
+
if (cdve := et_element.find("COMPU-DEFAULT-VALUE")) is not None:
|
36
|
+
compu_default_value = CompuDefaultValue.compuvalue_from_et(
|
37
|
+
cdve, data_type=physical_type)
|
38
|
+
|
39
|
+
return CompuInternalToPhys(
|
40
|
+
compu_scales=compu_scales, prog_code=prog_code, compu_default_value=compu_default_value)
|
41
|
+
|
42
|
+
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
43
|
+
result = {}
|
44
|
+
|
45
|
+
if self.prog_code is not None:
|
46
|
+
result.update(self.prog_code._build_odxlinks())
|
47
|
+
|
48
|
+
return result
|
49
|
+
|
50
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
51
|
+
if self.prog_code is not None:
|
52
|
+
self.prog_code._resolve_odxlinks(odxlinks)
|
53
|
+
|
54
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
55
|
+
if self.prog_code is not None:
|
56
|
+
self.prog_code._resolve_snrefs(context)
|
@@ -1,28 +1,107 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
import abc
|
3
2
|
from dataclasses import dataclass
|
4
|
-
from
|
3
|
+
from enum import Enum
|
4
|
+
from typing import Any, Dict, List, Optional
|
5
|
+
from xml.etree import ElementTree
|
5
6
|
|
7
|
+
from ..exceptions import odxraise
|
8
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
6
9
|
from ..odxtypes import AtomicOdxType, DataType
|
10
|
+
from ..snrefcontext import SnRefContext
|
11
|
+
from .compuinternaltophys import CompuInternalToPhys
|
12
|
+
from .compuphystointernal import CompuPhysToInternal
|
7
13
|
|
8
|
-
|
9
|
-
|
10
|
-
"
|
11
|
-
"
|
12
|
-
"
|
13
|
-
"TEXTTABLE"
|
14
|
-
|
14
|
+
|
15
|
+
class CompuCategory(Enum):
|
16
|
+
IDENTICAL = "IDENTICAL"
|
17
|
+
LINEAR = "LINEAR"
|
18
|
+
SCALE_LINEAR = "SCALE-LINEAR"
|
19
|
+
TEXTTABLE = "TEXTTABLE"
|
20
|
+
COMPUCODE = "COMPUCODE"
|
21
|
+
TAB_INTP = "TAB-INTP"
|
22
|
+
RAT_FUNC = "RAT-FUNC"
|
23
|
+
SCALE_RAT_FUNC = "SCALE-RAT-FUNC"
|
15
24
|
|
16
25
|
|
17
26
|
@dataclass
|
18
|
-
class CompuMethod
|
19
|
-
|
27
|
+
class CompuMethod:
|
28
|
+
"""A compu method translates between the internal representation
|
29
|
+
of a value and their physical representation.
|
30
|
+
|
31
|
+
There are many compu methods, but all of them are specified using
|
32
|
+
the same mechanism: The conversion from internal to physical
|
33
|
+
quantities is specified using the COMPU-INTERNAL-TO-PHYS subtag,
|
34
|
+
and the inverse is covered by
|
35
|
+
COMPU-PHYS-TO-INTERNAL. Alternatively to directly specifying the
|
36
|
+
parameters needed for conversion, it is also possible to specify a
|
37
|
+
Java program which does the conversion (doing this excludes using
|
38
|
+
ODX in non-Java contexts, though).
|
39
|
+
|
40
|
+
For details, refer to ASAM specification MCD-2 D (ODX), section 7.3.6.6.
|
41
|
+
|
42
|
+
"""
|
43
|
+
|
44
|
+
category: CompuCategory
|
45
|
+
compu_internal_to_phys: Optional[CompuInternalToPhys]
|
46
|
+
compu_phys_to_internal: Optional[CompuPhysToInternal]
|
47
|
+
|
20
48
|
physical_type: DataType
|
49
|
+
internal_type: DataType
|
50
|
+
|
51
|
+
@staticmethod
|
52
|
+
def compu_method_from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment], *,
|
53
|
+
internal_type: DataType, physical_type: DataType) -> "CompuMethod":
|
54
|
+
cat_text = et_element.findtext("CATEGORY")
|
55
|
+
if cat_text is None:
|
56
|
+
odxraise("No category specified for compu method")
|
57
|
+
cat_text = "IDENTICAL"
|
58
|
+
|
59
|
+
try:
|
60
|
+
category = CompuCategory(cat_text)
|
61
|
+
except ValueError:
|
62
|
+
odxraise(f"Encountered compu method of unknown category '{cat_text}'")
|
63
|
+
category = CompuCategory.IDENTICAL
|
64
|
+
|
65
|
+
compu_internal_to_phys = None
|
66
|
+
if (citp_elem := et_element.find("COMPU-INTERNAL-TO-PHYS")) is not None:
|
67
|
+
compu_internal_to_phys = CompuInternalToPhys.compu_internal_to_phys_from_et(
|
68
|
+
citp_elem, doc_frags, internal_type=internal_type, physical_type=physical_type)
|
69
|
+
compu_phys_to_internal = None
|
70
|
+
if (cpti_elem := et_element.find("COMPU-PHYS-TO-INTERNAL")) is not None:
|
71
|
+
compu_phys_to_internal = CompuPhysToInternal.compu_phys_to_internal_from_et(
|
72
|
+
cpti_elem, doc_frags, internal_type=internal_type, physical_type=physical_type)
|
73
|
+
|
74
|
+
return CompuMethod(
|
75
|
+
category=category,
|
76
|
+
compu_internal_to_phys=compu_internal_to_phys,
|
77
|
+
compu_phys_to_internal=compu_phys_to_internal,
|
78
|
+
physical_type=physical_type,
|
79
|
+
internal_type=internal_type)
|
80
|
+
|
81
|
+
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
82
|
+
result = {}
|
83
|
+
|
84
|
+
if self.compu_internal_to_phys is not None:
|
85
|
+
result.update(self.compu_internal_to_phys._build_odxlinks())
|
86
|
+
|
87
|
+
if self.compu_phys_to_internal is not None:
|
88
|
+
result.update(self.compu_phys_to_internal._build_odxlinks())
|
89
|
+
|
90
|
+
return result
|
91
|
+
|
92
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
93
|
+
if self.compu_internal_to_phys is not None:
|
94
|
+
self.compu_internal_to_phys._resolve_odxlinks(odxlinks)
|
95
|
+
|
96
|
+
if self.compu_phys_to_internal is not None:
|
97
|
+
self.compu_phys_to_internal._resolve_odxlinks(odxlinks)
|
98
|
+
|
99
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
100
|
+
if self.compu_internal_to_phys is not None:
|
101
|
+
self.compu_internal_to_phys._resolve_snrefs(context)
|
21
102
|
|
22
|
-
|
23
|
-
|
24
|
-
def category(self) -> CompuMethodCategory:
|
25
|
-
pass
|
103
|
+
if self.compu_phys_to_internal is not None:
|
104
|
+
self.compu_phys_to_internal._resolve_snrefs(context)
|
26
105
|
|
27
106
|
def convert_physical_to_internal(self, physical_value: AtomicOdxType) -> AtomicOdxType:
|
28
107
|
raise NotImplementedError()
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import Any, Dict, List, Optional
|
4
|
+
from xml.etree import ElementTree
|
5
|
+
|
6
|
+
from ..odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
7
|
+
from ..odxtypes import DataType
|
8
|
+
from ..progcode import ProgCode
|
9
|
+
from ..snrefcontext import SnRefContext
|
10
|
+
from .compudefaultvalue import CompuDefaultValue
|
11
|
+
from .compuscale import CompuScale
|
12
|
+
|
13
|
+
|
14
|
+
@dataclass
|
15
|
+
class CompuPhysToInternal:
|
16
|
+
compu_scales: List[CompuScale]
|
17
|
+
prog_code: Optional[ProgCode]
|
18
|
+
compu_default_value: Optional[CompuDefaultValue]
|
19
|
+
|
20
|
+
@staticmethod
|
21
|
+
def compu_phys_to_internal_from_et(et_element: ElementTree.Element,
|
22
|
+
doc_frags: List[OdxDocFragment], *, internal_type: DataType,
|
23
|
+
physical_type: DataType) -> "CompuPhysToInternal":
|
24
|
+
compu_scales = [
|
25
|
+
CompuScale.compuscale_from_et(
|
26
|
+
cse, doc_frags, domain_type=physical_type, range_type=internal_type)
|
27
|
+
for cse in et_element.iterfind("COMPU-SCALES/COMPU-SCALE")
|
28
|
+
]
|
29
|
+
|
30
|
+
prog_code = None
|
31
|
+
if (pce := et_element.find("PROG-CODE")) is not None:
|
32
|
+
prog_code = ProgCode.from_et(pce, doc_frags)
|
33
|
+
|
34
|
+
compu_default_value = None
|
35
|
+
if (cdve := et_element.find("COMPU-DEFAULT-VALUE")) is not None:
|
36
|
+
compu_default_value = CompuDefaultValue.compuvalue_from_et(
|
37
|
+
cdve, data_type=internal_type)
|
38
|
+
|
39
|
+
return CompuPhysToInternal(
|
40
|
+
compu_scales=compu_scales, prog_code=prog_code, compu_default_value=compu_default_value)
|
41
|
+
|
42
|
+
def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
|
43
|
+
result = {}
|
44
|
+
|
45
|
+
if self.prog_code is not None:
|
46
|
+
result.update(self.prog_code._build_odxlinks())
|
47
|
+
|
48
|
+
return result
|
49
|
+
|
50
|
+
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
51
|
+
if self.prog_code is not None:
|
52
|
+
self.prog_code._resolve_odxlinks(odxlinks)
|
53
|
+
|
54
|
+
def _resolve_snrefs(self, context: SnRefContext) -> None:
|
55
|
+
if self.prog_code is not None:
|
56
|
+
self.prog_code._resolve_snrefs(context)
|