Mit Snap7 & Python Prozessdaten aus der LOGO!8 auslesen

Logo 8 mit Python und Snap7

Die Steuerung LOGO! 8 (von Siemens) wird gerne bei kleineren Automatisierungsprojekten eingesetzt. Darunter häufig Automatisierung von Maschinen oder Anlagen, aber auch in der Gebäudeautomation oder Lüftungstechnik findet man sie oft vor.

Möchte man nun auf den internen Speicher der LOGO! 8 (z.B. Messwerte von Sensoren oder Werte zur Ansteuerung von Aktuatoren) zugreifen, um Werte zu lesen oder zu schreiben, dann hat man mehrere Möglichkeiten:

  • S7 Protokoll
  • ModbusTCP

Beide Wege können über Open Source Bibliotheken und mittels Python realisiert werden, was die Verwendung der Logo in eigenen IoT Projekten sehr attraktiv macht. In diesem Artikel möchte ich zeigen, wie man mit der Bibliothek Snap7 und dem zugehörigen Python Wrapper auf die Daten in der Logo (via S7 Kommunikation) lesend und schreibend zugreifen kann.

Prinzipiell ist der Zugriff auf den Speicherbereich der Logo mit der o.g. Bibliothek recht komfortabel, jedoch muss das Address-Mapping der IOs und der VMs bekannt sein. Dies ist von Siemens veröffentlicht und kann hier eingesehen werden. Ich habe das Mapping weiter unten nochmal etwas ausführlicher dargestellt. Das Mapping unterscheidet sich zwischen der Logo 0BA8 und der 0BA7. Ich gehe hier nur auf die 0BA8 ein, da diese die 0BA7 ersetzt hat.

1. Konfiguration der LOGO! 8

Um nun auf den Speicherbereich zuzugreifen, müssen wir in der Logo die S7 Kommunikation aktivieren. Wir erstellen dazu in Logo Soft Comfort ein Netzwerkprojekt, in dem die Logo als Basismodul angelegt wird. Die S7 Kommunikation aktivieren wir über einen Rechtsklick auf einen freien (türkisen) Slot unterhalb der Logo. Dann wählen wir "S7 Server" aus und fahren mit der eigentlichen Konfiguration in dem neuen Fenster fort. Die Logo wird somit als S7 Server konfiguriert unser Python Script wird der Client.

Fast alle notwendigen Einstellungen sind soweit gesetzt. Wichtig ist, dass die Werte bei TSAP notiert werden, da diese anschließend im Python Script verwendet werden müssen. (TSAP steht für "Transport Service Access Point" und kommt von früheren Generation der Siemens SIMATIC Steuerungen. Wer mehr dazu wissen möchte, erfährt genaueres dazu im Siemens Support Forum.)

Die Checkbox "Connect with an Operator Panel (OP)" lassen wir offen, da diese für z.B. den Zugriff von SIMATIC Basic Panels gedacht ist. Es sind an der Logo zwar mehrere Netzwerk-Slots verfügbar, aber der Zugriff für ein Operator Panel kann nur einzig bei einem Slot gesetzt werden.

2. Python Skript vorbereiten

Da python-snap7 auf PyPI gehostet ist, kann es ganz bequem über pip installiert werden. Ich habe es in einem Virtual Environment installiert, geht aber auch systemweit. Für die x64 Betriebssysteme kann die Bibliothek folgendermaßen installiert werden (Windows, Linux, macOS):

$ pip install python-snap7

3. Python Skript

Im Skript kann nun recht komfortabel auf den Speicherbereich der Logo zugegriffen werden. Mit plc.read(address) wird der Wert im genannten Register gelesen, mit plc.write(address, value) wird der genannte Wert in der Logo in den genannten Speicher geschrieben.

Wie bereits in der Anleitung angedeutet, muss die Zuordnung bzw. das Address Mapping bekannt sein. Durch das Mapping wird es möglich die Zustände bzw. Werte der in Logo Soft Comfort angelegten Programmierung bzw. den Funktionsblöcken in unserem Python Skript zu verwenden. Ich habe dazu ein Logo Snap7 Mapping Cheat Sheet angelegt, dies ist weiter unten zum Download verfügbar und kann beim Programmieren gute Dienste erweisen. Weitere Informationen zum Mapping gibt es auch im Siemens Industry Support.

