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.0.tar.gz (68.6 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.0-py3-none-any.whl (42.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pys7-2.6.0.tar.gz
  • Upload date:
  • Size: 68.6 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.0.tar.gz
Algorithm Hash digest
SHA256 55730141f48f15d332a6fb3a5692d526ed56415f6270e6d631cc4f66f8d38276
MD5 59a49f2ef630444d24874d538cefb32b
BLAKE2b-256 06708e49016deb2b1b8d4a37530391d0aa97529423cc72ed1b97d22e45fba358

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pys7-2.6.0-py3-none-any.whl
  • Upload date:
  • Size: 42.7 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f8a2b2d97a7abd5a103df2545158a8933d7edc9b17139cfada36757d74ffa298
MD5 9d5285a60678f6d264082e68bf665e83
BLAKE2b-256 08b6b405a5b12566d34f5dd9813724f8cdac201364e7d63553456136fc2f7abb

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