Operate with hexadecimal

I would like to operate with hexadecimal values inside the function node. 1) convert integer to hexadecimal, 2) concatonate multiple hedecimal values and 3) convert them again to integer.

Is it possible?

Of course.

But why do you need to do those operations in a function node?

What is it you are trying to achieve?

There may be a smarter, more "node-red" solution.

because I receive the information from the incoming message in octets but some variable values is greater than FF=255, i.e. 94 15 (HEX) -> 37909 (DEC)

So there is no real need to do this in a function as I suspected.

Where is data coning from? Could you show me a sample and describe what you want it to be? And I will show you how to use the buffer parser node

This is my flow

[{"id":"8c22840f.1823c8","type":"tab","label":"Flow 4","disabled":false,"info":""},{"id":"61144909.833ad8","type":"pcap","z":"8c22840f.1823c8","name":"","ifname":"enp0s3","output":"object","filter":"ip dst host 84.88.40.59","path":"","x":270,"y":380,"wires":[["cf7729c9.d2926"]]},{"id":"2b89234.6f459dc","type":"debug","z":"8c22840f.1823c8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":910,"y":360,"wires":[]},{"id":"cf7729c9.d2926","type":"function","z":"8c22840f.1823c8","name":"","func":"//data = msg.payload.payload.payload;\n//p = data.dhost.addr[0];\n\n//data = payload.payload.payload.payload.data[0]\n//data = msg.payload.payload.payload;\n//p = data.payload.payload.data[0]\n//payload.payload.payload.payload.data[0]\n\n//// GOOD\n//msg.payload = msg.payload.payload.payload.payload.data[0];\n//return msg;\n\n////\n//var1=' ';\n//data = msg.payload.payload.payload.payload;\n//data = msg.payload\n//var1 = data.data[0].payload;\n//msg.payload.var = msg.payload.payload.payload.payload.data[0];\n//return msg.var;\n//return var1;\n\n\nmsg.var1 = msg.payload.payload.payload.payload.data[0];\nmsg.var2 = msg.payload.payload.payload.payload.data[41];\n\nmsg.payload = \n{\n \"A_Key\": msg.var1,\n \"C_Key\": msg.var2,\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":500,"y":360,"wires":[["2b89234.6f459dc"]]}]

I¡m using the pcap node to snif packets generated in my computer.

The information comes from an UDP payload. This is the whole payload:

ff ff ff ff ff ff 08 00 27 ce a0 de 89 47 11 00 
1a 01 20 50 00 80 00 2d 01 00 00 00 08 00 27 ce 
a0 de a7 84 11 99 19 54 08 fa ce 45 20 f1 01 f0 
07 cc 00 00 00 00 07 d1 00 00 02 02 00 00 00 e0 
94 15 00 59 ca 4a b3 ed 92 b9 27 00 00 00 00 00 
30 d4 1e 00 e1 1f c0 fa 7e bf e9 ed 07 37 fe eb 
ff f6 00

From the above payload, I need to split it and convert it to integer. Another option I though is using the node-asn1 node.

Some examples of variables:

protocolVersion = 02
messageID = 02
station ID: 00 00 00 e0

Let me know if you need more information.

So I am guessing that protocolVersion is in byte 58, messageID is in byte 59 & station ID is bytes 60~63 and is UINT32.

So you can achieve this without writing functions (apart from to clean up the input data) e.g...

image

flow...

