
Reading and Writing Variables in JavaScript
We have learn how to map a variable from a PLC program. Whenever we have mapped a variable then we can read the variable in the following way, as described by the Beckhoff site.
TcHmi.Symbol.readEx2('%s%PLC1.MAIN.sTest%/s%', function (data) {
if (data.error === TcHmi.Errors.NONE) {
// Handle result value...
var value = data.value;
console.log(value);
} else {
// Handle error...
}
});
Now let’s say we have three variables (doorAtHome, motorStatus, and motorOutPut). If the first two variables are read OK and the results are true, then we can write to the third variable (motorSpeed). How do we manage these with the function given by Beckhoff? If we use the above function to read these two variables, it will be hard to manage. It could be like the following:
TcHmi.Symbol.readEx2('%s%PLC1.MAIN.doorAtHome%/s%', function (data) {
if (data.error === TcHmi.Errors.NONE) {
// Handle result value...
var value = data.value;
if(value == true){
//Read motorStatus in the same way, it can be nightmare if we repeat the code //here, you handle error and write nested code inside nested code, ops!.
//Write motorOutPut finally and check the result
}
} else {
// Handle error...
}
});
If we nest in this way, then it is hard to manage the code. One better way, we use the above asynchronous function synchronously.
We can use the JavaScript Promise mechanism, which is supported in ES6 (ECMAScript 2015). We can build two global functions that can be declared in the CodeBehind file (so we can access them from anywhere).
We can use ReadFromServer to read a variable from PLC, we can use the symbol as ‘%s%PLC1.MAIN.MotorStatus%/s%’ as symboAsParameter.
//Reading a variable by passing symbol expression
function ReadFromServer(symboAsParameter) {
return new Promise((resolve, reject) => {
var symbol = new TcHmi.Symbol(symboAsParameter);
symbol.readEx(function (data) {
if (data.error === TcHmi.Errors.NONE) {
resolve(data.value);
} else {
console.log(`Error in ReadFromServer ${symboAsParameter}`);
console.log(`data.details.code = ${data.details.code}`);
reject(data.error);
}
});
});
}
//Writing a variable by passing symbol expression and the value
function WriteToServer(symboAsParameter, dataParameter) {
return new Promise((resolve, reject) => {
var symbol = new TcHmi.Symbol(symboAsParameter);
TcHmi.Symbol.writeEx(symboAsParameter, dataParameter, function (data) {
if (data.error === TcHmi.Errors.NONE) {
resolve(data.error);
} else {
console.log(`Error in WriteToServer ${symboAsParameter}, ${dataParameter} `);
console.log(`data.details.code = ${data.details.code}`);
reject(data.error);
}
});
});
}
If you have issues understanding, then we can take a look at https://www.hemelix.com/scada-hmi/twincat-hmi/twincat-hmi-async-function/
We can use the above JavaScript functions in the following way:
We must use async keyword before the function and await keyword.
async function ReadWriteAllVariables() {
try { var doorAtHome = await ReadFromServer('%s%PLC1.MAIN.doorAtHome%/s%'); var motorStatus = await ReadFromServer('%s%PLC1.MAIN.motorStatus%/s%'); if(doorAtHome == true && motorStatus == true){ var ret = await WriteToServer('%s%PLC1.MAIN.motorOutPut%/s%', true); var someControl = TcHmi.Controls.get('TcHmiTextbox'); var myRet = `Write Status = ${ret}`; console.log(myRet); someControl.setText(myRet); } else { console.log('doorAtHome or motorStatus is not true'); } }
catch(error) { console.log(`error in ReadWriteAllVariables = ${error}`); //Show info to user if needed } } ReadWriteAllVariables();

YouTube Video:
Please check the video along with the text version and the sample to master the topics.
Download:
Download the sample from this link TcHmiJSBasicPromise_Debug.zip
References:
Download the sample from the link given above.
See next how to debug JavaScript code at https://www.hemelix.com/scada-hmi/twincat-hmi/debugging-javascript-code/
Ask questions related to Hemelix sample code and design at Google group https://groups.google.com/g/hemelix