odxtools 6.7.0__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 +6 -4
- odxtools/additionalaudience.py +3 -5
- odxtools/admindata.py +5 -7
- odxtools/audience.py +10 -13
- odxtools/basecomparam.py +3 -5
- odxtools/basicstructure.py +55 -240
- odxtools/cli/_parser_utils.py +1 -1
- odxtools/cli/_print_utils.py +168 -134
- odxtools/cli/browse.py +111 -92
- odxtools/cli/compare.py +90 -71
- odxtools/cli/list.py +24 -15
- odxtools/cli/snoop.py +28 -5
- 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 +7 -9
- 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 +93 -12
- odxtools/compumethods/compuphystointernal.py +56 -0
- odxtools/compumethods/compurationalcoeffs.py +20 -9
- odxtools/compumethods/compuscale.py +30 -35
- odxtools/compumethods/createanycompumethod.py +28 -161
- odxtools/compumethods/identicalcompumethod.py +31 -6
- odxtools/compumethods/linearcompumethod.py +69 -189
- 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 +119 -99
- odxtools/compumethods/texttablecompumethod.py +107 -43
- odxtools/createanydiagcodedtype.py +10 -67
- odxtools/database.py +167 -87
- odxtools/dataobjectproperty.py +15 -25
- odxtools/decodestate.py +9 -15
- odxtools/description.py +47 -0
- odxtools/determinenumberofitems.py +4 -5
- odxtools/diagcodedtype.py +36 -106
- odxtools/diagcomm.py +24 -12
- odxtools/diagdatadictionaryspec.py +33 -34
- 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/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} +209 -448
- 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 +56 -43
- odxtools/diagvariable.py +113 -0
- odxtools/docrevision.py +5 -7
- odxtools/dopbase.py +15 -17
- odxtools/dtcdop.py +168 -50
- odxtools/dynamicendmarkerfield.py +134 -0
- odxtools/dynamiclengthfield.py +41 -37
- 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 -38
- odxtools/exceptions.py +11 -2
- odxtools/field.py +10 -10
- odxtools/functionalclass.py +3 -5
- odxtools/inputparam.py +3 -12
- 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 +128 -73
- odxtools/multiplexercase.py +13 -14
- odxtools/multiplexerdefaultcase.py +15 -12
- odxtools/multiplexerswitchkey.py +4 -5
- odxtools/nameditemlist.py +29 -5
- odxtools/negoutputparam.py +3 -5
- odxtools/odxcategory.py +83 -0
- odxtools/odxlink.py +60 -51
- odxtools/odxtypes.py +37 -5
- odxtools/outputparam.py +4 -15
- odxtools/parameterinfo.py +218 -67
- odxtools/parameters/codedconstparameter.py +16 -24
- odxtools/parameters/dynamicparameter.py +5 -4
- odxtools/parameters/lengthkeyparameter.py +60 -26
- odxtools/parameters/matchingrequestparameter.py +23 -11
- odxtools/parameters/nrcconstparameter.py +45 -46
- odxtools/parameters/parameter.py +54 -56
- odxtools/parameters/parameterwithdop.py +15 -25
- odxtools/parameters/physicalconstantparameter.py +15 -18
- odxtools/parameters/reservedparameter.py +6 -2
- odxtools/parameters/systemparameter.py +55 -11
- odxtools/parameters/tableentryparameter.py +3 -2
- odxtools/parameters/tablekeyparameter.py +103 -49
- odxtools/parameters/tablestructparameter.py +47 -48
- odxtools/parameters/valueparameter.py +16 -20
- odxtools/paramlengthinfotype.py +52 -32
- odxtools/parentref.py +16 -2
- 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 +3 -3
- 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 +7 -17
- odxtools/staticfield.py +31 -25
- odxtools/subcomponent.py +288 -0
- odxtools/swvariable.py +21 -0
- odxtools/table.py +7 -8
- odxtools/tablerow.py +19 -11
- 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 -133
- 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 +4 -3
- odxtools/templates/macros/printOdxCategory.xml.jinja2 +28 -0
- odxtools/templates/macros/printParam.xml.jinja2 +11 -12
- 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 +1 -1
- 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} +20 -10
- odxtools/xdoc.py +3 -5
- {odxtools-6.7.0.dist-info → odxtools-9.3.0.dist-info}/METADATA +20 -21
- odxtools-9.3.0.dist-info/RECORD +228 -0
- {odxtools-6.7.0.dist-info → odxtools-9.3.0.dist-info}/WHEEL +1 -1
- odxtools/createcompanydatas.py +0 -17
- odxtools/createsdgs.py +0 -19
- 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 -216
- odxtools-6.7.0.dist-info/RECORD +0 -182
- /odxtools/{diaglayertype.py → diaglayers/diaglayertype.py} +0 -0
- {odxtools-6.7.0.dist-info → odxtools-9.3.0.dist-info}/LICENSE +0 -0
- {odxtools-6.7.0.dist-info → odxtools-9.3.0.dist-info}/entry_points.txt +0 -0
- {odxtools-6.7.0.dist-info → odxtools-9.3.0.dist-info}/top_level.txt +0 -0
odxtools/parameterinfo.py
CHANGED
@@ -1,105 +1,256 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
|
-
import
|
3
|
-
from
|
2
|
+
import textwrap
|
3
|
+
from io import StringIO
|
4
|
+
from typing import Iterable
|
4
5
|
|
6
|
+
from .compumethods.compucodecompumethod import CompuCodeCompuMethod
|
5
7
|
from .compumethods.identicalcompumethod import IdenticalCompuMethod
|
6
8
|
from .compumethods.limit import IntervalType
|
7
9
|
from .compumethods.linearcompumethod import LinearCompuMethod
|
10
|
+
from .compumethods.linearsegment import LinearSegment
|
11
|
+
from .compumethods.ratfunccompumethod import RatFuncCompuMethod
|
12
|
+
from .compumethods.ratfuncsegment import RatFuncSegment
|
13
|
+
from .compumethods.scalelinearcompumethod import ScaleLinearCompuMethod
|
14
|
+
from .compumethods.scaleratfunccompumethod import ScaleRatFuncCompuMethod
|
8
15
|
from .compumethods.texttablecompumethod import TexttableCompuMethod
|
9
16
|
from .dataobjectproperty import DataObjectProperty
|
17
|
+
from .dtcdop import DtcDop
|
18
|
+
from .dynamiclengthfield import DynamicLengthField
|
10
19
|
from .endofpdufield import EndOfPduField
|
11
|
-
from .
|
20
|
+
from .exceptions import odxrequire
|
21
|
+
from .multiplexer import Multiplexer
|
12
22
|
from .parameters.codedconstparameter import CodedConstParameter
|
13
23
|
from .parameters.matchingrequestparameter import MatchingRequestParameter
|
24
|
+
from .parameters.nrcconstparameter import NrcConstParameter
|
14
25
|
from .parameters.parameter import Parameter
|
15
26
|
from .parameters.parameterwithdop import ParameterWithDOP
|
16
27
|
from .parameters.reservedparameter import ReservedParameter
|
28
|
+
from .parameters.systemparameter import SystemParameter
|
29
|
+
from .parameters.tablekeyparameter import TableKeyParameter
|
30
|
+
from .parameters.tablestructparameter import TableStructParameter
|
31
|
+
from .paramlengthinfotype import ParamLengthInfoType
|
32
|
+
from .staticfield import StaticField
|
17
33
|
|
18
34
|
|
19
|
-
def
|
20
|
-
|
35
|
+
def _get_linear_segment_info(segment: LinearSegment) -> str:
|
36
|
+
ll = segment.physical_lower_limit
|
37
|
+
if ll is None or ll.interval_type == IntervalType.INFINITE:
|
38
|
+
ll_str = "(-inf"
|
39
|
+
else:
|
40
|
+
ll_delim = '(' if ll.interval_type == IntervalType.OPEN else '['
|
41
|
+
ll_str = f"{ll_delim}{ll._value!r}"
|
42
|
+
|
43
|
+
ul = segment.physical_upper_limit
|
44
|
+
if ul is None or ul.interval_type == IntervalType.INFINITE:
|
45
|
+
ul_str = "inf)"
|
46
|
+
else:
|
47
|
+
ul_delim = ')' if ul.interval_type == IntervalType.OPEN else ']'
|
48
|
+
ul_str = f"{ul._value!r}{ul_delim}"
|
49
|
+
|
50
|
+
return f"{ll_str}, {ul_str}"
|
51
|
+
|
52
|
+
|
53
|
+
def _get_rat_func_segment_info(segment: RatFuncSegment) -> str:
|
54
|
+
ll = segment.lower_limit
|
55
|
+
if ll is None or ll.interval_type == IntervalType.INFINITE:
|
56
|
+
ll_str = "(-inf"
|
57
|
+
else:
|
58
|
+
ll_delim = '(' if ll.interval_type == IntervalType.OPEN else '['
|
59
|
+
ll_str = f"{ll_delim}{ll._value!r}"
|
60
|
+
|
61
|
+
ul = segment.upper_limit
|
62
|
+
if ul is None or ul.interval_type == IntervalType.INFINITE:
|
63
|
+
ul_str = "inf)"
|
64
|
+
else:
|
65
|
+
ul_delim = ')' if ul.interval_type == IntervalType.OPEN else ']'
|
66
|
+
ul_str = f"{ul._value!r}{ul_delim}"
|
67
|
+
|
68
|
+
return f"{ll_str}, {ul_str}"
|
69
|
+
|
70
|
+
|
71
|
+
def parameter_info(param_list: Iterable[Parameter], quoted_names: bool = False) -> str:
|
72
|
+
q = "'" if quoted_names else ""
|
73
|
+
of = StringIO()
|
21
74
|
for param in param_list:
|
22
75
|
if isinstance(param, CodedConstParameter):
|
23
|
-
|
76
|
+
of.write(f"{q}{param.short_name}{q}: const = {param._coded_value_str}\n")
|
24
77
|
continue
|
25
78
|
elif isinstance(param, MatchingRequestParameter):
|
26
|
-
|
79
|
+
of.write(f"{q}{param.short_name}{q}: <matches request>\n")
|
80
|
+
continue
|
81
|
+
elif isinstance(param, NrcConstParameter):
|
82
|
+
of.write(f"{q}{param.short_name}{q}: const; choices = {param.coded_values}\n")
|
27
83
|
continue
|
28
84
|
elif isinstance(param, ReservedParameter):
|
29
|
-
|
85
|
+
of.write(f"{q}{param.short_name}{q}: <reserved>\n")
|
30
86
|
continue
|
31
|
-
elif
|
32
|
-
|
87
|
+
elif isinstance(param, SystemParameter):
|
88
|
+
of.write(
|
89
|
+
f"{q}{param.short_name}{q}: <system; kind = \"{param.sysparam}\">; required = {param.is_required}\n"
|
90
|
+
)
|
33
91
|
continue
|
92
|
+
elif isinstance(param, TableKeyParameter):
|
93
|
+
of.write(
|
94
|
+
f"{q}{param.short_name}{q}: <optional> table key; table = '{param.table.short_name}'; choices:\n"
|
95
|
+
)
|
96
|
+
for tr in param.table.table_rows:
|
97
|
+
of.write(f" '{tr.short_name}',\n")
|
34
98
|
|
35
|
-
dop = param.dop
|
36
|
-
|
37
|
-
if isinstance(dop, EndOfPduField):
|
38
|
-
result += f"{param.short_name} : <optional> list({{\n"
|
39
|
-
tmp = parameter_info(dop.structure.parameters).strip()
|
40
|
-
tmp = re.sub("^", " ", tmp)
|
41
|
-
result += tmp + "\n"
|
42
|
-
result += f"}})\n"
|
43
99
|
continue
|
100
|
+
elif isinstance(param, TableStructParameter):
|
101
|
+
of.write(
|
102
|
+
f"{q}{param.short_name}{q}: table struct; key = '{param.table_key.short_name}'; choices:\n"
|
103
|
+
)
|
104
|
+
for tr in param.table_key.table.table_rows:
|
105
|
+
of.write(f" ('{tr.short_name}',\n")
|
106
|
+
of.write(f" {{\n")
|
107
|
+
of.write(
|
108
|
+
textwrap.indent(
|
109
|
+
parameter_info(odxrequire(tr.structure).parameters, True), " "))
|
110
|
+
of.write(f" }}),\n")
|
44
111
|
|
45
|
-
|
112
|
+
continue
|
113
|
+
elif not isinstance(param, ParameterWithDOP):
|
114
|
+
of.write(
|
115
|
+
f"{q}{param.short_name}{q}: <unhandled parameter type '{type(param).__name__}'>\n")
|
116
|
+
continue
|
46
117
|
|
118
|
+
dop = param.dop
|
47
119
|
if dop is None:
|
48
|
-
|
120
|
+
of.write("{q}{param.short_name}{q}: <no DOP>\n")
|
49
121
|
continue
|
50
|
-
elif
|
51
|
-
|
122
|
+
elif isinstance(dop, EndOfPduField):
|
123
|
+
of.write(f"{q}{param.short_name}{q}: list({{\n")
|
124
|
+
of.write(textwrap.indent(parameter_info(dop.structure.parameters, True), " "))
|
125
|
+
of.write(f"}})\n")
|
52
126
|
continue
|
53
|
-
|
54
|
-
|
55
|
-
|
127
|
+
elif isinstance(dop, StaticField):
|
128
|
+
of.write(f"{q}{param.short_name}{q}: length={dop.fixed_number_of_items}; list({{\n")
|
129
|
+
of.write(textwrap.indent(parameter_info(dop.structure.parameters, True), " "))
|
130
|
+
of.write(f"}})\n")
|
131
|
+
continue
|
132
|
+
elif isinstance(dop, DynamicLengthField):
|
133
|
+
of.write(f"{q}{param.short_name}{q}: list({{\n")
|
134
|
+
of.write(textwrap.indent(parameter_info(dop.structure.parameters, True), " "))
|
135
|
+
of.write(f"}})\n")
|
136
|
+
continue
|
137
|
+
elif isinstance(dop, ParamLengthInfoType):
|
138
|
+
of.write(f"{q}{param.short_name}{q}: ")
|
139
|
+
of.write("<optional> ")
|
140
|
+
of.write(f"int; length_key='{dop.length_key.short_name}'\n")
|
56
141
|
continue
|
142
|
+
elif isinstance(dop, DtcDop):
|
143
|
+
of.write(f"{q}{param.short_name}{q}: ")
|
144
|
+
of.write(f"DTC; choices:\n")
|
145
|
+
for dtc in dop.dtcs:
|
146
|
+
if dtc.display_trouble_code is not None:
|
147
|
+
dtc_desc = dtc.text and f"; \"{dtc.text}\""
|
148
|
+
of.write(
|
149
|
+
f" '{dtc.display_trouble_code}' (0x{dtc.trouble_code:06x}{dtc_desc})\n")
|
150
|
+
else:
|
151
|
+
dtc_desc = dtc.text and f" (\"{dtc.text}\")"
|
152
|
+
of.write(f" 0x{dtc.trouble_code:06x}{dtc_desc}\n")
|
153
|
+
continue
|
154
|
+
elif isinstance(dop, Multiplexer):
|
155
|
+
of.write(f"{q}{param.short_name}{q}: ")
|
156
|
+
if dop.default_case is not None:
|
157
|
+
of.write(f"<optional>")
|
158
|
+
of.write(f"multiplexer; choices:\n")
|
159
|
+
for mux_case in dop.cases:
|
160
|
+
of.write(f" ({repr(mux_case.short_name)}, {{\n")
|
161
|
+
if (struc := mux_case.structure) is not None:
|
162
|
+
of.write(textwrap.indent(parameter_info(struc.parameters, True), " "))
|
163
|
+
of.write(f" }})\n")
|
164
|
+
continue
|
165
|
+
elif isinstance(dop, DataObjectProperty):
|
166
|
+
# a "simple" DOP
|
167
|
+
if (cm := dop.compu_method) is None:
|
168
|
+
of.write(f"{q}{param.short_name}{q}: <no compu method>\n")
|
169
|
+
continue
|
57
170
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
bdt = dop.physical_type.base_data_type
|
65
|
-
if bdt in (DataType.A_UTF8STRING, DataType.A_UNICODE2STRING, DataType.A_ASCIISTRING):
|
66
|
-
result += f": str"
|
67
|
-
elif bdt in (DataType.A_BYTEFIELD,):
|
68
|
-
result += f": bytes"
|
69
|
-
elif bdt.name.startswith("A_FLOAT"):
|
70
|
-
result += f": float"
|
71
|
-
elif bdt.name.startswith("A_UINT"):
|
72
|
-
result += f": uint"
|
73
|
-
elif bdt.name.startswith("A_INT"):
|
74
|
-
result += f": int"
|
75
|
-
else:
|
76
|
-
result += f": <unknown type>"
|
171
|
+
if isinstance(cm, TexttableCompuMethod):
|
172
|
+
of.write(f"{q}{param.short_name}{q}: enum; choices:\n")
|
173
|
+
for scale in odxrequire(cm.compu_internal_to_phys).compu_scales:
|
174
|
+
val_str = ""
|
175
|
+
if scale.lower_limit is not None:
|
176
|
+
val_str = f"({repr(scale.lower_limit.value)})"
|
77
177
|
|
78
|
-
|
79
|
-
|
178
|
+
if scale.compu_const is None:
|
179
|
+
of.write(f" <ERROR in ODX data: no value specified>\n")
|
180
|
+
else:
|
181
|
+
vt = scale.compu_const.vt
|
182
|
+
v = scale.compu_const.v
|
183
|
+
if vt is not None:
|
184
|
+
of.write(f" \"{vt}\" {val_str}\n")
|
185
|
+
else:
|
186
|
+
of.write(f" {v}\n")
|
80
187
|
|
81
|
-
|
188
|
+
elif isinstance(cm, IdenticalCompuMethod):
|
189
|
+
of.write(f"{q}{param.short_name}{q}: {dop.physical_type.base_data_type}\n")
|
82
190
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
if ll is None:
|
88
|
-
ll_str = "(inf"
|
89
|
-
else:
|
90
|
-
ll_delim = '[' if ll.interval_type == IntervalType.CLOSED else '('
|
91
|
-
ll_str = f"{ll_delim}{ll._value!r}"
|
191
|
+
elif isinstance(cm, ScaleLinearCompuMethod):
|
192
|
+
of.write(f"{q}{param.short_name}{q}: {dop.physical_type.base_data_type}")
|
193
|
+
seg_list = [_get_linear_segment_info(x) for x in cm.segments]
|
194
|
+
of.write(f"; ranges = {{ {', '.join(seg_list)} }}")
|
92
195
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
196
|
+
unit = dop.unit
|
197
|
+
unit_str = unit.display_name if unit is not None else None
|
198
|
+
if unit_str is not None:
|
199
|
+
of.write(f"; unit: {unit_str}")
|
200
|
+
|
201
|
+
of.write("\n")
|
202
|
+
|
203
|
+
elif isinstance(cm, LinearCompuMethod):
|
204
|
+
of.write(f"{q}{param.short_name}{q}: {dop.physical_type.base_data_type}")
|
205
|
+
of.write(f"; range: {_get_linear_segment_info(cm.segment)}")
|
206
|
+
|
207
|
+
unit = dop.unit
|
208
|
+
unit_str = unit.display_name if unit is not None else None
|
209
|
+
if unit_str is not None:
|
210
|
+
of.write(f"; unit: {unit_str}")
|
211
|
+
|
212
|
+
of.write("\n")
|
99
213
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
214
|
+
elif isinstance(cm, ScaleRatFuncCompuMethod):
|
215
|
+
of.write(f"{q}{param.short_name}{q}: {dop.physical_type.base_data_type}")
|
216
|
+
if cm._phys_to_int_segments is None:
|
217
|
+
of.write("<NOT ENCODABLE>")
|
218
|
+
else:
|
219
|
+
seg_list = [_get_rat_func_segment_info(x) for x in cm._phys_to_int_segments]
|
220
|
+
of.write(f"; ranges = {{ {', '.join(seg_list)} }}")
|
221
|
+
|
222
|
+
unit = dop.unit
|
223
|
+
unit_str = unit.display_name if unit is not None else None
|
224
|
+
if unit_str is not None:
|
225
|
+
of.write(f"; unit: {unit_str}")
|
226
|
+
|
227
|
+
of.write("\n")
|
228
|
+
|
229
|
+
elif isinstance(cm, RatFuncCompuMethod):
|
230
|
+
of.write(f"{q}{param.short_name}{q}: {dop.physical_type.base_data_type}")
|
231
|
+
if cm._phys_to_int_segment is None:
|
232
|
+
of.write("<NOT ENCODABLE>")
|
233
|
+
else:
|
234
|
+
of.write(f"; range: {_get_rat_func_segment_info(cm._phys_to_int_segment)}")
|
235
|
+
|
236
|
+
unit = dop.unit
|
237
|
+
unit_str = unit.display_name if unit is not None else None
|
238
|
+
if unit_str is not None:
|
239
|
+
of.write(f"; unit: {unit_str}")
|
240
|
+
|
241
|
+
of.write("\n")
|
242
|
+
|
243
|
+
elif isinstance(cm, CompuCodeCompuMethod):
|
244
|
+
of.write(f"{q}{param.short_name}{q}: {dop.physical_type.base_data_type}")
|
245
|
+
of.write(f"; <programmatic translation>")
|
246
|
+
|
247
|
+
of.write("\n")
|
248
|
+
|
249
|
+
else:
|
250
|
+
of.write(
|
251
|
+
f"{q}{param.short_name}{q}: unknown compu method {type(dop.compu_method).__name__}\n"
|
252
|
+
)
|
253
|
+
else:
|
254
|
+
of.write(f"{q}{param.short_name}{q}: <unhandled DOP '{type(dop).__name__}'>\n")
|
104
255
|
|
105
|
-
return
|
256
|
+
return of.getvalue()
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import warnings
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import
|
4
|
+
from typing import Any, Dict, List, Optional
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from typing_extensions import override
|
@@ -10,15 +10,12 @@ from ..createanydiagcodedtype import create_any_diag_coded_type_from_et
|
|
10
10
|
from ..decodestate import DecodeState
|
11
11
|
from ..diagcodedtype import DiagCodedType
|
12
12
|
from ..encodestate import EncodeState
|
13
|
-
from ..exceptions import DecodeError, odxrequire
|
14
|
-
from ..odxlink import OdxDocFragment,
|
15
|
-
from ..odxtypes import AtomicOdxType, DataType
|
13
|
+
from ..exceptions import DecodeError, EncodeError, odxraise, odxrequire
|
14
|
+
from ..odxlink import OdxDocFragment, OdxLinkId
|
15
|
+
from ..odxtypes import AtomicOdxType, DataType, ParameterValue
|
16
16
|
from ..utils import dataclass_fields_asdict
|
17
17
|
from .parameter import Parameter, ParameterType
|
18
18
|
|
19
|
-
if TYPE_CHECKING:
|
20
|
-
from ..diaglayer import DiagLayer
|
21
|
-
|
22
19
|
|
23
20
|
@dataclass
|
24
21
|
class CodedConstParameter(Parameter):
|
@@ -54,14 +51,6 @@ class CodedConstParameter(Parameter):
|
|
54
51
|
|
55
52
|
return result
|
56
53
|
|
57
|
-
@override
|
58
|
-
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
59
|
-
super()._resolve_odxlinks(odxlinks)
|
60
|
-
|
61
|
-
@override
|
62
|
-
def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
|
63
|
-
super()._resolve_snrefs(diag_layer)
|
64
|
-
|
65
54
|
@override
|
66
55
|
def get_static_bit_length(self) -> Optional[int]:
|
67
56
|
return self.diag_coded_type.get_static_bit_length()
|
@@ -81,20 +70,23 @@ class CodedConstParameter(Parameter):
|
|
81
70
|
return False
|
82
71
|
|
83
72
|
@override
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
73
|
+
def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
|
74
|
+
encode_state: EncodeState) -> None:
|
75
|
+
if physical_value is not None and physical_value != self.coded_value:
|
76
|
+
odxraise(
|
77
|
+
f"Value for constant parameter `{self.short_name}` name can "
|
78
|
+
f"only be specified as {self.coded_value!r} (is: {physical_value!r})", EncodeError)
|
79
|
+
|
80
|
+
internal_value = self.coded_value
|
81
|
+
|
82
|
+
self.diag_coded_type.encode_into_pdu(
|
83
|
+
internal_value=internal_value, encode_state=encode_state)
|
92
84
|
|
93
85
|
@override
|
94
86
|
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> AtomicOdxType:
|
95
87
|
coded_val = self.diag_coded_type.decode_from_pdu(decode_state)
|
96
88
|
|
97
|
-
# Check if the coded value
|
89
|
+
# Check if the coded value contained by the message is correct.
|
98
90
|
if self.coded_value != coded_val:
|
99
91
|
warnings.warn(
|
100
92
|
f"Coded constant parameter does not match! "
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import List
|
3
|
+
from typing import List, Optional
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from typing_extensions import override
|
@@ -41,9 +41,10 @@ class DynamicParameter(Parameter):
|
|
41
41
|
raise NotImplementedError(".is_settable for a DynamicParameter")
|
42
42
|
|
43
43
|
@override
|
44
|
-
def
|
45
|
-
|
44
|
+
def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
|
45
|
+
encode_state: EncodeState) -> None:
|
46
|
+
raise NotImplementedError("Encoding DynamicParameter is not implemented yet.")
|
46
47
|
|
47
48
|
@override
|
48
49
|
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
49
|
-
raise NotImplementedError("Decoding
|
50
|
+
raise NotImplementedError("Decoding DynamicParameter is not implemented yet.")
|
@@ -1,22 +1,19 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import
|
3
|
+
from typing import Any, Dict, List, Optional
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
|
-
from typing_extensions import override
|
6
|
+
from typing_extensions import final, override
|
7
7
|
|
8
8
|
from ..decodestate import DecodeState
|
9
9
|
from ..encodestate import EncodeState
|
10
|
-
from ..exceptions import odxraise, odxrequire
|
11
|
-
from ..odxlink import OdxDocFragment,
|
10
|
+
from ..exceptions import EncodeError, odxraise, odxrequire
|
11
|
+
from ..odxlink import OdxDocFragment, OdxLinkId
|
12
12
|
from ..odxtypes import ParameterValue
|
13
13
|
from ..utils import dataclass_fields_asdict
|
14
14
|
from .parameter import ParameterType
|
15
15
|
from .parameterwithdop import ParameterWithDOP
|
16
16
|
|
17
|
-
if TYPE_CHECKING:
|
18
|
-
from ..diaglayer import DiagLayer
|
19
|
-
|
20
17
|
|
21
18
|
@dataclass
|
22
19
|
class LengthKeyParameter(ParameterWithDOP):
|
@@ -55,14 +52,6 @@ class LengthKeyParameter(ParameterWithDOP):
|
|
55
52
|
|
56
53
|
return result
|
57
54
|
|
58
|
-
@override
|
59
|
-
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
60
|
-
super()._resolve_odxlinks(odxlinks)
|
61
|
-
|
62
|
-
@override
|
63
|
-
def _resolve_snrefs(self, diag_layer: "DiagLayer") -> None:
|
64
|
-
super()._resolve_snrefs(diag_layer)
|
65
|
-
|
66
55
|
@property
|
67
56
|
@override
|
68
57
|
def is_required(self) -> bool:
|
@@ -77,17 +66,62 @@ class LengthKeyParameter(ParameterWithDOP):
|
|
77
66
|
return True
|
78
67
|
|
79
68
|
@override
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
def
|
90
|
-
|
69
|
+
@final
|
70
|
+
def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
|
71
|
+
encode_state: EncodeState) -> None:
|
72
|
+
# if you get this exception, you ought to use
|
73
|
+
# `.encode_placeholder_into_pdu()` followed by (after the
|
74
|
+
# value of the length key has been determined)
|
75
|
+
# `.encode_value_into_pdu()`.
|
76
|
+
raise RuntimeError("_encode_positioned_into_pdu() cannot be called for length keys.")
|
77
|
+
|
78
|
+
def encode_placeholder_into_pdu(self, physical_value: Optional[ParameterValue],
|
79
|
+
encode_state: EncodeState) -> None:
|
80
|
+
|
81
|
+
if physical_value is not None:
|
82
|
+
if not self.dop.is_valid_physical_value(physical_value):
|
83
|
+
odxraise(f"Invalid explicitly specified physical value '{physical_value!r}' "
|
84
|
+
f"for length key '{self.short_name}'.")
|
85
|
+
|
86
|
+
lkv = encode_state.length_keys.get(self.short_name)
|
87
|
+
if lkv is not None and lkv != physical_value:
|
88
|
+
odxraise(f"Got conflicting values for length key {self.short_name}: "
|
89
|
+
f"{lkv} and {physical_value!r}")
|
90
|
+
|
91
|
+
if not isinstance(physical_value, int):
|
92
|
+
odxraise(
|
93
|
+
f"Value of length key {self.short_name} is of type {type(physical_value).__name__} "
|
94
|
+
f"instead of int")
|
95
|
+
|
96
|
+
encode_state.length_keys[self.short_name] = physical_value
|
97
|
+
|
98
|
+
pos = encode_state.cursor_byte_position
|
99
|
+
if self.byte_position is not None:
|
100
|
+
pos = encode_state.origin_byte_position + self.byte_position
|
101
|
+
encode_state.key_pos[self.short_name] = pos
|
102
|
+
encode_state.cursor_byte_position = pos
|
103
|
+
encode_state.cursor_bit_position = self.bit_position or 0
|
104
|
+
|
105
|
+
# emplace a value of zero into the encode state, but pretend the bits not to be used
|
106
|
+
n = odxrequire(self.dop.get_static_bit_length()) + encode_state.cursor_bit_position
|
107
|
+
tmp_val = b'\x00' * ((n + 7) // 8)
|
108
|
+
encode_state.cursor_bit_position = 0
|
109
|
+
encode_state.emplace_bytes(tmp_val, obj_used_mask=tmp_val)
|
110
|
+
|
111
|
+
def encode_value_into_pdu(self, encode_state: EncodeState) -> None:
|
112
|
+
|
113
|
+
if self.short_name not in encode_state.length_keys:
|
114
|
+
odxraise(
|
115
|
+
f"Length key {self.short_name} has not been defined before "
|
116
|
+
f"it is required.", EncodeError)
|
117
|
+
return
|
118
|
+
else:
|
119
|
+
physical_value = encode_state.length_keys[self.short_name]
|
120
|
+
|
121
|
+
encode_state.cursor_byte_position = encode_state.key_pos[self.short_name]
|
122
|
+
encode_state.cursor_bit_position = self.bit_position or 0
|
123
|
+
|
124
|
+
self.dop.encode_into_pdu(encode_state=encode_state, physical_value=physical_value)
|
91
125
|
|
92
126
|
@override
|
93
127
|
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
@@ -7,7 +7,7 @@ from typing_extensions import override
|
|
7
7
|
|
8
8
|
from ..decodestate import DecodeState
|
9
9
|
from ..encodestate import EncodeState
|
10
|
-
from ..exceptions import EncodeError, odxrequire
|
10
|
+
from ..exceptions import EncodeError, odxraise, odxrequire
|
11
11
|
from ..odxlink import OdxDocFragment
|
12
12
|
from ..odxtypes import DataType, ParameterValue
|
13
13
|
from ..utils import dataclass_fields_asdict
|
@@ -52,19 +52,31 @@ class MatchingRequestParameter(Parameter):
|
|
52
52
|
return False
|
53
53
|
|
54
54
|
@override
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
55
|
+
def _encode_positioned_into_pdu(self, physical_value: Optional[ParameterValue],
|
56
|
+
encode_state: EncodeState) -> None:
|
57
|
+
if encode_state.triggering_request is None:
|
58
|
+
odxraise(
|
59
|
+
f"Parameter '{self.short_name}' is of matching request type,"
|
60
|
+
f" but no original request has been specified.", EncodeError)
|
61
|
+
return
|
62
|
+
|
63
|
+
rq_pos = self.request_byte_position
|
64
|
+
rq_len = self.byte_length
|
65
|
+
|
66
|
+
if len(encode_state.triggering_request) < rq_pos + rq_len:
|
67
|
+
odxraise(
|
68
|
+
f"Specified triggering request 0x{encode_state.triggering_request.hex()} "
|
69
|
+
f"is not long enough to encode matching request parameter "
|
70
|
+
f"'{self.short_name}': Have {len(encode_state.triggering_request)} "
|
71
|
+
f"bytes, need at least {rq_pos + rq_len} bytes", EncodeError)
|
72
|
+
return
|
73
|
+
|
74
|
+
encode_state.emplace_bytes(encode_state.triggering_request[rq_pos:rq_pos + rq_len],
|
75
|
+
self.short_name)
|
62
76
|
|
63
77
|
@override
|
64
78
|
def _decode_positioned_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
65
|
-
|
79
|
+
return decode_state.extract_atomic_value(
|
66
80
|
bit_length=self.byte_length * 8,
|
67
81
|
base_data_type=DataType.A_UINT32,
|
68
82
|
is_highlow_byte_order=False)
|
69
|
-
|
70
|
-
return result
|