How to read values from Python Dictionary in Simulink Matlab Function Block?

8 views (last 30 days)
I have problems reading values from a Python dictionary in to Simulink using a Matlab Function Block. The Python Dictionary is stored in the Matlab Base Workspace. It contains Data delivered by a MQTT-Broker. The keys of the dicitonary are the topics and the values are the payload of specific MQTT-Messages. Because all of the topics contain slashes it is not possible to convert the Python-Dictionary to a Matlab struct. Now I want to read the values of defined topics to my Simulink Model. Unfortunately the syntax that works in Matlab doesn't work in the Simulink Matlab Function Block.
In Matlab I am able to read data from the dictionary by using the key in curly brackets:
MQTTValue = PythonDict{'level1/level2/value'}
To read the payload of the same MQTT-Message to Simulink i used the following code in a Matlab Function Block:
function MQTTValue = fcn()
coder.extrinsic('evalin');
PythonDict = evalin('base','PythonDict');
MQTTValue = PythonDict{'level1/level2/value'};
However I get the following error when running the Model:
Brace indexing is not supported for variables of this type.
I expected to be able to read the value from the dictionary just like in Matlab.
Also when trying to read multiple entries of the dictionary using a cell-Array called TopicArray and the following code Matlab crashes completely during the compilation of the model:
function MQTTValues = fcn(TopicArray)
coder.extrinsic('evalin');
MQTTValues = zeros(1,length(TopicArray));
PythonDict = evalin('base','PythonDict');
for i = 1:length(MQTTValues)
MQTTValues(i) = PythonDict{TopicArray{i}};
end
  2 Comments
Prateekshya
Prateekshya on 23 Aug 2023
As per my understanding you are trying to use Python dictionary in Simulink. The error you are encountering in the Simulink MATLAB function block occurs because brace indexing, "{}", is not supported for variables of type "dict" in Simulink. However, there are alternative approaches you can use to read values from a Python dictionary in Simulink. Here are a couple of suggestions:
  • Use the "get" method: Instead of using brace indexing, you can use the "get" method of the Python dictionary to retrieve values based on the keys. Modify your code in the Matlab Function Block as follows:
function MQTTValue = fcn()
coder.extrinsic('evalin');
PythonDict = evalin('base', 'PythonDict');
MQTTValue = PythonDict.get('level1/level2/value');
end
The "get" method retrieves the value associated with the specified key. If the key is not found in the dictionary, it returns an optional default value (which is "None" if not provided).
  • Convert the Python dictionary to a MATLAB struct: If the keys in your Python dictionary contain slashes, preventing direct conversion to a MATLAB struct, you can preprocess the dictionary to replace the slashes with a different character (e.g., underscore "_") before converting it to a struct. Then, you can access the values using struct field names in Simulink.
function MQTTValue = fcn()
coder.extrinsic('evalin');
PythonDict = evalin('base', 'PythonDict');
% Preprocess the dictionary keys
processedDict = struct();
keys = PythonDict.keys();
for i = 1:length(keys)
key = char(keys{i});
processedKey = strrep(key, '/', '_');
processedDict.(processedKey) = PythonDict.get(key);
end
% Access the value using struct field name
MQTTValue = processedDict.level1_level2_value;
end
In this approach, the dictionary keys are modified by replacing slashes with underscores. Then, the modified dictionary is converted to a MATLAB struct, allowing you to access the values using struct field names.
Choose the approach that suits your requirements and integrate it into your Simulink model to read values from the Python dictionary successfully.
Simon Scholler
Simon Scholler on 24 Aug 2023
Thanks for your answer, Prateekshya.
Your second approach would work but I found out it is not suitable for my case, because some of our topics exceed the limit of 63 characters for struct field names. Because of that, converting the Python-Dict to a Matlab struct could lead to duplicate field names.
Unfortunately your first approach doesn't work. Trying it, I get the error
Attempt to extract field 'get' from 'mxArray'.
I tried to preinitialize PythonDict with the following lines but this doesn't solve the problem:
coder.extrinsic('py.dict')
PythonDict = py.dict;
Also trying to read multiple entries of the dict using the "get"-method in a for-loop still leads to a complete crash of Matlab just like using brace indexing.

Sign in to comment.

Answers (1)

Yatharth
Yatharth on 29 Aug 2023
Hi, I understand that you are trying to import Python dictionary in Simulink from MATLAB workspace. However from workspace Block in simulink doesn't support the python dictionary format. You cannot convert the dictionary to a MATLAB Structure due to your constarints of using '/'.
You can try implementing using Python Importer Wizard and make a custom simulink block according to your use case.
Here is the documentation on how to use Python Importer Wizard for Simulink.
Here is the suggested workflow:
  1. You can create custom blocks to import your .py files with dictionaries
  2. Use the same function in the block itself that you wanted to use within the MATLAB function block and set the output accordingly.
Note: Take care of the Input and Output Datatypes for your custom function blocks to be more compatible with your workflow

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!