Extract Numbers from msg.payload (String)

Hello Guys!

After repeatedly trying to get my flow to work, I've decided to ask for help.

What I want to achieve: I've got a string with a lot of data from our heating system and I need to separate it into single numeric values for my ioBroker vis. I've tried python scripts with regular expressions, tried the switch and change nodes and the nr-regexp-filter node, but I havent had any success.

In addition to this I've got another string from our heating system that I want to implement in my ioBroker vis.

First String: pm 54.3 54.5 18.1 -20.0 -20.0 -20.0 7934.3 13.5 26.0 -20.0 -9.0 -9.0 -9.0 55.7 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 18.0 0.0 0.0 0.0 0.0 130.0 12.0 0.0 0.0 0.0 1.0 0000 0004 0005 0002 0000 0000 0000 0000 <\r><\n><\n>

Second String: z 21:27:35 Lambdaheizung ein <\n><\r>

The first string contains various values and is sent by the heating system every second. The second string contains messages when, for example, an error occures.

I would like to split the first string into single numeric values and then output them to ioBroker topics.
I already made a regex in python and javascript:

It's big, so don't be scared. :slight_smile: (python)
pm (?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P

[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[-?\d.])\s(?P[\w])\s(?P[\w])\s(?P[\w])\s(?P[\w])\s(?P[\w])\s(?P[\w])\s(?P[\w])\s(?P[\w])[^<]

Regex for second string (python):
z (?P[\d:\d:\d:])(?P[\s\S][^<])

I just cant get my hand around how to implement this into a flow.

I hope somebody can help me :smiley:

Edit: Corrected typos
Edit2: Ok, I don't know why, but I can't post the original regex without being messed up. It always cuts out the names of the capturing groups with comparative signs

For your first string, a simple split might be better suited?

See if this helps you get any closer to a solution...

[{"id":"4311d3e4.8ae2ac","type":"inject","z":"b9a43aed.f09838","name":"demo data 54.3 54.5 18.1 -20.0 -20.0 -20....","topic":"","payload":"54.3 54.5 18.1 -20.0 -20.0 -20.0 7934.3 13.5 26.0 -20.0 -9.0 -9.0 -9.0 55.7 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 18.0 0.0 0.0 0.0 0.0 130.0 12.0 0.0 0.0 0.0 1.0 0000 0004 0005 0002 0000 0000 0000 0000","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":930,"y":100,"wires":[["f5159f84.5f0ab"]]},{"id":"f5159f84.5f0ab","type":"function","z":"b9a43aed.f09838","name":"convert to individual topic/payloads","func":"\nvar topics = {\n    0: \"topic 1/reaname/me\",\n    1: \"topic 2/rename/me/too\",\n    3: \"topic 4\",\n    18: \"topic 19\",\n    32: \"topic 33\",\n    }\n    \nvar data = msg.payload.split(\" \");\nfor(let i = 0; i < data.length; i++){\n    let t = topics[i];\n    let v = data[i];\n    if(t) {\n        node.send({\n            topic: t,\n            payload: parseFloat(v)\n        })\n    }\n}\n\nreturn null;","outputs":1,"noerr":0,"x":950,"y":160,"wires":[["76ed3c2d.5fecd4"]]},{"id":"76ed3c2d.5fecd4","type":"debug","z":"b9a43aed.f09838","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1030,"y":220,"wires":[]}]

I was about to reply but then saw Steve is about to reply and I'm on a tablet virtual keyboard so I'll withdraw. :joy:

Edit: top notch reply as always and better job I could've done on a tablet as I expected.

no no - i did a quick hack - give us your answer @ristomatti :slight_smile:

I was about to suggest pretty much the same but without the fancy animations. :slightly_smiling_face:

1 Like

Thank you for your really fast reply (didn't expect that :slight_smile:).

I will give it a try.

We are a helpful lot here :slight_smile:

Plus, the wife is on a zoom chat :smiley:

1 Like

You could also possibly use the csv node set to split on a space rather than a comma. That way you could also assign property names to each column if you know what they are.

1 Like

Nice solution Dave.

Good use of the CSV node

@Tangensphi - this would be a solution without the function node...
image

[{"id":"879a195a.741c98","type":"inject","z":"b9a43aed.f09838","name":"demo data 54.3 54.5 18.1 -20.0 -20.0 -20....","topic":"","payload":"54.3 54.5 18.1 -20.0 -20.0 -20.0 7934.3 13.5 26.0 -20.0 -9.0 -9.0 -9.0 55.7 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 18.0 0.0 0.0 0.0 0.0 130.0 12.0 0.0 0.0 0.0 1.0 0000 0004 0005 0002 0000 0000 0000 0000","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":430,"y":120,"wires":[["9581da1e.b12ed8"]]},{"id":"9581da1e.b12ed8","type":"csv","z":"b9a43aed.f09838","name":"","sep":" ","hdrin":"","hdrout":"","multi":"one","ret":"\\n","temp":"topic/1,topic/2,topic/3,topic/4","skip":"0","strings":true,"x":350,"y":180,"wires":[["2168c8bd.e54a68"]]},{"id":"715c958a.e0077c","type":"debug","z":"b9a43aed.f09838","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":650,"y":180,"wires":[]},{"id":"2168c8bd.e54a68","type":"split","z":"b9a43aed.f09838","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"topic","x":490,"y":180,"wires":[["715c958a.e0077c"]]}]

You will need to set the topics in the CSV Columns field

Hey Guys,

just wanted to let you know that I've used the csv Node like you suggested. It works like a charm.
Thank you all! :slight_smile:

1 Like

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