odxtools 9.6.1__py3-none-any.whl → 10.0.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/additionalaudience.py +3 -3
- odxtools/addressing.py +8 -0
- odxtools/admindata.py +8 -8
- odxtools/audience.py +10 -10
- odxtools/basecomparam.py +7 -20
- odxtools/basevariantpattern.py +4 -5
- odxtools/basicstructure.py +12 -11
- odxtools/cli/_print_utils.py +35 -23
- odxtools/cli/browse.py +9 -9
- odxtools/cli/compare.py +24 -24
- odxtools/cli/decode.py +3 -4
- odxtools/cli/find.py +4 -5
- odxtools/cli/list.py +7 -7
- odxtools/cli/main.py +2 -2
- odxtools/cli/snoop.py +3 -3
- odxtools/codec.py +3 -186
- odxtools/commrelation.py +12 -19
- odxtools/commrelationvaluetype.py +9 -0
- odxtools/companydata.py +5 -5
- odxtools/companydocinfo.py +8 -8
- odxtools/companyrevisioninfo.py +5 -5
- odxtools/companyspecificinfo.py +5 -5
- odxtools/comparam.py +3 -3
- odxtools/comparaminstance.py +10 -10
- odxtools/comparamspec.py +3 -3
- odxtools/comparamsubset.py +5 -5
- odxtools/complexcomparam.py +7 -7
- odxtools/compositecodec.py +191 -0
- odxtools/compumethods/compucategory.py +13 -0
- odxtools/compumethods/compucodecompumethod.py +6 -5
- odxtools/compumethods/compuconst.py +4 -5
- odxtools/compumethods/compudefaultvalue.py +1 -2
- odxtools/compumethods/compuinternaltophys.py +6 -6
- odxtools/compumethods/compumethod.py +6 -17
- odxtools/compumethods/compuphystointernal.py +6 -6
- odxtools/compumethods/compurationalcoeffs.py +4 -4
- odxtools/compumethods/compuscale.py +9 -10
- odxtools/compumethods/createanycompumethod.py +1 -2
- odxtools/compumethods/identicalcompumethod.py +1 -2
- odxtools/compumethods/intervaltype.py +8 -0
- odxtools/compumethods/limit.py +13 -19
- odxtools/compumethods/linearcompumethod.py +4 -3
- odxtools/compumethods/linearsegment.py +14 -15
- odxtools/compumethods/ratfunccompumethod.py +5 -4
- odxtools/compumethods/ratfuncsegment.py +7 -8
- odxtools/compumethods/scalelinearcompumethod.py +10 -9
- odxtools/compumethods/scaleratfunccompumethod.py +6 -5
- odxtools/compumethods/tabintpcompumethod.py +19 -20
- odxtools/compumethods/texttablecompumethod.py +5 -4
- odxtools/createanycomparam.py +2 -4
- odxtools/createanydiagcodedtype.py +1 -2
- odxtools/database.py +9 -8
- odxtools/dataobjectproperty.py +10 -10
- odxtools/decodestate.py +5 -5
- odxtools/description.py +6 -22
- odxtools/determinenumberofitems.py +4 -4
- odxtools/diagclasstype.py +11 -0
- odxtools/diagcodedtype.py +7 -7
- odxtools/diagcomm.py +19 -42
- odxtools/diagdatadictionaryspec.py +6 -6
- odxtools/diaglayercontainer.py +4 -4
- odxtools/diaglayers/basevariant.py +10 -9
- odxtools/diaglayers/basevariantraw.py +9 -9
- odxtools/diaglayers/diaglayer.py +20 -19
- odxtools/diaglayers/diaglayerraw.py +10 -10
- odxtools/diaglayers/diaglayertype.py +1 -2
- odxtools/diaglayers/ecushareddata.py +4 -4
- odxtools/diaglayers/ecushareddataraw.py +6 -6
- odxtools/diaglayers/ecuvariant.py +11 -10
- odxtools/diaglayers/ecuvariantraw.py +9 -9
- odxtools/diaglayers/functionalgroup.py +8 -7
- odxtools/diaglayers/functionalgroupraw.py +7 -7
- odxtools/diaglayers/hierarchyelement.py +43 -49
- odxtools/diaglayers/hierarchyelementraw.py +4 -4
- odxtools/diaglayers/protocol.py +4 -4
- odxtools/diaglayers/protocolraw.py +6 -6
- odxtools/diagnostictroublecode.py +8 -8
- odxtools/diagservice.py +21 -97
- odxtools/diagvariable.py +14 -14
- odxtools/docrevision.py +11 -11
- odxtools/dopbase.py +6 -6
- odxtools/dtcconnector.py +45 -0
- odxtools/dtcdop.py +15 -56
- odxtools/dynamicendmarkerfield.py +5 -4
- odxtools/dynamiclengthfield.py +5 -4
- odxtools/dyndefinedspec.py +7 -159
- odxtools/dynenddopref.py +5 -5
- odxtools/dyniddefmodeinfo.py +161 -0
- odxtools/ecuvariantpattern.py +4 -5
- odxtools/element.py +5 -6
- odxtools/encodestate.py +11 -11
- odxtools/encoding.py +2 -3
- odxtools/endofpdufield.py +6 -6
- odxtools/envdataconnector.py +49 -0
- odxtools/environmentdata.py +3 -4
- odxtools/environmentdatadescription.py +11 -11
- odxtools/exceptions.py +5 -5
- odxtools/externalaccessmethod.py +22 -0
- odxtools/externaldoc.py +23 -0
- odxtools/field.py +9 -10
- odxtools/functionalclass.py +4 -4
- odxtools/inputparam.py +6 -6
- odxtools/internalconstr.py +4 -5
- odxtools/isotp_state_machine.py +12 -11
- odxtools/leadinglengthinfotype.py +2 -3
- odxtools/library.py +5 -5
- odxtools/linkeddtcdop.py +62 -0
- odxtools/loadfile.py +5 -6
- odxtools/matchingbasevariantparameter.py +2 -3
- odxtools/matchingparameter.py +7 -7
- odxtools/minmaxlengthtype.py +5 -11
- odxtools/modification.py +4 -4
- odxtools/multiplexer.py +11 -11
- odxtools/multiplexercase.py +6 -6
- odxtools/multiplexerdefaultcase.py +6 -6
- odxtools/multiplexerswitchkey.py +4 -4
- odxtools/nameditemlist.py +14 -14
- odxtools/negoutputparam.py +3 -3
- odxtools/obd.py +1 -2
- odxtools/odxcategory.py +6 -6
- odxtools/odxlink.py +19 -20
- odxtools/odxtypes.py +21 -18
- odxtools/outputparam.py +4 -4
- odxtools/parameterinfo.py +2 -2
- odxtools/parameters/codedconstparameter.py +5 -5
- odxtools/parameters/createanyparameter.py +1 -2
- odxtools/parameters/dynamicparameter.py +2 -3
- odxtools/parameters/lengthkeyparameter.py +5 -5
- odxtools/parameters/matchingrequestparameter.py +3 -4
- odxtools/parameters/nrcconstparameter.py +7 -7
- odxtools/parameters/parameter.py +11 -11
- odxtools/parameters/parameterwithdop.py +9 -9
- odxtools/parameters/physicalconstantparameter.py +4 -4
- odxtools/parameters/reservedparameter.py +3 -4
- odxtools/parameters/rowfragment.py +7 -0
- odxtools/parameters/systemparameter.py +2 -3
- odxtools/parameters/tableentryparameter.py +4 -9
- odxtools/parameters/tablekeyparameter.py +10 -10
- odxtools/parameters/tablestructparameter.py +7 -7
- odxtools/parameters/valueparameter.py +7 -7
- odxtools/paramlengthinfotype.py +5 -3
- odxtools/parentref.py +9 -9
- odxtools/physicaldimension.py +11 -11
- odxtools/physicaltype.py +4 -12
- odxtools/posresponsesuppressible.py +72 -0
- odxtools/preconditionstateref.py +7 -7
- odxtools/progcode.py +6 -6
- odxtools/protstack.py +4 -4
- odxtools/radix.py +9 -0
- odxtools/relateddiagcommref.py +22 -0
- odxtools/relateddoc.py +6 -6
- odxtools/request.py +14 -12
- odxtools/response.py +15 -13
- odxtools/scaleconstr.py +4 -12
- odxtools/servicebinner.py +5 -5
- odxtools/singleecujob.py +4 -4
- odxtools/snrefcontext.py +2 -2
- odxtools/specialdata.py +5 -5
- odxtools/specialdatagroup.py +9 -9
- odxtools/specialdatagroupcaption.py +3 -3
- odxtools/standardizationlevel.py +9 -0
- odxtools/standardlengthtype.py +12 -21
- odxtools/state.py +3 -3
- odxtools/statechart.py +4 -4
- odxtools/statemachine.py +4 -3
- odxtools/statetransition.py +5 -18
- odxtools/statetransitionref.py +18 -18
- odxtools/staticfield.py +5 -4
- odxtools/structure.py +2 -3
- odxtools/subcomponent.py +12 -245
- odxtools/subcomponentparamconnector.py +103 -0
- odxtools/subcomponentpattern.py +42 -0
- odxtools/swvariable.py +3 -4
- odxtools/table.py +17 -55
- odxtools/tablediagcommconnector.py +47 -0
- odxtools/tablerow.py +30 -30
- odxtools/tablerowconnector.py +46 -0
- odxtools/teammember.py +11 -11
- odxtools/templates/macros/printService.xml.jinja2 +2 -1
- odxtools/termination.py +8 -0
- odxtools/text.py +2 -3
- odxtools/transmode.py +9 -0
- odxtools/uds.py +2 -3
- odxtools/unit.py +9 -9
- odxtools/unitgroup.py +6 -11
- odxtools/unitgroupcategory.py +7 -0
- odxtools/unitspec.py +6 -6
- odxtools/usage.py +9 -0
- odxtools/utils.py +31 -2
- odxtools/validtype.py +9 -0
- odxtools/variablegroup.py +2 -2
- odxtools/variantmatcher.py +10 -10
- odxtools/variantpattern.py +3 -3
- odxtools/version.py +2 -2
- odxtools/writepdxfile.py +5 -5
- odxtools/xdoc.py +9 -9
- {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/METADATA +4 -5
- odxtools-10.0.0.dist-info/RECORD +264 -0
- odxtools-9.6.1.dist-info/RECORD +0 -238
- {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/WHEEL +0 -0
- {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/entry_points.txt +0 -0
- {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/licenses/LICENSE +0 -0
- {odxtools-9.6.1.dist-info → odxtools-10.0.0.dist-info}/top_level.txt +0 -0
odxtools/cli/list.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import argparse
|
3
|
-
from
|
3
|
+
from collections.abc import Callable
|
4
4
|
|
5
5
|
import rich
|
6
6
|
|
@@ -32,11 +32,11 @@ def print_summary(odxdb: Database,
|
|
32
32
|
print_state_transitions: bool = False,
|
33
33
|
print_audiences: bool = False,
|
34
34
|
allow_unknown_bit_lengths: bool = False,
|
35
|
-
variants:
|
35
|
+
variants: list[str] | None = None,
|
36
36
|
service_filter: Callable[[DiagComm], bool] = lambda x: True) -> None:
|
37
37
|
|
38
38
|
diag_layer_names = [dl.short_name for dl in odxdb.diag_layers]
|
39
|
-
diag_layers:
|
39
|
+
diag_layers: list[DiagLayer] = []
|
40
40
|
|
41
41
|
if variants is None:
|
42
42
|
variants = diag_layer_names
|
@@ -59,9 +59,9 @@ def print_summary(odxdb: Database,
|
|
59
59
|
rich.print(f"Diagnostic layer: '{dl.short_name}'")
|
60
60
|
rich.print(f" Variant Type: {dl.variant_type.value}")
|
61
61
|
|
62
|
-
all_services:
|
62
|
+
all_services: list[DiagComm] = sorted(dl.services, key=lambda x: x.short_name)
|
63
63
|
|
64
|
-
if isinstance(dl,
|
64
|
+
if isinstance(dl, BaseVariant | EcuVariant):
|
65
65
|
for proto in dl.protocols:
|
66
66
|
if (can_rx_id := dl.get_can_receive_id(proto.short_name)) is not None:
|
67
67
|
rich.print(
|
@@ -99,7 +99,7 @@ def print_summary(odxdb: Database,
|
|
99
99
|
else:
|
100
100
|
rich.print(f" Unidentifiable service: {service}")
|
101
101
|
ddd_spec = dl.diag_data_dictionary_spec
|
102
|
-
data_object_properties:
|
102
|
+
data_object_properties: list[
|
103
103
|
DataObjectProperty] = [] if ddd_spec is None else ddd_spec.data_object_props
|
104
104
|
if print_dops and len(data_object_properties) > 0:
|
105
105
|
rich.print("\n")
|
@@ -108,7 +108,7 @@ def print_summary(odxdb: Database,
|
|
108
108
|
data_object_properties, key=lambda x: (type(x).__name__, x.short_name)):
|
109
109
|
rich.print(" " + str(dop.short_name).replace("\n", "\n "))
|
110
110
|
|
111
|
-
comparam_refs:
|
111
|
+
comparam_refs: list[ComparamInstance] = []
|
112
112
|
if isinstance(dl, HierarchyElement):
|
113
113
|
comparam_refs = dl.comparam_refs
|
114
114
|
|
odxtools/cli/main.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import argparse
|
3
3
|
import importlib
|
4
|
-
from typing import Any
|
4
|
+
from typing import Any
|
5
5
|
|
6
6
|
import odxtools
|
7
7
|
import odxtools.exceptions
|
@@ -11,7 +11,7 @@ from .dummy_sub_parser import DummyTool
|
|
11
11
|
|
12
12
|
# import the tool modules which can be loaded. if a tool
|
13
13
|
# can't be loaded, add a dummy one
|
14
|
-
tool_modules:
|
14
|
+
tool_modules: list[Any] = []
|
15
15
|
for tool_name in ["list", "browse", "snoop", "find", "decode", "compare"]:
|
16
16
|
try:
|
17
17
|
tool_modules.append(importlib.import_module(f".{tool_name}", package="odxtools.cli"))
|
odxtools/cli/snoop.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
import argparse
|
5
5
|
import asyncio
|
6
6
|
import sys
|
7
|
-
from typing import Any
|
7
|
+
from typing import Any
|
8
8
|
|
9
9
|
import can
|
10
10
|
|
@@ -103,7 +103,7 @@ def handle_telegram(telegram_id: int, payload: bytes) -> None:
|
|
103
103
|
f"({payload!r}, {len(payload)} bytes)")
|
104
104
|
|
105
105
|
|
106
|
-
def init_verbose_state_machine(BaseClass:
|
106
|
+
def init_verbose_state_machine(BaseClass: type[IsoTpStateMachine], *args: Any,
|
107
107
|
**kwargs: Any) -> IsoTpStateMachine:
|
108
108
|
|
109
109
|
class InformativeIsoTpDecoder(BaseClass): # type: ignore[valid-type, misc]
|
@@ -246,7 +246,7 @@ def run(args: argparse.Namespace) -> None:
|
|
246
246
|
|
247
247
|
protocol_name = args.protocol
|
248
248
|
if odx_diag_layer is not None and protocol_name is not None:
|
249
|
-
protocols:
|
249
|
+
protocols: list[Protocol] | None = getattr(odx_diag_layer, "protocols", None)
|
250
250
|
|
251
251
|
if protocols is None:
|
252
252
|
print(f"ECU variant {odx_diag_layer.short_name} is of type "
|
odxtools/codec.py
CHANGED
@@ -1,15 +1,10 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import typing
|
3
|
-
from typing import
|
3
|
+
from typing import runtime_checkable
|
4
4
|
|
5
5
|
from .decodestate import DecodeState
|
6
6
|
from .encodestate import EncodeState
|
7
|
-
from .exceptions import EncodeError, odxraise
|
8
7
|
from .odxtypes import ParameterValue
|
9
|
-
from .parameters.codedconstparameter import CodedConstParameter
|
10
|
-
from .parameters.matchingrequestparameter import MatchingRequestParameter
|
11
|
-
from .parameters.parameter import Parameter
|
12
|
-
from .parameters.physicalconstantparameter import PhysicalConstantParameter
|
13
8
|
|
14
9
|
|
15
10
|
@runtime_checkable
|
@@ -22,190 +17,12 @@ class Codec(typing.Protocol):
|
|
22
17
|
def short_name(self) -> str:
|
23
18
|
return ""
|
24
19
|
|
25
|
-
def encode_into_pdu(self, physical_value:
|
20
|
+
def encode_into_pdu(self, physical_value: ParameterValue | None,
|
26
21
|
encode_state: EncodeState) -> None:
|
27
22
|
...
|
28
23
|
|
29
24
|
def decode_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
|
30
25
|
...
|
31
26
|
|
32
|
-
def get_static_bit_length(self) ->
|
27
|
+
def get_static_bit_length(self) -> int | None:
|
33
28
|
...
|
34
|
-
|
35
|
-
|
36
|
-
@runtime_checkable
|
37
|
-
class CompositeCodec(Codec, typing.Protocol):
|
38
|
-
"""Any object which can be en- or decoded to be transferred over
|
39
|
-
the wire which is composed of multiple parameter implements this
|
40
|
-
API.
|
41
|
-
|
42
|
-
"""
|
43
|
-
|
44
|
-
@property
|
45
|
-
def parameters(self) -> List[Parameter]:
|
46
|
-
return []
|
47
|
-
|
48
|
-
@property
|
49
|
-
def required_parameters(self) -> List[Parameter]:
|
50
|
-
return []
|
51
|
-
|
52
|
-
@property
|
53
|
-
def free_parameters(self) -> List[Parameter]:
|
54
|
-
return []
|
55
|
-
|
56
|
-
|
57
|
-
# some helper functions useful for composite codec objects
|
58
|
-
def composite_codec_get_static_bit_length(codec: CompositeCodec) -> Optional[int]:
|
59
|
-
"""Compute the length of a composite codec object in bits
|
60
|
-
|
61
|
-
This is basically the sum of the lengths of all parameters. If the
|
62
|
-
length of any parameter can only determined at runtime, `None` is
|
63
|
-
returned.
|
64
|
-
"""
|
65
|
-
|
66
|
-
cursor = 0
|
67
|
-
byte_length = 0
|
68
|
-
for param in codec.parameters:
|
69
|
-
param_bit_length = param.get_static_bit_length()
|
70
|
-
if param_bit_length is None:
|
71
|
-
# We were not able to calculate a static bit length
|
72
|
-
return None
|
73
|
-
elif param.byte_position is not None:
|
74
|
-
cursor = param.byte_position
|
75
|
-
|
76
|
-
cursor += ((param.bit_position or 0) + param_bit_length + 7) // 8
|
77
|
-
byte_length = max(byte_length, cursor)
|
78
|
-
|
79
|
-
return byte_length * 8
|
80
|
-
|
81
|
-
|
82
|
-
def composite_codec_get_required_parameters(codec: CompositeCodec) -> List[Parameter]:
|
83
|
-
"""Return the list of parameters which are required to be
|
84
|
-
specified for encoding the composite codec object
|
85
|
-
|
86
|
-
I.e., all free parameters that do not exhibit a default value.
|
87
|
-
"""
|
88
|
-
return [p for p in codec.parameters if p.is_required]
|
89
|
-
|
90
|
-
|
91
|
-
def composite_codec_get_free_parameters(codec: CompositeCodec) -> List[Parameter]:
|
92
|
-
"""Return the list of parameters which can be freely specified by
|
93
|
-
the user when encoding the composite codec object
|
94
|
-
|
95
|
-
This means all required parameters plus parameters that can be
|
96
|
-
omitted because they specify a default.
|
97
|
-
"""
|
98
|
-
return [p for p in codec.parameters if p.is_settable]
|
99
|
-
|
100
|
-
|
101
|
-
def composite_codec_get_coded_const_prefix(codec: CompositeCodec,
|
102
|
-
request_prefix: bytes = b'') -> bytes:
|
103
|
-
encode_state = EncodeState(coded_message=bytearray(), triggering_request=request_prefix)
|
104
|
-
|
105
|
-
for param in codec.parameters:
|
106
|
-
if (isinstance(param, MatchingRequestParameter) and param.request_byte_position < len(request_prefix)) or \
|
107
|
-
isinstance(param, (CodedConstParameter, PhysicalConstantParameter)):
|
108
|
-
param.encode_into_pdu(physical_value=None, encode_state=encode_state)
|
109
|
-
else:
|
110
|
-
break
|
111
|
-
|
112
|
-
return encode_state.coded_message
|
113
|
-
|
114
|
-
|
115
|
-
def composite_codec_encode_into_pdu(codec: CompositeCodec, physical_value: Optional[ParameterValue],
|
116
|
-
encode_state: EncodeState) -> None:
|
117
|
-
from .parameters.lengthkeyparameter import LengthKeyParameter
|
118
|
-
from .parameters.tablekeyparameter import TableKeyParameter
|
119
|
-
|
120
|
-
if not isinstance(physical_value, dict):
|
121
|
-
odxraise(
|
122
|
-
f"Expected a dictionary for the values of {codec.short_name}, "
|
123
|
-
f"got {type(physical_value).__name__}", EncodeError)
|
124
|
-
elif encode_state.cursor_bit_position != 0:
|
125
|
-
odxraise(
|
126
|
-
f"Compositional codec objecs must be byte aligned, but "
|
127
|
-
f"{codec.short_name} requested to be at bit position "
|
128
|
-
f"{encode_state.cursor_bit_position}", EncodeError)
|
129
|
-
encode_state.bit_position = 0
|
130
|
-
|
131
|
-
orig_origin = encode_state.origin_byte_position
|
132
|
-
encode_state.origin_byte_position = encode_state.cursor_byte_position
|
133
|
-
|
134
|
-
orig_is_end_of_pdu = encode_state.is_end_of_pdu
|
135
|
-
encode_state.is_end_of_pdu = False
|
136
|
-
|
137
|
-
# ensure that no values for unknown parameters are specified.
|
138
|
-
if not encode_state.allow_unknown_parameters:
|
139
|
-
param_names = {param.short_name for param in codec.parameters}
|
140
|
-
for param_value_name in physical_value:
|
141
|
-
if param_value_name not in param_names:
|
142
|
-
odxraise(f"Value for unknown parameter '{param_value_name}' specified "
|
143
|
-
f"for composite codec object {codec.short_name}")
|
144
|
-
|
145
|
-
for param in codec.parameters:
|
146
|
-
if id(param) == id(codec.parameters[-1]):
|
147
|
-
# The last parameter of the composite codec object is at
|
148
|
-
# the end of the PDU if the codec object itself is at the
|
149
|
-
# end of the PDU.
|
150
|
-
#
|
151
|
-
# TODO: This assumes that the last parameter specified in
|
152
|
-
# the ODX is located last in the PDU...
|
153
|
-
encode_state.is_end_of_pdu = orig_is_end_of_pdu
|
154
|
-
|
155
|
-
if isinstance(param, (LengthKeyParameter, TableKeyParameter)):
|
156
|
-
# At this point, we encode a placeholder value for length-
|
157
|
-
# and table keys, since these can be specified
|
158
|
-
# implicitly (i.e., by means of parameters that use
|
159
|
-
# these keys). To avoid getting an "overlapping
|
160
|
-
# parameter" warning, we must encode a value of zero
|
161
|
-
# into the PDU here and add the real value of the
|
162
|
-
# parameter in a post-processing step.
|
163
|
-
param.encode_placeholder_into_pdu(
|
164
|
-
physical_value=physical_value.get(param.short_name), encode_state=encode_state)
|
165
|
-
|
166
|
-
continue
|
167
|
-
|
168
|
-
if param.is_required and param.short_name not in physical_value:
|
169
|
-
odxraise(f"No value for required parameter {param.short_name} specified", EncodeError)
|
170
|
-
|
171
|
-
param_phys_value = physical_value.get(param.short_name)
|
172
|
-
param.encode_into_pdu(physical_value=param_phys_value, encode_state=encode_state)
|
173
|
-
|
174
|
-
encode_state.journal.append((param, param_phys_value))
|
175
|
-
|
176
|
-
encode_state.is_end_of_pdu = False
|
177
|
-
|
178
|
-
# encode the length- and table keys. This cannot be done above
|
179
|
-
# because we allow these to be defined implicitly (i.e. they
|
180
|
-
# are defined by their respective users)
|
181
|
-
for param in codec.parameters:
|
182
|
-
if not isinstance(param, (LengthKeyParameter, TableKeyParameter)):
|
183
|
-
# the current parameter is neither a length- nor a table key
|
184
|
-
continue
|
185
|
-
|
186
|
-
# Encode the value of the key parameter into the message
|
187
|
-
param.encode_value_into_pdu(encode_state=encode_state)
|
188
|
-
|
189
|
-
encode_state.origin_byte_position = orig_origin
|
190
|
-
|
191
|
-
|
192
|
-
def composite_codec_decode_from_pdu(codec: CompositeCodec,
|
193
|
-
decode_state: DecodeState) -> ParameterValue:
|
194
|
-
# move the origin since positions specified by sub-parameters of
|
195
|
-
# composite codec objects are relative to the beginning of the
|
196
|
-
# object.
|
197
|
-
orig_origin = decode_state.origin_byte_position
|
198
|
-
decode_state.origin_byte_position = decode_state.cursor_byte_position
|
199
|
-
|
200
|
-
result = {}
|
201
|
-
for param in codec.parameters:
|
202
|
-
value = param.decode_from_pdu(decode_state)
|
203
|
-
|
204
|
-
decode_state.journal.append((param, value))
|
205
|
-
result[param.short_name] = value
|
206
|
-
|
207
|
-
# decoding of the composite codec object finished. go back the
|
208
|
-
# original origin.
|
209
|
-
decode_state.origin_byte_position = orig_origin
|
210
|
-
|
211
|
-
return result
|
odxtools/commrelation.py
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import warnings
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from
|
5
|
-
from typing import Any, Dict, List, Optional
|
4
|
+
from typing import Any
|
6
5
|
from xml.etree import ElementTree
|
7
6
|
|
7
|
+
from .commrelationvaluetype import CommRelationValueType
|
8
8
|
from .description import Description
|
9
9
|
from .diagcomm import DiagComm
|
10
10
|
from .diagservice import DiagService
|
@@ -14,35 +14,28 @@ from .parameters.parameter import Parameter
|
|
14
14
|
from .snrefcontext import SnRefContext
|
15
15
|
|
16
16
|
|
17
|
-
class CommRelationValueType(Enum):
|
18
|
-
CURRENT = "CURRENT"
|
19
|
-
STORED = "STORED"
|
20
|
-
STATIC = "STATIC"
|
21
|
-
SUBSTITUTED = "SUBSTITUTED"
|
22
|
-
|
23
|
-
|
24
17
|
@dataclass
|
25
18
|
class CommRelation:
|
26
|
-
description:
|
19
|
+
description: Description | None
|
27
20
|
relation_type: str
|
28
|
-
diag_comm_ref:
|
29
|
-
diag_comm_snref:
|
30
|
-
in_param_if_snref:
|
21
|
+
diag_comm_ref: OdxLinkRef | None
|
22
|
+
diag_comm_snref: str | None
|
23
|
+
in_param_if_snref: str | None
|
31
24
|
#in_param_if_snpathref: Optional[str] # TODO
|
32
|
-
out_param_if_snref:
|
25
|
+
out_param_if_snref: str | None
|
33
26
|
#out_param_if_snpathref: Optional[str] # TODO
|
34
|
-
value_type_raw:
|
27
|
+
value_type_raw: CommRelationValueType | None
|
35
28
|
|
36
29
|
@property
|
37
30
|
def diag_comm(self) -> DiagComm:
|
38
31
|
return self._diag_comm
|
39
32
|
|
40
33
|
@property
|
41
|
-
def in_param_if(self) ->
|
34
|
+
def in_param_if(self) -> Parameter | None:
|
42
35
|
return self._in_param_if
|
43
36
|
|
44
37
|
@property
|
45
|
-
def out_param_if(self) ->
|
38
|
+
def out_param_if(self) -> Parameter | None:
|
46
39
|
return self._out_param_if
|
47
40
|
|
48
41
|
@property
|
@@ -53,7 +46,7 @@ class CommRelation:
|
|
53
46
|
return self.value_type_raw
|
54
47
|
|
55
48
|
@staticmethod
|
56
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
49
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "CommRelation":
|
57
50
|
description = Description.from_et(et_element.find("DESC"), doc_frags)
|
58
51
|
relation_type = odxrequire(et_element.findtext("RELATION-TYPE"))
|
59
52
|
|
@@ -92,7 +85,7 @@ class CommRelation:
|
|
92
85
|
out_param_if_snref=out_param_if_snref,
|
93
86
|
value_type_raw=value_type_raw)
|
94
87
|
|
95
|
-
def _build_odxlinks(self) ->
|
88
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
96
89
|
return {}
|
97
90
|
|
98
91
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/companydata.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .companyspecificinfo import CompanySpecificInfo
|
@@ -15,12 +15,12 @@ from .utils import dataclass_fields_asdict
|
|
15
15
|
|
16
16
|
@dataclass
|
17
17
|
class CompanyData(IdentifiableElement):
|
18
|
-
roles:
|
18
|
+
roles: list[str]
|
19
19
|
team_members: NamedItemList[TeamMember]
|
20
|
-
company_specific_info:
|
20
|
+
company_specific_info: CompanySpecificInfo | None
|
21
21
|
|
22
22
|
@staticmethod
|
23
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
23
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "CompanyData":
|
24
24
|
|
25
25
|
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
|
26
26
|
|
@@ -43,7 +43,7 @@ class CompanyData(IdentifiableElement):
|
|
43
43
|
**kwargs,
|
44
44
|
)
|
45
45
|
|
46
|
-
def _build_odxlinks(self) ->
|
46
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
47
47
|
result = {self.odx_id: self}
|
48
48
|
|
49
49
|
for tm in self.team_members:
|
odxtools/companydocinfo.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .companydata import CompanyData
|
@@ -14,21 +14,21 @@ from .teammember import TeamMember
|
|
14
14
|
@dataclass
|
15
15
|
class CompanyDocInfo:
|
16
16
|
company_data_ref: OdxLinkRef
|
17
|
-
team_member_ref:
|
18
|
-
doc_label:
|
19
|
-
sdgs:
|
17
|
+
team_member_ref: OdxLinkRef | None
|
18
|
+
doc_label: str | None
|
19
|
+
sdgs: list[SpecialDataGroup]
|
20
20
|
|
21
21
|
@property
|
22
22
|
def company_data(self) -> CompanyData:
|
23
23
|
return self._company_data
|
24
24
|
|
25
25
|
@property
|
26
|
-
def team_member(self) ->
|
26
|
+
def team_member(self) -> TeamMember | None:
|
27
27
|
return self._team_member
|
28
28
|
|
29
29
|
@staticmethod
|
30
30
|
def from_et(et_element: ElementTree.Element,
|
31
|
-
doc_frags:
|
31
|
+
doc_frags: list[OdxDocFragment]) -> "CompanyDocInfo":
|
32
32
|
# the company data reference is mandatory
|
33
33
|
company_data_ref = odxrequire(
|
34
34
|
OdxLinkRef.from_et(et_element.find("COMPANY-DATA-REF"), doc_frags))
|
@@ -45,7 +45,7 @@ class CompanyDocInfo:
|
|
45
45
|
sdgs=sdgs,
|
46
46
|
)
|
47
47
|
|
48
|
-
def _build_odxlinks(self) ->
|
48
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
49
49
|
result = {}
|
50
50
|
|
51
51
|
for sdg in self.sdgs:
|
@@ -56,7 +56,7 @@ class CompanyDocInfo:
|
|
56
56
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
57
57
|
self._company_data = odxlinks.resolve(self.company_data_ref, CompanyData)
|
58
58
|
|
59
|
-
self._team_member:
|
59
|
+
self._team_member: TeamMember | None = None
|
60
60
|
if self.team_member_ref is not None:
|
61
61
|
self._team_member = odxlinks.resolve(self.team_member_ref, TeamMember)
|
62
62
|
|
odxtools/companyrevisioninfo.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .companydata import CompanyData
|
@@ -12,8 +12,8 @@ from .snrefcontext import SnRefContext
|
|
12
12
|
@dataclass
|
13
13
|
class CompanyRevisionInfo:
|
14
14
|
company_data_ref: OdxLinkRef
|
15
|
-
revision_label:
|
16
|
-
state:
|
15
|
+
revision_label: str | None
|
16
|
+
state: str | None
|
17
17
|
|
18
18
|
@property
|
19
19
|
def company_data(self) -> CompanyData:
|
@@ -21,7 +21,7 @@ class CompanyRevisionInfo:
|
|
21
21
|
|
22
22
|
@staticmethod
|
23
23
|
def from_et(et_element: ElementTree.Element,
|
24
|
-
doc_frags:
|
24
|
+
doc_frags: list[OdxDocFragment]) -> "CompanyRevisionInfo":
|
25
25
|
|
26
26
|
company_data_ref = odxrequire(
|
27
27
|
OdxLinkRef.from_et(et_element.find("COMPANY-DATA-REF"), doc_frags))
|
@@ -31,7 +31,7 @@ class CompanyRevisionInfo:
|
|
31
31
|
return CompanyRevisionInfo(
|
32
32
|
company_data_ref=company_data_ref, revision_label=revision_label, state=state)
|
33
33
|
|
34
|
-
def _build_odxlinks(self) ->
|
34
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
35
35
|
return {}
|
36
36
|
|
37
37
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/companyspecificinfo.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
|
@@ -11,12 +11,12 @@ from .specialdatagroup import SpecialDataGroup
|
|
11
11
|
|
12
12
|
@dataclass
|
13
13
|
class CompanySpecificInfo:
|
14
|
-
related_docs:
|
15
|
-
sdgs:
|
14
|
+
related_docs: list[RelatedDoc]
|
15
|
+
sdgs: list[SpecialDataGroup]
|
16
16
|
|
17
17
|
@staticmethod
|
18
18
|
def from_et(et_element: ElementTree.Element,
|
19
|
-
doc_frags:
|
19
|
+
doc_frags: list[OdxDocFragment]) -> "CompanySpecificInfo":
|
20
20
|
related_docs = [
|
21
21
|
RelatedDoc.from_et(rd, doc_frags)
|
22
22
|
for rd in et_element.iterfind("RELATED-DOCS/RELATED-DOC")
|
@@ -28,7 +28,7 @@ class CompanySpecificInfo:
|
|
28
28
|
|
29
29
|
return CompanySpecificInfo(related_docs=related_docs, sdgs=sdgs)
|
30
30
|
|
31
|
-
def _build_odxlinks(self) ->
|
31
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
32
32
|
result = {}
|
33
33
|
|
34
34
|
for rd in self.related_docs:
|
odxtools/comparam.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import Any
|
3
|
+
from typing import Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .basecomparam import BaseComparam
|
@@ -27,7 +27,7 @@ class Comparam(BaseComparam):
|
|
27
27
|
return self._dop
|
28
28
|
|
29
29
|
@staticmethod
|
30
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
30
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "Comparam":
|
31
31
|
kwargs = dataclass_fields_asdict(BaseComparam.from_et(et_element, doc_frags))
|
32
32
|
|
33
33
|
physical_default_value_raw = odxrequire(et_element.findtext("PHYSICAL-DEFAULT-VALUE"))
|
@@ -36,7 +36,7 @@ class Comparam(BaseComparam):
|
|
36
36
|
return Comparam(
|
37
37
|
dop_ref=dop_ref, physical_default_value_raw=physical_default_value_raw, **kwargs)
|
38
38
|
|
39
|
-
def _build_odxlinks(self) ->
|
39
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
40
40
|
return super()._build_odxlinks()
|
41
41
|
|
42
42
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
odxtools/comparaminstance.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
import warnings
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import Any
|
4
|
+
from typing import Any
|
5
5
|
from xml.etree import ElementTree
|
6
6
|
|
7
7
|
from .basecomparam import BaseComparam
|
@@ -20,10 +20,10 @@ class ComparamInstance:
|
|
20
20
|
|
21
21
|
Be aware that the ODX specification calls this class COMPARAM-REF!
|
22
22
|
"""
|
23
|
-
value:
|
24
|
-
description:
|
25
|
-
protocol_snref:
|
26
|
-
prot_stack_snref:
|
23
|
+
value: str | ComplexValue
|
24
|
+
description: Description | None
|
25
|
+
protocol_snref: str | None
|
26
|
+
prot_stack_snref: str | None
|
27
27
|
spec_ref: OdxLinkRef
|
28
28
|
|
29
29
|
@property
|
@@ -36,13 +36,13 @@ class ComparamInstance:
|
|
36
36
|
|
37
37
|
@staticmethod
|
38
38
|
def from_et(et_element: ElementTree.Element,
|
39
|
-
doc_frags:
|
39
|
+
doc_frags: list[OdxDocFragment]) -> "ComparamInstance":
|
40
40
|
spec_ref = odxrequire(OdxLinkRef.from_et(et_element, doc_frags))
|
41
41
|
|
42
42
|
# ODX standard v2.0.0 defined only VALUE. ODX v2.0.1 decided
|
43
43
|
# to break things and change it to a choice between SIMPLE-VALUE
|
44
44
|
# and COMPLEX-VALUE
|
45
|
-
value:
|
45
|
+
value: str | list[str | ComplexValue]
|
46
46
|
if et_element.find("VALUE") is not None:
|
47
47
|
value = odxrequire(et_element.findtext("VALUE"))
|
48
48
|
elif et_element.find("SIMPLE-VALUE") is not None:
|
@@ -68,7 +68,7 @@ class ComparamInstance:
|
|
68
68
|
prot_stack_snref=prot_stack_snref,
|
69
69
|
)
|
70
70
|
|
71
|
-
def _build_odxlinks(self) ->
|
71
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
72
72
|
return {}
|
73
73
|
|
74
74
|
def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
|
@@ -98,7 +98,7 @@ class ComparamInstance:
|
|
98
98
|
|
99
99
|
return result
|
100
100
|
|
101
|
-
def get_subvalue(self, subparam_name: str) ->
|
101
|
+
def get_subvalue(self, subparam_name: str) -> str | None:
|
102
102
|
"""Retrieve the value of a complex communication parameter's sub-parameter by name
|
103
103
|
|
104
104
|
This takes the default value of the comparam (if any) into
|
@@ -133,7 +133,7 @@ class ComparamInstance:
|
|
133
133
|
return None
|
134
134
|
|
135
135
|
result = value_list[idx]
|
136
|
-
if result is None and isinstance(subparam,
|
136
|
+
if result is None and isinstance(subparam, Comparam | ComplexComparam):
|
137
137
|
result = subparam.physical_default_value
|
138
138
|
if not isinstance(result, str):
|
139
139
|
odxraise()
|
odxtools/comparamspec.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import TYPE_CHECKING, Any
|
3
|
+
from typing import TYPE_CHECKING, Any
|
4
4
|
from xml.etree import ElementTree
|
5
5
|
|
6
6
|
from .nameditemlist import NamedItemList
|
@@ -20,7 +20,7 @@ class ComparamSpec(OdxCategory):
|
|
20
20
|
prot_stacks: NamedItemList[ProtStack]
|
21
21
|
|
22
22
|
@staticmethod
|
23
|
-
def from_et(et_element: ElementTree.Element, doc_frags:
|
23
|
+
def from_et(et_element: ElementTree.Element, doc_frags: list[OdxDocFragment]) -> "ComparamSpec":
|
24
24
|
|
25
25
|
base_obj = OdxCategory.category_from_et(
|
26
26
|
et_element, doc_frags, doc_type=DocType.COMPARAM_SPEC)
|
@@ -34,7 +34,7 @@ class ComparamSpec(OdxCategory):
|
|
34
34
|
|
35
35
|
return ComparamSpec(prot_stacks=prot_stacks, **kwargs)
|
36
36
|
|
37
|
-
def _build_odxlinks(self) ->
|
37
|
+
def _build_odxlinks(self) -> dict[OdxLinkId, Any]:
|
38
38
|
odxlinks = super()._build_odxlinks()
|
39
39
|
|
40
40
|
for ps in self.prot_stacks:
|