[{"id":"3fd37e51.c77472","type":"inject","z":"86da601e.048d6","name":"raw string data","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"ff ff ff ff ff ff 08 00 27 ce a0 de 89 47 11 00  1a 01 20 50 00 80 00 2d 01 00 00 00 08 00 27 ce  a0 de a7 84 11 99 19 54 08 fa ce 45 20 f1 01 f0  07 cc 00 00 00 00 07 d1 00 00 02 02 00 00 00 e0  94 15 00 59 ca 4a b3 ed 92 b9 27 00 00 00 00 00  30 d4 1e 00 e1 1f c0 fa 7e bf e9 ed 07 37 fe eb  ff f6 00","payloadType":"str","x":1020,"y":80,"wires":[["2ff7a6ff.f3839a"]]},{"id":"2ff7a6ff.f3839a","type":"function","z":"86da601e.048d6","name":"clean up data","func":"//remove non-alphanumeric\nmsg.payload = msg.payload.replace(/\\W/g, '');\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1040,"y":120,"wires":[["1bb3ea64.a56f36","b049b686.079018"]]},{"id":"1bb3ea64.a56f36","type":"debug","z":"86da601e.048d6","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1210,"y":120,"wires":[]},{"id":"b049b686.079018","type":"buffer-parser","z":"86da601e.048d6","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint8","name":"protocolVersion","offset":58,"length":1,"offsetbit":0,"scale":1,"mask":""},{"type":"uint8","name":"messageID","offset":59,"length":1,"offsetbit":0,"scale":1,"mask":""},{"type":"uint32be","name":"stationID","offset":60,"length":1,"offsetbit":0,"scale":1,"mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"output","multipleResult":false,"setTopic":true,"x":1160,"y":160,"wires":[["20381407.10a6bc"]]},{"id":"20381407.10a6bc","type":"debug","z":"86da601e.048d6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1190,"y":200,"wires":[]}]

Requires node-red-contrib-buffer-parser

2 Likes

The problem is that when I read the byte, it automatically converts it in integer so, in single-octet variable the value matches like the first two variables presented, however, in a two or more octet size value, I should first convert from integer to HEX, concatonate them and convert them again into integer.

Can you explain with a real example with actual values before and after + your logic on how you achieve that? I suspect its just a byte swap issue.

Anyhow, you do realise that integer and hex are the same value right (just an alternate base representation)?
j3Vp8R43th

Or do you actually WANT hex strings? cos you can get hex strings too...

image

I know it is the same value represented in a different base. The whole hexadecimal chain I've sent you is not collected like this by the function node, it is just the payload from a UDP message sniffed with pcap. I collect the octets individually (I don't how to collect them in group) by using this command:

msg.var1 = msg.payload.payload.payload.payload.data[0];

image

When I read the first position value of data, I get the value 255 not FF. How do I expect to get the value, for instance, generationDeltaTime = 94 15 (HEX) -> 37909 If I can just collect the byte separately?

Again, use the buffer parser node!

94 15 converted to a UINT16(BE) == 37909

e.g...

demo flow...

[{"id":"3fd37e51.c77472","type":"inject","z":"86da601e.048d6","name":"A buffer of data","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[255,255,255,255,255,255,8,0,39,206,160,222,137,71,17,0,26,1,32,80,0,128,0,45,1,0,0,0,8,0,39,206,160,222,167,132,17,153,25,84,8,250,206,69,32,241,1,240,7,204,0,0,0,0,7,209,0,0,2,2,0,0,0,224,148,21,0,89,202,74,179,237,146,185,39,0,0,0,0,0,48,212,30,0,225,31,192,250,126,191,233,237,7,55,254,235,255,246,0]","payloadType":"bin","x":980,"y":100,"wires":[["b049b686.079018","1bb3ea64.a56f36"]]},{"id":"b049b686.079018","type":"buffer-parser","z":"86da601e.048d6","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint8","name":"protocolVersion","offset":58,"length":1,"offsetbit":0,"scale":1,"mask":""},{"type":"uint8","name":"messageID","offset":59,"length":1,"offsetbit":0,"scale":1,"mask":""},{"type":"uint32be","name":"stationID","offset":60,"length":1,"offsetbit":0,"scale":1,"mask":""},{"type":"uint16be","name":"Item4[94 15]","offset":64,"length":1,"offsetbit":0,"scale":1,"mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"output","multipleResult":false,"setTopic":true,"x":1160,"y":160,"wires":[["20381407.10a6bc"]]},{"id":"20381407.10a6bc","type":"debug","z":"86da601e.048d6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1190,"y":200,"wires":[]},{"id":"1bb3ea64.a56f36","type":"debug","z":"86da601e.048d6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1170,"y":100,"wires":[]}]

So ^ I fed a buffer of data into the buffer parser & as you can see, it know how to convert the bytes


Yeah! My demo was based on the data you provided in post #5.

So I provided a solution.

But, regardless, as I have demonstrated above - it doesnt matter - feed a buffer into it instead of a hex string!

So long as you have an array of ints or a HEX String or a buffer (as you do in your screen shot) - feed it into the buffer parser, tell it what values you want & in what format (byte/int8/uint8,uint16/uint32 etc etc etc etc etc)

How do I create this buffer :

[255,255,255,255,255,255,8,0,39,206,160,222,137,71,17,0,26,1,32,80,0,128,0,45,1,0,0,0,8,0,39,206,160,222,167,132,17,153,25,84,8,250,206,69,32,241,1,240,7,204,0,0,0,0,7,209,0,0,2,2,0,0,0,224,148,21,0,89,202,74,179,237,146,185,39,0,0,0,0,0,48,212,30,0,225,31,192,250,126,191,233,237,7,55,254,235,255,246,0]

from this command at the function code

msg.var1 = msg.payload.payload.payload.payload.data[0];

From pcap doesn't come the buffer I've inserted, it was the chunck of information I need to parse

Is msg.payload.payload.payload.payload.data a buffer or an array?

Set the debug to show "complete message" & click the copy button that appears under you mouse then paste that in a reply

like this...

EDIT - also, expand your message so that msg.payload.payload.payload.payload.data is visible - does the debug node describe it as a buffer or array?

{"payload":{"link_type":"LINKTYPE_ETHERNET","pcap_header":{"tv_sec":1604796151,"tv_usec":651857,"caplen":141,"len":141},"payload":{"dhost":{"addr":[128,120,113,67,87,122]},"shost":{"addr":[8,0,39,206,160,222]},"ethertype":2048,"vlan":null,"payload":{"version":4,"headerLength":20,"diffserv":0,"length":127,"identification":39821,"flags":{"reserved":false,"doNotFragment":true,"moreFragments":false},"fragmentOffset":0,"ttl":64,"protocol":17,"headerChecksum":24686,"saddr":{"addr":[192,168,1,55]},"daddr":{"addr":[84,88,40,59]},"payload":{"sport":445,"dport":445,"length":107,"checksum":16111,"data":[255,255,255,255,255,255,8,0,39,206,160,222,137,71,17,0,26,1,32,80,0,128,0,45,1,0,0,0,8,0,39,206,160,222,167,132,17,153,25,84,8,250,206,69,32,241,1,240,7,204,0,0,0,0,7,209,0,0,2,2,0,0,0,224,82,232,0,89,202,95,177,45,146,179,165,224,0,0,0,0,48,212,30,0,225,31,192,250,126,191,233,237,7,55,254,235,255,246,0]}}}},"topic":"enp0s3","_msgid":"d4caea19.3a07d8","var1":255,"var2":250}

This is the flow:

[{"id":"8c22840f.1823c8","type":"tab","label":"Flow 4","disabled":false,"info":""},{"id":"61144909.833ad8","type":"pcap","z":"8c22840f.1823c8","name":"","ifname":"enp0s3","output":"object","filter":"ip dst host 84.88.40.59","path":"","x":270,"y":380,"wires":[["cf7729c9.d2926"]]},{"id":"2b89234.6f459dc","type":"debug","z":"8c22840f.1823c8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":890,"y":360,"wires":[]},{"id":"cf7729c9.d2926","type":"function","z":"8c22840f.1823c8","name":"","func":"//data = msg.payload.payload.payload;\n//p = data.dhost.addr[0];\n\n//data = payload.payload.payload.payload.data[0]\n//data = msg.payload.payload.payload;\n//p = data.payload.payload.data[0]\n//payload.payload.payload.payload.data[0]\n\n//// GOOD\n//msg.payload = msg.payload.payload.payload.payload.data[0];\n//return msg;\n\n////\n//var1=' ';\n//data = msg.payload.payload.payload.payload;\n//data = msg.payload\n//var1 = data.data[0].payload;\n//msg.payload.var = msg.payload.payload.payload.payload.data[0];\n//return msg.var;\n//return var1;\n\n\nmsg.var1 = msg.payload.payload.payload.payload.data[0];\nmsg.var2 = msg.payload.payload.payload.payload.data[41];\n\n//msg.payload = \n//{\n// \"A_Key\": msg.var1,\n// \"C_Key\": msg.var2,\n//}\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":500,"y":360,"wires":[["2b89234.6f459dc"]]}]

So, you didnt fully expand the debug msg in your screenshot to show me the data type of msg.payload.payload.payload.payload.data - never mind, I will just convert it to buffer whatever it is.

[{"id":"3fd37e51.c77472","type":"inject","z":"86da601e.048d6","name":"click me","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":540,"y":80,"wires":[["50ffcf0a.efe37"]]},{"id":"b049b686.079018","type":"buffer-parser","z":"86da601e.048d6","name":"","data":"data","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint8","name":"protocolVersion","offset":58,"length":1,"offsetbit":0,"scale":1,"mask":""},{"type":"uint8","name":"messageID","offset":59,"length":1,"offsetbit":0,"scale":1,"mask":""},{"type":"uint32be","name":"stationID","offset":60,"length":1,"offsetbit":0,"scale":1,"mask":""},{"type":"uint16be","name":"Item4","offset":64,"length":1,"offsetbit":0,"scale":1,"mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"output","multipleResult":false,"setTopic":true,"x":1010,"y":120,"wires":[["20381407.10a6bc"]]},{"id":"20381407.10a6bc","type":"debug","z":"86da601e.048d6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1210,"y":120,"wires":[]},{"id":"1bb3ea64.a56f36","type":"debug","z":"86da601e.048d6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1210,"y":80,"wires":[]},{"id":"50ffcf0a.efe37","type":"function","z":"86da601e.048d6","name":"fake pcap","func":"\nreturn {\"payload\":{\"link_type\":\"LINKTYPE_ETHERNET\",\"pcap_header\":{\"tv_sec\":1604796151,\"tv_usec\":651857,\"caplen\":141,\"len\":141},\"payload\":{\"dhost\":{\"addr\":[128,120,113,67,87,122]},\"shost\":{\"addr\":[8,0,39,206,160,222]},\"ethertype\":2048,\"vlan\":null,\"payload\":{\"version\":4,\"headerLength\":20,\"diffserv\":0,\"length\":127,\"identification\":39821,\"flags\":{\"reserved\":false,\"doNotFragment\":true,\"moreFragments\":false},\"fragmentOffset\":0,\"ttl\":64,\"protocol\":17,\"headerChecksum\":24686,\"saddr\":{\"addr\":[192,168,1,55]},\"daddr\":{\"addr\":[84,88,40,59]},\"payload\":{\"sport\":445,\"dport\":445,\"length\":107,\"checksum\":16111,\"data\":[255,255,255,255,255,255,8,0,39,206,160,222,137,71,17,0,26,1,32,80,0,128,0,45,1,0,0,0,8,0,39,206,160,222,167,132,17,153,25,84,8,250,206,69,32,241,1,240,7,204,0,0,0,0,7,209,0,0,2,2,0,0,0,224,82,232,0,89,202,95,177,45,146,179,165,224,0,0,0,0,48,212,30,0,225,31,192,250,126,191,233,237,7,55,254,235,255,246,0]}}}},\"topic\":\"enp0s3\",\"_msgid\":\"d4caea19.3a07d8\",\"var1\":255,\"var2\":250};","outputs":1,"noerr":0,"initialize":"","finalize":"","x":680,"y":80,"wires":[["f36edb31.433228"]]},{"id":"f36edb31.433228","type":"function","z":"86da601e.048d6","name":"convert data to buffer","func":"msg.data = Buffer.from(msg.payload.payload.payload.payload.data)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":980,"y":80,"wires":[["1bb3ea64.a56f36","b049b686.079018"]]},{"id":"719a99b7.7d1f28","type":"comment","z":"86da601e.048d6","name":"Just faking pcap as I dont have that node. Delete me.","info":"","x":600,"y":40,"wires":[]}]

I want to get those output values to create a given JSON structure, I've tried to create this code within the function node (after the buffer).

var protocolVersion, messageID;
msg.payload = 
{
    "protocolVersion": protocolVersion,
    "messageID": messageID,
}
return msg;

However, I get this error:

11/9/2020, 10:01:39 AMnode: df05e58e.66506 enp0s3 : msg.payload : Object { protocolVersion: undefined, messageID: undefined }

That is exactly what the buffer parser does for you in a nice UI (without all the custom function code).

Look at the output in the last screenshot - it is a JS object containing exactly that.

If you actually mean you want JSON (JavaScript Object Notation - i.e. a STRING representation of a JS object) then pass the JS object through a JSON node to convert it from a JS object to a JSON string.

What are you not understanding? What am i missing here?

I need the JSON structure in a given way like this:

image

And the output from the parser sends the information in the same branch.

ok, so now it is clearer.

  1. Use the buffer parser to generate all the values (as demonstrated above)
  2. Re-arrange the JS object (that you get from the buffer parser) in a function node like this...
var newFormat = {}; //make an empty object before adding fields
newFormat.version = "1.0.0"; //add version field
newFormat.source_uuid= 1; //add source_uuid field
newFormat.timestamp = msg.payload.timestamp;
newFormat.message = {}; //make an empty object before adding fields
newFormat.message.protocol_version = msg.payload.protocolVersion;
newFormat.message.station_id = msg.payload.stationID;
newFormat.message.generation_delta_time = msg.payload.timestamp;
newFormat.message.basic_container = {}; //make an empty object before adding fields
newFormat.message.basic_container.station_type = 5;
newFormat.message.basic_container.reference_position = {}; //make an empty object before adding fields
newFormat.message.basic_container.reference_position.lattitude = msg.payload.lattitude;
newFormat.message.basic_container.reference_position.longitude = msg.payload.longitude; 
//and so on until you have taken the buffer parser data and made an object matching your requirement

//now return that to the next node...
msg.payload = newFormat;
return msg;

No you don't, a JSON object is a string, you want a javascript object.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.