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 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.
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
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":[]}]
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)
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);
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:
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: