Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ CHANGES
4.0.0 (unreleased)
-------------------

Major release: new `s7` package with S7CommPlus protocol support.
Major release: new `s7commplus` package with S7CommPlus protocol support.

* New `s7` package as recommended entry point with protocol auto-detection
* New `s7commplus` package for S7CommPlus protocol (S7-1200/1500)
* S7CommPlus V1, V2 (TLS), and V3 support for S7-1200/1500
* S7CommPlus area read/write (M, I, Q, counters, timers)
* S7CommPlus PLC start/stop via INVOKE
Expand Down
49 changes: 23 additions & 26 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,16 @@ Python-snap7 is a pure Python S7 communication library for interfacing with Siem
- **snap7/type.py**: Type definitions and enums (Area, Block, WordLen, etc.)
- **snap7/error.py**: Error handling and exceptions

### s7/ — Unified client with S7CommPlus + legacy fallback
- **s7/client.py**: Unified Client — tries S7CommPlus, falls back to snap7.Client
- **s7/async_client.py**: Unified AsyncClient — same pattern, async
- **s7/server.py**: Unified Server wrapping both legacy and S7CommPlus
- **s7/_protocol.py**: Protocol enum (AUTO/LEGACY/S7COMMPLUS)
- **s7/_s7commplus_client.py**: Pure S7CommPlus sync client (internal)
- **s7/_s7commplus_async_client.py**: Pure S7CommPlus async client (internal)
- **s7/_s7commplus_server.py**: S7CommPlus server emulator (internal)
- **s7/connection.py**: S7CommPlus low-level connection
- **s7/protocol.py**: S7CommPlus protocol constants/enums
- **s7/codec.py**: S7CommPlus encoding/decoding
- **s7/vlq.py**: Variable-Length Quantity encoding
- **s7/legitimation.py**: Authentication helpers
### s7commplus/ — S7CommPlus protocol (S7-1200/1500)
- **s7commplus/client.py**: S7CommPlus sync client
- **s7commplus/async_client.py**: S7CommPlus async client
- **s7commplus/server.py**: S7CommPlus server emulator
- **s7commplus/connection.py**: S7CommPlus low-level connection
- **s7commplus/protocol.py**: S7CommPlus protocol constants/enums
- **s7commplus/codec.py**: S7CommPlus encoding/decoding
- **s7commplus/vlq.py**: Variable-Length Quantity encoding
- **s7commplus/legitimation.py**: Authentication helpers
- **s7commplus/typeinfo.py**: S7CommPlus type information

## Implementation Details

Expand All @@ -56,23 +53,23 @@ The library implements the complete S7 protocol stack:
- Block operations (list, info, upload, download)
- Date/time operations

### Usage (unified s7 package — recommended for S7-1200/1500)
### Usage (s7commplus package — S7-1200/1500)

```python
from s7 import Client
from s7commplus import Client

client = Client()
client.connect("192.168.1.10", 0, 1) # auto-detects S7CommPlus vs legacy
client.connect("192.168.1.10", 0, 1)
data = client.db_read(1, 0, 4)
client.disconnect()
```

### Usage (legacy snap7 package — S7-300/400)
### Usage (s7 package — S7-300/400)

```python
import snap7
from s7 import Client

client = snap7.Client()
client = Client()
client.connect("192.168.1.10", 0, 1)

data = client.db_read(1, 0, 4)
Expand All @@ -87,8 +84,8 @@ client.disconnect()
### Server Usage

```python
from snap7.server import Server, mainloop
from snap7.type import SrvArea
from s7.server import Server, mainloop
from s7.type import SrvArea
from ctypes import c_char

# Start a simple server
Expand Down Expand Up @@ -120,15 +117,15 @@ pytest tests/test_client.py
### Code Quality
```bash
# Type checking
mypy snap7 s7 tests example
mypy snap7 s7commplus tests example

# Linting and formatting check
ruff check snap7 s7 tests example
ruff format --diff snap7 s7 tests example
ruff check snap7 s7commplus tests example
ruff format --diff snap7 s7commplus tests example

# Auto-format code
ruff format snap7 s7 tests example
ruff check --fix snap7 s7 tests example
ruff format snap7 s7commplus tests example
ruff check --fix snap7 s7commplus tests example
```

