Deklaration von Variablen, die auf einem Interface basieren

Syntax
VAR | VAR_INPUT | VAR_OUTPUT
  name_1, name_2, ..., name_n : interface;
(* Additional pieces of data, such as partial addresses, are also possible for the variables. *)
END_VAR
 
TYPE
name_1: STRUCT
  name_e1 : interface; (* Additional pieces of data, such as partial addresses, are also possible for the structure element. *)
  ...
  END_STRUCT; 
END_TYPE
Bedeutung

Deklaration einer oder mehrerer →Variablen, die auf einem →Interface basieren (ein Feature der →objektorientierten Programmierung)
Solche Variablen verhalten sich wie Referenz-Variablen (siehe "Deklaration von Referenz-Variablen (inkl. Zuweisungen darauf)" für Details). Das bedeutet, solche Variablen werden mit dem Wert NULL initialisiert (d.h., eine Variable, die auf einem Interface basiert, verweist auf nichts).

Einschränkungen und Hinweise zur Verwendung

  • Für Variablen, die auf einem Interface basieren, sind die folgenden Möglichkeiten nicht zulässig, auch wenn der jeweilige Abschnitt selbst diese Möglichkeit unterstützt:

  • Für den Zugriff auf eine Methode des Interfaces über die Variable geben Sie den Namen der Variable (z.B. IN1) und den Namen der Methode (z.B. SwitchState) durch das Zeichen . voneinander getrennt ein.Beispiel: IN1.SwitchState

    Beachten Sie beim Zugriff auf Variablen basierend auf einem Interface mit dem Wert NULL:

    Neuron Power Engineer prüft diese ST-Konstrukte nicht bei der Eingabe im ST-Editor, sondern erst beim Ausführen der Anwendung. Dabei erfolgt diese Fehlerbehandlung:

    1. Der Ausgang ENO der umfassenden →POE wird auf den Wert FALSE (bzw. eine Entsprechung) gesetzt.

    2. Der restliche Baustein-Code wird nicht mehr ausgeführt.

    Neuron empfiehlt Ihnen, Code in Ihrer Anwendung (z.B. IF-Anweisungen) einzufügen, um die Verwendung von solchen Variablen mit dem Inhalt NULL zu erkennen. Derzeit bietet lNeuron Power Engineer jedoch noch keine Möglichkeit, um dies im ST-Code zu prüfen

  • Mit Hilfe eines Zuweisungsversuchs erhalten Sie für Variablen basierend auf einem Interface entweder eine gültige Referenz auf die referenzierte Instanz oder das Ergebnis NULL.

 

Die Deklaration von Variablen basierend auf einem Interface ist innerhalb dieser Abschnitte möglich:
(Informieren Sie sich in der jeweiligen Beschreibung zum Abschnitt über evtl. zusätzliche Möglichkeiten für die Variable.)

Abschnitt

Die Deklaration der Variable erfolgt als:

VAR ... END_VAR

interne Variable (siehe "Deklaration von internen Variablen")

VAR_INPUT ... END_VAR

Eingangsvariable (siehe "Deklaration von Eingangsvariablen in ST")
Dies ist nicht möglich, wenn eine →Klasse das Interface implementiert.

VAR_OUTPUT ... END_VAR

Ausgangsvariable (siehe "Deklaration von Ausgangsvariablen in ST")
Dies ist nicht möglich, wenn eine →Klasse das Interface implementiert.

TYPE  name_1: STRUCT ... END_STRUCT;END_TYPE

als Strukturelement (siehe "Deklaration eines strukturierten Datentyps in ST")

Abweichung zur IEC-Norm

In Neuron ist es nicht möglich, Variablen basierend auf einem Interface im Abschnitt für →temporäre Variablen (VAR_TEMP ... END_VAR) zu deklarieren.

Zuweisungen auf Variablen basierend auf einem Interface

→Zuweisungen auf Variablen basierend auf einem Interface sind – wie üblich – mit dem Zuweisungsoperators := möglich. Zusätzlich unterstützt Neuron Power Engineer auch den Operator ?= (siehe "Zuweisungsversuch in ST" für Details).

Syntax für Zuweisungen:

Syntax
interface_variable_1 := function_block_instance_1;

interface_variable_1 := class_instance_1;

interface_variable_1 := interface_variable_2;
interface_variable_1 := NULL;

Der Ausdruck auf der rechten Seite des Zuweisungsoperators ":=" darf eines der folgenden Konstrukte sein:

  • eine →Instanz eines →Funktionsbaustein-Typs oder einer →Klasse, der/die das gleiche Interface implementiert oder der/die von einem Basis-Funktionsbaustein oder einer Klasse abgeleitet wurde und dieser Basis-Funktionsbaustein bzw. diese Klasse das gleiche Interface implementiert.

  • eine andere deklarierte Variable basierend auf dem gleichen oder einem abgeleiteten Interface

  • NULL

