Message handeling..... stuck

I've tried. I'm stuck.

I am getting this and need to process it.

{"topic":"STATUS/WIFIDEVICEID","payload":"{\"WIFI_DEVICE\":\"GPS\",\"IP_Address\":\"192.168.1.4\"}","qos":0,"retain":false,"time":"2019-6-4 19:51:11","_event":"node:628072fd.2be434","parts":{"id":"f5bf9f17.778d9","type":"string","ch":"\n","index":0,"count":1},"_msgid":"e4447221.197f7"};

This is what I captured from a MQTT node to simulate the message for the sake of not needing to keep getting the message sent.

I am want to get it into a structure:
msg.topic (existing)
msg.WIFI_DEVICE .....
msg.IP .....
msg.time ......
I think that the msg.payload is JSON formatted - or I think it is.
I have put it through the JSON node to try and get rid of the formatting, but that doesn't seem to work. Though I have memory of using it once before under Nick's advise.

When you say you are getting it, what exactly to you mean? Do you mean that is a message object?
What do you see in a debug node when you feed that message into it and what do you see in a debug node when you feed it into a JSON node. Telling us it doesn't seem to work is not very helpful.

This message arrives for me to process as needed.

But I am having trouble creating what I want.

If you pass it to the Debug node it will tell you instantly if it is a String property, or if it has already been parsed to an Object.

From the look of what you've shared, payload is a JSON string. You say you've put it through a JSON node - which means you've converted the Object you want to a JSON string you don't want. Get rid of the JSON node and look at what you get when you pass it to Debug.

(As per normal I have not explained myself correctly.)

This is the flow:

