01/10/2024

Creating an HTML5 Control for ctrlX PLC Engineering and CODESYS WebVisu

Introduction

An unheralded feature of CODESYS is the option to develop user-defined HTML5 controls for WebVisu, thereby leveraging the power of JavaScript and CSS. This document gives a brief overview of the process of creating such controls or "widgets" for ctrlX PLC Engineering. These controls may be incorporated into the internal visualizations of ctrlX PLC Engineering or CODESYS WebVisu screens.

Overview

As an example, we will create an HTML5 control based on the scalable vector graphic (svg) pictured below. The control is meant to give a visual representation of the state of charge of a battery.  The control will also indicate whether the battery is currently being charged or not.  The free software tool Inkscape was used to generate the image.

Scalable vector graphic used as basis for our HTML5 control (left); sample output at various battery levels (right)

We will modify the appearance of the svg based on two inputs:

  • battery level or "state of charge" (%)
  • charging or discharging

The intended visual output is shown in the attached

HTML5_BatteryControl.mp4
175.77KB
.  Note that the battery level is shown in increments of 10% and is color-coded.  If the level drops below 10%, the level bar blinks.

JavaScript

Despite the name, HTML5 controls for ctrlX PLC Engineering or WebVisu do not incorporate directly any HTML markup.  Rather, all HTML components are defined in JavaScript. In the code snippet below we define our svg container tag, together with paths that describe the outline of the image and the central "bolt".  We also define the 10 rectangles stacked one on top of the other which will be colored to indicate the current battery level.  The paths are copied directly from the svg source file (viewing it in a text editor like Notepad).

HTML5_BatteryElementWrapper = function(idGenerator) {

  this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  this.svg.setAttribute("viewBox", "0 0 50 100")

  this.outline = document.createElementNS("http://www.w3.org/2000/svg",
    "path");
  this.outline.setAttributeNS(null, "d",
    "m 15.468947,1.162241 v 9.464372 H 2.6369413 c -0.9974863,0 -1.8004088,0.802922 -1.8004088,1.800408 v 84.609918 c 0,0.99749 0.8029225,1.80082 1.8004088,1.80082 H 47.363063 c 0.99748,0 1.800405,-0.80333 1.800405,-1.80082 V 12.427021 c 0,-0.997486 -0.802925,-1.800408 -1.800405,-1.800408 H 34.140256 V 1.162241 Z"
    );

  this.bolt = document.createElementNS("http://www.w3.org/2000/svg", "path");
  this.bolt.setAttributeNS(null, "d",
    "m 28.913606,26.038854 -1.95511,19.486785 7.82044,0.06431 -13.68575,27.371519 1.9551,-19.655011 -7.82039,0.103928 13.68571,-27.371525"
    );
  this.bolt.setAttribute('id', 'is_charging');
  this.bolt.classList.add('bolt');

  this.g = document.createElementNS("http://www.w3.org/2000/svg", "g");

  this.rect = [10]

  for (let i = 0; i < 10; i++) {
    let _id = `level_${10 + 10*i}`

    this.rect[i] = document.createElementNS("http://www.w3.org/2000/svg",
      "rect");
    this.rect[i].setAttribute('x', 2.5);
    this.rect[i].setAttribute('y', 90 - i * 8.5);
    this.rect[i].setAttribute('width', 45.0);
    this.rect[i].setAttribute('height', 8.0);
    this.rect[i].setAttribute('id', _id);
    this.rect[i].classList.add('level')


    this.g.appendChild(this.rect[i]);
  }

  this.svg.appendChild(this.outline);
  this.svg.appendChild(this.g);
  this.svg.appendChild(this.bolt);
  document.body.appendChild(this.svg);
};

In our JavaScript file we also define prototype functions that will be called whenever the associated input (i.e. battery level or charging state) changes.  Note that in each method, we set a style (fill, opacity) or add or remove a class (’blink’) based on the input value, thus altering the appearace of the svg element in question.

