IBH Link UA:Python/Methoden/Datenmodelle
Diese Option ist nur im IBH-Link-UA-QC aktiviert, da hierfür mehr Speicher benötigt wird.
Es lassen sich jetzt mit der Programmiersprache Python Methoden realisieren, sowie Daten einfacher austauschen und verarbeiten.
Einige Beispiele zur Umsetzung komplexer Funktionen:
Es lassen sich komplexe Aufgaben automatisieren, wie z.B. die
Überwachung von Maschinenparametern oder die Optimierung von Produktionsprozessen.
Große Datenmengen können analysiert und ausgewertet werden,
um Trends und Muster zu erkennen und Prozesse zu optimieren.
Durch die Integration von Python-Modulen für Machine Learning können Maschinenparameter und -daten analysiert werden, um Vorhersagen und Empfehlungen für die Optimierung der Maschinenleistung zu treffen. Daten sind aus verschiedenen Quellen und Systemen integrierbar, um ein umfassendes Bild der Maschinenleistung und -produktivität zu erhalten Um Datenmodelle bzw. Companion Specs mit Python-Modulen auf dem IBH Link UA zu koppeln, wird zunächst das gewünschte Companion Spec oder Datenmodell in das Projekt auf dem IBH Link UA eingebunden. Dazu kann das entsprechende XML-File über den Webserver des IBH Link UA hochgeladen werden. Die OPC Foundation hat Datenmodelle für eine Vielzahl von Branchen spezifiziert. Für die Industrieautomatisierung etwa gibt es Datenmodelle für die Automatisierung von Produktionsanlagen und Maschinen, wie Maschinensteuerung, Überwachung und Diagnose, sowie Produktionsprozessverwaltung und Energiemanagement. Die Datenmodelle können mit speziellen Nodeset-Tools (UAModeler – ein kostenpflichtiges Werkzeug von Unified Automation oder Siome – eine Freeware von Siemens) erstellt werden und beschreiben die Schnittstelle, über die die Daten ausgetauscht werden sollen.
Inhaltsverzeichnis
Aufbau eines Python Programmes
Im Python Programm werden die speziellen Funktionen des IBHLinkUA importiert. Zur Initialisierung ruft der IBHLinkUA die Funktion "init_opc()" auf. Beispiel:
import ibhua
def init_opc(): return
Es können mehrere Python Programme eingelesen werden. Zusätzlich sind auch Python Programme ohne diese Spezialfunktionen möglich.
Funktionen aus dem Modul ibhua
RedirectLogOutput()
Leitet alle print, stdout und stderr Ausgaben ins Systemlog um. Diese kann in der Web-Oberfläche unter „Diagnose Systemereignisse“ betrachtet werden.
Beispiel:
import ibhua ibhua.RedirectLogOutput() print("Test")
setSystemLog (Gruppe,logtext,status)
Schreibt einen Eintrag ins Systemlog. Diese kann in der Web-Oberfläche unter „Diagnose Systemereignisse“ betrachtet werden.
Parameter:
- Gruppe : String - logtext : String - Status : Integer
Beispiel:
import ibhua ibhua.setSystemLog("meine Gruppe","mein Logtext",4711)
Breakpoint()
Setzt einen Breakpoint. Wenn der Breakpoint erreicht wird, wird der Debugger aktiviert. Man kann den Debugger über einen Webbrowser über das Port 5555 erreichen.
http://<adresse IBHLinkUA>:5555
Beispiel:
import ibhua def init_opc(): a=1 ibhua.Breakpoint() b=a+20 b=b+a+20
Nach Laden des Beispiels:
Nach Drücken der Step Taste:
OPCReadVar(node)
Funktion zum Lesen von OPC - Nodes.
Parameter:
- node: Nodeid
- Returnwert: Scalarwert oder Stringvariable
Beispiel:
import ibhua ibhua.RedirectLogOutput() uhrzeit=ibhua.OPCReadVar("ns=0;i=2258") print(uhrzeit)
In diesem Beispiel wird in die Diagnose nach dem Neustart die aktuelle Uhrzeit eingetragen.
monitor("node", "Monitor Funktion", Intervall, Triggermode, Deadband)
Bei Änderung der OPC-Variablen “Node” wird die Funktion “Monitor Funktion“ aufgerufen.
„Intervall“: bestimmt den Abtastintervall in ms.
„Triggermode“ :
- 0 = wird immer Getriggert
- 1=Trigger bei Wertänderung
- 2=Trigger bei ansteigender Flanke
- 3=Trigger bei abfallender Flanke
„Deadband“: bestimmt die minimale Wertänderung, die zum Trigger führt Die Monitorfunktion enthält einen Eingangsparameter mit dem gelesenen Wert.
Beispiel:
import ibhua ibhua.RedirectLogOutput() def Monitor(Var): print(Var) return def init_opc(): ibhua.monitor("ns=0;i=2258","Monitor",1000,0,0) return
In diesem Beispiel wird in die Diagnose jede Sekunde die aktuelle Uhrzeit eingetragen.
OPCWriteVar(node,var)
Funktion zum Schreiben von Scalar Nodes und String Nodes. Der OPCTyp wird aus der Zielvariablen automatisch ermittelt.
Parameter:
- node: Nodeid
- var: Scalar oder String Wert
Beispiel:
import ibhua def Monitor(Var): ibhua.OPCWriteVar("ns=4;s=QuadcoreNodesetExample.SoftPLC.Generic.ActualWatch",Var) return def init_opc(): ibhua.monitor("ns=0;i=2258","Monitor",1000,0,0) return
In diesem Beispiel wird die Uhrzeit jede Sekunde in die SPS Stringvariable "QuadcoreNodesetExample.SoftPLC.Generic.ActualWatch" eingetragen.
OPCResult()
Gibt das Ergebnis der Funktionen OPCReadVar, OPCWriteVar und OPCCallMethod zurück.
Parameter:
- Returnwert: 0=Erfolgreich
Zugriff auf externe OPC Server
Zum Zugriff auf externe OPC Sever muss zuerst in der Client Funktion ein externer Server eingerichtet werden.
Den Funktionen:
OPCReadVar
OPCWriteVar
OPCCallMethod
wird als erstes Parameter der Servername angegeben.
Achtung ! Der Servername muss exakt wie in der Weboberfläche (Leerzeichen vor dem „(„ beachten) angegeben werden !
Beispiel:
ExternerServer = "urn:ibhlinkua-002808:IBHsoftec:IBHLinkUA (opc.tcp://10.0.12.88:48010)" … OPCVar=ibhua.OPCReadVar(ExternerServer,"ns=4;s=PC-Station.Software PLC_1.GlobalVars.Tag_1")
OPCConnectedServers ()
Diese Funktion gibt eine Liste mit den Verbundenen OPC Servern zurück.
Mit dieser Funktion kann man einfach den kompletten Namen eines externen Servers ermitteln.
Beispiel:
In den folgenden Beispielen wird davon ausgegangen, dass sie in der Clientfunktion eine Verbindung zu dem Demo Server von Unified Automation (opc.tcp://opcuaserver.com:48010) hergestellt haben.
import ibhua ibhua.RedirectLogOutput() ExternServer="" def init_opc(): #search in ExternServer "opcuaserver.com" ExternServers=ibhua.OPCConnectedServers () print (ibhua.OPCConnectedServers ()) for line in ExternServers: if "opcuaserver.com" in line: ExternServer=line if ExternServer: print (ExternServer) else: print("no extern Server") if ExternServer: FillLevelSetPoint=ibhua.OPCReadVar(ExternServer,"ns=2;s=Demo.BoilerDemo.Boiler1.FillLevelSetPoint") print(FillLevelSetPoint)
OPCCallMethod(ExternerServer,object-nodeid, method-nodeid)
Aufruf einer Methode ohne Parameter
Parameter:
- ExternerServer
- object-nodeid : Nodename des übergeordneten Objekts
- method-nodeid : Nodename der Methode
- return : Ergebnis (0=Erfolgreich)
Beispiel:
import ibhua ibhua.RedirectLogOutput() ExternServer="" def init_opc(): #search in ExternServer "opcuaserver.com" ExternServers=ibhua.OPCConnectedServers () for line in ExternServers: if "opcuaserver.com" in line: ExternServer=line if ExternServer: result=ibhua.OPCCallMethod(ExternServer,"ns=2;s=Demo","ns=2;s=Demo.StartSimulation") print(result)
OPCCallMethod(ExternerServer,object-nodeid, method-nodeid,[parameter_1,…parameter_n)
Aufruf einer Methode mit Parametern
Parameter:
- ExternerServer
- object-nodeid : Nodename des übergeordneten Objekts
- method-nodeid : Nodename der Methode
- [parameter]: Eingangs-Parameterliste
- return Ausgangs-Parameterliste
Beispiel:
import ibhua ibhua.RedirectLogOutput() ExternServer="" def init_opc(): #search in ExternServer "opcuaserver.com" ExternServers=ibhua.OPCConnectedServers () for line in ExternServers: if "opcuaserver.com" in line: ExternServer=line if ExternServer: results=ibhua.OPCCallMethod(ExternServer,"ns=2;s=Demo.Method","ns=2;s=Demo.Method.Multiply",[2.14,3.5]) status=ibhua.OPCResult() if status==0: for result in results: print(result) else: print("Error")
Anbei ein Beispiel, das eine Methode mit Parametern aus der SPS steuert:
import ibhua ibhua.RedirectLogOutput() ExternServer="" def Multiply(var): global ExternServer if ExternServer: Mul_a=ibhua.OPCReadVar("ns=4;s=QuadcoreNodesetExample.SoftPLC.Generic.Mul_a") Mul_b=ibhua.OPCReadVar("ns=4;s=QuadcoreNodesetExample.SoftPLC.Generic.Mul_b") results=ibhua.OPCCallMethod(ExternServer,"ns=2;s=Demo.Method","ns=2;s=Demo.Method.Multiply",[Mul_a,Mul_b]) status=ibhua.OPCResult() if status==0: for result in results: ibhua.OPCWriteVar("ns=4;s=QuadcoreNodesetExample.SoftPLC.Generic.MUL_Result ",result) else: print("Error") def init_opc(): global ExternServer #search in ExternServer "opcuaserver.com" ExternServers=ibhua.OPCConnectedServers () for line in ExternServers: if "opcuaserver.com" in line: ExternServer=line ibhua.monitor("ns=4;s=QuadcoreNodesetExample.SoftPLC.Generic.StartMul","Multiply",1000,2,0)
Arbeiten mit Nodesets
Es ist jetzt möglich Nodesets einzulesen und mit Python Modulen zu verknüpfen.
Die Nodesets werden mit dem UAModeler oder mit SiOME (Freeware von Siemens) erstellt. Im Modeler gibt man das Projekt als XML File aus.
Eine Dokumentation zum SiOME finden Sie hier: https://support.industry.siemens.com/cs/document/109755133/siemens-opc-ua-modeling-editor-(siome)?dti=0&lc=de-DE
Das Handbuch finden Sie hier: https://support.industry.siemens.com/cs/attachments/109755133/109755133_SiOME_MAN_V27_de.pdf
Führen Sie laut Handbuch "Modellieren des Adressraums" aus und exportieren Sie das Informationsmodell (3.19):
Laden Sie das Informationsmodell
Danach erscheint das angelegte Objet im Adressraum des OPC Servers:
Jetzt können Sie die Variablen und Methoden mit dem Python Programm verknüpfen.
OPCError (OPC Fehlercode)
Bricht bei einem Fehlercode ungleich 0 die Ausführung ab und gibt den OPC-Fehlercode zurück.
Wird eine 0 übergeben, hat die Funktion keine Wirkung.
get_namespace(name)
Diese Funktion gibt die Namespacenummer zurück. Als Eingansparameter gibt man den Namespacenamen an. Der Namespacename findet man im UAExpert unter Server:
Beispiel:
import ibhua ibhua.RedirectLogOutput() def init_opc(): ns=ibhua.get_namespace("http://example.com") print(ns)
method(ns, id, "funktion")
Verknüpft eine Methode, die in einem eingelesenen Nodeset definiert wurde, mit einer Python Funktion.
Parameter: * ns : Namespacenummer * Id : Nodename oder Numerischer ID * Funktion die beim Aufruf der Methode aufgerufen wird
Die Funktion enthält für jedes Eingangsparamter ein Argument und kann für jedes Ausgangsparameter ein Argument zurückgeben.
Funktionen ohne einen Ausgangsparameter dürfen keinen Wert zrückgeben.
Das Funktionsergebnis (Erfolg/Misserfolg) muss generell mit OPCError() übergeben werden.
„id“ kannen mit dem UAExpert ernittelt werden :
Beispiel:
import ibhua ibhua.RedirectLogOutput() def UserMethod(a,b): result=0 c=a*b ibhua.OPCError(result) return c def init_opc(): ns=ibhua.get_namespace("http://example.com") ibhua.method(ns,7000,"UserMethod")
variable(ns, id, "read funktion", "write funktion")
Verknüpft eine Variable, die in einem eingelesenen Nodeset definiert wurde, mit einer Python Funktion.
Parameter:
- ns : Namespacenummer
- Id : Nodename oder Numerischer ID
- read funktion : Funktion die beim lesen der Variablen aufgerufen wird
Die Funktion enthält kein Eingangsparamter und ein Ausgangsparameter.
- write funktion : Funktion die beim schreiben der Variablen aufgerufen wird
Die Funktion enthält ein Eingangsparamter und kein Ausgangsparameter.
Beispiel:
import ibhua OPCVar=123.456 def UserRead(): result=0 global OPCVar ibhua.OPCError(result) return OPCVar def UserWrite(var): result=0 global OPCVar OPCVar=var ibhua.OPCError(result) return def init_opc(): ns=ibhua.get_namespace("http://example.com") ibhua.variable(ns,6008,"UserRead","UserWrite")
map(ns, id, ns_destination, id_destination )
Verbindet die OPCVariable (ns,id) mit einer anderen Variablen.
Der Vorteil dieser Funktion ist, dass kein Python Programm beim lesen und schreiben durchlaufen wird. (schneller)
Achtung: Die Datentypen müssen übereinstimmen!
Parameter:
- ns : Namespacenummer
- id : Nodename oder Numerischer ID
- ns_destination : Namespacenummer der Zielvariablen
- id_destination : Nodename oder Numerischer ID der Zielvariablen
- node : Nodeid der Variablen in einem anderen Namespace
- Returnwert: 1=Erfolgreich, -1=nicht erfolgreich
Beispiel:
import ibhua def init_opc(): ns=ibhua.get_namespace("http://example.com") ibhua.map(ns,6011,4,"QuadcoreNodesetExample.SoftPLC.Generic.PLCFloatVar")
Ausführliche Beispiele
Beispiel mit einer S7-1500
Die Dokumentation und die Beispiele werden uns von unserem Schulungspartner TTI zur Verfügung gestellt.
Dokumentation passend zum Beispiel S7-1500
Beispiel passend zur Dokumention
Die Zip Datei enthält Phyton, IBH OPC UA Editor Beispiele, sowie das TIA V18 Projekt
Eine Methode aus dem Nodeset führt einen Funktionsbaustein in der SPS aus
Python Programm :
import ibhua import time #OPC Error Codes Bad_Timeout=0x800A0000 Bad_UnexpectedError=0x80010000 def SetTemperature(SetPoint): Method_Control=ibhua.OPCReadVar("ns=4;s=QuadcoreNodesetExample.SoftPLC.GlobalVars.UA_Method_Control") if Method_Control==0: ibhua.OPCWriteVar("ns=4;s=QuadcoreNodesetExample.SoftPLC.Programs.DB 1.SetPoint",SetPoint) ibhua.OPCWriteVar("ns=4;s=QuadcoreNodesetExample.SoftPLC.GlobalVars.UA_Method_Control",1) Method_Control=1 seconds = time.time() while Method_Control==1: Method_Control=ibhua.OPCReadVar("ns=4;s=QuadcoreNodesetExample.SoftPLC.GlobalVars.UA_Method_Control") if time.time()>(seconds+2): ibhua.OPCError(Bad_Timeout) ibhua.OPCWriteVar("ns=4;s=QuadcoreNodesetExample.SoftPLC.GlobalVars.UA_Method_Control",0) ActualTemperature=Method_Control=ibhua.OPCReadVar("ns=4;s=QuadcoreNodesetExample.SoftPLC.Programs.DB 1.Actual") else: ibhua.OPCError(Bad_UnexpectedError) return ActualTemperature def ReadTemp(): return ibhua.OPCReadVar("ns=4;s=QuadcoreNodesetExample.SoftPLC.GlobalVars.Temperature") def init_opc(): ns=ibhua.get_namespace("http://example.com") print(ns) ibhua.method(ns,7001,"SetTemperature") ibhua.monitor("ns=4;s=QuadcoreNodesetExample.SoftPLC.GlobalVars.Temperature","Temperature",1000,0,0) ibhua.variable(ns,6014,"ReadTemp","")
Auszug aus dem SPS Programm:
L "UA_Method_Control" // Call Method L 1 <>I SPB noc CALL FB 1, DB 1 SetPoint := Actual := L 2 // Method Complete T "UA_Method_Control" noc: