BaInterfaceHandler

Der BaInterfaceHandler ist eine Helferklasse, die die Verwaltung des BaInterfaces eines Controls übernimmt.

Mit Hilfe des BaInterfaces ist es möglich, mehrere Datenpunkte von einem Control mit nur einem Binding zu verknüpfen.

BaInterface

Das BaInterface-Attribut wird mit einem TcHmi-Symbol verbunden. Dieses Symbol muss einen bestimmten Aufbau haben, der durch die BaInterface-Definition beschrieben wird.

Beispiel

Das BaInterface einer Checkbox hat folgenden Aufbau:

export type BaInterface = {
    state: boolean,
    stateFeedback?: boolean,
    activeText?: string,
    inactiveText?: string,
}

Damit das verbundene Symbol für das BaInterface der Checkbox gültig ist, muss das Symbol die beschriebenen Untersymbole mit dem entsprechenden Datentyp haben.

BaInterfaceDefinition

Ein Control, das den BaInterfaceHandler verwendet, muss das Interface IUsesBaInterface<T> implementieren.

Der Typ-Parameter T soll dabei den Aufbau des verwendeten BaInterfaces beschreiben.

Hier am Beispiel des Datentyps Checkbox.BaInterface:

export class Checkbox implements IUsesBaInterface<Checkbox.BaInterface>

Da TypeScript Typen zur Laufzeit von JavaScript nicht interpretiert werden können, ist es notwendig die BaInterfaceDefinition als Konstante zu definieren.

Hier muss der Datentyp des jeweiligen Elements angegeben werden und über die Eigenschaft optional können optionale Elemente des BaInterfaces definiert werden.

Optionale Elemente werden bei der späteren Validierung des BaInterfaces nicht berücksichtigt. Falls benötigte Elemente bei der Validierung nicht gefunden werden, kommt es zu Fehlermeldungen und das BaInterface wird nicht weiterverarbeitet.

export const BaInterfaceDef: BaInterfaceDefinition<BaInterface> = {
    state: {
        type: 'boolean'
    },
    stateFeedback: {
        type: 'boolean',
        optional: true
    },
    activeText: {
        type: 'string',
        optional: true
    },
    inactiveText: {
        type: 'string',
        optional: true
    }
};

Es ist möglich mehrere Datentypen anzugeben.

command: {
    type: ['number', 'boolean']
}

BaInterfaceSymbolNames

Die Standardwerte der BaInterfaceSymbolNames, sowie die erwarteten Datentypen sind im Tooltipp des Dialoges zum Einstellen der BaInterfaceSymbolNames zu finden.

BaInterfaceHandler 1:

Damit der BaInterfaceHandler auf die entsprechenden Untersymbole des BaInterfaces zugreifen kann, ist es notwendig für jedes Element des Interfaces einen Symbolnamen anzugeben. Der Symbolname entspricht dabei dem Namen der Variablen in dem verbundenen Funktionsblock / Struktur. Dies kann z. B. durch eine Variable Checkbox.BaInterfaceSymbolNames geschehen:

export let BaInterfaceSymbolNames: BaInterfaceSymbolNames<BaInterface> = {
    state: {
      symbolName: 'State'
    },
    stateFeedback: {
      symbolName: 'StateFeedback'
    },
    activeText: {
      symbolName: 'ActiveText'
    },
    inactiveText: {
      symbolName: 'InactiveText'
    }
}

Der Symbolname soll bei der späteren Verwendung angepasst werden können, sofern das Symbol in dem verbundenen Funktionsblock/Struktur anders heißt (z. B. symbolName: "bState" ).

Ebenfalls ist es möglich Untersymbole zu nutzen. Liegt der State z. B. in einer Struktur oder einem Funktionsblock innerhalb des verbundenen Symbols kann auf diesen zugegriffen werden (z. B. symbolName: "Command::bValueRm").

Für das Überschreiben dieser Standard-Symbolnamen gibt es zwei Möglichkeiten, die im Folgenden erläutert werden.

Attribut BaInterfaceSymbolNames

Da im Interface IUsesBaInterface<T> bereits die Setter und Getter für die BaInterfaceSymbolNames definiert sind, kann in der Description.json das folgende Attribut definiert werden, damit die Symbolnamen aus dem Designer heraus geändert werden können:

