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

EncodeError: signal required for encoding when passing a partial dictionnary to Message.encode() #663

Open
Becheler opened this issue May 15, 2024 · 3 comments

Comments

@Becheler
Copy link

Becheler commented May 15, 2024

Hello!

Great work with this library!

I have a simple question. I would expect to be able to write the following:

example_message = db.get_message_by_name('ExampleMessage')
data = example_message.encode( {'Temperature': 250.1} ) # note the missing keys here
message = can.Message(arbitration_id=example_message.frame_id, data=data)
can_bus.send(message)

This would be handy to shorten notation by defaulting values and manipulate variables as in data = message.encode( {key:val} )

However, it seems one has to specify the entire dictionary:

data = example_message.encode({'Temperature': 250.1, 'AverageRadius': 3.2, 'Enable': 1})

or else we get a cantools.database.errors.EncodeError: The signal "AverageRadius" is required for encoding.

Is there a way to bypass such limitation without having to build an entire dictionnary with defaulted values ?

Best wishes,

@zariiii9003
Copy link
Collaborator

Set strict=False. See docs

@Becheler
Copy link
Author

Thanks for your answer,
However it seems it does not entirely solve my problem:

File "mymainl.py", line 73, in __myfunc
    data = message.encode( { key : val }, strict=False )
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\...\cantools\database\can\message.py", line 950, in encode
    encoded, padding_mask, all_signals = self._encode(self._codecs,
                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\...\cantools\database\can\message.py", line 786, in _encode
    encoded = encode_data(data,
              ^^^^^^^^^^^^^^^^^
  File "C:\Users\...\cantools\database\utils.py", line 112, in encode_data
    raw_signal_values = _encode_signal_values(signals, signal_values, scaling)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\...\cantools\database\utils.py", line 82, in _encode_signal_values
    value = signal_values[name]
  KeyError: 'OneOfMyKeys'

My guess is that the values have not been initialized by default (how to do so?) and so the signal_values does not contain the key name 🤔

@andlaus
Copy link
Member

andlaus commented May 16, 2024

cantools does not provide default values for signals. The closest thing it has are the initial values, but they are conceptually slightly different (If I understood this correctly). If you want to use these as default values, you can do so using

db_msg = db.get_message_by_name("MyMessage")

msg_data = {}
for signal in db_msg.signals:
  if signal.initial is not None:
    msg_data[signal.name] = signal.initial

# set the values which you actually want to send

raw_data = db.encode_message(db_msg.name, msg_data) 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants