Kommunikation & Daten
OPC UA auf der S7-1500: Grenzen, die selten dabeistehen
Strukturen sind nicht konsistent lesbar, der Server läuft im CPU-STOP weiter, Zeitstempel meinen etwas anderes: Was vor einer MES-Anbindung zu klären ist.
Kommunikation · S7-Zugriff
Optimierter Bausteinzugriff, PUT/GET-Freigabe, Zugriffsstufe: Drei Hürden trennen ein Python-Skript von den Daten der S7-1500 — und das Abwählen kostet.
Lars HilseStand:
Die Aufgabe klingt einfach: Ein Python-Skript soll ein paar Werte aus einer S7-1500 lesen — Stückzahlen, Temperaturen, Zustände. Ein Nachmittag Arbeit.
In der Praxis stehen drei Hürden im Weg, und keine davon liegt im Skript. Sie liegen in der Steuerung, sie haben mit Sicherheit und mit Speicherarchitektur zu tun, und mindestens eine davon hat einen Preis, den kaum jemand nennt, bevor sie genommen wird.
Dieser Artikel erklärt, warum der Zugriff scheitert, was das Umgehen kostet und wann der andere Weg der bessere ist — mit dem Programmcode auf beiden Seiten. Wenn ohnehin Altsteuerungen im Bestand stehen, lohnt es, diese Frage gleich mitzuentscheiden.
Eigene Darstellung nach Siemens-Funktionshandbuch „Kommunikation" (S7-1500/ET 200, Beitrag 59192925, Ausgabe 11/2025), Kapitel S7-Kommunikation, und STEP-7-Onlinehilfe.
Werkzeuge wie Snap7 sprechen die klassische S7-Kommunikation. Die adressiert absolut — Datenbaustein, Byte-Offset, Länge. Und genau das geht bei einem optimierten Datenbaustein nicht.
Siemens formuliert es im Funktionshandbuch „Kommunikation“ (S7-1500/ET 200, Beitrag 59192925, Ausgabe 11/2025; Kapitel S7-Kommunikation, Hinweis zu den Datenbausteinen für PUT/GET) unmissverständlich: Bei Verwendung der Anweisungen PUT/GET dürfen nur Datenbausteine mit absoluter Adressierung eingesetzt werden; symbolische Adressierung ist nicht möglich. Das gilt für jeden Client, der denselben Dienst der CPU nutzt — Snap7 eingeschlossen.
Die häufigste Antwort in Foren lautet: Häkchen raus. Das funktioniert — hat aber Folgen, die selten dabeistehen.
Der Preis des Häkchens
Was sich am Baustein ändert.
Abgewählt
Nicht optimierter Baustein
Feste Byte-Offsets wie bei der S7-300.
Von außen lesbar
Voreinstellung
Optimierter Baustein
Die Steuerung ordnet die Variablen selbst an.
Nur symbolisch erreichbar
Die Entscheidung gehört deshalb an den Baustein, nicht an das Skript: Ein kleiner, eigens angelegter Schnittstellen-Baustein ohne Optimierung ist fast immer besser, als die Optimierung an einem gewachsenen Datenbaustein abzuwählen.
Der teure Punkt ist der dritte: Laden ohne Reinitialisierung. Bei einem Rezept- oder Parameterbaustein im laufenden Betrieb ist sein Wegfall keine Kleinigkeit, sondern ein Grund, jede künftige Änderung auf den nächsten Stillstand zu verschieben.
Zwei getrennte Schalter
Beide stehen ab Werk auf zu — an verschiedenen Stellen.
Schalter 1
Zugriff über PUT/GET erlauben
Steht bei den Verbindungsmechanismen der CPU und ist ab Werk deaktiviert. Die Begründung dafür ist die eigentliche Information: In diesem Modus ist lesender und schreibender Zugriff möglich, ohne dass in der CPU eine Verbindung projektiert sein muss.
Wer das Häkchen setzt, öffnet also nicht einen Kanal für sein Skript, sondern einen für jeden, der die Adresse kennt.
Schutz & Security · Verbindungsmechanismen
Schalter 2
Zugriffsstufe der CPU
Weniger bekannt und ab Werk auf komplettem Schutz. In dieser Stufe ist die Serverfunktion für diese Kommunikation deaktiviert — und nicht änderbar. Das Häkchen von Schalter 1 lässt sich erst setzen, wenn die Zugriffsstufe mindestens HMI-Zugriff zulässt — HMI-Zugriff, Lesezugriff oder Vollzugriff.
Schutz & Security · Zugriffsstufe
Folge
Beide Einstellungen müssen zusammenpassen
Sie sind zwei getrennte Einträge unter „Schutz & Security“ und werden oft von verschiedenen Personen gesetzt. Das ist der Grund, warum ein Zugriff „ohne erkennbaren Grund scheitert“: Die Verbindung kommt zustande, aber jeder Lesezugriff endet mit einem Fehlercode der CPU („Function not available“, „Item not available“), der die Ursache nicht nennt — und wie ein Adressfehler im Skript aussieht.
Wer nur das eine Häkchen setzt und einen Fehler bekommt, sucht ihn meist im Skript.
Für die PUT/GET-Freigabe heißt das ab V3.1: Die Zugriffskontrolle muss aktiv und der Benutzer „Anonymous“ — ab Werk deaktiviert, das entspricht dem kompletten Schutz — mit einem der Funktionsrechte HMI-Zugriff, Lesezugriff oder Vollzugriff freigeschaltet sein. Erst dann lässt sich das Häkchen setzen.
Zwei weitere Punkte gehören in dieselbe Betrachtung:
Sichere Kommunikation schaltet die Altwelt ab. Seit Firmware V2.9 (TIA Portal V17) lässt sich einstellen, dass die Kommunikation mit Programmiergerät und HMI ausschließlich gesichert läuft — und bei neu projektierten CPUs ist genau das die Voreinstellung. Wer den Mischbetrieb nicht ausdrücklich zulässt oder ihn im Rahmen eines Sicherheitsaudits wieder abschaltet, legt damit die klassischen PG- und HMI-Verbindungen still — python-snap7 meldet sich in der Voreinstellung als Programmiergerät an und ist damit betroffen. Ob eine Verbindung vom Typ „sonstige“ wie im Beispiel unten davon unberührt bleibt, gehört vor der Auslegung an der konkreten CPU geprüft. Der Zusammenhang wird selten hergestellt, weil die Umstellung an anderer Stelle beschlossen wird als die Datenanbindung.
Der alte Port bleibt offen. Während Webserver, OPC UA und andere Dienste ab Werk deaktiviert sind, ist der Port der klassischen S7-Kommunikation voreingestellt aktiv und lässt sich nicht abschalten. Die Angriffsfläche der Steuerung ist also asymmetrisch: Alles Moderne ist zu, ausgerechnet der alte Kanal ist offen. Für eine Bestandsaufnahme im Produktionsnetz ist das ein Punkt, der auf jede Liste gehört.
Zwei Eigenschaften, die keine Fehlermeldung erzeugen und trotzdem Projekte kosten.
Die Daten sind nicht zykluskonsistent. Siemens hält fest, dass die ausgetauschten Daten während der Laufzeit des Anwenderprogramms aktualisiert werden und es innerhalb des Zyklus keinen Zeitpunkt gibt, an dem sie konsistent ausgetauscht werden. Was die S7-1500 zusichert, ist nur, dass ein Lesevorgang bis 512 Byte als Block konsistent kopiert wird. Ein 12-Byte-Satz kommt also in sich stimmig an — aber zu einem beliebigen Zeitpunkt im Zyklus, zwischen zwei Schreibbefehlen des Programms: Stückzahl aus dem neuen Zyklus, Zeitstempel aus dem alten. Das ist die Ursache der Fehlerklasse „das Skript liest manchmal Mist“, die dann meist dem Netzwerk angelastet wird.
Jede Verbindung belegt eine Ressource. Eine S7-1500 reserviert eine kleine Zahl von Verbindungsressourcen für Programmiergerät und HMI — vier davon für das Programmiergerät; alles Weitere kommt aus einem dynamischen Pool. Bibliotheken melden sich voreingestellt als Programmiergerät an — bei python-snap7 steht das so im Quelltext. Mehrere parallel laufende Skripte, die sich als Programmiergerät melden, verbrauchen zuerst die vier reservierten PG-Plätze und konkurrieren danach mit dem TIA Portal um den dynamischen Pool. Wenn der erschöpft ist, kommt das Engineering nicht mehr online — und niemand bringt das mit dem Auswerteskript in Verbindung, das seit Wochen läuft.
Wenn nach alledem die klassische Kommunikation der richtige Weg bleibt — weil ein Bestandssystem sie verlangt oder Altsteuerungen im Spiel sind — dann so:
Anleitung
Vom Wunsch zum belastbaren Zugriff.
Der Aufwand liegt in der Steuerung, nicht im Skript. Wer die Reihenfolge umdreht, sucht Fehler an der falschen Stelle.
Nicht die Optimierung am gewachsenen Datenbaustein abwählen, sondern einen kleinen, neuen Baustein ohne Optimierung anlegen, der nur die Werte enthält, die nach außen gehen. Der Rest des Programms bleibt unangetastet — und die 64-kB-Grenze ist bei einer Handvoll Werte kein Thema.
Die Zykluskonsistenz, die das Protokoll nicht zusichert, stellt das Anwenderprogramm selbst her: Ein Zähler wird vor und nach dem Kopieren erhöht. Ungerade heißt „wird gerade beschrieben“.
Der Kopierblock darf nicht in jedem Zyklus laufen, sondern in einem festen Raster, das deutlich über der Umlaufzeit zweier Lesezugriffe liegt — etwa aus einem Weckalarm-OB (OB30, 100 ms). Sonst hat sich der Zähler zwischen den beiden Lesezugriffen praktisch immer geändert, und das Skript verwirft jeden Satz.
// Schnittstellen-DB "IF_Auswertung" — bewusst OHNE optimierten Bausteinzugriff.
// Deklaration: Zaehler : Int (0.0) · Stueckzahl : DInt (2.0) ·
// Temperatur : Real (6.0) · Zustand : Int (10.0) — 12 Byte.
// Reihenfolge und Typen sind der Vertrag mit dem Skript (Format ">hifh");
// BOOL oder BYTE würden die Ausrichtung verschieben.
// Er enthält nur die Werte, die nach außen gehen. Der gewachsene Rezept-DB
// bleibt optimiert und unangetastet.
//
// Reihenfolge ist hier keine Kosmetik: Der Zähler klammert das Kopieren ein.
"IF_Auswertung".Zaehler := "IF_Auswertung".Zaehler + 1; // ungerade: in Arbeit
"IF_Auswertung".Stueckzahl := #stueckzahl;
"IF_Auswertung".Temperatur := #temperatur;
"IF_Auswertung".Zustand := #zustand;
"IF_Auswertung".Zaehler := "IF_Auswertung".Zaehler + 1; // gerade: gültigDer Zähler ist zugleich das Lebenszeichen: Steht er, steht die Steuerung — und das übergeordnete System merkt einen CPU-Stopp, statt eingefrorene Werte weiterzuverarbeiten.
Beide Schalter aus Hürde 2 sind nötig, aber sie sind nicht die einzige Stellschraube. Was zusätzlich geht und selten gemacht wird:
Ein Lesevorgang ohne Konsistenzprüfung liefert irgendwann falsche Werte, ohne das zu melden. Die Prüfung kostet einen zweiten, sehr kurzen Lesezugriff. Bei Sätzen bis 512 Byte an einer S7-1500 genügt ein gerader Zähler im ersten Lesevorgang; der zweite Zugriff sichert größere Sätze und Altsteuerungen ab.
"""Werte aus einem Schnittstellen-DB der S7-1500 lesen — mit Konsistenzprüfung.
Seit Version 3.0 ist python-snap7 reines Python: Es gibt keine Snap7-Bibliothek
mehr, die irgendwo liegen müsste. Jede Anleitung, die das Kopieren einer
Binärdatei in den Suchpfad beschreibt, ist überholt.
"""
import struct
import snap7
DB_NUMMER = 100
SATZ = ">hifh" # Zaehler(INT) Stueckzahl(DINT) Temperatur(REAL) Zustand(INT)
LAENGE = struct.calcsize(SATZ) # 12 Byte; nicht optimierte DBs liegen big-endian
def lese_satz(client: snap7.Client, versuche: int = 3) -> dict[str, int | float]:
"""Liefert einen in sich stimmigen Datensatz oder wirft eine Ausnahme.
Die Steuerung erhöht den Zähler vor und nach dem Kopieren. Ungerade heißt
"wird gerade beschrieben"; ein zweimal gleicher gerader Wert heißt "die
Werte gehören zusammen".
"""
for _ in range(versuche):
roh = client.db_read(DB_NUMMER, 0, LAENGE)
zaehler, stueckzahl, temperatur, zustand = struct.unpack(SATZ, roh)
if zaehler % 2: # Steuerung schreibt gerade
continue
nachher = struct.unpack(">h", client.db_read(DB_NUMMER, 0, 2))[0]
if nachher != zaehler: # dazwischen ein neuer Zyklus
continue
return {"stueckzahl": stueckzahl, "temperatur": temperatur, "zustand": zustand}
raise RuntimeError("Kein stimmiger Satz — Leserate oder Zykluszeit prüfen")
client = snap7.Client()
client.set_connection_type(3) # 1 = PG (Voreinstellung), 2 = OP/HMI, 3 = S7-Basis („sonstige")
client.connect("192.168.0.10", rack=0, slot=1)
try:
print(lese_satz(client))
finally:
client.disconnect() # Verbindungsressource der CPU wieder freigebenGeprüft gegen python-snap7 3.1.2 vom 10.08.2026. Der Verbindungstyp folgt der Kodierung im TSAP; die Voreinstellung 1 steht im Quelltext ausdrücklich für „PG" — also für eine der vier für das Programmiergerät reservierten Ressourcen der CPU. Achtung bei 3.0.0: Dort wurde der gesetzte Verbindungstyp beim Verbinden ignoriert und immer PG gemeldet — behoben ab 3.1.0. Version prüfen: snap7.__version__.
Ein Auswerteskript läuft Jahre, nicht Stunden. Was dafür geklärt sein muss:
Wer auf dieser Grundlage plant, sollte wissen, wie viel Bewegung gerade in den Werkzeugen ist — und an welcher Stelle nichts mehr passiert.
Werkzeugstand
Was sich geändert hat und was eingefroren ist.
2017 / 2025
Snap7: Stand der C-Bibliothek
C/C++Version 1.4.2 (2017) auf SourceForge; Mitte 2025 folgte 1.4.3 mit dem Umzug auf GitHub und kleinen Fehlerbehebungen. Am Protokoll hat sich nichts geändert — und es ist keine Anpassung an neuere Firmware-Stände, Sicherheitsmechanismen oder Protokollerweiterungen zu erwarten. Seit Juli 2026 ist zudem eine Schwachstelle in der PDU-Aushandlung der C-Bibliothek gemeldet (CVE-2026-16225, betroffen bis 1.4.3, Einstufung niedrig, Stand 30.08.2026 ungeprüft und ohne Korrekturversion) — ein Grund mehr, 2.x-Installationen mit Binärdatei nicht weiterzuziehen.
bis 02/2026
python-snap7 2.x: Aufsatz auf die C-Bibliothek
2.1.0Der Stand, den praktisch jede deutschsprachige Anleitung im Netz beschreibt — samt der Fehlersuche, wo die Bibliotheksdatei liegen muss.
18.03.2026
python-snap7 3.0: eigene Implementierung des Protokolls
BruchKeine plattformabhängigen Binärdateien mehr. Der Parameter für den Bibliothekspfad ist zwar noch da, wird aber laut Quelltext ignoriert — er steht nur noch für die Rückwärtskompatibilität.
10.08.2026
python-snap7 3.1.2: aktueller Stand
geprüftReines Python, ohne Binärdateien im Paket. Die seit 3.1 beworbene „symbolische Adressierung" (Tags) übersetzt nur Namen in absolute Adressen — an der Grenze zum optimierten Baustein ändert sie nichts. Alles in diesem Artikel Gezeigte ist gegen diesen Stand geprüft.
offen
S7CommPlus: im Entwicklungszweig, nicht veröffentlicht
unfertigDort liegt — als Paket s7commplus, vom Projekt für eine Version 4.0 angekündigt — eine Implementierung des neueren Protokolls; der symbolische Zugriff auf optimierte Bausteine ist darin als experimentell gekennzeichnet. Im veröffentlichten Paket ist davon nichts enthalten. Wer heute plant, sollte nicht damit rechnen — aber die Entwicklung im Blick behalten.
Versionsstände und Daten aus den Paket-Metadaten und dem Quelltext des veröffentlichten Pakets, geprüft am 26.08.2026; Snap7-Stand 1.4.3 nach HISTORY.txt im GitHub-Repository davenardella/snap7 und Schwachstellenmeldung GHSA-cc6f-5g4h-cf75, geprüft am 30.08.2026.
Von außen hineingreifen oder von innen anbieten?
Die Reihenfolge zählt: Der erste Fall, der zutrifft, ist die Antwort.
Wenn
Neue Anbindung, S7-1500, Firmware aktuell
Dann
OPC UA
Symbolisch, authentifizierbar, verträgt optimierte Bausteine — ohne Freigabe, die für jeden gilt.
Wenn
Nur Daten heraus, hohe Frequenz nicht nötig
Dann
Von der Steuerung veröffentlichen lassen
Die Steuerung schickt selbst, statt sich abfragen zu lassen: keine Freigabe, kein offener Serverdienst. Eine Verbindungsressource belegt auch dieser Weg — aber eine geplante, im Programm sichtbare.
Wenn
Altsteuerung S7-300 oder S7-400 im Bestand
Dann
Klassische S7-Kommunikation
Dort ist sie der vorgesehene Weg, und die Frage nach dem optimierten Bausteinzugriff stellt sich gar nicht.
Wenn
Ein Bestandssystem verlangt die klassische Kommunikation
Dann
Eigener Schnittstellen-Baustein
Minimal gehalten, nur mit den Werten, die nach außen gehen — wie oben gezeigt.
Die Grundregel dahinter: Von außen in eine Steuerung hineinzugreifen ist der aufwendigere Weg. Er verlangt Freigaben, die die Angriffsfläche vergrößern, und er erzwingt Kompromisse an der Datenstruktur. Wo es die Aufgabe zulässt, ist der Weg über eine Schnittstelle, die die Steuerung selbst anbietet, technisch und sicherheitstechnisch der sauberere — mit eigenen Grenzen von OPC UA auf der S7-1500.
Fahrplan
Vier Punkte, die über Machbarkeit und Folgekosten entscheiden — in dieser Reihenfolge zu klären.
Firmware-Stand der CPU feststellen
Ab Firmware V3.1 mit TIA Portal V19 vergeben Benutzerrollen die Zugriffsrechte; Anleitungen, die von Zugriffsstufen sprechen, führen dann an die falsche Stelle im Projekt.
Prüfen, ob die Daten überhaupt absolut adressierbar sind
Klassische S7-Kommunikation erreicht nur Datenbausteine ohne optimierten Bausteinzugriff. Ob das Abwählen vertretbar ist, entscheidet sich am Baustein, nicht am Skript.
Die beiden Freigaben unterscheiden
Die PUT/GET-Freigabe und die Zugriffsstufe der CPU sind zwei getrennte Einstellungen. Beide müssen passen, sonst scheitert jeder Lesezugriff mit einem Fehlercode, der die Ursache nicht nennt.
Konsistenz und Verbindungsressourcen klären
Klassische Lesezugriffe sind nicht zykluskonsistent, und jede offene Verbindung belegt eine Ressource der CPU. Beides gehört in die Auslegung, nicht in die Fehlersuche.
FAQ
Weil er wahrscheinlich mit optimiertem Bausteinzugriff angelegt ist — der Voreinstellung für jeden neuen Datenbaustein der S7-1500. Optimierte Bausteine haben kein garantiertes Speicherlayout: Die Steuerung ordnet die Variablen selbst an und darf die Anordnung beim Übersetzen ändern. Es gibt also keinen Byte-Offset, den die klassische S7-Kommunikation lesen könnte. Der Baustein ist nicht geschützt, sondern für diesen Weg schlicht unsichtbar.
Mehr als Geschwindigkeit. Ein Baustein ohne Optimierung ist auf 64 kB begrenzt, während ein optimierter Baustein je nach CPU bis an die Grenze des Datenarbeitsspeichers wachsen darf — ein Vielfaches davon. Und das Laden ohne Reinitialisierung entfällt: Jede Änderung an der Struktur setzt im Betrieb die Aktualwerte zurück. Bei einem Rezept- oder Parameterbaustein heißt das, jede künftige Erweiterung wartet auf den nächsten Stillstand.
Nicht immer. Das Häkchen bei den Verbindungsmechanismen ist nur eine von zwei Einstellungen. Daneben steht die Zugriffsstufe der CPU, die ab Werk auf komplettem Schutz steht — in dieser Stufe ist die Serverfunktion deaktiviert und nicht änderbar. Beide müssen zusammenpassen, sonst kommt die Verbindung zwar zustande, aber jeder Lesezugriff scheitert mit einem Fehlercode, der die Ursache nicht nennt. Ab Firmware V3.1 entspricht dem der ab Werk deaktivierte Benutzer „Anonymous".
Nicht in Bezug auf den Zyklus. Die S7-1500 kopiert einen einzelnen Lesevorgang bis 512 Byte zwar als Block, aber zu einem beliebigen Zeitpunkt im Zyklus — zwischen zwei Schreibbefehlen des Programms. Ein Lesevorgang kann also Stückzahl aus dem neuen Zyklus und Zeitstempel aus dem alten liefern. Wer zusammengehörige Werte braucht, stellt die Konsistenz im Anwenderprogramm her — etwa mit einem Zähler, der das Kopieren einklammert.
Für neue Anbindungen in der Regel OPC UA: Es arbeitet symbolisch, verträgt sich mit optimierten Bausteinen und ist authentifizierbar — ohne eine Freigabe, die für jeden gilt, der die Adresse kennt. Wo nur Daten hinaus müssen, kann die Steuerung sie auch selbst veröffentlichen. Die klassische S7-Kommunikation bleibt sinnvoll, wo S7-300 oder S7-400 im Bestand stehen oder ein Bestandssystem sie voraussetzt — dann über einen eigenen, minimal gehaltenen Schnittstellen-Baustein.
Kommunikation & Daten
Strukturen sind nicht konsistent lesbar, der Server läuft im CPU-STOP weiter, Zeitstempel meinen etwas anderes: Was vor einer MES-Anbindung zu klären ist.
Kommunikation & Daten
Jitter und CRC-Fehler stehen in jedem Messbericht — als eigenes Abnahmekriterium kennt die PI-Richtlinie beide nicht. Die vier Pflichtgrößen und ihre Werte.
Engineering & Werkzeuge
Was TIA Portal Openness leistet, wo Python die einfachere Wahl ist und ab wann sich ein Skript rechnet — mit den Stolpersteinen beim Einstieg.
Kontakt
Eine erste Einschätzung zu Ihrem Vorhaben ist kostenfrei und unverbindlich.
Antwort innerhalb von zwei Werktagen