Reading String of Hex from T-zone RD05 problem

Firstly, I am a newbie from using Node Red,

I got 4 DHT22 sensors connected wirelessly to a TZ-RD05. And the TZ-RD05 is connected to my raspberry pi 3 through a serial port.
I have the data display is a string like in the picture. Can anyone help me to convert that string to a usable value? (The string is in RSSI value format and contains id, tag, check code, end code and the value of temperature and humidity).

After some quick learning some tutorials, I have an idea of adding some node such as "switch", "split", "set payload"... But have no idea how it works yet.

Thank you for any help.

Can you point to a concise definition of RSSI value format?

This is a data sample. I can read it from the TZ but can not decode.

This is a great use for https://flows.nodered.org/node/node-red-contrib-binary
(but this has it's own learning curve to get the parser spec correct... as it uses a underlying library called packet - https://github.com/bigeasy/packet but should be able to template that out quite easily.

Are you sure, given the fact that input data is a string?

If the string always follows the same format, couldn't you use slice() to extract whatever you need from it?
I'm assuming that you probably only need the battery, temperature & humidity.
Try this example where I extract the battery voltage 0E10;

[{"id":"c0167800.11f068","type":"inject","z":"c53060.842a0fa","name":"","topic":"","payload":"AB2375GG3655K0E10J87B","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":970,"wires":[["f3d7b97a.f156b8"]]},{"id":"f3d7b97a.f156b8","type":"function","z":"c53060.842a0fa","name":"","func":"var batt = msg.payload;\nbatt = batt.slice(11, -4); // Get battery voltage 0E10\nmsg.payload = parseInt(batt);\nreturn msg;","outputs":1,"noerr":0,"x":420,"y":970,"wires":[["bca2271.0c202d8"]]},{"id":"bca2271.0c202d8","type":"debug","z":"c53060.842a0fa","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":630,"y":970,"wires":[]}]

Good luck with node-red-contrib-binary. I tried. I failed!!

Yes, the TZ is working with a combination of 4 DHT22 sensors, but the output is a string of hex (shown in the first figure). I just cannot convert that string into decimal with value of temp and humidity ( noticed the space between the Hex number as well)

OK, I was looking at your later post;
sample
which doesn't have spaces.

But that is even better! take a look at a similar bit of code that I used to decode some sensor data - node-red-contrib-rf-decode/rf-decode.js at master · Paul-Reed/node-red-contrib-rf-decode · GitHub
I am using split(), shift(), pop() & slice() to extract what data sections that I needed.

In my case, the input data took the form of OK 23 22 1 0 0 0 0 237 94 188 4 (-61)

I am no expert, but got a lot of forum help writing it, especially from @dceejay and learned a lot along the way!

This may get you started...

[{"id":"da83610d.0f233","type":"inject","z":"1d34d3c1.70a2dc","name":"simulate TZ data","topic":"","payload":"7E 0D 12 34 56 62 16 01 79 00 0E 10 00 EC 4F 72 03","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":420,"y":580,"wires":[["2d8bf6a5.5e34aa"]]},{"id":"2d8bf6a5.5e34aa","type":"function","z":"1d34d3c1.70a2dc","name":"Parse data","func":"let parsed = {} \nlet p = msg.payload\nparsed.parts = p.split(\" \");\nparsed.data = p;\nparsed.datalength = parseInt(parsed.parts[1],16);\nparsed.id = parsed.parts[2] + parsed.parts[3] + parsed.parts[4] ;\nparsed.tagId = parsed.parts[5] + parsed.parts[6] + parsed.parts[7] + parsed.parts[8] ;\nparsed.tagStatus = parseInt(parsed.parts[9] ,16);\nparsed.batteryVoltage = parseInt(parsed.parts[10] + parsed.parts[11] ,16);\nparsed.temperature = parseInt(parsed.parts[12] + parsed.parts[13] ,16);\nparsed.humidity = parseInt(parsed.parts[14],16);\nparsed.checkCode = parseInt(parsed.parts[15],16);\n\nmsg.payload = parsed \nreturn msg;","outputs":1,"noerr":0,"x":530,"y":620,"wires":[["1a1b15d4.375f1a"]]},{"id":"1a1b15d4.375f1a","type":"debug","z":"1d34d3c1.70a2dc","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":650,"y":660,"wires":[]}]
1 Like

@Steve-Mcl This will no doubt come up again, and would be good to have your example in the flow library.

Sorry the data sample is from the data-sheet of the TZ-RD05, not what i have. But will try, thank you.

Its not really hardened and doenst use the checksum to verify data (I assume checksum is some BCC or XOR)

And I am uncertain of this device and this string format - is it ALWAYS that way for that particular sensor input?

But if you believe it helps other people, feel free to take it, improve it & add it as a flow library Paul. I'm fine with that (no need to mention me in the post tho haha).

@Bond did this work for you? Looking at your data output it looks like it should just work.

1 Like

This example using the contrib binary node
(assumes that the data is actually arriving as a buffer rather than a string but easy to convert if required.

[{"id":"9c328481.dfcfa8","type":"inject","z":"a68cca8a.e5ba98","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":1100,"wires":[["a05ae5fb.4cbda8"]]},{"id":"a05ae5fb.4cbda8","type":"function","z":"a68cca8a.e5ba98","name":"","func":"msg.payload = new Buffer('7e0d12345662160179000e1000ec4f7203', 'hex');\nreturn msg;","outputs":1,"noerr":0,"x":310,"y":1100,"wires":[["ef82130.ae0e5f"]]},{"id":"ef82130.ae0e5f","type":"binary","z":"a68cca8a.e5ba98","name":"","pattern":"x8, b8 => len, b8[3] => id, b8[4] => tag, b8 => status, b16 => volt, b16 => temp, b8 => hum, b8 => crc,  x8","x":470,"y":1100,"wires":[["45e7eef1.5d59b"]]},{"id":"45e7eef1.5d59b","type":"debug","z":"a68cca8a.e5ba98","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":650,"y":1100,"wires":[]}]
1 Like

Easy when you know how!!
I spent hours reading about the underlying package, and never got anywhere near reaching a solution.

Yeah - I'll try and get hold of the author and see what we can do.

1 Like

Sorry I have been away. I tried slice(), for some reason the output is only one character regardless of what index I put in the slice() function.

var test = msg.payload;
test = test.slice(0,1);
msg.payload = parseInt(test);
return msg;

Then I try the code from @Steve-Mcl, and I have problem in the line shown in the pic.
I also try to get rid of the space by using trim() but it only works for the first and last space, not the spaces in between. Therefore, could not use example from @dceejay.
I still don't know why my output got 47 indexes (shown in the first pic).

How did you import my flow? You copied the function code from this thread and pasted it directly into a function node in I suspect?.

Youre supposed to copy the whole flow code from the forum, go to node-red editor, press CTRL+I (to import), paste in the flow code, then import.

Line 3 should be parsed.parts = p.split(" ")

Try importing my sample and testing that, then hook it up to your data.

Got it working now, thank you so much.
Now i want to split the temperature value to binary as well, because the first two bits indicate sign and stage of temperature, the other bits are real value of temperature.
Thanks again for your help, i'm still learning :slight_smile:

well the binary node may be able to do that as well as it can handle bits as well - but we can't see the spec of what you're after - so it's up to you at this point.

Search Web for...
JavaScript get bit from number
And
JavaScript mask number

These will help you understand how to get bit 15 and bit 14 then use a mask of 0x3fff to delete bits 15&14 to leave you with the correct temperature.

Add something like this inside the function node you already have...

function getbit(value, bit){
  // You need to figure this out
}
var sign = getbit(temperature, 15);
var stat = getbit(temperature, 14);
temperature = temperature & 0x3fff;
if(sign)
  temperature = -temperature;
msg.payload.temperature = temperature;

**Note, this code is untested and you will need to search for how to get bits **