This topic addresses communications between the client web page and the server, and also how the display list is used to update the screens with the new data.
Communications between the client (web browser) and the HMI server takes place over HTTP. HTTP is the standard web protocol carried over TCP/IP. The client regularly polls the server requesting data which it displays on its web page. Unlike traditional web pages, this polling takes place continuously, not just when the web page is loaded. This is often called "AJAX" (Asynchronous Javascript And XML). The process works as follows:
Synchronous communications is where the client (web browser) waits for a response from the server before proceeding with any other tasks it may have. Asynchronous communications is where the client does not wait for the response before proceeding with other tasks. Although the first "A" in "AJAX" stands for "Asynchronous", there is no requirement for the communications to actually be asynchronous. The HMI protocol communications library allows for both options.
Synchronous communications is simpler than asynchronous communications and may be easier to understand and debug. If the client and server have fast and reliable communications with one another then asynchronous communications has no real advantage. Asynchronous communications is better where the communications may be unreliable. If a request fails, the client can automatically try again instead of waiting indefinitely for a response.
The data to be polled is defined by HMI "tags". A tag is an alias for a server data table memory address. The HMI server may obtain this data from another device (e.g. a PLC or I/O field device), but ultimately, there is a source of data. A tag must be defined in the server before the client can request to read or write it.
All tag names used by the client must be defined before hand. There are several types of tags.
Tags which are to be read on a cyclical basis are defined by listing them in Javascript arrays and passing the arrays to the communications library when it is initialised. Address tags are defined in the "read list". Alarm zones are defined in the alarm "zone list". Event zones are defined in the event "zone list".
Tags which are written to are defined directly in the function which is responsible for initiating the write operation. Only address tags are written to. It is not possible to write to a zone tag (or an event or alarm tag). It is possible to read and write to the same tag, provided the server will permit it. Some tags may be write protected, in which case attempting to write to them will return an error.
This shows how the communications is initialised in the "in-line" javascript. Firs the read list and zone lists are defined. Then the communications object is initialised with the host name, port, client ID string, the read and zone lists, and a flag indicating whether the communications should be synchronous or asynchronous.
This should be done once and once only when a web client is started. All communications has to go through one point, and the web client can only talk to one server.
// Make a list of all the address tags to be monitored. This is what we // send to the server asking for values. var ReadList = ["PL1", "PL2", "PL3", "PL4", "PB5", "PLWriteProt", "Tank1Level", "Tank2Level", "Tank1Number", "Tank2Number", "PumpSpeedCmd", "PumpSpeedActual", "StripChart1", "StripChart2", "Testholdingreg32", "Testholdingregfloat", "Testholdingregdouble", "Testholdingregstr8", "Testholdingregstr16"]; // Make a list of the alarm and event zones to be monitored. Zones are // used to filter alarms and events to only those we are interested in. var AlarmZoneList = ["zone1", "zone2", "zone3"]; var EventZoneList = ["zone1", "zone2", "zone3"]; /* This handles communications with the server. The configuration parameters are read from a file. The final parameter enables asynchronous communications. */ /* This handles communications with the server. The parameters are: 1) The host name the web page was loaded from. 2) The port number the web page was loaded from. 3) The client ID string. 4) The list of tags to poll for data. 5) The list of alarm zones to poll for new alarms. 6) The list of event zones to poll for new events. 7) true = Enable asynchronous communications. The first two parameters use a standard Javascript feature. Alternatively, these can be hard coded values if the host and port are known in advance. */ var MBHMIProtocol = new HMIClient(window.location.hostname, window.location.port, "HMI 9876 from Water Pressure INC.", ReadList, AlarmZoneList, EventZoneList, true);
This defines the "on-load" function to execute. This is located at the start of the page body, near the top of the web page. This must always be present in some form.
<!-- This gets executed when the page is done loading. --> <body onload="pageinit();">
This is the function which actually gets executed by the "onload". It can also perform any other initialisation operations that must be done once on start up.
// Start up and initialisation. function pageinit() { // Call the function back again at the set interval. window.setTimeout("RunScanCycle()",500); }
This function gets started by "pageinit", and then sets up a call to itself (a "call-back") on a regular basis thereafter. This example does the following:
// Run all the operations required each scan cycle. function RunScanCycle() { // Query the server for updates. MBHMIProtocol.SendRequest(); // Check the comms watch dog counters. ComsTimeOut = MBHMIProtocol.CommsWatchDogTimeOut(10); if (ComsTimeOut) { CommWD.UpdateScreen(1); } else { CommWD.UpdateScreen(0); } // Call the function back again at the set interval. // The time interval should be set to a larger value. // on very slow computers. window.setTimeout("RunScanCycle()", 1500); }
The following Javascript library functions are useful for this feature:
Much of the web client HMI functionality is implemented using Javascript. Javascript is the standard programming language built into almost all web browsers. Despite the similarity in names, "Javascript" is not related to "Java" (another programming language), and in fact has only slight similiarties to Java. Javascript is executed directly in the web browser and is the normal means of providing programmability for web applications.
The Javascript programming language is standardised and is very similar in all web browsers, except for Microsoft's Internet Explorer, which uses its own proprietary dialect. If you are reading any reference material for Javascript, make sure that the material isn't refering to Microsoft's proprietary dialect.
The HMI system provides several standard libraries to implement its functionality these are:
The standard HMI Javscript libraries are not stored in the same directory as the user HMI application. Instead they are stored in a library directory called "hmilib". This allows the user written HMI components to be easily identified for backup, and it also allows the application software to be upgraded without interfering with the user HMI web pages.
When a web browser requests an HMI web page, the system looks first in the user HMI web page directory (hmipages). If the file is not found there, the system looks next in the library directory ("hmilib"). If the file is not found there, then an error is assumed and the system will return a standard file not found response.
This order allows the standard libraries to be replaced by customised versions simply by placing the customised version in the user HMI web page directory. If the requested file is found in the user HMI web page directory, the system will not look for it in the library directory.
However, it is not recommended to substitute files in this manner. If there is a reason to use a customised version of a library, it is better to simply give it a new name, place it into the HMI web page directory and to import it into the web page using that name rather that the standard one. The system does not attempt to track which libraries were imported, so there is no need to use the same file names.
The "display list" is a list of HMI objects inside the communications library which is called to update the display when a response is received from the server. The objects in the display list will be things such as pilot lights, numeric and text displays, alarms, events, and other display objects.
An object is added to the display list by the following means.
When a response is received from the server, the communications library goes through the display list and calls each display object's "UpdateScreen" function (method) and passed the new data to it. The display object is responsible for knowing what to do with the data in order to update the screen.
Most HMI library objects only redraw their data on the screen if the data has changed. However, some must redraw the screen each time they are called because they operate continuously (e.g. strip charts).
An object is compatible with the display list if it contains an "UpdateScreen" function that takes one parameter.
AddToDisplayList takes three parameters. The first is the object which is to be added to the list, the second is the address tag which is to be monitored, and the third is the "tag type". The "tag type" tells the communications library where the source of the data is, and in some cases will over-ride the address tag parameter.
The display list tag types are:
If the tag type is "read", the address tag parameter determines the source of the data. If the tag type is any other value, the address tag parameter is ignored and the appropriate data source is selected.
// This defines a pilot light control. var PL1 = new MB_PilotLight(document, "PL1", "black", "green", "red"); var PL2 = new MB_PilotLight(document, "PL2", "black", "green", "red"); var PL3 = new MB_PilotLight(document, "PL3", "black", "blue", "yellow"); var ColourList = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"]; var PL4 = new MB_PLMultiColour(document, "PL4", "black", ColourList); var PB5 = new MB_PilotLight(document, "PB5", "black", "violet", "orange"); // Now, add each of these screen objects to the list of things to update. MBHMIProtocol.AddToDisplayList(PL1, "PL1", "read"); MBHMIProtocol.AddToDisplayList(PL2, "PL2", "read"); MBHMIProtocol.AddToDisplayList(PL3, "PL3", "read"); MBHMIProtocol.AddToDisplayList(PL4, "PL4", "read"); MBHMIProtocol.AddToDisplayList(PB5, "PB5", "read");
The following Javascript library functions are useful for this feature: