Skip to content

feat(s7commplus): add symbolic data subscriptions - #825

Open
gijzelaerr wants to merge 2 commits into
masterfrom
feat/710-v1-subscription-data
Open

feat(s7commplus): add symbolic data subscriptions#825
gijzelaerr wants to merge 2 commits into
masterfrom
feat/710-v1-subscription-data

Conversation

@gijzelaerr

@gijzelaerr gijzelaerr commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • retain the subscription-container object returned during session creation
  • create symbolic data subscriptions from access sequences returned by browse()
  • queue unsolicited notifications that arrive while waiting for request responses
  • parse V2 and SessionKey/V3 notification values and errors, including the padded BLOB form in the TIA Portal capture from S7-1200 Session Setup Incomplete #710
  • encode the complete subscription object and correct DeleteObject qualifier

Stack

Depends on #775 and targets its head branch. The two pull requests are prepared for GitHub native stack linking, with #775 as the bottom layer and this pull request as the top layer. Review only the commit introduced here.

Scope

This provides the symbolic subscription path needed by the V1-initial, SessionKey-authenticated PLC from #710. It does not make raw db_read(offset, size) work for optimized blocks because raw byte offsets cannot be translated into valid symbolic LIDs. Real S7-1200 validation is still needed, so this progresses rather than closes #710.

The subscription layout follows the TIA Portal capture attached to #710 and the reference implementation in https://github.com/thomas-v2/S7CommPlusDriver/blob/master/src/S7CommPlusDriver/Subscriptions/Subscription.cs.

Validation

  • 1776 passed, 82 skipped
  • repository-wide pre-commit hooks pass, including mypy and Ruff formatting/linting
  • source distribution and wheel build successfully

Progresses #710

Comment thread s7commplus/subscription.py
Comment thread s7commplus/client.py
@gijzelaerr
gijzelaerr changed the base branch from fix-tls-layering-v2 to master August 20, 2026 05:20
@gijzelaerr
gijzelaerr force-pushed the feat/710-v1-subscription-data branch from 65b4665 to 8b7fbf6 Compare August 20, 2026 05:33
@gijzelaerr

Copy link
Copy Markdown
Owner Author

@bvanelli I incorporated the working C# trace into the implementation and added byte-exact create/delete regression fixtures. The updated framing now uses the captured subscription name, signed-VLQ subsystem status, route mode, notification credits, and subscription-container deletion target.

Could you please rerun your symbolic subscription example against the current branch, including create, notification delivery, and delete, and review again if it now works on the PLC?

Install:

pip install --upgrade "python-snap7 @ git+https://github.com/gijzelaerr/python-snap7.git@feat/710-v1-subscription-data"

The PR history is now clean (two commits on master), all 42 CI checks pass, and the local suite reports 1,838 passed, 78 skipped.

@gijzelaerr
gijzelaerr requested a review from bvanelli August 20, 2026 06:50
@bvanelli

bvanelli commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Thanks, it now works:

INFO __main__: Connected to 192.168.101.34: protocol=V2 session=0x70000CB7 session_setup_ok=True tls_active=True
Found 23728 variables
  LGF_SinusCI_DB.amplitude (REAL) @ 8A0E0007.E
  LGF_SinusCI_DB.offset (REAL) @ 8A0E0007.F
  LGF_SinusCI_DB.periode (UDINT) @ 8A0E0007.10
  LGF_SinusCI_DB.value (REAL) @ 8A0E0007.12
  LGF_SinusCI_DB.error (BBOOL) @ 8A0E0007.13
INFO s7commplus.client: Subscription created, id=0x70000cb9
SubscriptionNotification(subscription_id=1879051449, credit_tick=1, sequence_number=0, change_counter=1, values={5: b'\x00', 4: b'=\xc0\xbb\xf5', 3: b'\x00\x00\x03\xe8', 2: b'\x00\x00\x00\x00', 1: b'?\x80\x00\x00'}, errors={}, timestamp_microseconds=1787240115351898, trailing_data=b'\x00\x00\x00\x00')
INFO s7commplus.client: Subscription 0x70000cb9 deleted
INFO snap7.connection: Disconnected from 192.168.101.34:102

I did vibecode the conversion real quick (for a different sample):

LGF_SinusCI_DB.error (BBOOL) = False  raw=00
LGF_SinusCI_DB.value (REAL) = -0.958521842956543  raw=bf7561b0
LGF_SinusCI_DB.periode (UDINT) = 1000  raw=000003e8
LGF_SinusCI_DB.offset (REAL) = 0.0  raw=00000000
LGF_SinusCI_DB.amplitude (REAL) = 1.0  raw=3f800000

And could also confirm that the static variables match.

Just a note: the data still comes fully as binary, and requires some effort for conversion. In a future SubscriptionItem this could be part of the item itself to convert the value. Right now, I still have to save the datatype and call decode_value.

Tested against two different PLCs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

S7-1200 Session Setup Incomplete

2 participants