How to concat a buffer


#1

Hi Guys, I would like to concat a buffer but i got the follow error:

I injecting in the function the follow buffer:

["0x01","0x80","0x49","0x02","0x10","0x02","0x13","0xbc","0x22","0x02","0x10","0x54","0x03"]

Blockquote

function : (error)

Blockquote

"TypeError: "list" argument must be an Array of Buffer or Uint8Array instances"

here is my code:

Blockquote

switch (msg.payload[2]){
//Analyze Device Annoucement
case 73:{ // device announcement message 0x43
var a,b;
var c = [];
a = msg.payload[9]; // analyze nwk short address [9] and [10]
b = msg.payload[10];
c= [a,b];
// Buffer concat arguments
var msg1 = { payload: new Buffer.concat(c)};
return msg1;

}

Blockquote
Somebody can help me to fix it?

Best Regards,
Alex


#2

Please can you fix the formatting of your post to properly display the code? It is hard to help debug code that isn't formatted properly.


#3

Hi knolleary!
I tried to do it. Please let me know if is ok for you right now?


#4

Hi Guys, I got success to concatenate two array components as a string using JOIN node. I didn´t know at this moment if is the best way but it worked.

I got buffer component for each function in the flow before join node using a follow code:

Blockquote
for (i= 0; i < msg.payload.length; i++) {

  switch (msg.payload[2]){
        //Analyze Device Annoucement 
       case 73:{ // device announcement message 
              var buf1 =[];
              buf1 = msg.payload[9]; // analyze nwk short address 

        var msg1 = { payload: buf1};
        return msg1;

       }
    break;  

}


#5

Hi Guys, i got success to concatenate but i´ll need to working with a hex values, as you can see my buffer have 0xcd and 0xfd at buffer position 9 and 10, but when I see that in the debug node the values appear in decimal, since my functions before the join node convert it to hex using parseInt.

my decimal components buffer is:
[1,2,16,77,2,16,2,28,103,205,253,2,16,23,136,2,17,2,18,26,131,232,128,123,3]

image

my debug log always it it in decimal base:

image

Somebody can help me to fix it?
I would like to have in debug log the cdfd hex value!


#6

Hi Alex,

It would be easier to help you if you format correctly the code you post in the forum.

You can do so by adding three backtick characters before the code and another set of three at the end of the code. If you can´t find it your keyboard it is ok, you can use the tilde character instead.

You don´t need to post again the code. It is better that you edit your previous posts to correct. This helps to keep the thread clean and useful for future reference.

```
a = msg.payload[9]; // analyze nwk short address [9] and [10]
b = msg.payload[10];
```

or

~~~
a = msg.payload[9]; // analyze nwk short address [9] and [10]
b = msg.payload[10];
~~~

will result

a = msg.payload[9]; // analyze nwk short address [9] and [10]
b = msg.payload[10];

#7

If you created it as a number type rather than a string then you can click on it in the debug sidebar and it will show you it in decimal or hex.

PS 0xcdfd is 52733 in decimal... so something isn't correct.


#8

@dceejay, thanks a lot, I´ll store it as a variable for use in another function node. I´ll check if the two bytes will persist in hex when I´ll store in a global variable, file or DB.

I found my wrong code, I used ParseInt improperly. I´ll try to explain better my need.
I need to format a parameter that have a role formation
Nwk Addr > msg.payload[9] concatenated with msg.payload[10].

for example: in a buffer received by my parser function have: 205 dec (cd hex), at position 9 and 253 dec (fd hex) at position 10. My Nwk addr should be: cdfd.

after I have withdrawn ParseInt my nwk addr persists as 205253. You can see below my actually code:

Function: DevAnn - ShortAddrPart1 The 2st function (ShortAddPart2) have the same code, but changes from msg.payload[9] to msg.payload[10].

for (i= 0; i < msg.payload.length; i++) {

// handling parameters and send a response mesage
      switch (msg.payload[3]){
            //Analyze Device Annoucement 
           case 77:{ // device announcement message 
              //var buf1 =[];
              //buf1 = parseInt (msg.payload[9],16); // analyze nwk short address
              var buf1;
              buf1 = msg.payload[9];
              var msg1 = { payload: buf1};
              return msg1;

           }
        break;  


        }

My Join node configuration:

@Andrei,
I finally wrote the right code.. Thanks a lot for your help!

@dceejay, do you can help to keep my nwk addr as a hex?


#9

Alex,

Let me get this straight: you want to input the binary buffer in the flow and get as result a string representation of bytes 9 and 10, right ?

In such case, for the given binary buffer the expected output would be "cdfd".

If the understanding is correct then the coding is quite simple if you use the Javascript method toString. Check here: https://www.w3schools.com/jsref/jsref_tostring_number.asp

This is the code to use in your function:

msg.add = msg.payload[9].toString(16) + msg.payload[10].toString(16);
return msg;

Result:

r-01


#10

Hi Andrei,
thanks a lot right now is working as I expected.
Would you can take me a last doubt?

I can get the added value and use it to salve in the global variable:

if (msg.payload.length == 27) {
**var nwkaddr = msg.add;**
global.set('NWKAd',nwkaddr);
msg.payload="Nwk_address  " +nwkaddr;
//msg.payload="Nwk_address "+msg.payload+" "+nwkaddr;
return msg;
} else
return {payload: new Buffer("Length out off range")};

But I have some problem to format a variable I would like to have 0xeb0f!

...} else {
            msg1=msg.payload[11]^0x10;
            msg.add = msg.payload[9].toString(16) + msg1.toString(16);
            return msg;
            }

But after using the code above i have the 2st part of nwk address unformatted!

I would like to format it to 0x0f How can i fix it?

image

Best Regards,
Alex


#11

Let me rephrase your post to check my understanding.

Your result is "ebf" whereas you were expecting "eb0f", right ?

Indeed, when converting a number to a string many times you want the end result to be padded with zeroes to have a fixed amount of digits. The easiest way is to use the JavaScript (ES6) method padStart().

let a = 0x1f;
let b = a ^ 0x10;
node.warn(b.toString(16));

let c = b.toString(16).padStart(2,"0");
node.warn(c);

return msg;

The above code shows the number 0x1f being stored in the variable a, then xored with 0x10 and stored in the variable b.When you represent the content of the variable b using toString(16) it will produce the string f, which is bad for you. The solution: using the method padStart() to add the "missing" zero in front of the result. You will get the string 0f stored in the variable c.

Testing flow:

[{"id":"9d9973da.b582d","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"fc8e586.700cca8","type":"function","z":"9d9973da.b582d","name":"padStart","func":"let a = 0x1f;\nlet b = a ^ 0x10;\nnode.warn(b.toString(16));\n\nlet c = b.toString(16).padStart(2,\"0\");\nnode.warn(c);\n\nreturn msg;","outputs":1,"noerr":0,"x":490,"y":180,"wires":[[]]},{"id":"d1a62239.fce05","type":"inject","z":"9d9973da.b582d","name":"Go","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":310,"y":180,"wires":[["fc8e586.700cca8"]]}]

Debug Panel:

r-01

Final remarks: There are a coupe of things that seems strange in your code example but I just disregarded them to keep focus on the main point that is how to represent an hexadecimal number in a string with two digits.


#12

Hi Andrei, thanks a lot! Right now is working well!
I edited my last post to make it better understandable!


#13

Andrei,
thanks a lot for help me to define my nwk_address parameter. To finish my challenge I need to split this parameter in 2 parts to send it via serial port. I have got my nwk_address global variable using "," to separte the it in two bytes. My nwk address in last example is: eb,0f

...
 a = msg.payload[13];
 b = msg.payload[13] ^ 0x10;
 msg.add = msg.payload[11].toString(16) + "," + b.toString(16).padStart(2,"0");
 return msg;
var nwkaddr = msg.add;
global.set('NWKAd',nwkaddr);
I need to pick 1st byte and 2st byte separately (0xeb and 0x0f) to form the command buffer.
I try to using a split function like that.

a = nwk_add.split(',', 1);
b = nwk_add.split(',', 2);


But it is not working!
Please would you advise me how can i do that?


Best Regards,
Alex

#14

The serial node has the ability to split the msg.payload based on a given character. You can chose if the output will be a binary data or ascii string . Therefore you don´t need to code the split inside your function. The serial node will handle it for you.


#15

Andrei I using this method to split stop (0x03) bytes from serial port. I need to split the nwk_address (global variable) in nwk_adds1 and nwk_adds1, in last example 0xeb and 0x1f to sent it trough serial port out node.

newMsg = {payload: new Buffer([0x01,0x02,0x10,0x45,0x02,0x10,0x02,0x12,0xCA,**nwk_adds1**,**nwk_adds2**,0x03])}
 node.send(newMsg);

to try to do it, and stop to start separating the main nwk_address, I save nwk_adds1 and nwk_adds2 in the individual global variable.

var nwkaddrs1 = msg.payload[10].toString(16);
var nwkaddrs2 = msg.payload[11].toString(16);
global.set('NWKAdS1',nwkaddrs1);
global.set('NWKAdS2',nwkaddrs2);

but when I include it on the new buffer, as can be seen above in the newMsg, to send via serial port nothing happens!

Best Regards,
Alex


#16

Which one is true in such case?
(a) Nothing happened
(b) You got an error or warning message in the debug panel
(c) You got wrong/unexpected values inside your output message?

Test this code inside a function node, in a brand new flow to see the difference when you use the first couple of statements and in a second trial when you comment the first couple of statement and uncomment the next two statements.

let nwk_adds1 = 0xeb;
let nwk_adds2 = 0x0f;

//let nwk_adds1 = "eb";
//let nwk_adds2 = "0f";

newMsg = {payload: new Buffer([0x01,0x02,0x10,0x45,0x02,0x10,0x02,0x12,0xCA,nwk_adds1,nwk_adds2,0x03])}

return newMsg;

#17

Sorry Andrei, I made an inaccuracy in my previous post!
As you can see bellow my answers:
I can see when I use static variable, I used [9] 0xe5 and [10] 0x8b, as you advise me, my outgoing command working very well as you can see below:

            let nwk_adds1 = 0xe5;
            let nwk_adds2 = 0x8b;

image

But when I using a global variable, using global get, the nwkaddrs1 and nwkaddrs2 is not working as you can see below:
image

I using those code, in different nodes, to set and get global variable.
used to analyze original buffer to understanding what is the nwk position and set global variable (nwkaddrs1 and nwkaddrs2).

...
 if (msg.payload[12]!=2) { 
         let nwkaddrs1 = msg.payload[11].toString(16);
         let nwkaddrs2 = msg.payload[12].toString(16);
         global.set('NWKAdS1',nwkaddrs1);
         global.set('NWKAdS2',nwkaddrs2);
         msg.add = msg.payload[11].toString(16) + "," + msg.payload[12].toString(16);
         msg.payload = "Nwk_address_Serial  " +nwkaddrs1 + nwkaddrs2;
         return msg;

Part of code to interpret the specific message and send a subsequent command using nwkaddrs1 and nwkaddrs2 dynamically. The last that we saw in the last PIC (0x0 and 0x38) is a wrong nwk value. When should it be 0x7a and 0x56!

// Zigate Commissioning procedure parser

//variables
var i;
let nwk_add=global.get('NWKAd') || 0;
let nwk_adds1=global.get('NWKAdS1') || 0;
let nwk_adds2=global.get('NWKAdS2') || 0;

// tratamento das respostas aos comandos do gateway
for (i = 0; i < msg.payload.length; i++) {

// handling parameters and send a response mesage
         switch (msg.payload[3]){
            //Analyze Device Announcement msg 
            case 77:{
                //Send Active Request msg
            //let nwk_adds1 = 0xe5;
            //let nwk_adds2 = 0x8b;
            newMsg = {payload: new Buffer([0x01,0x02,0x10,0x45,0x02,0x10,0x02,0x12,0xCA,nwk_adds1,nwk_adds2,0x03])}
            return newMsg;
            }
            break;
        }
}

The nwk_adds1 and nwk_adds2 correctly tested in the 1st code included in this post, could you see in the PIC bellow:

 msg.add = msg.payload[11].toString(16) + "," + msg.payload[12].toString(16);
         msg.payload = "Nwk_address_Serial  " +nwkaddrs1 + nwkaddrs2;

image


#18

Good, I guess you got the point.

Summarizing: when using the statement new Buffer you were mixing numbers and strings (nwk_adds1, nwk_adds2). This generates inconsistent results from what you expect.

The fix is to convert the strings back to numbers and this can be achieved with the JavaScript function parseInt that allows you the chose the numeric radix (hexadecimal in your case).

Test this code in a function node to see the result:

//let nwk_adds1 = 0xeb;
//let nwk_adds2 = 0x0f;

let nwk_adds1 = parseInt("eb",16);
let nwk_adds2 = parseInt("0f",16);
node.warn(nwk_adds1);
node.warn(nwk_adds2);

newMsg = {payload: new Buffer([0x01,0x02,0x10,0x45,0x02,0x10,0x02,0x12,0xCA,nwk_adds1,nwk_adds2,0x03])}

return newMsg;

#19

Hi Andrei, tanks a lot!!!
right now is working very well!
I post here the code for future reference!

var i;
let nwk_add=global.get('NWKAd') || 0;
let nwk_adds1= parseInt(global.get('NWKAdS1'),16);
let nwk_adds2= parseInt(global.get('NWKAdS2'),16);
node.warn(nwk_adds1);
node.warn(nwk_adds2);

// tratamento das respostas aos comandos do gateway
for (i = 0; i < msg.payload.length; i++) {

// handling parameters and send a response mesage
     switch (msg.payload[3]){
            //Analyze Device Announcement msg 
     case 77:{
                //Send Active Request msg
     newMsg = {payload: new 
     Buffer([0x01,0x02,0x10,0x45,0x02,0x10,0x02,0x12,0xCA,nwk_adds1,nwk_adds2,0x03])}
     return newMsg;
            }
     break;
        }
}

#20

Hi Alex,

I am happy that you sorted it out. My last piece of advice would be: for future projects involving protocol decoding always ask yourself if translating data from hex to decimal to string is really necessary when creating your functions. I have created a few flows for decoding protocols and don´t remember doing such a thing, at least not so frequently. Normally it is better to stick to hex format in each and every step. And a final question also: Only now I realized you are handling the Zigate protocol (I have been there). What is your use case ? What this flow will accomplish when it is fully tested and deployed?