Working with state changes

Hey there I have MODBUS Input module


which is working in modbus.
for some reason it is not working according to data sheet and instead of having one register per Input i get a decimal number two's complimentary i would like to do automation to detect the input status.

number is 16 bits
i found something which should do the work
node-red-contrib-binary
not sure if it will support the signed number however ,
is there any solution to manipulate the msg value ( i currently don't know how to get it in function node).

Feed the message into a debug node and copy/paste here what you see, then explain again what you want to convert it to.

10/20/2018, 4:19:09 PMnode: 513283da.a8848csensor.dio : msg.payload : string[1]

"9"

this is an example the number 9 indicate for two active inputs

the LSB and bit number 3
so 2^0+2^3= 9...

for the automation i would like to get state for each input.
basically i also could not find the reason why i cannot read the register directly and i only get one cumulative results.

What node type is that string coming from?

Event status

I don't understand. I assumed it was coming from a comms node of some sort. How can a Status node read modbus? If that is what you meant by Event status.

Hey it is very simple ..
i get a string which is represent by decimal number which if i convert it into 16 bit array
each bit will indicate for the input status..

i would like to do an automation which will read each bit separately.... and will send MQTT message...

  1. how can i convert the payload into number ?
  2. how to put the bits data into an array? 16 bits...

OK, if you don't want to tell us which node you are using in the hope we might make your life easier then that is up to you.

To convert a string to a number you can do, in a function node

var number = Number(msg.payload);

Then to access, for example, bit 2 (0 being the least significant bit) you can use

var bit2 = (number >> 2)&1;

so you could load up an array using something like that in a loop.

When I want to get an array of bits from a number, I build a string of 16 1's and 0's, split it into single characters, map those to numbers, and reverse the array, like so:

var bits = ('0000000000000000' + Number("9").toString(2)).slice(-16).split('').map(d => +d).reverse()

which returns this array:
[ 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]

Now you have a 16 element array, with the index # equal to each bit's position -- so to check bit 2, you would use the JS syntax bits[2]. There is probably a cleaner way than fiddling with all the 0 padding and slicing, but filling buffer arrays is not as intuitive for me...

Hey Thanks!

I am using function node

var bit2 = (number >> 2)&1; means rotate right ? 2 times and does And operand with 1?


second option
var bits = ('0000000000000000' + Number("9").toString(2)).slice(-16).split('').map(d => +d).reverse()

means add array of 16 bits of zero ,

what does slice -16 will do ? i assume map and reverse will convert the array to be in the right direction ?

I am using simple flow..
dio is the sensor ,
i could not see any output to this....
this is the new function i have created..
var number = Number(msg.payload);
var bit2 = (number >> 2)&1;
msg=bit2;
return msg;

when i tired to change return variable to number
return number;

i get the following:
Function tried to send a message of type number
on debug window

Which means your Function node is returning a number, not a message object.

Change your function to do:

msg.payload = bit2;

Thanks so can you elaborate the command
var bit2 = (number >> 2)&1;

does it means rotate right ? 2 bits?

No, shift right not rotate right.
The w3schools site is excellent for information on javascript (and lots of other stuff too). The operators can be seen at

The slice(-n) function returns the last n characters of a string -- and Array.reverse(), well it reverses an array ;*)

BUT, I have since found a more "natural" way to create an array of bit flags from any numeric value (either of datatype integer or string):

// create an empty array (of `N` bit flags)
var bits = new Array(16).fill(0);
// "AND" each element and "shift" to get its bit value
msg.payload =  bits.map((d,i) => (msg.payload & 2**i) >> i);
// return the original msg with the new payload array
return msg;