Extracting Data from payload

Hi all,

Hoping someone can help as this is doing my head in!
I have data coming in from a serial port (wireless USB dongle) which is connected fine and happily throwing out data whenever it arrives.
The data arrives in this format:
{SN:0451D4,TN1:22.40,TM1:22.40,TA1:22.40,TN2:-27.04,TM2:-27.04,TA2:-27.04}

What i am trying to do is get a specific value to appear on the dashboard Gauge. For some reason it wont seem to convert into just a specific value, in spite of trying the change node, split node and a few others. Im not a JSON or Function node expert which doesnt help.

Thanks for any help you can provide.

Nick

Have you read the page in the docs about working with messages?

Try starting with that and a debug node with ( and without) a jasn node

That data looks almost JSON. Have you tried sending the data to JSON node to see if it will convert.

And check out the help info about "working with messages". It will help you tremendously. It's about a 10min read. Definitely worth it.

Thanks for the advice. I haven’t tried the JSON node yet.
Tbh I’m a bit baffled by the whole thing!
I did try to read the beginners guide but again i just got lost.

Will do, thanks.

Which values do you want to extract? If you strip off the "{" and "} you have a well ordered set of data separated by "," and each pair is further separated by ":" - Just a pointer :slight_smile:

sadly it's close but not JSON so the JSON node won't help... if the sensor would send
{"SN":"0451D4","TN1":22.40, ... i.e. with quotes around any text, then you would be fine.

However you should be able to create an object like this flow below - you can then use a switch node to pick off the parts you want.

[{"id":"cc982ed3.321f5","type":"inject","z":"3658255b.2041aa","name":"","topic":"","payload":"{SN:0451D4,TN1:22.40,TM1:22.40,TA1:22.40,TN2:-27.04,TM2:-27.04,TA2:-27.04}","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":1340,"wires":[["a8e614aa.fd58d8"]]},{"id":"a8e614aa.fd58d8","type":"function","z":"3658255b.2041aa","name":"","func":"var bits = msg.payload.substr(1,msg.payload.length-2).split(\",\");\nnode.warn(bits)\nvar p = {};\nbits.forEach(function (item, index) {\n  b = item.split(\":\");\n  p[b[0]] = b[1];\n});\nmsg.payload = p;\nreturn msg;","outputs":1,"noerr":0,"x":260,"y":1340,"wires":[["c9e8fd75.36fea"]]},{"id":"c9e8fd75.36fea","type":"debug","z":"3658255b.2041aa","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":430,"y":1340,"wires":[]}]

Thanks for the help. I just want the TN1: number really, the rest i dont need. Just cant work out how to do it!.

Feed this into a split node and split it on a comma. Next feed the output into a switch node and select 'contains' and set the value to TN1 - that will only pass the TN1 string. Feed this to another split node and split it on ':' and you should have you're number (but it will be a string so you might need to convert that)

2 Likes

OMG thank you so much - worked perfectly.

I see you already have a solution -- but there are always other ways to do it!

Whenever I see a well-ordered string like this (that is not quite parsable as JSON), I think of using a regex parser... In the case of your specific data, here is a generic bit of JS code that can turn that string into a JS object, with fields for each of the keys:

let s = "{SN:0451D4,TN1:22.40,TM1:22.40,TA1:22.40,TN2:-27.04,TM2:-27.04,TA2:-27.04}";
let o = {};
s.replace(/([^{,:]+):([^,}]+)/g, (t,k,v) => o[k] = v);

The result is the generic JS object:

{
  SN: '0451D4',
  TN1: '22.40',
  TM1: '22.40',
  TA1: '22.40',
  TN2: '-27.04',
  TM2: '-27.04',
  TA2: '-27.04'
}

This can be used (with a few changes) inside a function node, or the same can be converted to a JSONata expression, and put directly into a change node, like so:

image

You can then pass this same object to many dashboard UI nodes, and each can be configured to pull out only the field of interest -- no need to split the object up any further! Which makes it extensible: as the sensor sends more fields, they are automatically added to the output msg payload and available downstream.

Edit:
Now that I think about it, you'll probably want to convert any "numeric" values to actual numbers for charting -- so I've included a quick regex test to find values that consist of only numbers, a decimal point, and optional sign:

payload.$match(/([^{,:]+):([^,}]+)/).[groups] {
    $[0]: $[1].$match(/^[+-.\d]+$/) ? $number($[1]) : $[1]
}
1 Like