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.

https://infosys.beckhoff.com/english.php?content=../content/1033/te2000_tc3_hmi_engineering/4702049035.html&id=

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();
The above function can be called from a suitable event (for example, from a button click event). If  ReadFromServer or WriteToServer fail for any reason, it will throw an exception, and the catch block can catch it. The reason for the exception can be handled as needed. The textblock is initialized as the value of motorOutPut (true or false). When we press the button, it reads doorAtHome and motorStatus. If both are true, then it writes motorOutput. If any of the action fails, it will throw an exception, which can be caught and shown to the user. See for example 5 at https://www.hemelix.com/scada-hmi/twincat-hmi/twincat-hmi-popup/

 

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