### Development with tox
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ doc: .venv/bin/sphinx-build

.PHONY: check
check: .venv/bin/pytest
uv run ruff check snap7 s7 tests example
uv run ruff format --diff snap7 s7 tests example
uv run ruff check snap7 s7 s7commplus tests example
uv run ruff format --diff snap7 s7 s7commplus tests example

.PHONY: ruff
ruff: .venv/bin/tox
Expand Down
24 changes: 15 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,23 @@ Install using pip::

Connect to any S7 PLC::

import snap7
from s7 import Client

client = snap7.Client()
client = Client()
client.connect("192.168.1.10", 0, 1)
data = client.db_read(1, 0, 4)
client.disconnect()

No native libraries or platform-specific dependencies are required.

.. note::

The ``s7`` package is the recommended import for the legacy S7 protocol.
The ``snap7`` package name continues to work for backwards compatibility.

Version 4.0 -- S7CommPlus & the ``s7`` Package (unreleased)
============================================================

Version 4.0 -- S7CommPlus & the ``s7commplus`` Package (unreleased)
====================================================================

.. note::

Expand All @@ -63,16 +68,17 @@ Version 4.0 -- S7CommPlus & the ``s7`` Package (unreleased)
required for communicating with S7-1200 and S7-1500 PLCs that have PUT/GET
disabled. python-snap7 now supports S7CommPlus V1, V2 (with TLS), and V3::

from s7 import Client
from s7commplus import Client

client = Client()
client.connect("192.168.1.10", 0, 1) # auto-detects S7CommPlus vs legacy S7
client.connect("192.168.1.10", 0, 1)
data = client.db_read(1, 0, 4)
client.disconnect()

The new ``s7`` package is the recommended entry point for all new projects. It
automatically tries S7CommPlus first (for S7-1200/1500) and falls back to legacy
S7 when needed. The existing ``snap7`` package continues to work unchanged.
The new ``s7commplus`` package provides S7CommPlus protocol support for
S7-1200/1500 PLCs. The ``s7`` package (recommended) and its ``snap7`` alias
continue to work unchanged for legacy S7-300/400 PLCs and S7-1200/1500 with
PUT/GET enabled.

**Other new features in 4.0:**

Expand Down
70 changes: 23 additions & 47 deletions doc/API/client.rst
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
Client
======

The ``s7`` package is the recommended entry point for communicating with any
supported Siemens S7 PLC. It provides a unified client that works with all
PLC models -- S7-300, S7-400, S7-1200 and S7-1500 -- and automatically
selects the best protocol (S7CommPlus or legacy S7).
python-snap7 provides two client packages:

Synchronous client
------------------
- ``s7commplus``: S7CommPlus protocol for S7-1200/1500 PLCs
- ``s7``: Classic S7 protocol for S7-300/400 and PUT/GET access on S7-1200/1500

s7commplus.Client
-----------------

.. code-block:: python

from s7 import Client
from s7commplus import Client

client = Client()
client.connect("192.168.1.10", 0, 1)
client.connect("192.168.1.10")
data = client.db_read(1, 0, 4)
print(client.protocol) # Protocol.S7COMMPLUS or Protocol.LEGACY
client.disconnect()

Asynchronous client
-------------------
s7commplus.AsyncClient
----------------------

.. code-block:: python

import asyncio
from s7 import AsyncClient
from s7commplus import AsyncClient

async def main():
client = AsyncClient()
await client.connect("192.168.1.10", 0, 1)
await client.connect("192.168.1.10")
data = await client.db_read(1, 0, 4)
await client.disconnect()

Expand All @@ -43,10 +42,10 @@ S7-1500 PLCs with firmware 2.x use S7CommPlus V2, which requires TLS. Pass

.. code-block:: python