Das folgende Script lässt die Hintergrundbeleuchtung des an der Logo angeschlossenen TDEs rotieren: orange, rot, weiß
Das Skript schreibt jeweils rotierend in die Merker der Logo M26, M30 und M31 den Wert True. Dies führt dazu, dass das Display die Hintergrundbeleuchtung in der jeweiligen Farbe aktiviert. Dass die Flags (Merker) über das Python Script gesetzt werden, kann man auch im Online Modus in Logo Soft Comfort verfolgen.

import snap7
import time

plc = snap7.logo.Logo()
plc.connect("1.1.2.1", 0x3000, 0x2000)

if plc.get_connected():
    print("Connected to LOGO!8")
    signals = (True, False, False)
    colors = ("Backlight color: white", "Backlight color: red", "Backlight color: amber")
    s_splits = 1
    c_splits = 1
    while(True):
        signals = (signals[len(signals) - s_splits:len(signals)] + signals[0:len(signals) - s_splits])
        colors = (colors[len(colors) - c_splits:len(colors)] + colors[0:len(colors) - c_splits])
        plc.write("V1107.1", signals[0]) # enable white backlight
        plc.write("V1107.5", signals[1]) # enable amber backlight
        plc.write("V1107.6", signals[2]) # enable red backlight
        print(colors[0])
        time.sleep(3)

else:
    pass

plc.disconnect()
plc.destroy()

4. Mapping

Viele Funktionsblöcke besitzen Parameter, die zur Laufzeit geändert werden können. Diese Parameter können zum Einen über das TDE oder das integrierte Display geändert werden, zum Anderen können wir darauf aber auch mit Snap7 zugreifen. Dazu müssen in Logo Soft Comfort diese Parameter in der Logo adressiert werden. Dies funktioniert in Logo Soft Comfort über Variablen Speicher bzw. Variable Memory Configuration. (Tools -> Parameter VM Mapping...).
Auf diesen Addressbereich wird analog zu allen anderen Bereichen lesend und schreibend zugegriffen z.B. plc.read("VW0") oder plc.read("VW2").

6. Download Mapping und Codebeispiele

7. weiteres Codebeispiel

import snap7
import time

plc = snap7.logo.Logo()
plc.connect("1.1.2.1", 0x3000, 0x2000)

if plc.get_connected():
    print("connected")
    
    # read analog inputs and AM
    print("AI1: " + str(plc.read("VW1032"))) # read from AI1
    print("AI1: " + str(plc.read("VW0"))) # read from B001.AnInAmp_1 - via parameter VM mapping
    print("AI1: " + str(plc.read("VW1118"))) # read from AM1
    
    print("AI2: " + str(plc.read("VW1034"))) # read from AI2
    print("AI2: " + str(plc.read("VW2"))) # read from B002.AnInAmp_2 - via parameter VM mapping
    print("AI2: " + str(plc.read("VW1120"))) # read from AM2

    # read digital inputs - bitwise access
    print("DI1: " + str(plc.read("V1024.0")))
    print("DI2: " + str(plc.read("V1024.1")))
    print("DI3: " + str(plc.read("V1024.2")))
    print("DI4: " + str(plc.read("V1024.3")))

    # write analog outputs and read from to check
    plc.write("VW1072", 8000)
    print("AO1: " + str(plc.read("VW1072")))

    # set digital outputs - bitwise access
    plc.write("V1064.0", True) # write DO 1 - Q1
    plc.write("V1064.1", True) # write DO 2 - Q2
    plc.write("V1064.2", True) # write DO 3 - Q3
    plc.write("V1064.3", True) # write DO 4 - Q4

    # read digital output states - bitwise access
    print("DO1: " + str(plc.read("V1064.0")))
    print("DO2: " + str(plc.read("V1064.1")))
    print("DO3: " + str(plc.read("V1064.2")))
    print("DO4: " + str(plc.read("V1064.3")))

    time.sleep(2)

    # reset digital outputs
    plc.write("V1064.0", False) # write DO 1 - Q1
    plc.write("V1064.1", False) # write DO 2 - Q2
    plc.write("V1064.2", False) # write DO 3 - Q3
    plc.write("V1064.3", False) # write DO 4 - Q4

else:
    pass

plc.disconnect()
plc.destroy()