Server - GOOSE Publisher (ohne Client-Server-Kommunikation)
In einem Server-Projekt wird von dem TwinCAT Telecontrol Configurator standardmäßig auch ein Server-Baustein und einer oder mehrere Instanzen des ServerSession-Bausteins generiert (siehe: „Allgemeine Server-Projektstruktur“). Der Server und ServerSession-Baustein kann z. B. dafür sorgen, dass der Publisher vom Client aus via Client-Server-Dienste wie „GetGoCBDataValues“ oder „SetGoCBDataValues“ aktiviert/deaktiviert oder die GoCBs konfiguriert werden können. In manchen Fällen soll aber auf eine Client-Server-Kommunikation mit dem Gerät verzichtet werden und nur ein „reiner“ GOOSE Publisher implementiert werden. Ein solcher Publisher kann nach dem SPS-Programmstart automatisch mit dem Versenden der GOOSE-Nachrichten beginnen. Dieses Beispiel zeigt die Implementierung eines Publishers, aber ohne den Client-Server-Kommunikationsteil. Die nicht benötigten Teile des Server-Projekts wurden in diesem Beispiel bewusst entfernt.
Download TwinCAT XAE Project (*.zip): Sample12.zip
Namensraum: TcTelecontrol
Typ: Globale Variablenliste (GVL)
In der globalen Variablenliste wird eine IED-Datenmodell-Bausteininstanz („fbIED“) und eine oder mehrere GSE-Bausteininstanzen für GOOSE-Kommunikation und GSE-Management („fbIEDGse“) benötigt. Dieses Beispiel verwendet nur einen Netzwerkadapter für die GOOSE-Kommunikation und drei GoCBs im IED-Datenmodell.
VAR_GLOBAL
ipCreator : I_AcsiCodeCreatorClass := GVL_AcsiVars.Creator.SetCodeRev(codeRev:=2).SetGuiVer(major:=1, minor:=0, build:=93, revision:=10);
fbIED : FB_IED_IED;
fbIEDGse : FB_IEDGse := (fbAdapter:=(ipIED:=fbIED, settings:=(sMulticastAddr:='01-0C-CD-01-00-01', eDispatchMode:=E_GseDispatchMode.NonPromiscuous)));
END_VAR
Das „MAIN“-Programm wird zyklisch von einer TwinCAT Task aufgerufen und muss nur das Programm „P_IEC61850MAIN“ aufrufen. „P_IEC61850MAIN“ ruft wiederum den GSE-Baustein auf, der für das Versenden der GOOSE-Nachrichten und das Mapping der empfangenen Daten vom IED-Datenmodell in die GOOSE-Nachrichten zuständig ist.
PROGRAM MAIN
VAR
END_VAR
P_IEC61850MAIN();
PROGRAM P_IEC61850MAIN
VAR
END_VAR
fbIEDGse();
In der Beispielimplementierung des GSE-Bausteins wird der Publishing-Prozess bei allen drei GoCBs nach dem SPS-Start automatisch gestartet. Eine steigende Flanke an der „bStop“-Variablen stoppt den Publishing-Prozess der GoCB‘s. Die Wertänderungen einiger GOOSE-Daten werden im Beispiel simuliert. Dabei werden alle 5s einige Werte der GoCB-DataSet-Member modifiziert und an der Variablen „bUpdate“ eine steigende Flanke generiert. Über diese steigende Flanke werden die Publisher veranlasst eine neue GOOSE-Nachricht zu generieren und zu versenden. Die SPS-Applikation muss sich um die GOOSE-Nachrichtenwiederholungen nicht kümmern. Dies erfolgt automatisch.
FUNCTION_BLOCK FB_IEDGse IMPLEMENTS I_GseSystemClockEventSink, I_GseLinkStatusEventSink
VAR_INPUT
fbAdapter : FB_GseAdapterClass := (ipSystemClock:=THIS^, ipLinkStatus:=THIS^);
END_VAR
VAR
eLinkStatus : E_GseLinkStatus;
bSuccess : BOOL;
ipError : I_ServiceErrorClass;
bStart : BOOL := TRUE;
bStop : BOOL;
bUpdate : BOOL;
bSimulation : BOOL := TRUE;
tSimulation : TIME := T#5S;
fbUpdateTimer : TON;
bSync : BOOL := TRUE;
tSync : T_UtcTime := String_TO_UtcTime(in:='UT#2019-07-12-12:00:00.000000000|000|3');
fbClock : FB_GseSystemClock;
END_VAR
fbUpdateTimer(IN:=bSimulation, PT:=tSimulation);
IF fbUpdateTimer.Q THEN
fbUpdateTimer(IN:=FALSE);
fbUpdateTimer(IN:=bSimulation);
fbIED.IEDLD1.LEDGGIO1.SPCSO1.stVal.bValue:= NOT fbIED.IEDLD1.LEDGGIO1.SPCSO1.stVal.bValue;
fbIED.IEDLD1.LEDGGIO2.SPCSO1.stVal.bValue:= NOT fbIED.IEDLD1.LEDGGIO2.SPCSO1.stVal.bValue;
fbIED.IEDLD1.LEDGGIO3.SPCSO1.stVal.bValue:= NOT fbIED.IEDLD1.LEDGGIO3.SPCSO1.stVal.bValue;
fbIED.IEDLD1.LEDGGIO4.SPCSO1.stVal.bValue:= NOT fbIED.IEDLD1.LEDGGIO4.SPCSO1.stVal.bValue;
fbIED.IEDLD1.LEDGGIO5.SPCSO1.stVal.bValue:= NOT fbIED.IEDLD1.LEDGGIO5.SPCSO1.stVal.bValue;
fbIED.IEDLD1.LEDGGIO6.SPCSO1.stVal.bValue:= NOT fbIED.IEDLD1.LEDGGIO6.SPCSO1.stVal.bValue;
fbIED.IEDLD1.LEDGGIO7.SPCSO1.stVal.bValue:= NOT fbIED.IEDLD1.LEDGGIO7.SPCSO1.stVal.bValue;
fbIED.IEDLD1.LEDGGIO8.SPCSO1.stVal.bValue:= NOT fbIED.IEDLD1.LEDGGIO8.SPCSO1.stVal.bValue;
fbIED.IEDLD1.MMXU1.TotW.mag.f.fValue:= fbIED.IEDLD1.MMXU1.TotW.mag.f.fValue + 0.1;
IF fbIED.IEDLD1.XCBR1.Pos.stVal.eValue = E_AcsiDbpos.On THEN
fbIED.IEDLD1.XCBR1.Pos.stVal.eValue:= E_AcsiDbpos.Off;
ELSE
fbIED.IEDLD1.XCBR1.Pos.stVal.eValue:= E_AcsiDbpos.On;
END_IF
fbIED.IEDLD1.XCBR1.Pos.q.OldData:= NOT fbIED.IEDLD1.XCBR1.Pos.q.OldData;
fbIED.IEDLD1.XCBR1.Pos.t.SecondSinceEpoch:= fbIED.IEDLD1.XCBR1.Pos.t.SecondSinceEpoch + TIME#1S;
bUpdate:= TRUE;
END_IF
IF bSync THEN
bSync:= FALSE;
bSuccess:= fbClock.SetToUtcTime(in:=tSync);
ELSE
fbClock.Execute();
END_IF
bSuccess:= fbAdapter.Execute(ipError=>ipError);
IF bStart THEN
bStart:= FALSE;
bSuccess:= fbIED.IEDLD1.LLN0.gocb01.Publisher.Start(ipAdapter:=fbAdapter, ipError=>ipError);
bSuccess:= fbIED.IEDLD1.LLN0.gocb02.Publisher.Start(ipAdapter:=fbAdapter, ipError=>ipError);
bSuccess:= fbIED.IEDLD1.LLN0.gocb03.Publisher.Start(ipAdapter:=fbAdapter, ipError=>ipError);
ELSIF bStop THEN
bStop:= FALSE;
bSuccess:= fbIED.IEDLD1.LLN0.gocb01.Publisher.Stop(ipError=>ipError);
bSuccess:= fbIED.IEDLD1.LLN0.gocb02.Publisher.Stop(ipError=>ipError);
bSuccess:= fbIED.IEDLD1.LLN0.gocb03.Publisher.Stop(ipError=>ipError);
ELSIF bUpdate THEN
bUpdate:= FALSE;
bSuccess:= fbIED.IEDLD1.LLN0.gocb01.Publisher.Update(ipError=>ipError);
bSuccess:= fbIED.IEDLD1.LLN0.gocb02.Publisher.Update(ipError=>ipError);
bSuccess:= fbIED.IEDLD1.LLN0.gocb03.Publisher.Update(ipError=>ipError);
ELSE
bSuccess:= fbIED.IEDLD1.LLN0.gocb01.Publisher.Execute(ipError=>ipError);
bSuccess:= fbIED.IEDLD1.LLN0.gocb02.Publisher.Execute(ipError=>ipError);
bSuccess:= fbIED.IEDLD1.LLN0.gocb03.Publisher.Execute(ipError=>ipError);
END_IF
Der GSE-Baustein implementiert die „I_GseSystemClockEventSink“-Schnittstelle. Die Methode: „OnGetSystemTime“ gehört zu dieser Schnittstellenimplementierung und wird immer dann aufgerufen, wenn ein Publisher für eine GOOSE-Nachricht einen neuen Zeitstempel benötigt. Die SPS-Applikation könnte z. B. einen eigenen Zeitstempel, der vielleicht von einer GPS-Uhr stammt, der GOOSE-Nachricht übergeben. Im Beispiel wird eine einfache Software-Demo-Uhr für die Zeitstempelung verwendet.
METHOD OnGetSystemTime : BOOL
VAR_INPUT
ipAdapter : I_GseAdapterClass;
END_VAR
VAR_OUTPUT
tT : T_UtcTime;
END_VAR
VAR
END_VAR
OnGetSystemTime:= fbClock.OnGetSystemTime(ipAdapter:=ipAdapter, tT=>tT);
Der GSE-Baustein implementiert die „I_GseLinkStatusEventSink“-Schnittstelle. Die Methode: „OnLinkStatusChange“ gehört zu dieser Schnittstellenimplementierung und wird immer dann aufgerufen, wenn sich der Status der Netzwerkverbindung (am Netzwerkadapter) ändert. Die SPS-Applikation kann z. B. den Netzwerkverbindungsstatus via „eLinkStatus“-Variable abfragen oder überprüfen.
METHOD OnLinkStatusChange
VAR_INPUT
ipAdapter : I_GseAdapterClass;
eStatus : E_GseLinkStatus;
END_VAR
VAR
END_VAR
eLinkStatus:= eStatus;
Im Projektbaum unter dem Zweig I/O-Device finden Sie eine Netzwerkadapterinstanz mit dem Namen „GSE (RT-Ethernet Adapter)“. Diese Adapterinstanz muss entsprechend konfiguriert werden, d.h. die I/O-Konfiguration muss an die vorhandene Hardware und auf die Zielplattform, auf der das Projekt laufen soll, angepasst werden.
Eine erneute I/O-Konfiguration ist auch dann nötig, wenn Sie die Zielplattform wechseln. Diese Konfiguration muss manuell in TwinCAT XAE vorgenommen werden. Zusätzlich zu der I/O-Konfiguration des Netzwerkadapters muss ein Link zwischen dem Netzwerkadapter und den SPS-Bausteinen für die Goose-Kommunikation hergestellt werden. Mit dem Link können die vom Netzwerkadapter empfangenen Daten an die Instanz des Funktionsbausteins: „FB_[IEDName]Gse“ weitergeleitet werden. In umgekehrter Richtung kann die Instanz des Funktionsbausteins „FB_[IEDName]Gse“ die zu sendenden Daten an den Netzwerkadapter weiterleiten.
Hier finden Sie weitere Informationen: RT – Ethernet Adapter Konfiguration.