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.