from s7 import Client
from s7commplus import Client

client = Client()
client.connect("192.168.1.10", 0, 1, use_tls=True)
client.connect("192.168.1.10", use_tls=True)
data = client.db_read(1, 0, 4)
client.disconnect()

Expand All @@ -55,7 +54,7 @@ For PLCs with custom certificates, provide the certificate paths:
.. code-block:: python

client.connect(
"192.168.1.10", 0, 1,
"192.168.1.10",
use_tls=True,
tls_cert="/path/to/client.pem",
tls_key="/path/to/client.key",
Expand All @@ -69,30 +68,13 @@ Password-protected PLCs require the ``password`` keyword argument:

.. code-block:: python

from s7 import Client
from s7commplus import Client

client = Client()
client.connect("192.168.1.10", 0, 1, use_tls=True, password="my_plc_password")
client.connect("192.168.1.10", use_tls=True, password="my_plc_password")
data = client.db_read(1, 0, 4)
client.disconnect()

Protocol selection
------------------

By default the client uses ``Protocol.AUTO`` which tries S7CommPlus first.
You can force a specific protocol:

.. code-block:: python

from s7 import Client, Protocol

# Force legacy S7 only
client = Client()
client.connect("192.168.1.10", 0, 1, protocol=Protocol.LEGACY)

# Force S7CommPlus (raises on failure)
client.connect("192.168.1.10", 0, 1, protocol=Protocol.S7COMMPLUS)

Concurrent async reads
----------------------

Expand All @@ -108,28 +90,22 @@ multiple coroutines can safely share a single connection:

----

s7.Client
---------

.. automodule:: s7.client
.. automodule:: s7commplus.client
:members:

s7.AsyncClient
--------------

.. automodule:: s7.async_client
.. automodule:: s7commplus.async_client
:members:

snap7.Client (legacy)
s7.Client (legacy)
---------------------

The ``snap7.Client`` is the legacy S7 protocol client. For new projects, use
``s7.Client`` above instead.
The ``s7.Client`` implements the classic S7 protocol for S7-300/400 PLCs
and PUT/GET access on S7-1200/1500.

.. automodule:: snap7.client
:members:

snap7.AsyncClient (legacy)
s7.AsyncClient (legacy)
--------------------------

.. automodule:: snap7.async_client
Expand Down
2 changes: 1 addition & 1 deletion doc/API/log.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ For JSON output (ELK, Datadog, Loki):

.. code-block:: python

from snap7.log import JSONFormatter
from s7.log import JSONFormatter

handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
Expand Down
12 changes: 2 additions & 10 deletions doc/API/partner.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ Partner

The ``Partner`` class implements S7 peer-to-peer communication for
bidirectional data exchange using BSend/BRecv. Both partners have equal
rights and can send data asynchronously.
rights and can send data asynchronously. Partner is part of the legacy
``s7`` package.

.. code:: python

Expand All @@ -19,14 +20,5 @@ rights and can send data asynchronously.

----

s7.Partner
----------

.. automodule:: s7.partner
:members:

snap7.Partner (legacy)
----------------------

.. automodule:: snap7.partner
:members:
17 changes: 9 additions & 8 deletions doc/API/server.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
Server
======

The ``s7.Server`` is the recommended server for testing. It wraps both a
legacy S7 server and an S7CommPlus server, so test environments can serve
both protocol stacks simultaneously.
python-snap7 provides two server implementations:

- ``s7commplus.Server``: S7CommPlus server emulator
- ``s7.server.Server``: Legacy S7 server for testing

.. code:: python

from s7 import Server
from s7commplus import Server

server = Server()
server.start(tcp_port=1102)
Expand All @@ -17,16 +18,16 @@ helper:

.. code:: python

from snap7.server import mainloop
from s7.server import mainloop

mainloop(tcp_port=1102)

----

s7.Server
---------
s7commplus.Server
-----------------

.. automodule:: s7.server
.. automodule:: s7commplus.server
:members:

snap7.Server (legacy)
Expand Down
Loading
Loading