Skip to content

Commit 9623e2e

Browse files
authored
Merge pull request #321 from andlaus/env_data_coding
implement de- and encoding of environment data descriptions
2 parents ad6e5c3 + 1238282 commit 9623e2e

10 files changed

+464
-104
lines changed

examples/somersault.pdx

-237 Bytes
Binary file not shown.

examples/somersault_modified.pdx

-234 Bytes
Binary file not shown.

examples/somersaultecu.py

Lines changed: 3 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
from odxtools.diaglayertype import DiagLayerType
3535
from odxtools.diagservice import DiagService
3636
from odxtools.docrevision import DocRevision
37-
from odxtools.environmentdata import EnvironmentData
38-
from odxtools.environmentdatadescription import EnvironmentDataDescription
3937
from odxtools.exceptions import odxrequire
4038
from odxtools.functionalclass import FunctionalClass
4139
from odxtools.modification import Modification
@@ -45,7 +43,6 @@
4543
from odxtools.parameters.codedconstparameter import CodedConstParameter
4644
from odxtools.parameters.matchingrequestparameter import MatchingRequestParameter
4745
from odxtools.parameters.nrcconstparameter import NrcConstParameter
48-
from odxtools.parameters.physicalconstantparameter import PhysicalConstantParameter
4946
from odxtools.parameters.tablekeyparameter import TableKeyParameter
5047
from odxtools.parameters.tablestructparameter import TableStructParameter
5148
from odxtools.parameters.valueparameter import ValueParameter
@@ -1270,65 +1267,6 @@ class SomersaultSID(IntEnum):
12701267
)
12711268
}
12721269

1273-
# env-data
1274-
somersault_env_datas = {
1275-
"flip_env_data":
1276-
EnvironmentData(
1277-
odx_id=OdxLinkId("somersault.env_data.flip_env_data", doc_frags),
1278-
short_name="flip_env_data",
1279-
long_name="Flip Env Data",
1280-
description=None,
1281-
admin_data=None,
1282-
sdgs=[],
1283-
byte_size=None,
1284-
dtc_values=[],
1285-
parameters=NamedItemList([
1286-
ValueParameter(
1287-
short_name="flip_speed",
1288-
long_name="Flip Speed",
1289-
description=None,
1290-
physical_default_value_raw=None,
1291-
byte_position=0,
1292-
semantic="DATA",
1293-
dop_ref=OdxLinkRef.from_id(somersault_dops["num_flips"].odx_id),
1294-
dop_snref=None,
1295-
bit_position=None,
1296-
sdgs=[],
1297-
),
1298-
PhysicalConstantParameter(
1299-
short_name="flip_direction",
1300-
long_name="Flip Direction",
1301-
description=None,
1302-
byte_position=1,
1303-
semantic="DATA",
1304-
physical_constant_value_raw="1",
1305-
dop_ref=OdxLinkRef.from_id(somersault_dops["num_flips"].odx_id),
1306-
dop_snref=None,
1307-
bit_position=None,
1308-
sdgs=[],
1309-
),
1310-
]),
1311-
all_value=True,
1312-
)
1313-
}
1314-
1315-
# env-data-desc
1316-
somersault_env_data_descs = {
1317-
"flip_env_data_desc":
1318-
EnvironmentDataDescription(
1319-
odx_id=OdxLinkId("somersault.env_data_desc.flip_env_data_desc", doc_frags),
1320-
short_name="flip_env_data_desc",
1321-
long_name="Flip Env Data Desc",
1322-
description=None,
1323-
admin_data=None,
1324-
param_snref="flip_speed",
1325-
param_snpathref=None,
1326-
env_datas=[],
1327-
env_data_refs=[OdxLinkRef("somersault.env_data.flip_env_data", doc_frags)],
1328-
sdgs=[],
1329-
)
1330-
}
1331-
13321270
# requests
13331271
somersault_requests = {
13341272
"start_session":
@@ -2063,8 +2001,8 @@ class SomersaultSID(IntEnum):
20632001
),
20642002
tables=NamedItemList(somersault_tables.values()),
20652003
muxs=NamedItemList(),
2066-
env_datas=NamedItemList(somersault_env_datas.values()),
2067-
env_data_descs=NamedItemList(somersault_env_data_descs.values()),
2004+
env_datas=NamedItemList(),
2005+
env_data_descs=NamedItemList(),
20682006
dtc_dops=NamedItemList(),
20692007
structures=NamedItemList(),
20702008
static_fields=NamedItemList(),
@@ -2338,8 +2276,8 @@ class SomersaultSID(IntEnum):
23382276
dynamic_length_fields=NamedItemList(),
23392277
dynamic_endmarker_fields=NamedItemList(),
23402278
tables=NamedItemList(),
2341-
env_data_descs=NamedItemList(),
23422279
env_datas=NamedItemList(),
2280+
env_data_descs=NamedItemList(),
23432281
muxs=NamedItemList(),
23442282
unit_spec=None,
23452283
sdgs=[],

