Mit einer Siemens-S7-MQTT-Integration veröffentlicht eine S7-1200 oder S7-1500 ihre Prozessdaten direkt an Dashboards, Historians und Cloud-Anwendungen, ohne einen SCADA-Server dazwischen. In diesem Tutorial vergleichen Sie die beiden praktikablen Ansätze, die SPS-native LMQTT-Bibliothek und ein externes Gateway, und bauen dann ein funktionierendes Python-Gateway, das einen Datenbaustein liest und per TLS an einen MQTT-Broker veröffentlicht. Am Ende haben Sie eine getestete Topic-Struktur, die sich in einen Unified Namespace (UNS) einfügt, und eine Checkliste für den Produktivbetrieb.
Zwei Wege zu Siemens S7 MQTT
S7-SPSen sprechen MQTT nicht von Haus aus, so wie sie S7-Kommunikation, PROFINET oder OPC UA sprechen. Sie haben zwei realistische Optionen.
Option 1: MQTT-Client in der SPS. Siemens stellt für das TIA Portal eine kostenlose Bibliothek bereit, meist LMQTT genannt, die einen MQTT-3.1.1-Client auf Basis der Open-User-Communication-Bausteine (TCON, TSEND, TRCV) implementiert. Die SPS selbst baut eine TCP- oder TLS-Verbindung zum Broker auf und veröffentlicht. Varianten dieses Ansatzes gibt es auch auf Kommunikationsprozessoren und Siemens-Edge-Geräten.
Option 2: Externes Gateway. Ein kleiner Industrie-PC, ein Edge-Gerät oder ein Container liest Tags aus der SPS über S7-Kommunikation (PUT/GET) oder den OPC-UA-Server der SPS und veröffentlicht sie per MQTT. Das SPS-Programm ändert sich nicht oder nur minimal.
| Kriterium | LMQTT in der SPS | Externes Gateway |
|---|---|---|
| Zusätzliche Hardware | Keine | Industrie-PC, Edge-Gerät oder VM |
| Änderungen am SPS-Programm | Ja: FB-Aufrufe, Puffer, JSON-Aufbau | Keine oder minimal |
| Auswirkung auf die SPS-Zykluszeit | Gering, aber real; String-Verarbeitung ist teuer | Keine |
| TLS | Bei aktueller Firmware mit Zertifikaten im TIA Portal unterstützt | Übernimmt Betriebssystem und Bibliothek des Gateways |
| Payload-Formatierung | In SCL aufgebaut, begrenzte String-Werkzeuge | Beliebiges Format, einfach JSON oder Sparkplug |
| Store-and-Forward | Durch SPS-Speicher begrenzt | Festplattenpuffer auf dem Gateway |
| Wer pflegt es | SPS-Programmierer | IT/OT- oder Softwareteam |
| Am besten geeignet für | Wenige Signale, keine Zusatzbox erlaubt | Viele Signale, viele SPSen, komplexere Logik |
Wenn Sie nur einige Dutzend Werte aus einer SPS benötigen und zusätzliche Hardware schwierig ist, ist LMQTT attraktiv. Wenn Sie eine Linie oder ein Werk anbinden, skaliert der Gateway-Ansatz besser und hält die SPS auf die Steuerung fokussiert. Die Architekturabwägungen behandelt der Artikel SPS-Anbindung an die Cloud ausführlicher.
Option 1: Die native LMQTT-Bibliothek
Der Ablauf im TIA Portal sieht so aus:
- Laden Sie die LMQTT-Bibliothek und ihre Dokumentation vom Siemens Industry Online Support herunter und fügen Sie sie Ihrem Projekt als globale Bibliothek hinzu.
- Ziehen Sie den Client-Funktionsbaustein in Ihr Programm und legen Sie einen Instanz-Datenbaustein an.
- Konfigurieren Sie die Verbindungsparameter: Broker-Hostname, Port, Client-ID, Benutzername und Passwort, Keep Alive.
- Für TLS importieren Sie das Root-CA-Zertifikat des Brokers in den globalen Zertifikatsmanager im TIA Portal und weisen es der SPS zu. Ein Broker mit Let's-Encrypt-Zertifikat benötigt das Zertifikat ISRG Root X1. Prüfen Sie in der Dokumentation der Bibliothek, ab welcher CPU-Firmware sichere Open User Communication unterstützt wird.
- Bauen Sie die Payload in SCL als Byte-Array oder String auf und lösen Sie dann mit einer steigenden Flanke ein Publish mit Topic, QoS und Retain-Flag aus.
- Überwachen Sie die Status- und Fehlerausgänge; der Baustein meldet Verbindungsfehler, Timeouts und Ablehnungen durch den Broker.
Einige Erfahrungen aus der Praxis:
- JSON sorgfältig aufbauen. String-Verkettung in SCL ist umständlich und fehleranfällig. Halten Sie Payloads klein und nutzen Sie feste Formate, oder veröffentlichen Sie reine Zahlen-Strings auf separaten Topics.
- Bei Änderung auslösen, nicht in jedem Zyklus. Ein Publish in jedem OB1-Zyklus überflutet den Broker und die Kommunikationsressourcen der SPS. Verwenden Sie einen Timer oder einen Totband-Vergleich.
- Auf die Client-ID achten. Zwei SPSen mit derselben Client-ID trennen sich gegenseitig in einer Endlosschleife. Bei einem verwalteten MQTT-Broker, der Client-IDs an Zugangsdaten bindet, braucht jede SPS ihren eigenen Satz Zugangsdaten.
- TLS ab dem ersten Tag verwenden. Zertifikate nach der Inbetriebnahme nachzurüsten bedeutet einen weiteren Download und ein weiteres Wartungsfenster.
Option 2: Python-Gateway mit python-snap7
Der Gateway-Ansatz nutzt python-snap7, um einen Datenbaustein über S7-Kommunikation zu lesen, und paho-mqtt zum Veröffentlichen. Er läuft auf jedem Linux- oder Windows-Rechner, der die SPS über TCP-Port 102 erreicht.
Die SPS im TIA Portal vorbereiten
S7-1200- und S7-1500-CPUs blockieren externe S7-Lesezugriffe standardmäßig. Nehmen Sie zwei Änderungen vor und laden Sie das Projekt:
- Aktivieren Sie in den CPU-Eigenschaften unter Schutz & Security die Option Zugriff über PUT/GET-Kommunikation durch entfernten Partner erlauben.
- Deaktivieren Sie in den Eigenschaften des zu lesenden Datenbausteins Optimierter Bausteinzugriff, damit die Variablen feste Byte-Offsets haben.
Legen Sie dann einen Datenbaustein an, zum Beispiel DB10, mit diesem Aufbau:
| Offset | Name | Typ |
|---|---|---|
| 0.0 | Temperature | Real |
| 4.0 | Pressure | Real |
| 8.0 | MotorSpeed | Int |
| 10.0 | Running | Bool |
PUT/GET ist nicht authentifiziert. Aktivieren Sie es daher nur in einem segmentierten Netz, in dem das Gateway der einzige Client ist, etwa in einer eigenen Zone nach dem Zonen- und Conduit-Modell der IEC 62443. Ist das an Ihrem Standort nicht zulässig, lesen Sie dieselben Daten stattdessen über den OPC-UA-Server der S7-1500, wie im Tutorial zum OPC-UA-zu-MQTT-Gateway beschrieben.
Die Bibliotheken installieren
python -m venv s7mqtt
source s7mqtt/bin/activate
pip install python-snap7 "paho-mqtt>=2.0"
Das Gateway-Skript
Dieses Skript liest DB10 jede Sekunde, wendet ein Totband an und veröffentlicht nur relevante Änderungen. Zudem pflegt es ein Retained-Status-Topic mit Last Will, damit Konsumenten wissen, wann das Gateway offline geht.
import json
import time
import uuid
from datetime import datetime, timezone
import snap7
from snap7.util import get_real, get_int, get_bool
import paho.mqtt.client as mqtt
PLC_IP = "192.168.0.10"
RACK, SLOT = 0, 1 # S7-1200- und S7-1500-CPUs verwenden Rack 0, Slot 1
DB_NUMBER, DB_SIZE = 10, 12
# Zuerst auf dem öffentlichen Broker testen. Zufälliges Präfix verwenden: Der öffentliche Bereich ist für jeden lesbar.
BROKER = "broker.connectmq.com"
PORT = 1883
USE_TLS = False
USERNAME = None # Produktion: "YOUR_USERNAME"
PASSWORD = None # Produktion: "YOUR_PASSWORD"
CLIENT_ID = f"s7-gw-{uuid.uuid4().hex[:8]}" # Produktion: "YOUR_CLIENT_ID"
BASE = f"connectmq/demo/{uuid.uuid4().hex[:6]}/plant1/packaging/line2/filler"
DEADBANDS = {"temperature": 0.2, "pressure": 0.05, "motor_speed": 5}
def read_plc(plc):
data = plc.db_read(DB_NUMBER, 0, DB_SIZE)
return {
"temperature": round(get_real(data, 0), 2),
"pressure": round(get_real(data, 4), 3),
"motor_speed": get_int(data, 8),
"running": get_bool(data, 10, 0),
}
def changed(name, new, last):
if name not in last:
return True
if isinstance(new, bool):
return new != last[name]
return abs(new - last[name]) >= DEADBANDS.get(name, 0)
def on_connect(client, userdata, flags, reason_code, properties):
print("MQTT connected:", reason_code)
client.publish(f"{BASE}/status", "online", qos=1, retain=True)
def main():
mq = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
if USERNAME:
mq.username_pw_set(USERNAME, PASSWORD)
if USE_TLS:
mq.tls_set() # der System-CA-Speicher validiert das Let's-Encrypt-Zertifikat
mq.will_set(f"{BASE}/status", "offline", qos=1, retain=True)
mq.on_connect = on_connect
mq.connect(BROKER, PORT, keepalive=30)
mq.loop_start()
plc = snap7.client.Client()
last = {}
last_full = 0.0
print("Publishing under", BASE)
while True:
try:
if not plc.get_connected():
plc.connect(PLC_IP, RACK, SLOT)
values = read_plc(plc)
now = time.time()
force = now - last_full > 300 # vollständige Aktualisierung alle 5 Minuten
ts = datetime.now(timezone.utc).isoformat(timespec="seconds")
for name, value in values.items():
if force or changed(name, value, last):
payload = json.dumps({"value": value, "ts": ts, "quality": "good"})
mq.publish(f"{BASE}/{name}", payload, qos=1)
last[name] = value
if force:
last_full = now
except Exception as exc: # SPS nicht erreichbar, falscher DB-Aufbau usw.
print("PLC read failed:", exc)
mq.publish(f"{BASE}/quality", "bad", qos=1, retain=True)
try:
plc.disconnect()
except Exception:
pass
time.sleep(5)
time.sleep(1)
if __name__ == "__main__":
main()
Die eintreffenden Daten beobachten
Starten Sie das Skript, notieren Sie das ausgegebene Präfix und abonnieren Sie es in einem anderen Terminal:
mosquitto_sub -h broker.connectmq.com -p 1883 -i s7-watch-01 \
-t 'connectmq/demo/+/plant1/packaging/line2/filler/#' -v
Ändern Sie einen Wert in der Beobachtungstabelle der SPS, und das zugehörige Topic aktualisiert sich innerhalb einer Sekunde. Werte, die sich um weniger als ihr Totband bewegen, bleiben still, genau das gewünschte Verhalten in einem ausgelasteten Werksnetz. Der kostenlose öffentliche MQTT-Broker eignet sich für diesen Test, senden Sie dorthin aber niemals echte Produktionsdaten.
Wechsel zu einem privaten Broker mit TLS
Für den Produktivbetrieb erstellen Sie einen privaten Broker und ändern drei Einstellungen: PORT = 8883, USE_TLS = True sowie Benutzername, Passwort und Client-ID aus dem Portal. Da ConnectMQ ein Let's-Encrypt-Zertifikat verwendet, validiert tls_set() es mit dem System-CA-Speicher, ohne dass Sie eine eigene CA-Datei ausliefern müssen. Lassen Sie das Präfix connectmq/demo/... weg und verwenden Sie einen sauberen ISA-95-Pfad wie plant1/packaging/line2/filler/temperature; das ConnectMQ-Portal erkennt Topics im ISA-95-Stil und zeigt Geräte gegliedert nach Unternehmen, Standort, Bereich und Linie.
Die SPS-Daten als Teil des Unified Namespace
Dieser ISA-95-Pfad ist mehr als eine Namenskonvention: Er macht die SPS zu einem Teil des Unified Namespace (UNS). Im UNS wird die ISA-95-Hierarchie (Enterprise → Site → Area → Line → Cell) zur Topic-Struktur auf dem MQTT-Broker, beispielsweise acme/werk-stuttgart/verpackung/linie-2/abfueller/temperature. Jede S7, jedes Gateway und jede weitere Datenquelle veröffentlicht ihren aktuellen Zustand an genau der Stelle, an der sie im Werk steht, und MES, ERP-Anbindung, Historian und Dashboards abonnieren diese Struktur, statt eigene Punkt-zu-Punkt-Verbindungen zur SPS zu pflegen. Wie Sie den UNS mit Sparkplug B kombinieren, beschreibt der Beitrag Sparkplug B und Unified Namespace.
Wenn Sie zwischen einem eigenen Broker neben den SPSen und einem verwalteten MQTT-Broker abwägen, überlegen Sie, wer ihn patcht, Zertifikate erneuert und um 3 Uhr nachts die Verbindungslimits im Blick behält.
Checkliste für den Produktivbetrieb
- Ein Satz Zugangsdaten und eine eindeutige Client-ID pro SPS oder Gateway.
- TLS auf Port 8883; kein unverschlüsseltes TCP außerhalb des Werksnetzes.
- PUT/GET nur in einem segmentierten Netz aktivieren oder stattdessen OPC UA nutzen.
- Totbänder pro Signal dimensioniert, mit periodischer vollständiger Aktualisierung.
- Retained-Status-Topic mit Last Will für den Online- und Offline-Zustand.
- QoS 1 für Messwerte; QoS 0 nur für hochfrequente Daten, deren Verlust verkraftbar ist.
- Gateway läuft als Dienst mit automatischem Neustart und Logging.
- Topic-Namen folgen über alle Linien und Werke einer abgestimmten ISA-95-Hierarchie, sodass alle SPSen im selben UNS zusammenfinden.
Fehlerbehebung bei Siemens-S7-MQTT-Verbindungen
- snap7-Fehler „CLI : function refused by CPU“. PUT/GET ist nicht aktiviert, oder die CPU wurde seit der Änderung nicht geladen.
- „Address out of range“. Der DB ist kleiner als die angeforderten Bytes, oder er ist noch optimiert. Prüfen Sie die Offset-Spalte im TIA Portal.
- Werte sehen wie Datenmüll aus. Die Offsets stimmen nicht. Denken Sie daran: Real hat 4 Byte, Int 2 Byte, und Bool wird in Bits gepackt.
- MQTT-Wiederverbindungsschleife. Doppelte Client-ID, falsche Zugangsdaten, oder das Gateway verbindet sich per TLS mit Port 1883.
- LMQTT hängt im Verbindungsaufbau. DNS ist auf der CPU nicht konfiguriert, oder das CA-Zertifikat fehlt im Zertifikatsspeicher der SPS.
Das übrige industrielle Gesamtbild, einschließlich Sparkplug B, Edge-Gateways und Namespace-Design, finden Sie im Leitfaden zu Industrial IoT mit MQTT. Sie betreiben auch Rockwell-Hardware? Das Tutorial Allen-Bradley und MQTT folgt demselben Muster mit EtherNet/IP.
Verbinden Sie Ihre Siemens-SPSen mit ConnectMQ
Ihr S7-Gateway braucht einen sicheren MQTT-Broker in der Cloud als Ziel. Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless-Broker, ganz ohne Kreditkarte, kopieren Sie die generierten Zugangsdaten in das Skript und sehen Sie zu, wie Ihre SPS-Tags im Live-Topic-Explorer erscheinen.
Häufig gestellte Fragen
Kann eine S7-1200 direkt per MQTT veröffentlichen?
Ja. Mit der Siemens-LMQTT-Bibliothek kann eine S7-1200 oder S7-1500 als MQTT-Client arbeiten. Prüfen Sie in der Dokumentation der Bibliothek die unterstützten Firmware-Versionen, besonders wenn Sie TLS benötigen.
Unterstützt Siemens S7 MQTT auch MQTT 5?
Die SPS-native Bibliothek implementiert MQTT 3.1.1. Wenn Sie Funktionen von MQTT 5 wie Message Expiry benötigen, verwenden Sie ein externes Gateway mit einer Bibliothek wie paho-mqtt.
Ist es sicher, den PUT/GET-Zugriff zu aktivieren?
PUT/GET hat keine Authentifizierung. Aktivieren Sie es daher nur in einem segmentierten Netz, in dem das Gateway der einzige Client ist. Der OPC-UA-Server der S7-1500 mit Benutzerauthentifizierung ist die sicherere Alternative.
Welche QoS sollten SPS-Daten verwenden?
QoS 1 ist ein guter Standard für Messwerte und Status. Verwenden Sie Retained Messages für Zustands-Topics, damit neue Abonnenten sofort den aktuellen Wert erhalten.



