Read Var from PLC and push to the list

Hello, I am trying to push DATA.DATA[1...5] to the list named myList. I am using readDirect in the loop at my function readArray which return a list.

At main module.run I've executed readArray(5). First console.log returns me the correct array, but the second with length returns me 0. Additional I have noticed, that when I try: for (let i in readArray(5)) - it looks like this array doesn't exist anymore. I definitely doing something wrong, but I don't know what exactly.

(function() {

    /**
     * replace module name with a custom name for the local-script.
     *
     * All local-script should be attached to the "custom.ls" package.
     * If more than one script is required for an application, a common root package
     * should be created (e.g. "custom.ls.customerName.*").
     */

    var MODULE_NAME = "readValue",
        ENABLE_LOGGING = false,
        RECORD_LOG = false,
        logger = shmi.requires("visuals.tools.logging").createLogger(MODULE_NAME, ENABLE_LOGGING, RECORD_LOG),
        fLog = logger.fLog,
        log = logger.log,
        module = shmi.pkg(MODULE_NAME);

    // MODULE CODE - START

    /* private functions */
    function readArray(count){
        let mylist = [];
        
        // Get a reference to the ItemManager
        const im = shmi.requires("visuals.session.ItemManager");

        for (let step = 1; step < count + 1; step++) {
            let itemName = `DATA.DATA[${step}]`;

            im.readDirect([itemName], function(err, result) {
                let a = result[itemName];
                if (!err) {
                    mylist.push(a);
                } else {
                    console.log("readDirect failed: " + err, "ReadDirect Error");
                }
            });
        }
        return mylist
    }
    

    /**
     * Implements local-script run function.
     *
     * This function will be called each time a local-script will be enabled.
     *
     * @param {LocalScript} self instance reference of local-script control
     */
    module.run = function(self) {
        let a = readArray(5);

        console.log(a);
        console.log(a.length);
        
        
        // var container = shmi.ctrl(".mybox"); 

        // for (var i in a) {
        //     if (container && container.isInitialized()) {
        //         container.addControl([{
        //             ui: "container",
        //             config: {
        //                 name: "generatedContainer"
        //             },
        //             children: [{
        //                 ui: "button",
        //                 config: {
        //                     label: i,
        //                     action: [{
        //                         name: "notify",
        //                         params: [
        //                             "Message #1",
        //                             "Title #1"
        //                         ]
        //                     }]
        //                 }
        //             }]
        //         }], function(err, controls) {
        //             if (err) {
        //                 console.error("Error creating controls:", )
        //             } else {
        //                 console.log("Controls initialized:", controls);
        //                 g = controls
        //                 /*
        //                     updateShape(250, 300, controls[0].controls[0])
        //                     updateShape(50, 50, controls[0].controls[1])
        //                     controls[0].controls[1].element.style.width 
        //                         */
        //             }
        //         });
        //     }
        // }

        /* called when this local-script is disabled */
        self.onDisable = function() {
            self.run = false; /* from original .onDisable function of LocalScript control */
        };
    };


    // MODULE CODE - END

    fLog("module loaded");
})();
Best reply by webiq-sk

It doesn't work, because the readDirect call is asynchronous and calls the callback function if finished.
However, the console log line is executed immediately after the request has been sent.

The solution would be to have an additional parameter "callback" that you provide to the function that you call inside the readDirect callback.

View original
5 replies