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