Binary and shift right function help

#1

Just started playing with node red and im loving it but due to my nascent skills developing, I am struggling to understand why msg.label only returns 0. For example the var equipStatus = msg.payload[0]['Equipment status']; is returning 7.

What i am missing?

var equipStatus = msg.payload[0]['Equipment status'];
var chargStatus = 0b11 & (equipStatus >> 2);
    switch (chargStatus) {
        case 0: eStatus = "Not charging";
               msg.label = eStatus;
    return msg;
        case 1: eStatus = "Float (13.8V)";
               msg.label = eStatus;
    return msg;
        case 2: eStatus = "Boost (14.4V)";
               msg.label = eStatus;
    return msg;
        case 3: eStatus = "Equalization (14.6V)";
               msg.label = eStatus;
    return msg;
    }
    if (equipStatus >> 4) {
        eStatus = "FAULT";
        msg.label = eStatus;
    return msg;
    }

thank you

0 Likes

#2

Not knowing what your incoming payload array contains, it's hard to say... Can you edit your post to show the input data?

FYI, when you post a chunk of code, it's clearest if you put a line with 3 backtics, like:
```
before and after your code... That makes it easier to read, and doesn't mess with any quotes or formatting, making the code easily imported by someone who wants to test it.

0 Likes

#3

There is no place in this chunk of code that assigns the value 0 to msg.label. If msg.label is indeed being assigned to 0 then it is happening outside of this code. Perhaps you could share the whole flow?

The binary and shift operations seem to be all right. You said that msg.payload[0]['Equipment status'] value is 7, so this is what is assigned to the variable equipStatus. The second line will assign the variable chargStatus with value 1. Therefore the switch case 1 will be true and msg.label will be assigned the value "Float (13.8V)"

I would suggest that there is a better way to code this logic without using if statement or switch/case but it is better that you sort the code out first.

0 Likes

#4

to improve the code use backticks ``` instead single quotes

0 Likes

#5

Thank you for the code formatting tip!

1 Like

#6

Thank you for looking into thie logic.

Yes the payload is 7 and yes I should be getting “Float...” but keep getting 0 or “Not Charging” in the msg.label.

Thank you all for your patience has I traverse this new exciting language.

0 Likes

#7

Please check this (simplified) testing flow. Perhaps it can help you to identify the issue. For me you code seems good.

[{"id":"c67c47cc.84e948","type":"function","z":"c7cb5cd0.9b042","name":"Setup msg.label","func":"var e = 7;\nvar c = 0b11 & (e >> 2);\n\n\nswitch (c) {\ncase 0: \n    var eStatus = \"Not charging\";\n    msg.label = eStatus;\n    node.warn(\"0\");\n    return msg;\n    \ncase 1: \n    eStatus = \"Float (13.8V)\";\n    msg.label = eStatus;\n    node.warn(\"1\");\n    return msg;\n\ncase 2: \n    var eStatus = \"Boost (14.4V)\";\n    msg.label = eStatus;\n    node.warn(\"2\");\n    return msg;\n\ncase 3: \n    var eStatus = \"Equalization (14.6V)\";\n    msg.label = eStatus;\n    node.warn(\"3\");\n    return msg;\n}\n\nif (equipStatus >> 4) {\n    var eStatus = \"FAULT\";\n    msg.label = eStatus;\n    node.warn(\"4\");\n    return msg;\n}\n\n","outputs":1,"noerr":0,"x":420,"y":200,"wires":[["8941ff81.9d0e1"]]}]

Result in the debug panel:

r-01

0 Likes

#8

I don't think you mean to bit-shift 4 in your "if" test... perhaps you should instead check the value of the charge status to see if it's greater than or equal to 4? Either way, I prefer to use the status as an index into an array of status strings -- something like this (untested):

var equipStatus = msg.payload[0]['Equipment status'];
var chargStatus = 0b11 & (equipStatus >> 2);
var statusLabels = [
    "Not Charging",
    "Float (13.8V)",
    "Boost (14.4V)",
    "Equalization (14.6V)"
];

var eStatus = "FAULT";
if (chargStatus < statusLabels.length) {
    eStatus = statusLabels[chargStatus];
}

msg.label = eStatus;
return msg;
0 Likes

#9

This worked perfectly, muito obrigado!

1 Like

#10

same thought, I find better to use an object rather than the switch / case:

var label = {
    "0":"Not charging",
    "1":"Float (13.8V)",
    "2":"Boost (14.4V)",
    "3":"Equalization (14.6V)"
};

var equipStatus  = 7;
var chargStatus = 0b11 & (equipStatus  >> 2);
msg.label = label[chargStatus];

return msg;
0 Likes

#11

Thank you all for the assistance, i am learning a lot, mostly by reference and reverse engineering.

1 Like

#12

Apologies still a bit inconsistent and i'm not sure as to why. As you can see the ['Equipment status'] payload is returning "11" but the function is still returning 0 when it should be 1.
If comment the first line and use "var e= 11" the function works.

image

var e = msg.payload[0]['Equipment status'];
//var e = 11
var c = 0b11 & (e >> 2);

switch (c) {
case 0: 
    var eStatus = "Not charging";
    msg.label = eStatus;
    msg.icon = "fa fa-bed fa-2x nr-dashboard-ok"
    //node.warn("0");
    return msg;
    
case 1: 
    eStatus = "Float (13.8V)";
    msg.label = eStatus;
    msg.icon = "fa fa-ship fa-2x nr-dashboard-ok"
    //node.warn("1");
    return msg;

case 2: 
    var eStatus = "Boost (14.4V)";
    msg.label = eStatus;
    //node.warn("2");
    return msg;

case 3: 
    var eStatus = "Equalization (14.6V)";
    msg.label = eStatus;
    //node.warn("3");
    return msg;
}

if (equipStatus >> 4) {
    var eStatus = "FAULT";
    msg.label = eStatus;
    //node.warn("4");
    return msg;
}
0 Likes

#13

What do you get displayed in the debug panel if you change the first line of your code as below?

node.warn(msg.payload[0]['Equipment status']);
var e = 11;
var c = 0b11 & (e >> 2);

I wonder if msg.payload[0]['Equipment status'] returns a binary value, in which case it would be evaluated to 3 (and c evaluated to 0), explaining the end result.

r-01

0 Likes

#14

I am not condiment enough to its not binary but if i look at the database I see 11.

Here is the result.

image

0 Likes

#15

ok, in such case I have to redo the question asked by Steve:

perhaps you should instead check the value of the charge status to see if it's greater than or equal to 4?

What is the result if you use the code that he proposed (copy below) ?

var equipStatus = msg.payload[0]['Equipment status'];
var chargStatus = 0b11 & (equipStatus >> 2);
var statusLabels = [
    "Not Charging",
    "Float (13.8V)",
    "Boost (14.4V)",
    "Equalization (14.6V)"
];

var eStatus = "FAULT";
if (chargStatus < statusLabels.length) {
    eStatus = statusLabels[chargStatus];
}

msg.label = eStatus;
return msg;

Edit: adding a question: if the value is indeed 11 what is the expected outcome for the status ? FAULT or something else ?

0 Likes

#16

Looking back at the result you posted. The value of msg.payload[0]['Equipment status'] is "undefined".

This explains why c evaluates to 0 and the resulting label is "not charging".

r-01

0 Likes

#17

It should return "Boost..."

I am getting the msg.payload[0]['Equipment status'] from this parse:

var pvvoltage = msg.payload[0]['PV array voltage'];
var pvcurrent = msg.payload[0]['PV array current'];
var pvpower = msg.payload[0]['PV array power'];
var voltage = msg.payload[0]['Battery voltage'];
var battcurrent = msg.payload[0]['Battery charging current'];
var battpower = msg.payload[0]['Battery charging power'];
var battsoc = msg.payload[0]['Battery SOC'];
var loadvoltage = msg.payload[0]['Load voltage'];
var loadcurrent = msg.payload[0]['Load current'];
var loadpower = msg.payload[0]['Load power'];
var systemvoltage = msg.payload[0]['System rated voltage'];
var chargertemp = msg.payload[0]['Charger temperature'];
var batterytemp = msg.payload[0]['Battery temperature'];
var BattStatus = msg.payload[0]['Battery status'];
var chargerstatus = msg.payload[0]['Equipment status'];

if ((msg.payload.indexOf('Database') === -1) && msg.topic.indexOf('Database') === -1){


var msg1 = {topic:"PV array voltage", payload: pvvoltage};
var msg2 = {topic:"PV array current", payload: pvcurrent};
var msg3 = {topic:"PV array power", payload: pvpower};
var msg4 = {topic:"Battery voltage", payload: voltage};
var msg5 = {topic:"Battery charging current", payload: battcurrent};
var msg6 = {topic:"Battery charging power", payload: battpower};
var msg7 = {topic:"Battery SOC", payload: battsoc};
var msg8 = {topic:"[`Load voltage`]", payload: loadvoltage};
var msg9 = {topic:"[`Load current`]", payload: loadcurrent};
var msg10 = {topic:"[`Load power`]", payload: loadpower};
var msg11 = {topic:"[`System rated voltage`]", payload: systemvoltage};
var msg12 = {topic:"[`Charger temperature`]", payload: chargertemp};
var msg13 = {topic:"[`Battery temperature`]", payload: batterytemp};
var msg14 = {topic:"[`Battery status`]", payload: BattStatus};
var msg15 = {topic:"[`Equipment status`]", payload: chargerstatus};


return [msg1,msg2,msg3,msg4,msg5,msg6,msg7,msg8,msg9,msg10,msg11,msg12,msg13,msg14,msg15];

} else {
return;
}

0 Likes

#18

So, it is like you said (and tested). When forcing the variable e to 11 the code in the function works and produces the correct label.

r-01

You have to look for the issue outside the code. Something between reading the database and delivering the data to the function node. For some reason the value arriving is "undefined" and this produces an undesirable (but predictable) label.

0 Likes

#19

In these images, you can see that msg.payload is a string with the value == "11"

So before you can bit-shift and do other numeric comparisons, use the + operator to coerce the string to a number -- change the first line to be:

var equipStatus = +msg.payload;
var chargStatus = 0b11 & (equipStatus >> 2);
...

Of course, that will fail if the payload does not contain a string that can be interpreted as a number...

1 Like

#20

That did it!
Thank you so much to everyone.

0 Likes