[{"id":"b54f4981.f5cbf8","type":"ring-buffer","z":"15af81c5.64999e","name":"List generator","capacity":"10","order":"new-to-old","sendOnlyIfFull":false,"pushAfterClear":false,"extra":false,"x":640,"y":3200,"wires":[["27d49363.41f694","517a1964.e5b8f"]]},{"id":"19c14e5b.aa83e2","type":"function","z":"15af81c5.64999e","name":"","func":"msg.time = new Date().toLocaleString();\nmsg.WIFI_DEVICE = \"GPS\";\nmsg.IP = \"192.168.1.4\";\nreturn msg;","outputs":1,"noerr":0,"x":480,"y":3200,"wires":[["b54f4981.f5cbf8","8b18d7f5.c70ea"]]},{"id":"e7955434.2ca548","type":"change","z":"15af81c5.64999e","name":"","rules":[{"t":"set","p":"clear","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":3270,"wires":[["b54f4981.f5cbf8"]]},{"id":"27d49363.41f694","type":"json","z":"15af81c5.64999e","name":"","property":"payload","action":"","pretty":false,"x":830,"y":3140,"wires":[[]]},{"id":"517a1964.e5b8f","type":"ui_template","z":"15af81c5.64999e","group":"1d4190d.ac88b6f","name":"IFF messages received","order":3,"width":"10","height":"4","format":"<table id=\"table\" border=\"1\">\n <tr>\n <th>TEST LIST</th> \n </tr>\n <tbody>\n <tr ng-repeat=\"row in msg.payload track by $index\">\n <td class=\"text\" >{{row}}</td>\n </tr>\n </tbody>\n</table>\n","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":860,"y":3200,"wires":[[]]},{"id":"eea916d8.6f4d7","type":"inject","z":"15af81c5.64999e","name":"","topic":"","payload":"{\"WIFI_DEVICE\":\"GPS\",\"IP_Address\":\"192.168.1.4\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":350,"y":3200,"wires":[["19c14e5b.aa83e2"]]},{"id":"8b18d7f5.c70ea","type":"debug","z":"15af81c5.64999e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"time","targetType":"msg","x":610,"y":3150,"wires":[]},{"id":"fdc83b64.2b5d28","type":"inject","z":"15af81c5.64999e","name":"","topic":"","payload":"{\"WIFI_DEVICE\":\"GPS\",\"IP_Address\":\"192.168.1.4\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":290,"y":3270,"wires":[["e7955434.2ca548"]]},{"id":"1d4190d.ac88b6f","type":"ui_group","z":"","name":"LIST","tab":"ca4afe7.a7c268","order":2,"disp":true,"width":"10","collapse":false},{"id":"ca4afe7.a7c268","type":"ui_tab","z":"","name":"List","icon":"dashboard"}]

Pretty simple.

You can see I am getting the time as msg.time and it is sent on as a ..... message.
But I am not getting why the time is not coming up when it is displayed in the list.
And why is there JSON (?) formatting around the payload?

Ok, I inject that with the function node, but that is what I am getting and want to process.

I am really sorry if I am not seeing the elephant.

(edit)
Oh, and another elephant I am missing:
IP_Address.
When I inject ... Ok. I think I have just dug a big hole for myself.

Look at your flow backwards

  1. the list node displays what it is sent in msg.payload
  2. the ring buffer node add what ever is in msg.payload to it's list and sends the list in msg.payload
  3. in your function node you are not setting msg.payload to anything so it is using what cam in from the inject node
  4. your in inject node you are not sending a timestamp you are sendng a object

so you are displaying what you are telling it to display.

1 Like

For clarity (I hope)

I have got it working else where in my flows.

The other flows generate a "list" of visible wifi networks.
I feed that into the ring-buffer node to make a list, then to the template node to make a list.

So my thinking is that I get other messages that happen "when ever" and do the same (in another list).

The message is what I have shown. Ok, it has a bit more complexity to it than the wifi networks, but..........

So I am getting the "complicated" message (that I have shown) and want to simplify it to something that can be handled by the ring-buffer and template nodes as with the other instance.

But "splitting" these messages seems to be more complex than I thought.
I shot myself big time with the function node after the inject node forgetting the inject node was sending the real information I wanted to process.

The function node got introduced as I was trying to tweak things to get them working.
Alas I then fell over big time with that.

My bad. Sorry.

Thanks.

I had kind of worked that out when I was posting an edit to a message.

Ok, so the original inject node doesn't have a time.

That's not good, but I think MQTT kills that, so I was creating a time stamp here (bigger, faster machine) to get it working and DEPLOY is done in seconds, not minutes.

I am wanting to take apart the message and construct a msg.payload with the sub-messages of the original one and a time stamp.

I've tried split, string and a couple of other nodes to pull apart the original message in the inject node, but am just missing something.

Does that help?

In the ui_template node you use:
<td class="text" >{{row}}</td>
so you are displaying everything in mag.payload. Since it is an object you see the raw object. If you want to display an item of the object you need something like this:
<td class="text" >{{row.IP_Address}}</td>

Maybe that will help you understand.

Ah!

Ok.

That's another way of attacking it I never considered.

I was just wanting to "pull apart" the incoming message and reconstruct a new one which was in the same format as the other message where msg.payload holds all the data, rather than other parts of the message.

I'll go and play with that and see what happens.

Thanks. I never thought of doing it that way - as said.

But before, I go:
Ok, so, if I want row.IP_Address; row.Device, row.time.......

I'll see what mess I can make.

If you want time added to the object, you need to add it in. In your function node you have:
msg.time = new Date().toLocaleString();
which will add it to the msg, but not to the msg.payload......

Yeah. I get that.
I quickly tried changing the {{row.blah}} but I seem to only be able to add one item.

If I want:
{{row.time}}, {{row.WIFI_DEVICE}}, {{row.IP}}
At this point it is beyond me. (Yeah, ok. I need to learn.)

So I was trying to attack it with what I know and:
get the message (the bigger one with all the sub-sets in it) and take it apart and create a new message with the sub components reformatted so it is a simple message format.
But as msg.payload is a bit more complicated that actually having sub-components) it isn't as easy as I thought.

I don't think it is because of MQTT as I captured this data from the remote machine's DEBUG node and pasted it into the inject node on this machine and am trying all locally.

I can't say which way is easier for me to do: The way you suggested or with the knowledge I have.

You are creating colums in a table with;
<td class="text" >{{row.IP_Address}}</td>
so you need one of those with each element

Um.....

Sorry, I'd beg to differ.

It isn't I want a 2D array of stuff from the data/input.

I just want a list of the messages that come in and shown in/on a 1D list.
It will show me the time, device name and IP address.
"Sorted" by time. But the sorting isn't really needed. As they happen they are displayed on the list, so that is not really a thing I need to do.

I am stuck pulling apart the original message (from the inject node) so I can access (?) the sub-data of device name, and IP address.
Time is easy enough.
But getting those 3 pieces of data and creating a new message to send to the ring-buffer and template node is where I am falling over.

How can I get that data?
So I have this:
"payload":"{\"WIFI_DEVICE\":\"GPS\",\"IP_Address\":\"192.168.1.4\"
I want to extract the GPS and 192.168.1.4 bit as variables and then stick them with the time and create a simple message package like:
"payload: <time> <device id> <IP address"
which would look to me/you like (from the example):
"payload: "2019 06 04 21:54:00 GPS 192.168.1.4"
and send that to the ring-buffer and template nodes.

All should be happy.

Clearer?

So msg.payload contains a JSON string. Pass the message through a JSON node to parse it to an object. You can then use msg.payload.WIFI_DEVICE etc.

Nick,

Thanks.

I shall do this and I know you are very much biting your lip as you say it. As I am 100% sure you have told me this before.

I even seem to remember it. But when I tried, I must have missed something.

With that last part about

May be the part which I just didn't quite get.

I'll stop posting/apologising and give it a go.

Honestly:

I don't know what I did earlier that I missed that trick.

Got a function node, combined the parts, spat out the newly constructed message and all is good.

var time_ = new Date().toLocaleString(); var WIFI_DEVICE = msg.payload.WIFI_DEVICE; var IP_ = msg.payload.IP_Address; msg = {payload:time_ + " " + WIFI_DEVICE + " " + IP_}; return msg;

Couldn't really be simpler-er.
(merecat accent - car insurance advert pun)

Wasn't practically the first thing I suggested to feed it into a JSON node and see what came out?

OK, I know I said this is solved, but since then another interesting thing has happened.

What's the difference between these two messages?

{"topic":"STATUS/WIFIDEVICEID","payload":"{\"WIFI-DEVICE\":\"GPS\",\"IP Address\":\"192.168.1.4\"}","qos":0,"retain":false,"_msgid":"bc31500.b046cb","time":"2019-6-6 07:41:28","ttl":0,"_queuetimestamp":1559770888993,"queueCount":1}

and

{"topic":"STATUS/WIFIDEVICEID","payload":"{\"WIFI_DEVICE\":\"GPS\",\"IP_Address\":\"192.168.1.4\"}","qos":0,"retain":false,"_msgid":"2ada05c1.9c8f7a","time":"2019-6-6 07:41:34","ttl":0,"_queuetimestamp":1559770894733,"queueCount":0}

because when one of these goes through the flow I get an undefined/undefined message.
But the other one works.

I have lost the exact error (wasn't thinking) as I thought I would be able to nut it out.

(via edit)
this is the flow (part)

[{"id":"51ace5f8.a38024","type":"json","z":"f49362a5.7218e8","name":"","property":"payload","action":"","pretty":false,"x":330,"y":280,"wires":[["6472439e.94273c"]]},{"id":"6472439e.94273c","type":"function","z":"f49362a5.7218e8","name":"Create message","func":"var time_ = new Date().toLocaleString();\nvar WIFI_DEVICE = msg.payload.WIFI_DEVICE;\nvar IP_ = msg.payload.IP_Address;\nmsg = {payload:time_ + \" \" + WIFI_DEVICE + \" \" + IP_};\nreturn msg;","outputs":1,"noerr":0,"x":490,"y":280,"wires":[["586d4a0.fd389b4"]]}]

Look at your function code. It expects in its input a msg.payload (an object) with the properties: WIFI_DEVICE and IP_Address.

var time_ = new Date().toLocaleString();
var WIFI_DEVICE = msg.payload.WIFI_DEVICE;
var IP_ = msg.payload.IP_Address;
msg = {payload:time_ + " " + WIFI_DEVICE + " " + IP_};
return msg;

One of your string has: WIFI-DEVICE and IP Address
The other has: WIFI_DEVICE and IP_Address

It is better that you use some kind of naming standard to avoid confusion between underscore and dash characters (and space).

1 Like