odxtools/basicstructure.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from .dataobjectproperty import DataObjectProperty
1111
from .decodestate import DecodeState
1212
from .encodestate import EncodeState
13-
from .exceptions import EncodeError, OdxWarning, odxassert, odxraise, strict_mode
13+
from .exceptions import EncodeError, OdxWarning, odxassert, odxraise
1414
from .nameditemlist import NamedItemList
1515
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
1616
from .odxtypes import ParameterDict, ParameterValue, ParameterValueDict
@@ -78,6 +78,7 @@ def coded_const_prefix(self, request_prefix: bytes = b'') -> bytes:
7878
param.encode_into_pdu(physical_value=None, encode_state=encode_state)
7979
else:
8080
break
81+
8182
return encode_state.coded_message
8283

8384
@property
@@ -159,8 +160,8 @@ def encode_into_pdu(self, physical_value: Optional[ParameterValue],
159160
orig_is_end_of_pdu = encode_state.is_end_of_pdu
160161
encode_state.is_end_of_pdu = False
161162

162-
# in strict mode, ensure that no values for unknown parameters are specified.
163-
if strict_mode:
163+
# ensure that no values for unknown parameters are specified.
164+
if not encode_state.allow_unknown_parameters:
164165
param_names = {param.short_name for param in self.parameters}
165166
for param_value_name in physical_value:
166167
if param_value_name not in param_names:
@@ -192,8 +193,10 @@ def encode_into_pdu(self, physical_value: Optional[ParameterValue],
192193
odxraise(f"No value for required parameter {param.short_name} specified",
193194
EncodeError)
194195

195-
param.encode_into_pdu(
196-
physical_value=physical_value.get(param.short_name), encode_state=encode_state)
196+
param_phys_value = physical_value.get(param.short_name)
197+
param.encode_into_pdu(physical_value=param_phys_value, encode_state=encode_state)
198+
199+
encode_state.journal.append((param, param_phys_value))
197200

198201
encode_state.is_end_of_pdu = False
199202
if self.byte_size is not None:
@@ -235,6 +238,7 @@ def decode_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
235238
for param in self.parameters:
236239
value = param.decode_from_pdu(decode_state)
237240

241+
decode_state.journal.append((param, value))
238242
result[param.short_name] = value
239243

240244
# decoding of the structure finished. go back the original origin.

odxtools/decodestate.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
# SPDX-License-Identifier: MIT
22
from dataclasses import dataclass, field
3-
from typing import TYPE_CHECKING, Dict, cast
3+
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, cast
44

55
import odxtools.exceptions as exceptions
66

77
from .exceptions import DecodeError
8-
from .odxtypes import AtomicOdxType, DataType
8+
from .odxtypes import AtomicOdxType, DataType, ParameterValue
99

1010
try:
1111
import bitstruct.c as bitstruct
1212
except ImportError:
1313
import bitstruct
1414

1515
if TYPE_CHECKING:
16+
from .parameters.parameter import Parameter
1617
from .tablerow import TableRow
1718

1819

@@ -46,6 +47,11 @@ class DecodeState:
4647
#: values of the table key parameters decoded so far
4748
table_keys: Dict[str, "TableRow"] = field(default_factory=dict)
4849

50+
#: List of parameters that have been decoded so far. The journal
51+
#: is used by some types of parameters which depend on the values of
52+
#: other parameters; i.e., environment data description parameters
53+
journal: List[Tuple["Parameter", Optional[ParameterValue]]] = field(default_factory=list)
54+
4955
def extract_atomic_value(
5056
self,
5157
bit_length: int,

odxtools/diagnostictroublecode.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SPDX-License-Identifier: MIT
22
from dataclasses import dataclass
3-
from typing import Any, Dict, List, Optional, Union
3+
from typing import Any, Dict, List, Optional
44
from xml.etree import ElementTree
55

66
from .element import IdentifiableElement
@@ -17,7 +17,7 @@ class DiagnosticTroubleCode(IdentifiableElement):
1717
trouble_code: int
1818
text: Optional[str]
1919
display_trouble_code: Optional[str]
20-
level: Union[int, None]
20+
level: Optional[int]
2121
is_temporary_raw: Optional[bool]
2222
sdgs: List[SpecialDataGroup]
2323

odxtools/dtcdop.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,22 +130,35 @@ def decode_from_pdu(self, decode_state: DecodeState) -> ParameterValue:
130130
sdgs=[],
131131
)
132132

133-
@override
134-
def encode_into_pdu(self, physical_value: Optional[ParameterValue],
135-
encode_state: EncodeState) -> None:
136-
if isinstance(physical_value, DiagnosticTroubleCode):
137-
trouble_code = physical_value.trouble_code
138-
elif isinstance(physical_value, int):
133+
def convert_to_numerical_trouble_code(self, dtc_value: ParameterValue) -> int:
134+
if isinstance(dtc_value, DiagnosticTroubleCode):
135+
return dtc_value.trouble_code
136+
elif isinstance(dtc_value, int):
139137
# assume that physical value is the trouble_code
140-
trouble_code = physical_value
141-
elif isinstance(physical_value, str):
138+
return dtc_value
139+
elif isinstance(dtc_value, str):
142140
# assume that physical value is the short_name
143-
dtcs = [dtc for dtc in self.dtcs if dtc.short_name == physical_value]
144-
odxassert(len(dtcs) == 1)
145-
trouble_code = dtcs[0].trouble_code
141+
dtcs = [dtc for dtc in self.dtcs if dtc.short_name == dtc_value]
142+
if len(dtcs) != 1:
143+
odxraise(f"No DTC named {dtc_value} found for DTC-DOP "
144+
f"{self.short_name}.", EncodeError)
145+
return cast(int, None)
146+
147+
return dtcs[0].trouble_code
146148
else:
147-
raise EncodeError(f"The DTC-DOP {self.short_name} expected a"
148-
f" DiagnosticTroubleCode but got {physical_value!r}.")
149+
odxraise(
150+
f"The DTC-DOP {self.short_name} expected a"
151+
f" diagnostic trouble code but got {type(dtc_value).__name__}", EncodeError)
152+
return cast(int, None)
153+
154+
@override
155+
def encode_into_pdu(self, physical_value: Optional[ParameterValue],
156+
encode_state: EncodeState) -> None:
157+
if physical_value is None:
158+
odxraise(f"No DTC specified", EncodeError)
159+
return
160+
161+
trouble_code = self.convert_to_numerical_trouble_code(physical_value)
149162

150163
internal_trouble_code = int(self.compu_method.convert_physical_to_internal(trouble_code))
151164

odxtools/encodestate.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
# SPDX-License-Identifier: MIT
22
import warnings
33
from dataclasses import dataclass, field
4-
from typing import Dict, Optional, SupportsBytes
4+
from typing import TYPE_CHECKING, Dict, List, Optional, SupportsBytes, Tuple
55

66
from .exceptions import EncodeError, OdxWarning, odxassert, odxraise
7-
from .odxtypes import AtomicOdxType, DataType
7+
from .odxtypes import AtomicOdxType, DataType, ParameterValue
88

99
try:
1010
import bitstruct.c as bitstruct
1111
except ImportError:
1212
import bitstruct
1313

14+
if TYPE_CHECKING:
15+
from .parameters.parameter import Parameter
16+
1417

1518
@dataclass
1619
class EncodeState:
@@ -56,6 +59,15 @@ class EncodeState:
5659
#: (needed for MinMaxLengthType, EndOfPduField, etc.)
5760
is_end_of_pdu: bool = True
5861

62+
#: list of parameters that have been encoded so far. The journal
63+
#: is used by some types of parameters which depend on the values of
64+
#: other parameters; e.g., environment data description parameters
65+
journal: List[Tuple["Parameter", Optional[ParameterValue]]] = field(default_factory=list)
66+
67+
#: If this is True, specifying unknown parameters for encoding
68+
#: will raise an OdxError exception in strict mode.
69+
allow_unknown_parameters = False
70+
5971
def __post_init__(self) -> None:
6072
# if a coded message has been specified, but no used_mask, we
6173
# assume that all of the bits of the coded message are

0 commit comments

Comments
 (0)