How to connect to a Siemens PLC from Python using Snap7

Based on contributions by How-to.

Snap7 is an open-source library that lets a Python script read and write data blocks on a Siemens S7 PLC directly, without you having to build your own communication protocol. Use it when you want a laptop or PC application to monitor or control PLC variables in real time.

What you need

  • A Siemens PLC (S7-1200/S7-1500 family) programmed in TIA Portal, with a data block (DB) you want to read or write.
  • Full access to the TIA Portal project so you can change protection settings and download to the PLC.
  • Python 3 with the python-snap7 package.
  • Your PC and the PLC on the same network.

Steps

1. Allow PUT/GET communication on the PLC

In TIA Portal, open the PLC’s device properties and go to Protection & Security. Set Access Level to Full Access and enable PUT/GET Communication from remote partner.

2. Turn off optimized block access on the data block

Right-click the data block (DB) you want to reach from Python and open Properties. Under Attributes, uncheck Optimized block access. Snap7 needs fixed byte offsets, which optimized blocks don’t expose.

3. Compile and download the project

Compile the project. If optimized block access is off, you’ll see a fixed Offset column next to each variable in the DB — note these down, you’ll need them from Python. Then download the project to the PLC.

4. Install the Snap7 library

pip install python-snap7

python-snap7 is a Python wrapper around the Snap7 C library. The three functions you’ll use most:

  • Connect — opens a connection to the PLC using its IP address and rack/slot number.
  • Read — reads raw bytes from a DB (or input/output/marker area) at a given address.
  • Write — writes raw bytes back to the PLC.

5. Connect and read/write a boolean

import logging
import snap7
from snap7.util import get_bool, set_bool


class SiemensPlc:
    def __init__(self):
        self.plc = None
        self.connected = False
        self.logger = logging.getLogger(__name__)

    def connect(self, ip="192.168.0.99", rack=0, slot=1):
        try:
            self.plc = snap7.client.Client()
            self.plc.connect(ip, rack, slot)  # adjust the IP and rack/slot to match your PLC
            self.connected = True
        except RuntimeError as e:
            self.logger.error(f"Error connecting to PLC: {e}")

    def disconnect(self):
        if self.plc is not None:
            self.plc.disconnect()
            self.connected = False

    def read_bool(self, db_number, start, byte_offset, bit_offset):
        """Read a single boolean from a DB, at DB address (start + byte_offset), bit bit_offset."""
        address = start + byte_offset
        data = self.plc.db_read(db_number, address, 1)  # read one byte
        return get_bool(data, 0, bit_offset)

    def write_bool(self, db_number, start, byte_offset, bit_offset, value):
        """Write a single boolean to a DB, at DB address (start + byte_offset), bit bit_offset."""
        address = start + byte_offset
        data = self.plc.db_read(db_number, address, 1)  # read the byte first
        set_bool(data, 0, bit_offset, value)             # modify the bit in place
        self.plc.db_write(db_number, address, data)      # write the modified byte back


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    plc = SiemensPlc()
    plc.connect()
    if plc.connected:
        value = plc.read_bool(db_number=1, start=0, byte_offset=0, bit_offset=0)
        print(f"Current value: {value}")
        plc.write_bool(db_number=1, start=0, byte_offset=0, bit_offset=0, value=True)
    plc.disconnect()

Adjust db_number, start, byte_offset and bit_offset to match the offsets you noted from the compiled DB in step 3.

:warning: Check: the address math in read_bool/write_bool (reading only the byte at start + byte_offset) was adjusted from the original source to avoid an out-of-range read when byte_offset > 0. Verify against your own DB layout before relying on it.

Related


Rewritten and consolidated (Sept 2026) from the original student how-to’s: Connect a computer to a Siemens PLC using the Snap7 library in Python.