{
  "name": "data-tchmi-ba-interface-symbol-names",
  "displayName": "BaInterfaceSymbolNames",
  "propertyName": "BaInterfaceSymbolNames",
  "propertySetterName": "setBaInterfaceSymbolNames",
  "propertyGetterName": "getBaInterfaceSymbolNames",
  "visible": true,
  "themeable": "None",
  "displayPriority": 61,
  "type": "tchmi:framework#/definitions/TcHmi.BuildingAutomation.Common.Checkbox.BaInterfaceSymbolNames",
  "category": "BaData",
  "description": "Symbol names for the interface symbol.",
  "requiredOnCompile": false,
  "readOnly": false,
  "bindable": true,
  "heritable": true,
  "defaultValue": null,
  "defaultValueInternal": null
}

Der

type

ist dabei in der Types.Schema.json zu definieren.

Überschreiben in onInitialized

Wenn die Symbolnamen für alle Controls überschrieben werden sollen, ist es nicht praktikabel das BaInterfaceSymbolNames-Attribut von jedem Control einzeln zu editieren.

Die Standard-Symbolnamen können global im onInitialized Event überschrieben werden. Dazu wird eine CodeBehind-Funktion mit folgendem Inhalt angelegt:

module TcHmi {
    var destroyOnInitialized = TcHmi.EventProvider.register('onInitialized', function (e, data) {
        e.destroy();
        
        // overwrite BaInterfaceSymbolNames of the Checkbox
        BuildingAutomation.Controls.Checkbox.BaInterfaceSymbolNames = {
            state: {
                symbolName: 'bState'
            },
            stateFeedback: {
                symbolName: 'bStatFdb'
            },
            activeText: {
                 symbolName: 'sActiveText'
            },
            inactiveText: {
                symbolName: 'sInactiveText'
            }
        }
    });
}
BaInterfaceHandler 2:

Es ist nicht notwendig die Symbolnamen aller Elemente zu setzen. Es sind nur die Elemente zu setzen, die nicht als optional gekennzeichnet wurden.

Initialisierung

Der BaInterfaceHandler muss in der __prevInit() Methode des Controls initialisiert werden. Bei der Initialisierung sind folgende Schritte zu durchlaufen.

// Create instance of BaInterfaceHandler
this.baInterfaceHandler = new BaInterfaceHandler<Checkbox.BaInterface>(this);
// Set the BaInterfaceDefinition
this.baInterfaceHandler.baInterfaceDefinition = Checkbox.BaInterfaceDef;
// Set the default symbol names
this.setBaInterfaceSymbolNames(Checkbox.BaInterfaceSymbolNames);

Verwendung

Die Implementierung des Setters für das BaInterface-Attribut kann wie folgt aussehen:

public setBaInterface(p: BaInterfaceSymbol<Checkbox.BaInterface> | null | undefined): this {
    this.baInterfaceHandler.setBaInterfaceSym(p, () => {
        // do work with the validated BaInterface
    });
    return this;
}

public getBaInterface() {
    return this.baInterfaceHandler.getBaInterfaceSym();
}

Hier ist zu sehen, dass für den Setter die Methode setBaInterfaceSym()des BaInterfaceHandlers verwendet wird. Diese erwartet neben dem Symbol auch noch eine Processor-Methode, die aufgerufen wird, wenn das BaInterfaceSymbol validiert wurde oder sich die BaInterfaceSymbolNames geändert haben.

Die Setter und Getter für das BaInterfaceSymbolNames-Attribut können wie folgt implementiert werden:

public setBaInterfaceSymbolNames(p: BaInterfaceSymbolNames<Checkbox.BaInterface> | BaInterfaceSymbolNamesDesigner | null | undefined): this {
    if (p != null)
        this.baInterfaceHandler.updateSymbolNames(BaInterfaceHandler.convertToBaInterfaceSymbolNames(p));
    return this;
}

public getBaInterfaceSymbolNames(): BaInterfaceSymbolNames<Checkbox.BaInterface> | null | undefined {
    return this.baInterfaceHandler.baInterfaceDescription;

Methoden

Im Folgenden werden die wichtigsten Methoden des BaInterfaceHandlers beschrieben.

Name

Beschreibung

hasSubSymbol

Überprüft, ob das BaInterface ein bestimmtes Unterelement hat. Diese Methode muss verwendet werden, wenn optionale Elemente gelesen oder geschrieben werden sollen.

writeSubSymbol

Schreibt den Wert eines Unterelements.

watchSubSymbol

Legt eine Subscription für ein Unterelement an.

updateSymbolNames

Aktualisiert die Symbolnamen der Unterelement des BaInterfaces.

convertToBaInterfaceSymbolNames

Konvertiert den Datentyp BaInterfaceSymbolNamesDesigner in BaInterfaceSymbolNames.

Wird der Methode bereits der Datentyp BaInterfaceSymbolNames übergeben, wird keine Konvertierung durchgeführt und das Objekt direkt zurückgegeben.