In the past it was hard to interface with industrial PLCs because the only possibility to connect was to make use of their proprietary field bus protocols. Nowadays, these field bus protocols make use of Ethernet technology and the TCP/IP stack but still remain proprietary - no reliable open source implementations exist. With the rise of Industry 4.0 and IIoT concepts new protocols were developed, which allow open communication between different devices, such as PLCs, PCs, embedded controllers, edge devices, etc. Two major and common used protocols are OPC UA and MQTT, reference implementations in various programming languages (licensed under OSS) exist and can be used. In this blog post I want to show how to set up a Siemens Simatic S7-1500 to communicate with an application written in Python using OPC UA and the library FreeOpcUa/python-opcua.
- OPC UA is short for Open Platform Communications Unified Architecture, which refers to the current revision of OPC UA (since 2011). Before 2011, OPC was short for OLE for Process Control, where OLE referred to the term Object Linking and Embedding. The current revision of OPC UA is based on XML and can be used on a variety of devices which allow vendor independent communication between industrial control devices and other computer systems.
OPC UA is based on TCP/IP and is available as a module on the Siemens Simatic S7-1500 which can easily be activated through the TIA portal. Setting up secure communication using message signing and encryption is also possible but will not be covered by this article.
This article Communication between Simatic S7-1500 and Python using OPC UA (unencrypted) covers the basics from setting up the TIA project and getting started with a simple python script.
The upcoming post Communication between Simatic S7-1500 and Python using OPC UA (Sign & Encrypt) makes use of the same project but extends the configuration on both sides to force authenticated and encrypted communication and forbids plain text data exchange.
We will cover:
- Creating a simple project in TIA portal to read two PT-1000 temperature sensors
- Enable OPC-UA Server on the S7-1500
- Setting up a OPC-UA user and password
- Python Script:
- Setting up our environment and installing the required python modules (FreeOpcUa/python-opcua)
- Reading xml tree from the S7-1500 and identifying the fields of interest using opcua-client
- Python script to request the desired data
Setting up a TIA project, configuring the modules and activating the OPC UA Server in the Simatic S7-1500
First of all, we start by setting up a new project and adding the S7-1500 and an analog input extension module. I used the following two components (6ES7 511-1AK02-0AB0, 6ES7531-7KF00-0AB0) and two standard PT-1000 temperature sensors. Wiring up the sensors is explained in the analog module reference on page 19.
The two chosen inputs were added afterwards to the tag table and named accordingly (I usually add a new tag table for every new input group, e.g. a separate table for resistive temperature sensors, another one for TC temperature sensors, etc, this makes the project more readable). Additionally, I created a new data block and added a function to the main loop, which converts the temperatures from °C in °F and K, as well. The corresponding values are stored in the data block. When reading the data from our client using OPC UA then we will access this data block. The tag tables were excluded from OPC-UA access on purpose because we decide on the server side which resources can be accessed.
After setting this up and testing the functionality so far, the next step is to enable the OPC-UA server functionality. As already stated above, for this example we will go for plain text data transmission between the two peers, no certificates and keys will be generated or configured for this example. Nevertheless, simple user authentication using a username and a password will be implemented.
To allow OPC UA communication it is mandatory that the S7-1500 is networked, it does not matter hereby whether the IP address is set in the project or directly at the device. Be sure to set up the IP-address properly and continue with the OPC UA server configuration.
The OPC server is configured in the S7-1500 device properties under General >> OPC UA. Activate the checkbox (as seen in the picture above) and save the project. This is sufficient to activate basic OPC server functionality and to connect with clients to the S7-1500. Nevertheless, we will setup basic user authentication and disable anonymous authentication to have our system secured at least at a minimal basis. Adding users and setting up their passwords is straight forward, as well. Open the remaining drop down items under OPC UA >> Server >> Security and select User authentication. Disable anonymous authentication and enable username and password authentication. Add a user (in this example I added a user with username: user and with password: 12345678). Save the project and download it to the device. Now we start setting up our python environment and start developing the python application.
Installing required python modules and implementing a simple script to read data from S7-1500
First, we setup our environment. I am working on a Unix system, the library is compatible to windows as well, but the installation procedure may differ from Unix/Linux. On windows use either the Developer Command Line for Visual Studio or use Visual Studio to install these requirements (when installing Python together with Visual Studio, VS allows to manage python packages instead of the command line)
pip install opcua opcua-client This installs the main library and a graphical client. Visit the repo on github for further information. Dependencies may be required, install them as well. I have successfully tested the library on Windows, macOS and Linux devices (also on embedded Linux systems, Raspbian and a custom Yocto build).
We first start by using the included graphical client, type opcua-client in your CLI and you will be presented with a graphical application (based on PyQt5) which we will use to find the data fields we are interested in. Connect by typing the correct URL into the address bar: opc.tcp://user:12345678@<S7-1500-ip-address>:4840. Once connected you will be presented with the XML tree. Have a look at the nodes by opening the child elements and check which information you can retrieve.
As stated above, we are clearly interested in the temperatures we have stored inside the data blocks in the TIA project. To get these values follow the tree Root >> Object >> DeviceSet >> S7-1500-OPCUA-Server >> DataBlocksGlobal >> storageTemperatures. With a right click on the temperature (child) you can select Add to Graph to log the data. We now have successfully identified the data (within the OPC UA XML tree) we are interested in. To access these data fields (child elements) within our python application, we need to copy the NodeId for identification. It is a simple string which we pass as an argument to client.get_node():
In my code sample below I just read the two temperature values in °C and print them to std.out.
from timeit import default_timer as timer
from opcua import Client
if __name__ == "__main__":
#client = Client("opc.tcp://220.127.116.11:4840") # if anonymous authentication is enabled
client = Client("opc.tcp://user:
start = timer()
# get a specific node knowing its node id
temp1c_node = client.get_node('ns=3;s="storageTemperatures"."Temperature1C"')
temp2c_node = client.get_node('ns=3;s="storageTemperatures"."Temperature2C"')
end = timer()
#print(var.get_data_value()) # get value of node as a DataValue object
temp1c = float(temp1c_node.get_value())
temp2c = float(temp2c_node.get_value())
print("Temp1: " + str(temp1c))
print("Temp2: " + str(temp2c))
print("RTT: " + str(end - start))
As you can see in the code above, the main method to connect, request data and close the connection to the server are not complicated to implement in your own application. You first generate a client instance where you pass the user credentials and the server address. Afterwards you connect and access the desired node by NodeId which generates a local object. To get the value for this node you just use the method
.get_value() which returns the raw value. Last step is to disconnect from server. That‘s it!
This article can be found in german language on my company's blog: siincos.com - Industrie 4.0 & IoT
In the 7zip archive below, you will find the project files, the python scripts and the TIA project for the Simatic S7-1500. This archive also includes the files for the upcoming post which describes the same communication, but over a secure and encrypted channel.