Help with functions in Node Red - using && operator not working

I am trying to use the AND “&&” operator to decide which switches to turn on and off but it is not working…

var roomHum = msg.payload["sensor.tr_tent_humidity"];
var targetHum = msg.payload["input_number.humidity_target"];
var theHumSetting = msg.payload["input_number.humidity_target"]
   + msg.payload["input_number.humidity_tolerance"];

var extHum = msg.payload["sonoff_10015db5d8_humidity"];

if (roomHum > theHumSetting && extHum < targetHum) {
    return [msg, null];

using the && operator seems to break it.

these work on their own so I don’t think I messed up the variable being compared

if (roomHum > theHumSetting)
if (extHum < targetHum)

Any suggestions!

Try this to make sure the interpreter reads it right for sure.

if ((roomHum > theHumSetting) && (extHum < targetHum)) {

And I can’t see the value of the targetHum, but it might be because you did not copy-pasted it in.

1 Like

Not sure what that line will do in the flow though.

1 Like

that’s the on or off for the switch.

I have seen people write that in a lot of different ways but this was how I learned back in the beginning.

I have to test it to see what it does.
I normally just do a return msg;

Always difficult to provide support based on a picture of half the problem :slight_smile:

By setting multiple outputs for a function node, returning an array of messages sends each message in order to a different output. By making messages null, nothing is sent. In effect this allows for switching / route selection in the function node itself.

With an array of array, multiple messages are sent in sequence from the output. An array of arrays sends multiple messages from multiple outputs. Great fun.

We have to assume that the OP’s code contains an else clause with

return [null, msg] or similar and that the function node is set with 2 outputs.

On the OP, the code should work as-is since comparison operators have a higher precedence than logical AND.

( ) can always help visually, as can naming. I assumed that the object here is to test for

isroom = room humidity > target + tolerance

isoutside = outside humidity < target

Which coded as two separate tests makes the final decision

isroom && isoutside

If the case is indeed that either test works as intended, the logical conclusion is that with AND requiring BOTH to be true, this is just not the case at the moment in time. A common cause of logic failure is to require a number that is both less than 3 AND greater than 5.
Well, it doesn’t fail as such, just always returns false.

Combined, both tests are I think

out < target < target + tolerance < room

and rearranged

out < target < room - tolerance

which should be fine. I am going with it all works but that the test is genuinely false.

Also as the OP asked for suggestions… Don’t use VAR to declare variables, use LET instead. VAR all end up as global variables on the stack and are not recovered until Node-RED restarts, leading to memory leakage. LET and CONST are declared in the function space and recoverable.

If this is the case why is var so widely used even in node red core nodes?

switch node

delay node

function node

I speak from experience and dealing with memory leakage in Node-RED.

I run several flows in loops, originally using function nodes (the subject of this tread), and although I have moved over to JSONata for most, I still have several function nodes.

After Node-RED shutdown after running out of memory, I dealt with poor loop-management programming on my part to fix the immediate issue, but following several posts last year, spent a lot of time looking into memory use and management in Node-RED.

I found that I was leaking memory on an ongoing and consistent basis, with potential to run out of heap within two months of non stop use. Only regular NR / HA update restarts were avoiding eventual heap memory failure.

In looking into the issue, top of the list of causes of memory leakage recommended in several resources on the subject - use of Var or not declaring variables in function calls.

Whilst monitoring my RSS and heap memory use by V8, I removed all my own uses of Var, over to the JS recommended use of Let.

I can only speak from my own experience, but my heap memory use is now almost stable, without the ongoing rise due to leakage.

I am aware that nodes use a mixture of JS and C (where memory is self-managed and not garbage collected) and I certainly cannot explain why standard nodes can get away with Var and (apparently) my function nodes can’t, but I will continue to recommend, as several best practice resources do, not to use Var in JS function calls (unless you really need a global variable).

1 Like

Appreciated, tbh the most common reason I revert to it, is because I don’t know enough. I wind up having variables stuck in code blocks that are not available further down the line. It seems like I need to use functions but the way to use them hasn’t fully clicked in my head.

I spent over a month last year looking into Node-RED memory use, and consequently Javascript and the V8 engine garbage collection.

Mind numbingly complex, there is an issue with attempting to run Node-RED for long periods of time and in industrial situations. Not that I am, but I probably use NR at the point where memory management is critical.

I started just using Var, but now understand that let or const are to be preferred, but that introduces more complexity with scope. Another reason why I like JSONata, although there are many different issues and inefficiencies there.

I am taking the view that, with regular restarts, most users will never know about memory leaks. And, for most users it doesn’t matter. However, when I see the use of Var when Let would do just as well, I believe it is worth mentioning. In passing.

Edit: and in thinking about it, the answer is probably that core and good contib nodes are written in Typescript not Javascript, thus enforcing both type and scope.