Beispiele für Verwendung von Interfaces und Variablen basierend auf diesen Interfaces (inkl. Zuweisungen)

Beispiel 1

INTERFACE ISwitch   (* declaration of an interface with a method prototype *)  
  METHOD SwitchState
    VAR_INPUT
      STATE : BOOL;
    END_VAR
  END_METHOD
END_INTERFACE
 
INTERFACE IValve   (* declaration of an interface with a method prototype *) 
  METHOD Open
  END_METHOD 
END_INTERFACE
 
FUNCTION_BLOCK MySwitch IMPLEMENTS ISwitch, IValve   (* declaration of a function block that implements the 2 interfaces *)
  VAR
    switchState : BOOL;
    valveOpen : BOOL;
  END_VAR
  METHOD PUBLIC SwitchState   (* within this function block: declaration of a method of the interface *) 
    VAR_INPUT
      STATE : BOOL;
    END_VAR
      switchState := STATE;
  END_METHOD
  METHOD PUBLIC Open   (* within this function block: declaration of a method of the interface *) 
    valveOpen := TRUE;
  END_METHOD 
END_FUNCTION_BLOCK
 
FUNCTION_BLOCK myFB
  VAR_INPUT
    IN1 : ISwitch;   (* declaration of a variable based on an interface *)
    IN2 : IValve;    (* declaration of a variable based on an interface *)
    IN3 : BOOL;
  END_VAR
  
  IN1.SwitchState(STATE := IN3);   (* accessing a method of an  interface via the variable "IN1" *)
 
  IF IN3 THEN
    IN2.Open();                    (* accessing a method of an interface via the variable "IN2" *)
  END_IF;
END_FUNCTION_BLOCK
 
PROGRAM TestSwitches
  VAR
    switchVal : MySwitch;    (* declaration of a function block instance *)
    fbinst : myFB;           (* declaration of a function block instance *)
    i_Switch : ISwitch;      (* declaration of a variable based on an interface *)
  END_VAR
 
  i_Switch := switchVal;     (* assigning the function block instance to the variable based on an interface *) 
 
  fbinst(IN1 := i_Switch, IN2 := switchVal, IN3 := TRUE);   (* calling a function block instance *)
END_PROGRAM

Im Vergleich:

  • Die obige Zuweisung i_Switch := switchVal; ist korrekt. Grund: Die Funktionsbaustein-Instanz switchVal wird der Variablen i_Switch zugewiesen und diese Variable basiert auf dem Interface ISwitch. Der Funktionsbaustein MySwitch implementiert dieses Interface ISwitch.

  • Die Zuweisung i_Switch := fbinst; würde jedoch als fehlerhaft gekennzeichnet werden. Grund: Die Funktionsbaustein-Instanz fbinst wird zwar der gleichen Variable i_Switch zugewiesen. Der Funktionsbaustein myFB implementiert das Interface ISwitch jedoch nicht.

Beispiel 2

INTERFACE ROOM    (* declaration: interface ROOM with 2 methods *) 
  METHOD DAYTIME   END_METHOD   // called during day-time
  METHOD NIGHTTIME END_METHOD   // called during night-time
END_INTERFACE
 
FUNCTION_BLOCK LIGHTROOM IMPLEMENTS ROOM    (* declaration: function block LIGHTROOM that implements the interface *)
  VAR
    LIGHT : BOOL;
  END_VAR
  METHOD PUBLIC DAYTIME
    LIGHT:= FALSE;
  END_METHOD
  METHOD PUBLIC NIGHTTIME
    LIGHT:= TRUE;
  END_METHOD
END_FUNCTION_BLOCK
 
FUNCTION_BLOCK ROOM_CTRL   (* declaration: function block ROOM_CTRL *)
  VAR_INPUT RM : ROOM; END_VAR  // interface ROOM as type of the input variable RM
  VAR_EXTERNAL
    Actual_TOD : TOD; END_VAR   // global time definition
        
  IF (RM = NULL) // Important: test valid reference!
  THEN RETURN;
  END_IF;
  IF Actual_TOD >= TOD#20:15:00 OR
     Actual_TOD <= TOD#06:00:00
  THEN RM.NIGHTTIME();          // call method of RM
  ELSE RM.DAYTIME();
  END_IF;
END_FUNCTION_BLOCK
 
PROGRAM B  // usage
  VAR                           // instantiations
    My_Room : LIGHTROOM;        // see LIGHTROOM IMPLEMENTS ROOM
    My_Room_Ctrl : ROOM_CTRL;   // see ROOM_CTRL above
  END_VAR
  VAR_GLOBAL
    Actual_TOD : TOD; END_VAR
  
  My_Room_Ctrl(RM:= My_Room);   // call of function block instance with passing the FB-instance My_Room to input RM of the interfaces ROOM
END_PROGRAM