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.