IBH Link UA:Phyton/Methoden/Datenmodelle

Aus IBHsoftec Wiki
Wechseln zu: Navigation, Suche

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.

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.

IBH Link UA Nodeset.png

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")

IBH Link UA Redirect.png

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)

IBH Link UA setsystemlog.png

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:

IBH Link UA Breakpoint1.png

Nach Drücken der Step Taste:

IBH Link UA Breakpoint2.png

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.

IBH Link UA Select Server.png

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):

IBH Link UA Siome.png


Laden Sie das Informationsmodell

IBH Link UA Siome Nodeset.png

Danach erscheint das angelegte Objet im Adressraum des OPC Servers:

IBH Link UA Nodeset Example.png

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:

IBH Link UA Name Space.png

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.

„id“ kannen mit dem UAExpert ernittelt werden :

IBH Link UA Attributes.png


Beispiel:

import ibhua
ibhua.RedirectLogOutput()

def UserMethod(a,b):
    c=a*b
    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():
    global OPCVar
    return OPCVar

def UserWrite(var):
    global OPCVar
    OPCVar=var
    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

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: