Skip to content
Closed
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
8 changes: 8 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ CHANGES

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

* Correlate S7CommPlus responses by opcode, function, and sequence; preserve
interleaved notifications and serialize synchronous wire requests.
* Verify authenticated V3 responses and cumulative fragment digests before
parsing, invalidating the connection with a dedicated integrity error on any
mismatch or truncated envelope.
* Complete symbolic subscription lifecycle handling with catalog-tag decoding,
bounded sync/async delivery, overflow and sequence-gap diagnostics, finite
credit replenishment, and stale-generation filtering.
* Decode corroborating CPU execution attributes so S7CommPlus `get_cpu_state()`
distinguishes RUN from STOP on S7-1500 and returns UNKNOWN for absent or
inconsistent state attributes, including S7-1200 responses that omit them.
Expand Down
28 changes: 19 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,22 +128,32 @@ PUT/GET enabled.
print(result.tag.name, result.value)
else:
print(result.tag.name, result.error)
* **Symbolic data subscriptions** -- monitor values using access sequences
returned by ``browse()``::
* **Symbolic data subscriptions** -- monitor catalog tags or access sequences
through bounded sync/async notification streams::

from s7commplus import Client

client = Client()
client.connect("192.168.1.10", 0, 1, password="secret")
subscription_id = client.create_subscription(["8A0E0007.A"], cycle_ms=100)
notification = client.receive_subscription_notification()
value = notification.values[1]
client.connect("192.168.1.10", password="secret")
tag = client.resolve_tag("DB1.Motor.Speed")
subscription_id = client.create_subscription([tag], cycle_ms=100)
notification = client.receive_subscription_notification(subscription_id)
value = notification.decoded_values[1]
raw_value = notification.values[1]
client.delete_subscription(subscription_id)
client.disconnect()

Reference IDs default to the one-based position of each access sequence.
Subscriptions use symbolic LIDs and therefore cannot be created from raw DB
byte offsets.
``iter_subscription_notifications()`` provides a bounded synchronous
iterator; the async client provides an async iterator and
``subscription_queue()``. Finite notification credits are replenished
automatically. ``subscription_diagnostics()`` reports queue overflow and
sequence gaps. Reference IDs default to the one-based item position. Raw
values remain available when a datatype is unknown or structured.

Deleting or disconnecting invalidates the local subscription state. Automatic
reconnect does not silently recreate subscriptions: create them again so the
caller can decide how to handle any update gap. Subscriptions use symbolic
LIDs and cannot be created from raw DB byte offsets.
* **TIA Portal XML import** -- import symbol tables from TIA Portal exports

**Help us test!** If you have access to any Siemens S7 PLC, we would greatly
Expand Down
5 changes: 4 additions & 1 deletion s7commplus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
data = client.db_read(1, 0, 4)
"""

from .async_client import AsyncSubscriptionQueue
from .async_client import S7CommPlusAsyncClient as AsyncClient
from .alarm import Alarm, AlarmNotification, AlarmText, LanguageId
from .blob_decompressor import decompress_blob, find_and_decompress
Expand All @@ -22,7 +23,7 @@
from .connection import S7CommPlusConnection
from .server import CPUState, DataBlock
from .server import S7CommPlusServer as Server
from .subscription import SubscriptionItem, SubscriptionNotification
from .subscription import SubscriptionDiagnostics, SubscriptionItem, SubscriptionNotification
from .tag_browser import (
DataBlock as ExploreDataBlock,
)
Expand All @@ -40,6 +41,7 @@
"AlarmText",
"ArrayDimension",
"AsyncClient",
"AsyncSubscriptionQueue",
"CPUState",
"Client",
"DBWriteItem",
Expand All @@ -51,6 +53,7 @@
"Server",
"SubscriptionItem",
"SubscriptionNotification",
"SubscriptionDiagnostics",
"SymbolCatalog",
"SymbolicReadItem",
"SymbolicTag",
Expand Down
Loading