- Index
- » Usage and Applications
- » OpenModelica Usage and Applications
- » Establishing communication between...
Establishing communication between OpenModelica and an OPC-UA client
Establishing communication between OpenModelica and an OPC-UA client
I am developing a server-client communication between OpenModelica (OM) and an external OPC-UA client. So, I have written an OM file as given below:
Code:
model test
input Real x;
Real y;
equation
y = x;
end test;
Along with this, I have written a Python script for running an OPC-UA client, as shown below:
Code:
from opcua import Client
from opcua import ua
import time
import logging
import matplotlib.pyplot as plt
# Define the URL on which the server is broadcasting
url = "opc.tcp://1xx.1xx.0.2:4841"
# 0 Server
# 1 step
# 2 run
# 3 realTimeScalingFactor
# 4 enableStopTime
# 5 time
# 6 x 0.0
# 7 y 0.0
if __name__ == "__main__":
client = Client(url)
logging.basicConfig(level=logging.WARN)
try:
client.connect()
print("Client connected!")
enableStopTime = client.get_node(ua.NodeId(10003, 0))
# enableStopTime.set_value(False)
print("Current state of enableStopTime : {}".format(enableStopTime.get_value()))
run = client.get_node(ua.NodeId(10001, 0))
run.set_value(True)
print("Current state of run : {}".format(run.get_value()))
root = client.get_root_node()
print("Root node is : ", root)
objects = client.get_objects_node()
print("Objects\' node is : ", objects)
writeID = 6 # x
readID = 7 # y
modelicaId = {}
modelicaId = objects.get_children()
set_point = 10
while True:
error = set_point - modelicaId[readID].get_value()
valWrite = 0.7*error
print("Error = {}, valWrite = {}".format(error, valWrite))
if (error > 0):
modelicaId[writeID].set_value(valWrite)
else:
print("Setpoint achieved!\n")
print("y value is: ", modelicaId[readID].get_value())
print("x value is: ", modelicaId[writeID].get_value())
time.sleep(2)
print("="*40)
except KeyboardInterrupt:
print("Stopping sequence!")
finally:
print("Done!")
client.disconnect()
Now, I simulate the OM file from OMEdit with the following arguments, as shown below:
General:
Start Time: 0
Stop Time: 15
Simulation Flags:
Additional Simulation Flags (Optional): -rt 1.0 -embeddedServer opc-ua
Next, I execute the client script, and server-client communication is established. As the Stop Time is set as 15, the simulation is halted after that duration. Thus, I am assuming that the client and server have communicated, and I should get a plot. However, when I click on the Plotting perspective of OM, I am not able to get any plot. I have also simulated the plant in OM from OMShell-terminal by executing the commands (simulate(test, startTime = 0.0, stopTime = 20.0, simflags = "-rt=1.0 -embeddedServer=opc-ua")) in a Linux Terminal . In that case, I can get the simulation result as a .mat file. Upon loading this result in OM, I can see the variables and can plot them as well.
Could anyone please provide some insights into this?
Re: Establishing communication between OpenModelica and an OPC-UA client
Dear SudhakarK
Thank you for your post! With this I finally managed to have a running example of a connection with OPC UA.
To your question: OpenModelica stores all files for a simulation in a specific folder, in your temp directory.
For me it is:
on Windows: C:\Users\%username%\AppData\Local\Temp\OpenModelica\OMEdit\
on Linux: /tmp/OpenModelica_%username%/OMEdit .
There you also find a .mat file that you can open with OMEdit.
Re: Establishing communication between OpenModelica and an OPC-UA client
Hello,
I am a new user of OpenModelica and I am hoping to replicate the above communication between OMEdit and my own opc-ua client. I have a python file that connects and communicates with the client and I have added the following simulation flag, as instructed from this discussion:
Code:
Additional Simulation Flags (Optional): -rt 1.0 -embeddedServer opc-ua
This simulation flag opens up an Interactive Plot, but how does the Modelica model connect to the client specified in the python code and read values for plotting?
Thanks in advance.
Re: Establishing communication between OpenModelica and an OPC-UA client
- adeas
- 454 Posts
Re: Establishing communication between OpenModelica and an OPC-UA client
Hi.Let us assume that you have saved your Modelica model as simTest.mo and your OPC-UA client as some clientScript.py. Now, to establish an OPC-UA client-server model, you need to begin the simulation of simTest.mo first. For this, I (on my Linux Ubuntu 20.04) follow the steps as given below:
1. Open a Terminal and navigate the directory (by using the cd command) where simTest.mo is located.
2. Launch OMShell-terminal. For this, type OMShell-terminal in the Linux terminal and press Enter.
3. Enter the command loadModel(Modelica) followed by loadFile("simTest.mo"). You should expect output as true in response to each of these two commands.
4. Now, we are ready to simulate simTest.mo. For this, enter the command simulate(simTest, startTime = 0, stopTime = 100, simflags = "-rt=1.0 -embeddedServer=opc-ua").
5. Now, run your OPC-UA script (clientScript.py) from another terminal. Once this script is executed, the client-server communication is established. You can print some values from the OpenModelica Model in your client script to check that the client can talk to the server.
6. At the end of the simulation (100 seconds in this case), you would get a .mat file (something like simTest_res.mat) in the folder where your Modelica model simTest.mo is located.
7. Launch OMEdit and go to File -> Open Result File(s). Now, select the .mat file (from the previous step) and click Open. It will open the Plotting Perspective, and all the parameters of the simulation will appear under Variables Browser. You can select the required parameter to draw the plot.
Re: Establishing communication between OpenModelica and an OPC-UA client
Hi SudhakarK, thank you for your response and instructions.
Can you please clarify what you mean in step 5:
You can print some values from the OpenModelica Model in your client script to check that the client can talk to the server.
When executing the python script, I am successfully reading/printing values from my pi server (as part of the python script), but I feel like I'm missing some connection between simulating the OM model and running the script.
Cheers
Re: Establishing communication between OpenModelica and an OPC-UA client
By step 5, I mean that you can make your client read certain values from the server and print it. That would help you know that the client is actually connected with the desired server.
In case you are facing any issues in connecting the Modelica model and your Python client, please share the code for these two and the error you are getting.
Re: Establishing communication between OpenModelica and an OPC-UA client
Ah yes, thank you for clarifying; I have been printing out node values from my python script. See below (code based on this forum discussion).
OM model:
Code:
model PlotTest
input Real RPM;
input Real coolantTEMP;
Real plotting;
equation
plotting = RPM*(1+(1/coolantTEMP)); // equation just for test purposes
end PlotTest;
Python:
Code:
from opcua import Client
from opcua import ua
import time
import logging
from opcua.ua.uatypes import VariantType
# Define the URL on which the server is broadcasting
url = "opc.tcp://my.raspberrypi.ip.address:4840/"
if __name__ == "__main__":
client = Client(url)
logging.basicConfig(level=logging.WARN)
try:
client.set_user("username")
client.set_password("password")
client.connect()
print("Client connected!")
# Set default value for RPM node. This node is set manually by a user
engineRPM_command = client.get_node("ns=4;s=engineRPM_command")
engineRPM_command.set_value(800, VariantType.Int32)
RPM = engineRPM_command.get_value()
print("Current state of engineRPM_command : {}".format(RPM))
# Read-only node. The value is set by my server every n seconds
enginecoolantTEMP = client.get_node("ns=4;s=current_100021")
print("Current state of enginecoolantTEMP : {}".format(enginecoolantTEMP.get_value()))
while (True):
engineRPM_command.set_value(int(1.1*RPM), VariantType.Int32)
RPM = engineRPM_command.get_value()
coolantTEMP = enginecoolantTEMP.get_value()
print("RPM value is: ", RPM)
print("coolantTEMP value is: ", coolantTEMP)
time.sleep(2)
print("="*40)
except KeyboardInterrupt:
print("Stopping sequence!")
finally:
print("Done!")
client.disconnect()
This is the OMShell output. This particular model is failing to build, but I have had success with other models (like the bouncing ball model and a simple ODE model).
Code:
>>loadModel(Modelica)
true
>>loadFile("PlotTest.mo")
true
>>simulate(PlotTest, startTime = 0, stopTime = 100, simflags = "-rt=1.0 -embeddedServer=opc-ua")
record SimulationResult
resultFile = "",
simulationOptions = "startTime = 0.0, stopTime = 100.0, numberOfIntervals = 500, tolerance = 1e-006, method = 'dassl', fileNamePrefix = 'PlotTest', options = '', outputFormat = 'mat', variableFilter = '.*', cflags = '', simflags = '-rt=1.0 -embeddedServer=opc-ua'",
messages = "Failed to build model: PlotTest",
timeFrontend = 0.4598676,
timeBackend = 0.0018066,
timeSimCode = 0.0005407,
timeTemplates = 0.0216975,
timeCompile = 0.0011373,
timeSimulation = 0.0,
timeTotal = 0.4850643
end SimulationResult;
For the models that did work, though, I was able to open the
Code:
res.mat
file in OMEdit, like you instructed. I'm confused as to how I can grab the server values for the OM model (ie. use
Code:
engineRPM_command.get_value()
as an input to my model)
Thanks
Re: Establishing communication between OpenModelica and an OPC-UA client
Hi! Thanks for sharing the code files. I believe that your OM Model (PlotTest.mo) needs to be fixed.
Code:
model PlotTest
input Real RPM;
input Real coolantTEMP;
Real plotting;
equation
plotting = RPM*(1+(1/coolantTEMP)); // equation just for test purposes
end PlotTest;
In this code, when you define RPM and coolantTEMP as input Real, Modelica assigns these variables as zero. So, the moment you simulate this model, the value of plotting would be
Code:
plotting = 0*(1+1/0)
That's why this model has a runtime error. You might want to fix it and get going. Please let me know in case the issue is not solved.
Re: Establishing communication between OpenModelica and an OPC-UA client
Thank you - runtime error has been fixed. Could you please explain how I might import a server node value (for example, the value of enginecoolantTEMP) into the model simulation (like as the variable coolantTEMP)? I understand how the python script communicates with the server but I am having trouble understanding how the OM model actually works/communicates with the python script.
Many thanks
Re: Establishing communication between OpenModelica and an OPC-UA client
Hi, of course.
I have a server running on a raspberry pi whose job is to simulate the values of a physical system. EnginecoolantTEMP is a node whose value fluctuates as per the server's control to simulate the readings of a sensor. The goal is to have my OM model read this node value as an input and react according to the value the model reads. For instance, if enginecoolantTEMP is really big, have the model perform action A; or, if enginecoolantTEMP is really small, perform action B.
Is this kind of communication possible?
Thanks
Re: Establishing communication between OpenModelica and an OPC-UA client
Hi. Thank you for your response.
I would like you to know that OpenModelica (OM) has a built-in OPC-UA server. So, from my understanding, it is better to configure OM as a server and Raspberry Pi as a client. Could you please let me know whether you can achieve your motive with this set-up (OM as server and Raspberry PI as a client)?
Re: Establishing communication between OpenModelica and an OPC-UA client
Hi, good to know and good idea. Could you please direct me to configuration instructions if you have any? I will try and get that setup running. Thank you very much for all your help.
Re: Establishing communication between OpenModelica and an OPC-UA client
- Index
- » Usage and Applications
- » OpenModelica Usage and Applications
- » Establishing communication between...