BaInterfaceHandler

The BaInterfaceHandler is a helper class that handles the management of the BaInterfaces of a control.

With the help of the BaInterfaces it is possible to link several data points from one control with only one binding.

BaInterface

The BaInterface attribute is associated with a TcHmi symbol. This symbol must have a certain structure, which is described by the BaInterface definition.

Sample

The BaInterface of a checkbox has the following structure:

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

For the connected symbol to be valid for the BaInterface of the checkbox, the symbol must have the described subsymbols with the corresponding data type.

BaInterfaceDefinition

A control that uses the BaInterfaceHandler must implement the interface IUsesBaInterface<T>.

The type parameter T should describe the structure of the used BaInterfaces.

Here using the data type Checkbox.BaInterface:

export class Checkbox implements IUsesBaInterface<Checkbox.BaInterface>

Since TypeScript types cannot be interpreted by JavaScript at runtime, it is necessary to define the BaInterfaceDefinition as a constant.

Here the data type of the respective element must be specified and optional elements of the BaInterfaces can be defined via the property optional.

Optional elements are not considered in the later validation of the BaInterfaces. If required elements are not found during validation, error messages will occur and the BaInterface will not be processed further.

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

It is possible to specify multiple data types.

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

BaInterfaceSymbolNames

So that the BaInterfaceHandler can access the corresponding sub-symbols of the BaInterfaces, it is necessary to specify a symbol name for each element of the interface. The symbol name corresponds to the name of the variable in the connected function block / structure. This can be done, for example, by a variable Checkbox.BaInterfaceSymbolNames :

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

The symbol name should be able to be adapted for later use if the symbol is called differently in the connected function block/structure (e.g. symbolName: "bState" ).

It is also possible to use subsymbols. If the state is e.g. in a structure or a function block within the connected symbol, it can be accessed (e.g. symbolName: "Command::bValueRm").

There are two possibilities for overwriting these default symbol names, which are explained below.

Attribute BaInterfaceSymbolNames

Since the setters and getters for the BaInterfaceSymbolNames are already defined in the interface IUsesBaInterface<T>, the following attribute can be defined in the Description.json so that the symbol names can be changed in the designer:

{
  "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
}

The

type

is to be defined in the Types.Schema.json.

Overwrite in onInitialized

If the symbol names for all controls are to be overwritten, it is not practical to edit the BaInterfaceSymbolNames attribute of each control separately.

The default symbol names can be globally overwritten in the onInitialized event. For this purpose, a CodeBehind function is created with the following content:

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

It is not necessary to set the symbol names of all elements. Only the elements that have not been marked as optional are to be set.

Initialization

The BaInterfaceHandler must be initialized in the __prevInit() method of the control. The following steps must be performed during initialization.

// 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);

Use

The implementation of the setter for the BaInterface attribute can look like this:

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();
}

Here you can see that for the setter the method setBaInterfaceSym()of the BaInterfaceHandler is used. In addition to the symbol, this also expects a Processor method that is called when the BaInterfaceSymbol has been validated or the BaInterfaceSymbolNames have changed.

The setters and getters for the BaInterfaceSymbolNames attribute can be implemented as follows:

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;

Methods

The most important methods of the BaInterfaceHandler are described below.

Name

Description

hasSubSymbol

Checks if the BaInterface has a specific subelement. This method must be used if optional elements are to be read or written.

writeSubSymbol

Writes the value of a subelement.

watchSubSymbol

Creates a subscription for a subelement.

updateSymbolNames

Updates the symbol names of the BaInterface subelements.

convertToBaInterfaceSymbolNames

Converts the data type BaInterfaceSymbolNamesDesigner to BaInterfaceSymbolNames.

If the data type BaInterfaceSymbolNames is already passed to the method, no conversion is performed and the object is returned directly.