WebView EWO JavaScript Interface

The WebView EWO JavaScript Interface is a bidirectional communication interface between JavaScript and Control. It allows the data exchange between the WebView EWO, the UI and Control.

Requirements

Following requirements must be met to use the WebView EWO JavaScrip Interface:

  • A valid WinCC OA UI license must be available
  • An active web server that can access your project. For using the WinCC OA web server e.g. a new CTRL manager with the parameter "webclient_http.ctl" can be started.
  • The JavaScript compatibility of the WebView EWO can be testes using the page "kangax.github.io/compat-table"

Configuration

The JavaScript Interface can be used within the WebView EWO. Using the function loadSnippet a corresponding HTML page can be loaded which contains and executes the JavaScript Code. By calling the function loadSnippet the library oaJsApi is available.

This HTML file needs to fulfill following criteria:

  • JavaScript Code must be placed within a correctly formed <script> tag.
  • All main HTML elements can be used.
  • The file must not contain <html>,<body> or <header> tags.
  • The file ending must be ".html".

Examples can be found within the JavaScript Interface Examples page or the JavaScript Demo Panels

Please note that when using the loadSnippet function the url parameter of the EWO is no longer used.

Usage inside of the ULC UX

For using your JavaScript code inside of the ULC UX on the client side the EWO property ulcClientSideWidget must be enabled. This allows the browser to download/access and perform the JavaScript code from within the browser instead of the UI manager on the server side.

This reduces the load for the server as well as enables the usage of the browsers JavaScript engine. Additionally a communication between multiple client side EWOs can be used without the explicit need to contact the server which further reduces the network load if no server data is required.

When using the JavaScript Interface within the ULC UX (the combination of loadSnippet() and ulcClientSideWidget = true) the Web Socket enables local access to the oaJsApi which can potentially be used to e.g. directly manipulate data point values from within the developer console of a web browser.

Please note that when using ulcClientSideWidget = true the code is executed on the client and therefor localization information (time, time zone, language, etc.) from the client is used.

JavaScript Interface

To access your project data from within JavaScript the WebView EWO provides the oaJsApi library. The library is automatically loaded if a JavaScript Snippet is added to the EWO using the loadSnippet function. The available functions can than be addressed within JavaScript by using the oaJsApi.<function name> syntax.

The oaJsApi provides a specific set of functions which can be found within the API documentation.

Notes

Following notes should be considered when working with the JavaScript interface:

  • It is recommended for data point functions to group the transferred elements into a single function call instead of using one function call per data point. This will significantly increase the throughput of data point values. This also applies for your native CTRL development but for JavaScript a higher impact can be seen.
  • To prevent the error "Values were discarded" when using the function toCtrl and sending a high number of messages from the JavaScript to the UI the config entry [general]ctrlMaxPendings value must be increased, e.g. "ctrlMaxPendings = 10000"
  • When using the ULC UX with one or more active ulcClientSideWidgets and a high number of requests in a short period of time, the maximum available transfer rate might be reached which can have am influence on the regular ULC UX communication.

Restrictions

Following restrictions must be considered when using the JavaScript interface:

  • The JavaScript Interface is not available to be used within the Mobile UI Application or the ULC UX. These features will only support the JavaScript interface within the WebView EWO in a later release of the product.
  • The data types bit32 and bit64 must be stated as bit strings, e.g. "1010101011" instead of 683 or "0x2AB"
  • The data type blob cannot be directly used. Manually encoding the data type is required, see "Encoding of Data Type BLOB"
  • The values of "Infinity", "Negative Infinity" and "Not-A-Number" (NaN) are not supported for the JavaScript Interface. They will be replaced with a value of "null" or a conversion error is triggered.

Interface Demonstration Panels

Demonstration and getting started example panel for the JavaScript interface can be found under /panels/examples/html/js/.

Data Type Mappings

Following mapping is used between the available CTRL data types and the JavaScript data types:

CTRL Data Type JavaScript Data Types Allowed Value Ranges
blob string -
bool bool true or false
float number -1.79769e+308 to +1.79769e+308
uint number 0 to +4,294,967,295
int number -2,147,483,648 to +2,147,483,647
long number -9,007,199,254,740,992 (JavaScript: Number.MIN_SAFE_INT) to +9,007,199,254,740,991 (JavaScript: Number.MAX_SAFE_INT)
ulong number 0 to +9,007,199,254,740,991 (JavaScript: Number.MAX_SAFE_INT)
string string -
char number 0-255
time string
anytype
mixed
dyn_string array
dyn_int array
dyn_float array
mapping object
bit32 string 0 to +4,294,967,295; must be stated as bit string
bit64 string 0 to +18,446,744,073,709,551,615; must be stated as bit string
shape string Name of the shape
dpidentifier string -
langString string String of the current language

Encoding of Data Type BLOB

Due to technical restrictions a direct transfer of the blob data type is not possible between Control and JavaScript. To use blobs a manual encoding to Base64 is required.

For data point elements of type "blob" this encoding/decoding is not required.

The following example implementation demonstrates how to correctly encode the blobs.

CTRL

mapping getOutArgsObject()
{
  blob blob0="01000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
  blob blob1="02000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";
  dyn_string blobArray = new dyn_string(base64Encode(blob0));
  dynAppend(blobArray,base64Encode(blob1));
  mapping outArgsObject = makeMapping(
  "blob", base64Encode(blob0),
  "blobList", blobArray);
  return outArgsObject;
}

JavaScript:

function msgReceived(arg)
{
  var decoded = window.atob(arg.blob);
  var decoded1 = window.atob(arg.blobList[0]);
}