Preface:
This was brought about because of a lot of help I got from other people in my quest to send complicated messages over MQTT
.
Thanks to @knolleary, @JGKK for helping me .... resolve the problem and for the inspiration to sit down and nut out the problem and so lead me to this trick.
What is MQTT
?
MQTT is a great thing I kind of took to early on and it is great for sending messages between devices.
Normally you are only sending simple messages which only have a payload
.
The topic
is used by/in MQTT
to control who gets the message.
I want to expand MQTT
's usability to make it more like how a link
node works on a machine.
You can use a LINK OUT
node to go to another tab where you have a LINK IN
node and it connects the two points as though they were connected.
They are used to help tidy flows up and separate parts so they are easier to understand.
What you send to the LINK OUT
is received and the LINK IN
.
Simple.
So basically a typical message going into a MQTT OUT
node would have a payload
and topic
. Though the topic
can be set in the MQTT OUT
node.
Terrific if you are only sending simple (or basic?) msg.payload
s
But what happens when you start getting adventurous with what you are sending?
Well: then it all gets complicated.
If you want to send (say) a payload
and a colour
?
msg.payload
and msg.colour
Then, you have to re-construct the msg
so it is actually structured as:
msg.payload.payload
and msg.payload.colour
This can be achieved by adding a function
node and putting a line in it like:
msg1.payload.payload = msg.payload;
msg1.payload.colour = msg.colour;
return msg1;
Maybe not exactly correct, but that is the idea of what is needed to send the message.
(And if you want to then add something else, you have to open the node and include a new line for the new piece of the message you want to send.)
Then, at the other end, you will receive the message in the new format.
Which had me going nuts for days back in the early days.
Also:
Back then, the MQTT IN
node also didn't have an option to make the payload
a JSON
string. So first off you had to put the message through a JSON
node.
Then on the other machine, you have to remember the new structure of the message.
Rather than being:
msg.payload
and msg.colour
, it becomes:
msg.payload.payload
for the payload and
msg.payload.colour
for the colour.
Really annoying.
I get it that MQTT
has its limits and I am not knocking them. It is just annoying if you have code on one machine and want to send a message (complicated) to another machine.
The structure of the messages will be different to what it was before it went through MQTT
.
So, to send it: you have to re-construct the message as just shown, and
when you receive it: the structure is different.
Therefore you can't just export/import code from one machine to the other and it works.
Yes, not the end of the world but can be a pain for people who are new to this, and annoying as you have to keep remembering to modify how the message is de-constructed at the receiving end.
(As well as having to remember to add a new line at the sending end too!)
This is a great cheat which is only two nodes
to be added.
One at the sending end and one at the receiving end.
With these two nodes included the flow at either side won't care/see what is happening.
This is an example flow to demonstrate the application of the two nodes
.
All nodes with an *
in their name has more to be read by opening them and looking in/on their comment page.
[{"id":"d8761a94.8ed48","type":"debug","z":"d103f472.19f3c8","name":"Received at other end","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":920,"y":3640,"wires":[]},{"id":"5161ffa8.9139b8","type":"mqtt out","z":"d103f472.19f3c8","name":"","topic":"temp","qos":"","retain":"","broker":"378c0403.8cda04","x":380,"y":3800,"wires":[]},{"id":"c5f87b0a.6c061","type":"mqtt in","z":"d103f472.19f3c8","name":"","topic":"temp","qos":"2","datatype":"json","broker":"378c0403.8cda04","x":530,"y":3800,"wires":[["50588e79.36139"]]},{"id":"50588e79.36139","type":"function","z":"d103f472.19f3c8","name":"*CHEAT NODE 2*","func":"var newMsg = msg.payload; \nreturn newMsg;","outputs":1,"noerr":0,"x":700,"y":3764,"wires":[["d8761a94.8ed48"]],"info":"This node takes the *modified* message and puts it back to what it was on the other machine before it was sent via MQTT.\nSimple.\n2 lines of code."},{"id":"5f7589e.a37ae78","type":"debug","z":"d103f472.19f3c8","name":"Message wanting to be sent","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":610,"y":3640,"wires":[]},{"id":"581f3926.17eb3","type":"function","z":"d103f472.19f3c8","name":"*CHEAT NODE 1*","func":"//node.warn(msg);\n\nvar newMsg = {payload:msg}\n\nreturn newMsg;\n\n","outputs":1,"noerr":0,"x":200,"y":3770,"wires":[["5161ffa8.9139b8","7c5b4d3d.dba8ac"]],"info":"This node has 2 lines and accepts dynamic message structures.\nSo you don't have to remmeber to add extra / new lines if/when you change the `message` structure.\n"},{"id":"8240bcf1.fb6dc8","type":"inject","z":"d103f472.19f3c8","name":"Test","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":3590,"wires":[["9c01ed2f.ab1a68"]]},{"id":"9c01ed2f.ab1a68","type":"function","z":"d103f472.19f3c8","name":"Make a copmlicated message structure","func":"msg = {\n payload:\"This is the payload\",\n blah1:\"This is blah 1\",\n part1:\"This is part 1\",\n something_else:\"This is something else\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":3640,"wires":[["581f3926.17eb3","5f7589e.a37ae78"]]},{"id":"7c5b4d3d.dba8ac","type":"debug","z":"d103f472.19f3c8","name":"Sent into MQTT","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":410,"y":3740,"wires":[]},{"id":"561afa98.ebdb2c","type":"comment","z":"d103f472.19f3c8","name":"Read me *","info":"This top part is an example which represents your existing flow which is sendig a *complicated* message.\nYou need to send this message to another machine. But without a lot of messing around you have to make a node (similar to the one below) but not as simple.\nEverything you want/need to send has to have a line put in to correctly *format/resctructure* it to pass through MQTT.\n","x":400,"y":3590,"wires":[]},{"id":"fd70d098.5b6d48","type":"comment","z":"d103f472.19f3c8","name":"These two `debug` nodes are what matter. *","info":"You see what you flow is sending and you see what is received on the other end of the `MQTT` pipe.\n","x":780,"y":3590,"wires":[]},{"id":"378c0403.8cda04","type":"mqtt-broker","z":"","name":"MQTT HOST","broker":"192.168.0.99","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"true","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
You can see that the message being sent in is the same as the one received.
Which is the idea.
I hope it is handy/useful for people who are sending messages via MQTT and are having trouble when needing to send more than a simple message.
All you need are the two CHEAT NODEs Shown in blue.
Yes, I probably should have called them Cheat OUT and Cheat IN.
Sorry. After thought.
But I hope they are found to be useful.