Like I've explained before I'm looking at Node-Red.
http://nodered.org/ is a "A visual tool for wiring the Internet of Things".
As a proof of concept this is what I've done:
1. Made a script called script_device_nodered.lua for Domoticz
It looks like this:
Code: Select all
--[[
Node-red device script
devicechanges are pushed to localhost port 1880 if there's any value to publish
node-red will be listening and will respond by calling back Domoticz in order to retrieve the status using the JSON interface
NB. Domoticz will add _ and property to the name of certain sensors (e.g. _temperature, _humidity). These are all ignored by filtering on value = empty
--]]
NodeRedUrl = "127.0.0.1:1880/domoticz"
commandArray = {}
logging = false
counter = 1
for i, v in pairs(devicechanged) do
if (logging) then print ("i="..i, "v="..v) end
value = v .. "" -- make sure value is a string
if (#value == 0) then
commandArray[counter]={['OpenURL']=string.gsub(NodeRedUrl..'?device='..i, "%s+", '%%20')}
counter = counter +1
end
end
return commandArray
2. In Node-Red I made a publish flow
The first flow, which I call "Domoticz out" consists of a "http in" node which is listening to the messages which are sent by the LUA script. The LUA script pushes the names of changed devices to Node-red. Node-red will first do a http-request back to Domoticz to get the status of all devices. Then it will filter out the device which was sent from LUA and finally it will publish it to MQTT in two different ways. First as a message to topic /domoticz/out/json containing the full json-status message. Secondly it will post the contents of the Data-field to topic /domoticz/out/device/[devicename]. Obviously this can be expanded with publishing to all sorts of MQTT-topics.
Code: Select all
[{"id":"86f0c28c.790f4","type":"mqtt-broker","broker":"localhost","port":"1883","clientid":""},{"id":"b5e13be0.4a1ec8","type":"http in","name":"domoticz","url":"/domoticz","method":"get","x":90,"y":28,"z":"d8820d48.277df","wires":[["f0adae54.0f525","3eb9cdbe.c14632"]]},{"id":"f0adae54.0f525","type":"http response","name":"","x":268,"y":28,"z":"d8820d48.277df","wires":[]},{"id":"f83a1546.07c5e8","type":"mqtt out","name":"","topic":"/domoticz/out/json","qos":"","retain":"","broker":"86f0c28c.790f4","x":743,"y":243,"z":"d8820d48.277df","wires":[]},{"id":"5bdbbd55.a42444","type":"inject","name":"","topic":"","payload":"{\"device\":\"Elektriciteit\"}","payloadType":"string","repeat":"","crontab":"","once":true,"x":88,"y":138,"z":"d8820d48.277df","wires":[["8e8dc74e.717238"]]},{"id":"8e8dc74e.717238","type":"http request","name":"","method":"GET","ret":"txt","url":"http://192.168.1.24:8080/json.htm?type=devices","x":309,"y":138,"z":"d8820d48.277df","wires":[["6b8cff2c.9473","150db3be.eaf24c"]]},{"id":"e7db09cb.1824f8","type":"function","name":"FilterResult","func":"var data = msg.payload.result;\n\nfunction FilterResultsByName(Name) {\n return data.filter(\n function(data){return data.Name == Name}\n );\n}\n\narray = FilterResultsByName(msg.device);\nif (array.length > 0) { \n\tmsg.payload.result = array[0];\n\tmsg.idx = msg.payload.result.idx;\n}\n\nreturn msg;","outputs":1,"x":481,"y":249,"z":"d8820d48.277df","wires":[["a951a4b1.56ae58","f83a1546.07c5e8","6696a892.996958","7e40be52.81bf4"]]},{"id":"a951a4b1.56ae58","type":"debug","name":"","active":false,"console":"false","complete":"idx","x":624,"y":122,"z":"d8820d48.277df","wires":[]},{"id":"3eb9cdbe.c14632","type":"function","name":"SaveDevice","func":"msg.device = msg.payload.device;\nreturn msg;","outputs":1,"x":201,"y":85,"z":"d8820d48.277df","wires":[["8e8dc74e.717238"]]},{"id":"150db3be.eaf24c","type":"debug","name":"","active":false,"console":"false","complete":"false","x":598,"y":70,"z":"d8820d48.277df","wires":[]},{"id":"6696a892.996958","type":"debug","name":"","active":false,"console":"false","complete":"device","x":677,"y":177,"z":"d8820d48.277df","wires":[]},{"id":"6b8cff2c.9473","type":"json","name":"","x":434,"y":184,"z":"d8820d48.277df","wires":[["e7db09cb.1824f8"]]},{"id":"3b97f57b.c4680a","type":"debug","name":"","active":true,"console":"false","complete":"payload","x":754,"y":315,"z":"d8820d48.277df","wires":[]},{"id":"507bd6e6.af8428","type":"mqtt out","name":"","topic":"","qos":"","retain":"","broker":"86f0c28c.790f4","x":745,"y":379,"z":"d8820d48.277df","wires":[]},{"id":"7e40be52.81bf4","type":"function","name":"Repub ()","func":"var newmsg = {};\nnewmsg.payload = msg.payload.result.Data;\nnewmsg.topic = \"/domoticz/out/device/\"+msg.payload.result.Name;\n\nreturn newmsg;","outputs":1,"x":589,"y":319,"z":"d8820d48.277df","wires":[["3b97f57b.c4680a","507bd6e6.af8428"]]}]
this is wat the message look like on the device topic hierarchy:
3. A flow to send back commands to Domoticz
For the opposite direction I've created another flow. This is a very simple example which will post messages from MQTT to Domoticz.
Code: Select all
[{"id":"86f0c28c.790f4","type":"mqtt-broker","broker":"localhost","port":"1883","clientid":""},{"id":"339707e6.cc68f8","type":"http request","name":"","method":"GET","ret":"txt","url":"","x":523,"y":285,"z":"8b1c06b3.74e3f8","wires":[["8f3947d6.70c6b8"]]},{"id":"c8a94fa4.3756b","type":"mqtt in","name":"","topic":"/domoticz/in/command/udevice/#","broker":"86f0c28c.790f4","x":162,"y":384,"z":"8b1c06b3.74e3f8","wires":[["57b203b3.a84dfc"]]},{"id":"8f3947d6.70c6b8","type":"debug","name":"","active":true,"console":"false","complete":"true","x":720,"y":381,"z":"8b1c06b3.74e3f8","wires":[]},{"id":"57b203b3.a84dfc","type":"function","name":"ConstructURL","func":"var parts = msg.topic.split(\"/\");\nmsg.idx = parts[parts.length-1];\nmsg.svalue = msg.payload;\nmsg.url = 'http://192.168.1.24:8080/json.htm?type=command¶m=udevice&idx='+msg.idx+'&svalue='+msg.svalue;\nreturn msg;","outputs":1,"x":405,"y":362,"z":"8b1c06b3.74e3f8","wires":[["8f3947d6.70c6b8","339707e6.cc68f8"]]}]
Now the message
mosquitto_pub -t /domoticz/in/command/udevice/211 -m 'This is a text message'
will update the device in domoticz:
4. Connecting the internet of things
Now that we've got the MQTT-stuff in place let's do some interfacing.
In this example I created a flow which subscribes to MQTT topic /domoticz/out/device/Gas
In the flow Node-red will check if the time is within 10 minutes past midnight and if so post the current Gas-meter value to mindergas.nl which is a dutch site for keeping track of gas-usage.
Code: Select all
[{"id":"86f0c28c.790f4","type":"mqtt-broker","broker":"localhost","port":"1883","clientid":""},{"id":"ce6aad20.31955","type":"mqtt in","name":"","topic":"/domoticz/out/device/Gas","broker":"86f0c28c.790f4","x":121,"y":97,"z":"2697221f.d968de","wires":[["d54ab5d6.2ab548"]]},{"id":"dc6d59eb.2392a8","type":"http request","name":"Mindergas.nl","method":"POST","ret":"txt","url":"https://www.mindergas.nl/api/gas_meter_readings","x":521,"y":186,"z":"2697221f.d968de","wires":[["30f622a5.cf09de"]]},{"id":"bd9f730c.42609","type":"inject","name":"","topic":"","payload":"{\"result\": {\"Data\":\"6014.32\"}}","payloadType":"string","repeat":"","crontab":"","once":false,"x":134,"y":38,"z":"2697221f.d968de","wires":[["d54ab5d6.2ab548"]]},{"id":"30f622a5.cf09de","type":"debug","name":"","active":false,"console":"false","complete":"true","x":688,"y":147,"z":"2697221f.d968de","wires":[]},{"id":"81df4693.7e20b8","type":"function","name":"Set values","func":"var newmsg = {};\nvar yesterday = new Date(new Date().setDate(new Date().getDate()-1));\nvar day = (\"0\" + yesterday.getDate()).slice(-2);\nvar month = (\"0\" + (yesterday.getMonth() + 1)).slice(-2);\nvar senddate = yesterday.getFullYear() + \"-\" + (month) + \"-\" + (day);\n\nif ((yesterday.getMinutes() < 10) && (yesterday.getHours() == 0)) {\t\t\t\n\tnewmsg.headers = { \"Content-Type\":\"application/json\" };\n\tnewmsg.headers[\"AUTH-TOKEN\"] = \"put your token here\";\n\t\n\tnewmsg.payload = {};\n newmsg.payload.date = senddate;\n newmsg.payload.reading = msg.payload;\n\treturn newmsg;\n}\n \n","outputs":1,"x":389,"y":134,"z":"2697221f.d968de","wires":[["dc6d59eb.2392a8","30f622a5.cf09de"]]},{"id":"d54ab5d6.2ab548","type":"json","name":"","x":286,"y":78,"z":"2697221f.d968de","wires":[["81df4693.7e20b8","30f622a5.cf09de"]]}]
In Node-red lot's of other little programs could be made which listen to a MQTT-topic and then do whatever is needed. Lot's of nodes are available, like nodes to send message to twitter, send e-mail, store data in a database, convert to XML/HTML etc.
By the way: technically MQTT is not really needed since the flows could also be linked directly instead of through MQTT. But this is a proof of concept so that's why I've done it like this.
Hope to hear what you guys think of all this!