Lightweight UDP / MQTT Gateway for the IoT
Attempt at a quick & dirty UDP / MQTT Gateway for the IoT
Warning: The gateway is not symetric ! Read below:
UDP -> MQTT
Your UDP message must be JSON formatted in this way:
{
"t":"<MQTT topic you want to publish to>"
"p": <your JSON escaped payload>
}
The gateway will relay your payload to the specified topic in a transparent fashion. Messages details (source port, ip) are not provided here to avoid tampering with the payload.
As MQTT protocol doesnt have a request/response conception, we also provide a way to reply to a message by wraping the source port and message payload and relaying to to topic "/IP/udp2mqtt".
MQTT -> UDP
To relay MQTT messages to UDP, you must explicitly send your MQTT message to topic "/IP/mqtt2udp". Your MQTT message must be JSON formatted in this way :
{
"payload":"<MQTT topic you want to publish to>"
"dst_port": <UDP destination port>
}
If you specify src_port instead of dst_port, it will use src_port+1 as a destination port.
Using two distinct ports allows using broadcasts for both thing->server and server->thing and still be able to differentiate both traffic type.
[{"id":"6106221f.a1af3c","type":"subflow","name":"full message","info":"","in":[{"x":50,"y":30,"wires":[{"id":"6fb46d08.bbd54c"}]}],"out":[{"x":620,"y":60,"wires":[{"id":"6fb46d08.bbd54c","port":0}]}]},{"id":"6fb46d08.bbd54c","type":"function","z":"6106221f.a1af3c","name":"","func":"msg.payload = msg;\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":60,"wires":[[]]},{"id":"f299263f.262e5","type":"udp in","z":"524b9ce9.6e5f24","name":"UDP2MQTT <gw listening UDP port>","iface":"","port":"<gw listening UDP port>","ipv":"udp4","multicast":"false","group":"","datatype":"utf8","x":190,"y":340,"wires":[["6cb01ecd.f94bd8","99f420ff.f3ffd8"]]},{"id":"fd0bdea2.37a1d8","type":"mqtt out","z":"524b9ce9.6e5f24","name":"auto topic","topic":"","qos":"","retain":"","broker":"77ea1e7c.1bf498","x":880,"y":340,"wires":[]},{"id":"c52f0e1a.983a98","type":"function","z":"524b9ce9.6e5f24","name":"transparent relay to mqtt","func":"msg.topic = msg.payload.t;\nmsg.payload = msg.payload.p;\n\nreturn msg;","outputs":1,"noerr":0,"x":650,"y":340,"wires":[["fd0bdea2.37a1d8"]]},{"id":"6cb01ecd.f94bd8","type":"json","z":"524b9ce9.6e5f24","name":"","property":"payload","action":"","pretty":false,"x":410,"y":340,"wires":[["c52f0e1a.983a98","b8cf3aaa.c6b248"]]},{"id":"b8cf3aaa.c6b248","type":"function","z":"524b9ce9.6e5f24","name":"wrapping relay to mqtt","func":"msg.topic = \"/\" + msg.ip + \"/udp2mqtt\";\n\nmsg.payload.src_ip = undefined; //avoid duplicates\nmsg.payload.src_port = msg.port;\nmsg.payload.topic = msg.t;\nmsg.payload.payload = msg.payload.p;\nmsg.payload.t = undefined;\nmsg.payload.p = undefined;\n\nreturn msg;","outputs":1,"noerr":0,"x":640,"y":400,"wires":[["f73cc324.7edf98"]]},{"id":"f73cc324.7edf98","type":"mqtt out","z":"524b9ce9.6e5f24","name":"/IP/udp2mqtt","topic":"","qos":"","retain":"","broker":"77ea1e7c.1bf498","x":890,"y":400,"wires":[]},{"id":"9d5643e.ed5534","type":"json","z":"524b9ce9.6e5f24","name":"","property":"payload","action":"","pretty":false,"x":410,"y":580,"wires":[["f33ace54.53c4e"]]},{"id":"5684dda1.e8af94","type":"comment","z":"524b9ce9.6e5f24","name":"Relay UDP to MQTT","info":"","x":170,"y":280,"wires":[]},{"id":"edb295f3.19fba","type":"comment","z":"524b9ce9.6e5f24","name":"Relay MQTT to UDP","info":"","x":170,"y":520,"wires":[]},{"id":"2d65456a.c1d012","type":"mqtt in","z":"524b9ce9.6e5f24","name":"/IP/mqtt2udp","topic":"/IP/mqtt2udp","qos":"2","broker":"77ea1e7c.1bf498","x":170,"y":580,"wires":[["9d5643e.ed5534","ead56341.6a88d8"]]},{"id":"f33ace54.53c4e","type":"function","z":"524b9ce9.6e5f24","name":"relay to udp","func":"msg.ip = msg.topic.split(\"/\")[1];\nmsg.port = dst_port || src_port+1;\nmsg.payload = msg.payload.payload;\n\nreturn msg;","outputs":1,"noerr":0,"x":610,"y":580,"wires":[["179940a3.ff70df"]]},{"id":"ead56341.6a88d8","type":"debug","z":"524b9ce9.6e5f24","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":430,"y":520,"wires":[]},{"id":"179940a3.ff70df","type":"udp out","z":"524b9ce9.6e5f24","name":"UDP auto port/ip","addr":"","iface":"","port":"","ipv":"udp4","outport":"","base64":false,"multicast":"false","x":910,"y":580,"wires":[]},{"id":"69affc7.2fcc284","type":"debug","z":"524b9ce9.6e5f24","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":630,"y":200,"wires":[]},{"id":"99f420ff.f3ffd8","type":"subflow:6106221f.a1af3c","z":"524b9ce9.6e5f24","x":380,"y":220,"wires":[["69affc7.2fcc284"]]},{"id":"77ea1e7c.1bf498","type":"mqtt-broker","z":"","name":"<IP of your MQTT broker>","broker":"<IP of your MQTT broker>","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""}]