Archived OpenModelica forums. Posting is disabled.

Alternative forums include GitHub discussions or StackOverflow (make sure to read the Stack Overflow rules; you need to have well-formed questions)


Forgot password? | Forgot username? | Register

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?

Edited by: SudhakarK - Oct-15-20 09:17:57

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

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.

Edited by: SudhakarK - Apr-06-21 20:41:47

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. Could you please explain the things which you want to achieve with this client-server model? Maybe, you can help me with the idea behind your project.

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

Hi. Thanks. I need to know the set-up actually like the things (sensors/ actuators) connected to the Raspberry Pi. Maybe, we can connect over a Google Meet.

Re: Establishing communication between OpenModelica and an OPC-UA client

Yes please, a chat would be great. Please let me know when you are available. I am available anytime in the next 2 hours if that is convenient for you.

Re: Establishing communication between OpenModelica and an OPC-UA client

Can we use https://meet.google.com/dmb-rsaw-dck for connecting right now?

There are 0 guests and 0 other users also viewing this topic
You are here: