Help with code in `function` node

I'm going over old code and updating things.

This has me not getting anywhere just now.

code:

//const time_ = new Date().toLocaleString()
const time_ = new Date().toLocaleString('en-AU', { hour12: false })

let Modem = context.get('Modem')||0
//node.warn(msg.device)
if (msg.device == "ROUTER")
{
    //node.warn("Modem test")
    //node.warn("Status is " + msg.payload)  //  Number if pinged.
    //if (msg.payload == "Line Good")
    if (msg.payload > 0)
    {
        context.set('Modem',1)
        node.status({fill:"yellow",shape:"dot",text:"Modem Seen"})
        msg = {payload: 'Online',device:'Modem',who:global.get("myDeviceName"),time:time_}
        //
        //      Construct msg.payload to say modem seen and message from TelePi.
        //
        return msg
    }
    else
    {
        context.set('Modem',0)
        node.status({fill:"black",shape:"dot",text:"Modem NOT Seen"})
        msg = {payload: 'OffLine',device:'Modem',who:global.get("myDeviceName"),time:time_}
        //
        //      Construct msg.payload to say modem not seen and message from TelePi.
        //
        //msg = 0
        return msg
    }
}
if (msg.device == "UPLINK")
{
    if (Modem == 1)
    {
        if (msg.payload > 0)
        {
            node.status({fill:"green",shape:"dot",text:"UpLink Ok"})
            msg = {payload: 'Online',device:'UpLink',who:global.get("myDeviceName"),time:time_}

//            node.warn("***********  uplink good  **********")
            //
            //      This needs modifying to say it is from TelePi.
            //
            return msg
        }
        else
        {
            node.status({fill:"red",shape:"dot",text:"UpLink Down"})
            msg = {payload: 'Offline',device:'UpLink',who:global.get("myDeviceName"),time:time_}
            //
            //      This needs modifying to say it is from TelePi.
            //
            return msg
        }
    }
    else
    {
        node.status({fill:"grey",shape:"dot",text:"Unknown"})
        context.set('MODEM',0)
            //
            //      This needs modifying to say it is from TelePi.
            //
        msg = {payload:'UNKNOWN',device:'Uplink',who:global.get("myDeviceName"),time:time_}
        return msg
    }
}

I am not getting to see the line node.status({fill:"green",shape:"dot",text:"UpLink Ok"}) reflected on the node.

It is Stuck on Modem seen message.

On the screen shot you can see on the right that Modem is set to 1.

And on this you can see the uplink good message. (Now commented out)

yet, the node.status is remaining at the Yellow state.

Now, ok, just thought of it:
Maybe the order in which the messages are received.

Shall check that.

But again: to prevent Sod's law happening, I'll ask here first.

:wink:

Update:

Yes, the original list did have the UPLINK before the MODEM so I put it after.

I also added a second line and indicated the other one.

Alas the messages still came up in the debug window the WRONG WAY around.

The second message was for the MODEM, which means the status would reflect that state until the next time and the UPLINK message would be displayed - I hope - but immediately overwritten by the MODEM state.

So I seem to be still missing something.

Try replacing == with === in your conditionals, I've ran into this and there seems to sometimes be version dependencies on when == is OK or not. Consensus seems to be just use === inside of conditionals.

Also in some versions I've had to do things like this when using msg.payload to match a specific string:

if(msg.payload.indexOf("Idle") === 0){ // presumably object oriented details that are not obvious to casual users like me.

I also don't see msg.topic in your logic, I can't read the details of your flow screenshot, but often the function node gets messages that it should ignore and if it is not your topic then you just pass it on without changing it, here it looks like you always modify the msg since you are ignoring the topic.

I will often create a second output for the function and create a debug message to return on the second output to see what is going on using a complete message object debug node

Something like:
debugMsg={Flash : flash, Ambiance : ambiance, Speed : speed, Brightness : brightness, GarageDoor : garageDoor, Armed : armed, Update : newSetting, topic : 'debugMsg', };

return [ msg, debugMsg ];

These were lifted from a long running (multiple years) flow on node-red 1.2.9 running on a Beaglebone Green.

I'm strongly an "If it ain't broke, don't fix it!" kind of guy. Especially if on IOT class hardware that is out of the mainstream.

Hope this gives you some ideas to try. I didn't see you mention the node-red version you are running, if you do, maybe some of the real gurus here might have an actual explanation.

The way this is written it doesn't make any difference which comes first (UPLINK or ROUTER). The node status is going to show whichever of the inputs occurs most frequently. To view both status messages you would have to have each msg in a separate Function node.

You could also try filter node(s) to only pass either UPLINK or ROUTER only when the status changes.

Thanks.

I know - and admit - I have made a mistake like using = instead of == in places.

I've double checked the code..... And can't see where you mean.

Here are the two messages (in a good condition)

{"payload":1.36,"topic":"101.173.234.196","_msgid":"927e84283214664d","device":"UPLINK","IP":"101.173.234.196"}
{"payload":0.814,"topic":"192.168.17.1","_msgid":"4848f7109d3f3814","device":"ROUTER","IP":"192.168.17.1"}

In the mean time, I added a bit more code and cheated with conditions.

Exert from code:


let Modem = context.get('Modem')||0
let Uplink = context.get('UpLink')||0
//node.warn(msg.device)
if (msg.device == "ROUTER")
{
    //node.warn("Modem test")
    //node.warn("Status is " + msg.payload)  //  Number if pinged.
    //if (msg.payload == "Line Good")
    if (msg.payload > 0)
    {
        context.set('Modem',1)
        if (Uplink == 0)
        {
            node.status({fill:"yellow",shape:"dot",text:"Modem Seen"})
        }
        msg = {payload: 'Online',device:'Modem',who:global.get("myDeviceName"),time:time_}

//        node.warn(***  modem good  ***)

        //
        //      Construct msg.payload to say modem seen and message from TelePi.
        //
        return msg
    }
    else
    {
        context.set('Modem',0)
        node.status({fill:"black",shape:"dot",text:"Modem NOT Seen"})
        msg = {payload: 'OffLine',device:'Modem',who:global.get("myDeviceName"),time:time_}
        //
        //      Construct msg.payload to say modem not seen and message from TelePi.
        //
        return msg
    }
}
if (msg.device == "UPLINK")
{
    if (Modem == 1)
    {
        if (msg.payload > 0)
        {
            node.status({fill:"green",shape:"dot",text:"UpLink and router Ok"})
            msg = {payload: 'Online',device:'UpLink',who:global.get("myDeviceName"),time:time_}
            context.set("UpLink",1)

//            node.warn(****  uplink good  ****)
            //
            //      This needs modifying to say it is from TelePi.
            //
            return msg
        }

So now a new context has been set: UpLink.
Now when an UPLINK message is received it sets UpLink to 1 which stops the Modem part happening.

Somewhat ugly, but it gets the job done.

There is code to clear UpLink if it's payload == 0.

Well, UPLINK and ROUTER both arrive at the same time every time.

I thought the sequencing of them was a problem, but somehow that didn't matter.
(Or maybe something else was happening and the sequence was still WRONG.)

Thanks though.