HTML5_BatteryElementWrapper.prototype = {
  setLevel: function(value) {
    let _temp = Math.floor(value / 10);

    let _color = '#cccccc';
    _color = _temp > 4 ? 'green' : _temp > 2 ? 'yellow' : 'red';

    for (let i = 0; i < _temp; i++) {
      this.rect[i].style.fill = _color;
    }

    for (let i = _temp; i < 10; i++) {
      this.rect[i].style.fill = '#cccccc';
    }

    _temp == 0 ? this.rect[0].classList.add('blink') : this.rect[0]
      .classList.remove('blink');
  },

  isCharging: function(value) {
    this.bolt.style.opacity = (value > 0 ? 1.0 : 0.1);
  }
};


CSS

We also include a cascading style sheet with our control. The classes blink, bolt and level, referred to in the JavaScript code above, allow us to set the default appearance of the sub-elements. Note that we also define here the transition property, allowing the control to transition smoothly from one color to another. 

.level {
    stroke: #333333;
    stroke-width: 1;
    stroke-dasharray: none;
    paint-order: stroke fill markers;
    stroke-opacity: 1;
    fill: #333333;
    transition: fill 0.5s ease;
}
.bolt {
    stroke-opacity: 1;
    fill: white;
}
@keyframes blink {
    0%,
    100% {
        fill: #cccccc;
    }
    50% {
        fill: red;
    }
}
.blink {
    animation: blink 1s infinite;
}


HTML5 Control Editor

HTML5 Control Editor is a small utility that will allow us to link our Javascript and CSS files, together with some metadata, in a descriptor file (type *.html5control.xml) that is importable into the Visual Element Repository in ctrlX PLC Engineering. This software is included in the ctrlX WORKS distribution.

A sample configuration is shown below. Particularly important is the configuration of the control properties on the central tab. Here we configure the control's inputs (Level, IsCharging) and associate these with the methods defined in our JavaScript file (setLevel, isCharging). This interface is roughly what the user sees when configuring the properties of a control instance in ctrlX PLC Engineering.

General: Provide control widget metadata (Company, Name, Description, etc.) and attach Javascript and CSS files
Control Properties: Define the control interface and the associated call methods
Localization: Define localization values for supported languages

File Structure

The finished control is a collection of files all stored in a single folder.  These include the JavaScript and CSS files discussed previously, the descriptor file, as well as some additional files required by the software.

HTML5 control file structure. ControlTexts.csv is autogenerated by HTML5 Control Editor based on the localization configuration. File image.svg is the file used by ctrlX PLC Engineering to represent the control in offline mode.

Visual Element Repository

To use the control, import it into the Visual Element Repository in ctrlX PLC Engineering under Tools.  (Note that the repository is available only when no project is open.)

Use the Visual Element Repository to manage all user-defined HTML5 controls.. See the radio button marked "HTML5 Controls".

Once imported, the HTML5 control should appear in the Visualization Toolbox under the chosen Toolbox Category provided that option "Support client animations and overlay of native elements" is enabled in the Visualization Manager.  Note that this option is available only if a WebVisu object as been added to the Visualization Manager.  (As a consequence, licenses CODESYS WebVisu and CODESYS PLC Standard are required.)  Use the control as you would any of the standard visualization elements.

 

User-defined HTML5 controls are incorporated automatically into the Visualization Toolbox.

For more information, see the CODESYS documentation here.  Additional examples are available here.

Note that HTML5ControlEditor.exe distributed with ctrlX WORKS 1.18.1 was used to prepare the HTML5 control described here. In typical installations this file may be found in C:\Program Files\Rexroth\ctrlX WORKS\StudioPlc\Common.

See

Resources.zip
407.19KB
for full source code.

3
HTML5_BatteryControl.mp4
175.77KB
Resources.zip
407.19KB

Latest published/updated articles

Types
How-to
Categories
HMI
Attachments
Project
Video