Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue with decode/encode signals of list type #5

Merged
merged 2 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 25 additions & 8 deletions ldfparser/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,25 @@ def encode(self,
as is (float and string values)
"""
converted = {}

def default_encoder(_value, _signal):
if isinstance(_value, int):
return _value
raise ValueError(f'No encoding type found for {signal_name} ({value})')

for (signal_name, value) in data.items():
signal = self._get_signal(signal_name)
encoder = default_encoder
if encoding_types is not None and signal_name in encoding_types:
converted[signal_name] = encoding_types[signal_name].encode(value, signal)
encoder = encoding_types[signal_name].encode
elif signal.encoding_type is not None:
converted[signal_name] = signal.encoding_type.encode(value, signal)
elif isinstance(value, int):
converted[signal_name] = value
encoder = signal.encoding_type.encode

if signal.is_array():
converted[signal_name] = [encoder(_v, signal) for _v in value]
else:
raise ValueError(f'No encoding type found for {signal_name} ({value})')
converted[signal_name] = encoder(value, signal)

return self.encode_raw(converted)

def _signal_map_to_message(self, signals: Dict[str, int]) -> List[int]:
Expand Down Expand Up @@ -206,16 +215,24 @@ def decode(self,
frame_layout = u6p2u8u1u1p6

"""
def default_decoder(_value, *args):
return _value

parsed = self.decode_raw(data)
converted = {}
for (signal_name, value) in parsed.items():
signal = self._get_signal(signal_name)
decoder = default_decoder
if encoding_types is not None and signal_name in encoding_types:
converted[signal_name] = encoding_types[signal_name].decode(value, signal, keep_unit)
decoder = encoding_types[signal_name].decode
elif signal.encoding_type is not None:
converted[signal_name] = signal.encoding_type.decode(value, signal, keep_unit)
decoder = signal.encoding_type.decode

if signal.is_array():
converted[signal_name] = [decoder(_v, signal, keep_unit) for _v in value]
else:
converted[signal_name] = value
converted[signal_name] = decoder(value, signal, keep_unit)

return converted

def decode_raw(self,
Expand Down
41 changes: 41 additions & 0 deletions tests/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,47 @@ def test_encode_error_type(self, frame, value):
with pytest.raises(ValueError):
frame.encode({'MotorSpeed': value})

@pytest.mark.unit
@pytest.mark.parametrize("use_converter", [True, False])
def test_encode_decode_array(use_converter):
signal = LinSignal('BattCurr', 24, [0, 0, 2])
encoding_type = LinSignalEncodingType(
"BattCurrCoding",
[PhysicalValue(0, 182272, 0.00390625, -512, "A")]
)
converters = {}
if use_converter:
converters["BattCurr"] = encoding_type
else:
signal.encoding_type = encoding_type

frame = LinUnconditionalFrame(0x20, "LinStatus", 3, {0: signal})
raw = {"BattCurr": [1, 1, 1]}
encoded_expected = bytearray([1, 1, 1])
decoded_expected = {"BattCurr": [-511.99609375, -511.99609375, -511.99609375]}
encoded_raw = frame.encode_raw(raw)
assert encoded_raw == encoded_expected

decoded = frame.decode(encoded_raw, converters)
assert decoded == decoded_expected

encoded = frame.encode(decoded, converters)
decoded_raw = frame.decode_raw(encoded)
assert decoded_raw == raw

@pytest.mark.unit
def test_encode_decode_array_no_converter():
signal = LinSignal('BattCurr', 24, [0, 0, 2])
frame = LinUnconditionalFrame(0x20, "LinStatus", 3, {0: signal})
raw = {"BattCurr": [1, 1, 1]}
encoded_expected = bytearray([1, 1, 1])

encoded = frame.encode(raw)
assert encoded == encoded_expected

decoded = frame.decode(encoded)
assert decoded == raw

@pytest.mark.unit
class TestLinUnconditionalFrameDecodingRaw:

Expand Down