Handling of complex data types
In many cases a control is intended to work with a complex data type, e.g. from the PLC. Alternatively, control configurations are to be created as an object or array. To do this, a JSON schema must be created and referenced accordingly in description.json.
However, the information in the schemas cannot be used directly in TypeScript. To do this, a TypeScript interface must be defined manually in your own source code.
A namespace
must be added in parallel to module
of the project name. The TypeScript interface can then be defined here.
module TcHmi {
export module Controls {
export module FrameworkPrj1 {
export class FrameworkPrj1Control extends TcHmi.Controls.System.TcHmiControl {
// more here
}
}
export namespace FrameworkPrj1 {
export interface plcValue {
/** Count Down on rising edge */
CountDown: boolean;
/** Load Start Value */
LOAD: boolean;
/** Start Value */
PV: number;
}
}
registerEx('FrameworkPrj1Control', ...
}
}
The data type is now known under the name TcHmi.Controls.FrameworkPrj1.plcValue
. Since the control is in the same execution context (scope), the type with the identifier FrameworkPrj1.plcValue
can be accessed.
An example of an attribute setter and process function is shown below:
protected __value: FrameworkPrj1.plcValue | undefined;
public setValue(valueNew: FrameworkPrj1.plcValue | null) {
// convert the value with the value converter
let convertedValue = TcHmi.ValueConverter.toObject<typeof valueNew>(valueNew);
// check if the converted value is valid
if (convertedValue === null) {
// if we have no value to set we have to fall back to the defaultValueInternal from description.json
convertedValue = this.getAttributeDefaultValueInternal('Value') as FrameworkPrj1.plcValue;
}
if (tchmi_equal(convertedValue, this.__value)) {
// skip processing when the value has not changed
return;
}
// remember the new value
this.__value = convertedValue;
// inform the system that the function has a changed result.
TcHmi.EventProvider.raise(this.__id + '.onPropertyChanged', { propertyName: 'Value' });
// call process function to process the new value
this.__processValue();
}
protected __processValue() {
if (this.__value) {
this.__value.CountDown; // known to TypeScript
this.__value.PV; // even tooltip “Start Value” is shown
}
}
Custom control administration objects can be defined and used in the same way.