Skip to main content

Lightweight Python library for Siemens S7 over ISO-on-TCP (RFC1006).

Project description

pyS7


pyS7 is a lightweight, pure Python library that implements the Siemens S7 communication protocol over ISO-on-TCP (RFC1006). It enables direct communication with Siemens S7-200, S7-300, S7-400, S7-1200, and S7-1500 PLCs from Python applications.

Production/Stable2x PerformanceFully Tested

⚠️ Neither this project nor its authors are affiliated with Siemens. S7-200, S7-300, S7-400, S7-1200, and S7-1500 are registered trademarks of Siemens AG.

ha-s7plc banner

Features

  • Pure Python – No external dependencies, easy installation across platforms
  • Intuitive API – Clean, readable code with full typing support for IDE assistance
  • High Performance – Optimized hot paths, 2x faster request preparation (v2.5.0)
  • Graceful error handling – read_detailed() and write_detailed() provide per-tag success/failure info
  • Transactional writes – Batch write with automatic rollback on read verification failure
  • Optimized multi-variable reads – Automatically groups contiguous tags to reduce network requests
  • Automatic chunking – Transparently splits large STRING/WSTRING reads exceeding PDU size
  • CPU diagnostics – Read PLC status (RUN/STOP) and information (model, firmware) via SZL protocol
  • Broad compatibility – Supports S7-200/300/400/1200/1500 series
  • Production Ready – 253 tests, 85% coverage, strict type checking

Safety Notice

Industrial safety must always remain your top priority. By using pyS7 you accept full responsibility for any damage, data loss, downtime, or unintended effects. Understand your system and the implications of each operation before interacting with live equipment.

Installation

Requires Python 3.8 or later.

pip install pys7

Or install from GitHub:

pip install git+https://github.com/xtimmy86x/pyS7

Quick Start

Reading data

from pyS7 import S7Client

with S7Client(address="192.168.5.100", rack=0, slot=1) as client:
    tags = [
        "DB1,X0.0",  # Bit 0 of DB1
        "DB1,I30",   # INT at byte 30 of DB1
        "M54.4",     # Bit 4 of marker memory
        "IW22",      # WORD at byte 22 of input area
        "QR24",      # REAL at byte 24 of output area
        "DB1,S10.5"  # String of 5 characters at byte 10 of DB1
    ]
    
    data = client.read(tags)
    print(data)  # [True, 123, True, 10, 3.14, 'Hello']

Writing data

from pyS7 import S7Client

with S7Client(address="192.168.5.100", rack=0, slot=1) as client:
    tags = ["DB1,X0.0", "DB1,I30", "DB1,R40", "DB1,S10.5"]
    values = [True, 25000, 1.2345, "Hello"]
    
    client.write(tags, values)

Graceful error handling

from pyS7 import S7Client

with S7Client(address="192.168.5.100", rack=0, slot=1) as client:
    # read_detailed() continues on errors, returns per-tag results
    results = client.read_detailed(["DB1,I0", "DB99,I0", "DB1,R4"])
    
    for result in results:
        if result.success:
            print(f"{result.tag}: {result.value}")
        else:
            print(f"{result.tag} failed: {result.error}")
    
    # write_detailed() provides per-tag success/failure info
    tags = ["DB1,I0", "DB1,I2", "DB99,I0"]
    values = [100, 200, 300]
    write_results = client.write_detailed(tags, values)
    
    for result in write_results:
        if result.success:
            print(f"✓ {result.tag}: Written")
        else:
            print(f"✗ {result.tag}: {result.error}")

Transactional batch writes

from pyS7 import S7Client

with S7Client(address="192.168.5.100", rack=0, slot=1) as client:
    # Batch write with automatic rollback on verification failure
    with client.batch_write() as batch:
        batch.add("DB1,I0", 100)
        batch.add("DB1,I2", 200)
        batch.add("DB1,R4", 3.14)
        # Auto-commits on exit, rolls back on error
    
    # Or with explicit control
    batch = client.batch_write(auto_commit=False)
    batch.add("DB1,I0", 100)
    batch.add("DB1,I2", 200)
    
    try:
        batch.commit()  # Write and verify
    except Exception as e:
        batch.rollback()  # Restore original values
        print(f"Write failed: {e}")

Reading CPU status

from pyS7 import S7Client

with S7Client(address="192.168.5.100", rack=0, slot=1) as client:
    # Get CPU status
    status = client.get_cpu_status()
    print(f"CPU Status: {status}")  # "RUN" or "STOP"

    # Get CPU information
    info = client.get_cpu_info()
    print(f"Model: {info['module_type_name']}")
    print(f"Firmware: {info['firmware_version']}")
    print(f"Hardware: {info['hardware_version']}")

See docs/CPU_STATUS_READING.md for details.

String data types

pyS7 supports both ASCII and Unicode strings:

# STRING (ASCII) - All S7 models
tags = ["DB1,S10.20"]  # STRING at byte 10, max 20 chars
data = client.read(tags)
print(data[0])  # "Hello World"

# WSTRING (Unicode) - S7-1200/1500 only
tags = ["DB1,WS100.30"]  # WSTRING at byte 100, max 30 chars
data = client.read(tags)
print(data[0])  # "Hello 世界! 🌍"

# Large strings automatically chunked if exceeding PDU size
tags = ["DB1,S100.254"]  # STRING[254] - handled transparently
data = client.read(tags)  # Complete string returned

Documentation

Guides

Technical Documentation

Quick Links

Examples

Example scripts in the examples/ directory demonstrate:

  • read_data.py – Basic reading operations
  • write_data.py – Basic writing operations
  • read_detailed_demo.py – Graceful error handling for reads
  • write_detailed_demo.py – Graceful error handling for writes
  • batch_write_demo.py – Transactional batch writes with rollback
  • get_cpu_status.py – CPU status monitoring
  • get_cpu_info.py – CPU information retrieval
  • read_data_tsap.py – TSAP connection example
  • bit_read_workaround.py – Bit operations
  • manage_reconnection.py – Connection handling
  • connection_state_demo.py – Connection state management

License

This project is distributed under the MIT License. See the LICENSE file for details.

Acknowledgements

Special thanks to filocara for the original project that inspired this work.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pys7-2.6.2.tar.gz (69.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pys7-2.6.2-py3-none-any.whl (43.8 kB view details)

Uploaded Python 3

File details

Details for the file pys7-2.6.2.tar.gz.

File metadata

  • Download URL: pys7-2.6.2.tar.gz
  • Upload date:
  • Size: 69.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for pys7-2.6.2.tar.gz
Algorithm Hash digest
SHA256 35313d031869959556c4d15d9cdbe6833a09e16b9494399a0839134cff52ee8c
MD5 c2e9eb943943369bedeaaa9d22b4aaa1
BLAKE2b-256 610051c50b4b55cc79266c089dce717b5a01405954194e2299df9be18da2f1ad

See more details on using hashes here.

File details

Details for the file pys7-2.6.2-py3-none-any.whl.

File metadata

  • Download URL: pys7-2.6.2-py3-none-any.whl
  • Upload date:
  • Size: 43.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for pys7-2.6.2-py3-none-any.whl
Algorithm Hash digest
SHA256 2d0cf714c68a744e0f56ab8cb2e776d783a3b49493810b80a64b2a708551a8a1
MD5 8c3a095ccc43375bd8963b224bd8ba39
BLAKE2b-256 770898e6a3fcbfce2d36178534380be3219b8de194c6bf87b048c5421bffddea

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page