Connect a computer to a Siemens PLC using the Snap7 library in Python

Settings Siemens PLC - TIA Portal

Ensure that your PLC is set up correctly. In the general properties of your device, navigate to Protection & Security. Change the Access Level to Full Access and enable the PUT Get Communications.

Next, go to the data block (DB) you wish to control, right-click, and select Properties. Under Attributes, ensure that Optimized Block Access is turned off.

If everything has been configured correctly, compile your project. You should see an offset next to the variables of the DB. Finally, download your project to the PLC, and your PLC will be ready to use.

image

Snap7 - Python

Install the Snap7 library.

pip install python-snap7

The Snap7 library is a popular open-source library used for communication with Siemens S7 PLCs (Programmable Logic Controllers). Here are three important functions of the Snap7 library:

  1. Connect: This function establishes a connection to the PLC. It requires parameters such as the IP address of the PLC and the connection type. Establishing a connection is crucial for any subsequent read or write operations.
  2. Read: This function is used to read data from the PLC. You can specify the type of data you want to read (e.g., DB, input, output, or marker) and the specific address or block from which to read the data. This function is essential for monitoring the state of variables in the PLC.
  3. Write: This function allows you to write data to the PLC. Similar to the Read function, it requires specifying the data type and address. Writing data is important for controlling the PLC’s operation and sending commands or updates to the PLC’s memory.

Example code for reading and writing booleans:

import snap7
from snap7.util import get_bool, set_bool

class SiemensPlc:
    def connect(self):
        try:
            self.plc = snap7.client.Client()
            self.plc.connect("192.168.0.99", 0, 1)  # Adjust the IP and rack/slot if needed
            self.connected = True
        except RuntimeError as e:
            self.logger.error(f"Error updating camera feed: {e}")

    def read_bool(self, db_number, start, byte_offset, bit_offset):
        """Read a boolean value from a specific DB"""
        data = self.plc.db_read(db_number, start, 1)  # Read one byte
        value = get_bool(data, byte_offset, bit_offset)
        return value

    def write_bool(self, db_number, start, byte_offset, bit_offset, value):
        """Write a boolean value to a specific DB"""
        data = self.plc.db_read(db_number, start, 1)  # Read the byte first
        set_bool(data, byte_offset, bit_offset, value)  # Modify the bool at byte.bit position
        self.plc.db_write(db_number, start, data)  # Write the modified byte back

Thanks @QuintusKessler!