How to save writing with if and else in function node

If you haven’t determined all the conditions your going to test, then ‘Yes’ you have an impossible task. So break it down into smaller bits. For example, if you were to add a switch node and test to see if setboiler was on or off, you could have two outputs on the node and if you had two function nodes (one getting the msgs where setboiler is on and the other getting the off msgs, each function you code would have one less item to test.

You and I think the same way! I was just looking for an elegant solution to the problem.

Your question is very vague and confusing. If you mean you want 6 incoming vars in your if statement, then you would increase the sting to 6 digits and add 64 items to the lookup table.
e.g.

//create lookup string eg "111111"
const bools = (msg.payload.setboiler === "on" ? "1" : "0") +
    (msg.payload.solarboiler === "on" ? "1" : "0") +
    (msg.payload.solarpool == "on" ? "1" : "0") +
    (msg.payload.D1_mini == "online" ? "1" : "0") +
    (msg.payload.another1 == "empty" ? "1" : "0") +
    (msg.payload.another2 == "on" ? "1" : "0");
// lookup table of outputs
const bool_pool = {
        "111111": [1,"off"], 
        "111110": [1,"off"], 
        "111100": [1,"off"], 
        "111101": [1,"off"], 
        "101111": [0,"off"],
        "101110": [0,"off"],
        "101100": [0,"off"],
        "101101": [0,"off"]
        //add other 56 lookup items
};
// lookup outputs
const outputs = bool_pool[bools]
//output if outputs finds a result
if(outputs){
    return [{ payload: outputs[0]}, { payload: outputs[1]}];
}

Often it is better to look for patterns in the conditions being tested and try to make use of those. For example, in the example you have posted, I would split up the comparisons for the first and second messages. So looking at slr_boiler it can be seen that it does not depend on the solarpool state, so you could start with something like

let msg1 = {}
if ( msg.payload.setboiler == "on" && msg.payload.solarboiler == "on" && msg.payload.D1_mini == "online" ) {
  msg1.payload = "on"
} else {
  msg1/payload = "off"
}

which should give you the first message to be output at the end.
Then I would look for similar patterns in the second one.

Not often I go back to my college days but Boolean algebra can help you minify your code.

Setup the variables

A = setboiler (on/off)
B = solarboiler (on/off)
C = solarpool (on/off)
D = D1_mini (online/offline)

Interpret the logic & simplify using Boolean Algebra

A B C D Send Boolean Algebra
1 1 1 1 [1,"off"] (ABCD)+(AB!CD) == ABD
1 1 0 1 "
0 1 1 1 [0,"on"] (!ABCD)+(!A!BCD)+(!AB!CD)+(ABC!D)+(!ABC!D)+(A!BC!D)+(!A!BC!D) == (B+C)⋅(C+D)⋅(!A+!D)
0 0 1 1 "
0 1 0 1 "
1 1 1 0 "
0 1 1 0 "
1 0 1 0 "
0 0 1 0 "
1 0 1 1 [0,"off"] everything else
1 0 0 1 "
0 0 0 1 "
1 1 0 0 "
1 0 0 0 "
0 1 0 0 "
0 0 0 0 "

Understanding the reduction.

  • ABD → if A and B and D, == 1 then return [1, "off"]
  • (B+C)⋅(C+D)⋅(!A+!D) → if (B or C == 1) and (C or D == 1) and (A or D == 0) then return [0, "on"]
  • Everything else, return [0, "off"]

Resulting function Code...

const A = msg.payload.setboiler === "on" 
const B = msg.payload.solarboiler === "on"
const C = msg.payload.solarpool == "on"
const D = msg.payload.D1_mini == "online"

if ( A && B && C) {
    return [{ payload: 1 }, { payload: "off" }]
} else if ( (B || C) && (C || D) && (!A || !D) ) {
    return [{ payload: 0 }, { payload: "on" }]
}
return [{ payload: 0 }, { payload: "off" }]

Disclaimer
Although the theory is sound, I did not check all posts nor did I test the code :slight_smile:
If I misinterpreted the original logic you will need to revise the Boolean algebra.

1 Like

I was looking for a way to shorten the writing because as you say it's 64 lines with six conditions. The problem comes from this code

var boiler = msg.payload.boiler ;
var hysteresis = 5;
var solar = msg.payload.solar;

if (solar >= (boiler+hysteresis)) {
    msg.payload = "on";
}
else if (solar <= boiler) {
    msg.payload = "off";
} 
else {
    msg.payload = "nothing";
}
msg.topic = "solarboiler";
return msg;

I changed nothing to off, but it's not right.
therefore I have to add this condition in the code that I publish at the beginning.

That makes more sense you require on off and empty. Then you would set 0, 1 or 2.
then add lookup items for any solarboiler output and add the 2.
If you omit a lookup property the code will just ignore and not output, which may be of use or not.
e.g.

//create lookup string eg "1111"
const bools = (msg.payload.setboiler === "on" ? "1" : "0") +
    (msg.payload.solarboiler === "on" ? "1" : (msg.payload.solarboiler === "off" ? "0" : "2")) +
    (msg.payload.solarpool == "on" ? "1" : "0") +
    (msg.payload.D1_mini == "online" ? "1" : "0");
// lookup table of outputs
const bool_pool = {
        "1111": [1,"off"], 
        "1211": [1,"off"], 
        "1101": [1,"off"],
        "0111": [0,"on"],
        "0011": [0,"on"],
        "0101": [0,"on"],
        "1110": [0,"on"],
        "0110": [0,"on"],
        "1010": [0,"on"],
        "0010": [0,"on"],
        "1011": [0,"off"],
        "1001": [0,"off"],
        "0001": [0,"off"],
        "1100": [0,"off"],
        "1000": [0,"off"],
        "0100": [0,"off"],
        "0000": [0,"off"]
};
// lookup outputs
const outputs = bool_pool[bools]
//output if outputs finds a result
if(outputs){
    return [{ payload: outputs[0]}, { payload: outputs[1]}];
}

You can have shorter if you follow @Steve-Mcl algebra, you need to weigh up readability/editability against length. I know what i would choose, you need to decide if shortness is better than readable and editable

A joke. I'm writing to you slowly because I know you read slowly.
Well... my job is the same. I don't know English well, I write with a translator and they do!

Shouldn't it be

switch (t)

since d1 is either 0 or 1.