Core
Establishing a Connection to the Machine
A machine connection is established when creating a new machine variable.
var machine = new LUX.Machine()
Options can be passed to the constructor to modify connection parameters.
var options = {
ipAddress: '192.16.0.1',
port: 8000,
timeout_ms: 500,
maxRetryCount: 5,
maxReconnectCount: 5
}
var machine = new LUX.Machine(options)
Option | Description | Default Value |
---|---|---|
ipAddress | IP address of the machine WebSocket server | IP address hosting the web interface (location.hostname ) |
port | Port of the machine WebSocket server | 8000 |
timeout_ms | Time, in milliseconds, to wait for a machine response before trying again | 250 |
maxRetryCount | Maximum number of read or write attempts before registering an error | 5 |
maxReconnectCount | Maximum number of reconnect attempts before prompting the user | 5 |
Any options not set in code will fall back to the default value.
Reestablishing Connection
If the machine connection is lost, the library will attempt to reconnect automatically, up to maxReconnectCount
times. If the connection cannot be established, it will alert the user and give the option to try again or abort. Aborting will typically require a page refresh to reestablish the connection. This behavior can be customized by providing a function to machine.connection.onDisconnect
. Here is an example implementation of the default behavior.
machine.connection.onDisconnect = function () {
if (reconnectCount <= maxReconnectCount) {
// Try to reconnect
reconnectCount++
machine.connection.reconnect()
} else {
// Prompt user for reconnection
let shouldReconnect = confirm('Machine connection lost! Please check machine controller and physical connections.\nPress OK to attempt to reconnect.\nPress Cancel to end machine communication (a page reload will be required to reestablish communication)')
if (shouldReconnect) {
machine.connection.reconnect()
}
}
}
Reading Machine Variables
To read the value of a machine variable, call the readVariable(varName)
method. The varName
parameter is a string containing the name of the machine variable to read. For local machine variables, this must take the form of 'taskName:varName'
. For global variables, no prefix is necessary. If you would like to cyclically update the value, use the initCyclicRead(varName)
method, instead. This will update the value as quickly as possible. It is also possible to pass an array of variable names to either of these functions.
machine.readVariable('globalVar') // Read variable once
machine.initCyclicRead('myTask:localVar') // Read variable continually, as quickly as possible
machine.readVariable(['globalVar, myTask:localVar']) // Read multiple variables
Message Format
{
"type": "read",
"data": "[globalVar, myTask:localVar]"
}
{
"type": "readresponse",
"data": [
{
"globalVar": 25
},
{
"myTask:localVar": {
"elem1": "Hello",
"elem2": 123.456
}
}
]
}
Events
Events are triggered on the document when reading machine variables. Here is an example of how to use these with jQuery.
$(document).on({
'readcomplete': function() {
// Called after a read has been completed.
},
'readsuccess': function() {
// Called after a read was successful.
},
'readerror': function() {
// Called after a read failed.
}
})
Writing Machine variables
To write the value of a machine variable, call the writeVariable(varName, [value])
method. The varName
parameter follows the same rules as for reading variables. The value
parameter is optional. If no value is specified, then the current HMI value of the variable will be written to the machine.
machine.writeVariable('globalVar', 52)
machine['myTask:localVar'].elem1 = "World!"
machine['myTask:localVar'].elem2 = 654.321
machine.writeVariable('myTask:localVar')
Message Format
{
"type": "write",
"data": {
"globalVar": 52,
"myTask:localVar": {
"elem1": "Hi!",
"elem2": 654.321
}
}
}
{
"type": "writeresponse",
"data": {
"globalVar": 52,
"myTask:localVar": {
"elem1": "Hi!",
"elem2": 654.321
}
}
}
Events
Events are triggered on the document when writing machine variables as well. Here is another example.
$(document).on({
'writecomplete': function() {
// Called after a write has been completed.
},
'writesuccess': function() {
// Called after a write was successful.
},
'writeerror': function() {
// Called after a write failed.
}
})
Binding to HMI App Data Instead of the PLC
We often augment hmi elements based on data from the PLC using databinding to the LUX Machine.
Sometimes, we want to augment hmi elements based on data local to the hmi app. The data and the elements are accessible programmatically, but implemting locking/hiding/IO/LED behavior requires custom javascript. The following capabilities allow us to extend typical Loupe UX databinding behavior to local hmi application data in a uniform way.
Instantiating the HMI object
An HMI object is established when creating a new hmi variable.
var hmi = new LUX.hmi(customCallback);
Unlike a LUX.Machine, the data is local to the hmi app rather than the PLC, so there is no connection or connection options.
Instead, one or more callback functions are passed.
Providing the Callback Function
The callback functions[s] are responsible for populating the hmi object with app data.
function customCallback(){
hmi['datapoint'] = appData.datapoint;
}
Binding Loupe UX Elements to the HMI Object
Loupe UX elements can now bind to the hmi object by changing the data-machine-name
to the new hmi object.
<span class="lux-num-value" data-machine-name="hmi" data-var-name="datapoint"></span>