Server side geofencing with Owntracks, Node-Red and Domoticz

Where to start?

The first challenge was getting data from my phone on public networks to my private MQTT server. At home I run Mosquitto for handling any message brokering, particularly with Domoticz and Node-Red pushing messages around.

I won’t go into the details, but suffice to say I have Mosquitto at home, and Mosquitto on a server I rent in OVH. The one in OVH is TLS, and protected by a username and password. It is this server to which Owntracks is configured to push messages to.

In turn, the two Mosquitto servers are bridged, as per and in order for the topic to which the phone publishes to be available internally at home.

The end result of this is the periodic announcement of my phones location on my internal home network

mqttitude/bagpuss_thecat/galaxys2 {“_type”: “location”, “lat”: “55.9182683”, “lon”: “-4.2232088”, “tst”: “1457045018”, “acc”: “20.0”, “batt”: “48”}

From here, it gets ingested into Node-Red by firstly subscribing to the mqttitude/bagpuss_thecat/galaxys2 topic, then the JSON is parsed out, and then it’s processed by a couple of node-red-node-geofence nodes in order to determine if the phone is in a certain location or not. These simply return the msg.location.isat parameter if the device matches any of the geofences.

Depending on the status of the .isat parameter, I then use the multiple messages feature of node-red to send messages to each of my Domoticz switches to alter their state.

if ( msg.location.isat == "Home") {
var home = { payload:'{"idx":181,"nvalue":1}' };
var work = { payload:'{"idx":180,"nvalue":0}' };
} else if ( msg.location.isat == "Work") {
var home = { payload:'{"idx":181,"nvalue":0}' };
var work = { payload:'{"idx":180,"nvalue":1}' };
} else {
var home = { payload:'{"idx":181,"nvalue":0}' };
var work = { payload:'{"idx":180,"nvalue":0}' };
return [ [ work, home ] ];

As you can see from the above code, the Domoticz IDX of the switch to say that I’m at work is 180, Home is 181, and I can then use those dummy switch states in Domoticz to do additional logic within the home automation system.


UPDATE: 08/08/2017

As requested, a copy of the flow. I haven’t used it for a while now, since moving to with native Owntracks support, but it might prove useful.

Geofencing, with node-red

[{“id”:”ceb5e9b3.255318″,”type”:”mqtt-broker”,”z”:””,”broker”:””,”port”:”1883″,”clientid”:””,”usetls”:false,”compatmode”:true,”keepalive”:”15″,”cleansession”:true,”willTopic”:””,”willQos”:”0″,”willPayload”:””,”birthTopic”:””,”birthQos”:”0″,”birthPayload”:””},{“id”:”5d41030f.a2ba8c”,”type”:”mqtt in”,”z”:”e55a6d11.377b9″,”name”:”KyleG Owntracks”,”topic”:”owntracks/bagpuss/a0001″,”broker”:”ceb5e9b3.255318″,”x”:121,”y”:107,”wires”:[[“d256ba45.4be048”]]},{“id”:”a2dace61.598″,”type”:”mqtt out”,”z”:”e55a6d11.377b9″,”name”:”domoticz/in”,”topic”:”domoticz/in”,”qos”:””,”retain”:””,”broker”:”ceb5e9b3.255318″,”x”:957,”y”:112,”wires”:[]},{“id”:”52f3dc6d.f8fbd4″,”type”:”geofence”,”z”:”e55a6d11.377b9″,”name”:”Home”,”mode”:”circle”,”inside”:”true”,”rad”:88.99011032254676,”points”:[],”centre”:{“latitude”:55.918150666279054,”longitude”:-4.223449230194092},”x”:480,”y”:64,”wires”:[[“b2213e67.26d87″,”4961a9e.b165358”]]},{“id”:”d256ba45.4be048″,”type”:”function”,”z”:”e55a6d11.377b9″,”name”:”Lat/Long”,”func”:”msg.location = JSON.parse(msg.payload);\n\nreturn msg;”,”outputs”:1,”noerr”:0,”x”:309,”y”:107,”wires”:[[“52f3dc6d.f8fbd4″,”2415d034.e094a”,”154cf4bc.0c969b”,”b3a50cee.841fd”,”cd886406.0e8ea8″]]},{“id”:”b2213e67.26d87″,”type”:”function”,”z”:”e55a6d11.377b9″,”name”:”Location selector”,”func”:”// Home == 10\n// Work == 20\n\nif ( msg.location.isat == \”Home\”) {\n var home = { payload:'{\”idx\”:181,\”nvalue\”:1}’ };\n var work = { payload:'{\”idx\”:180,\”nvalue\”:0}’ };\n} else if ( msg.location.isat == \”Work\”) {\n var home = { payload:'{\”idx\”:181,\”nvalue\”:0}’ };\n var work = { payload:'{\”idx\”:180,\”nvalue\”:1}’ };\n} else {\n var home = { payload:'{\”idx\”:181,\”nvalue\”:0}’ };\n var work = { payload:'{\”idx\”:180,\”nvalue\”:0}’ };\n}\n\n\nreturn [ [ work, home ] ];”,”outputs”:”1″,”noerr”:0,”x”:708,”y”:113,”wires”:[[“a2dace61.598″,”7d37ae41.94953”]]},{“id”:”2415d034.e094a”,”type”:”geofence”,”z”:”e55a6d11.377b9″,”name”:”Work”,”mode”:”circle”,”inside”:”true”,”rad”:691.5530147043348,”points”:[],”centre”:{“latitude”:55.756722472194724,”longitude”:-4.288358688354492},”x”:476,”y”:140,”wires”:[[“b2213e67.26d87″,”4961a9e.b165358”]]},{“id”:”4961a9e.b165358″,”type”:”debug”,”z”:”e55a6d11.377b9″,”name”:””,”active”:true,”console”:”false”,”complete”:”location.isat”,”x”:706,”y”:65,”wires”:[]},{“id”:”7d37ae41.94953″,”type”:”debug”,”z”:”e55a6d11.377b9″,”name”:”Domotic payload toggles”,”active”:true,”console”:”false”,”complete”:”payload”,”x”:997,”y”:69,”wires”:[]},{“id”:”154cf4bc.0c969b”,”type”:”geofence”,”z”:”e55a6d11.377b9″,”name”:”Canteen”,”mode”:”circle”,”inside”:”true”,”rad”:16.778117069341608,”points”:[],”centre”:{“latitude”:55.756552675540114,”longitude”:-4.287972450256348},”x”:489.3333435058594,”y”:203.33333587646484,”wires”:[[“d4136e7.f6cfc9”]]},{“id”:”d4136e7.f6cfc9″,”type”:”mqtt out”,”z”:”e55a6d11.377b9″,”name”:””,”topic”:”testing/canteen”,”qos”:””,”retain”:””,”broker”:”ceb5e9b3.255318″,”x”:720.3333740234375,”y”:206.33334350585938,”wires”:[]},{“id”:”332b5b84.1a89e4″,”type”:”file”,”z”:”e55a6d11.377b9″,”name”:”location”,”filename”:”/tmp/location.csv”,”appendNewline”:true,”createDir”:false,”overwriteFile”:”false”,”x”:711.3333435058594,”y”:294.33333587646484,”wires”:[]},{“id”:”b3a50cee.841fd”,”type”:”function”,”z”:”e55a6d11.377b9″,”name”:”csvify”,”func”:”//msg.timestamp = new Date().toISOString();\n\nvar now = new Date(); \nvar year = now.getFullYear();\nvar month = now.getMonth()+1; \nvar day = now.getDate();\nvar hour = now.getHours();\nvar minute = now.getMinutes();\nvar second = now.getSeconds(); \nif(month.toString().length == 1) {\nvar month = ‘0’+month;\n}\nif(day.toString().length == 1) {\nvar day = ‘0’+day;\n} \nif(hour.toString().length == 1) {\nvar hour = ‘0’+hour;\n}\nif(minute.toString().length == 1) {\nvar minute = ‘0’+minute;\n}\nif(second.toString().length == 1) {\nvar second = ‘0’+second;\n} \nmsg.timestamp = year+’-‘+month+’-‘+day+’ ‘+hour+’:’+minute+’:’+second;\n\n\nmsg.parameters = JSON.parse(msg.payload);\n\nmsg.payload = msg.timestamp + ‘,’ + + ‘,’ + msg.parameters.lon;\n\nreturn msg;”,”outputs”:1,”noerr”:0,”x”:489.8333435058594,”y”:275.33333587646484,”wires”:[[“332b5b84.1a89e4”]]},{“id”:”cd886406.0e8ea8″,”type”:”debug”,”z”:”e55a6d11.377b9″,”name”:””,”active”:false,”console”:”false”,”complete”:””,”x”:265,”y”:248,”wires”:[]}]


Attached Files:

1-wire, Node-Red, Domoticz & Grafana

Recently I posted a shiny graph of my garage temperature after I’d put a car with a hot engine in there. The spikes were fairly pronounced, and it was possibly to see where I’d left the door open whilst I worked on the car, before going for a test drive in the evening.

I was subsequently asked…

tl;dr 1-Wire -> ESP8266 -> MQTT -> Node-Red -> MQTT -> Domoticz -> MQTT -> Node-Red -> InfluxDB -> Grafana

It starts out simply enough, with a string of DS18B20 1-wire sensors hooked up to a WeMos D1 Mini NodeMCU board. On that board, there’s a copy of flashed onto, and it scans the bus periodically, reads the values, and publishes them to an MQTT broker. Each ROM ID (1-wire device) gets its own topic, and a plain number is published to the relevant topic.

My home automation controller of choice is Domoticz , and it likes a particular flavour of JSON being published on the /domoticz/in topic. This is where Node-Red steps in to do a translation.

[{“id”:”aa0d4469.8e7458″,”type”:”mqtt in”,”z”:”d5caab33.2a3558″,”name”:”esp8266 on temp/#”,”topic”:”temp/#”,”qos”:”2″,”broker”:”66a92c76.9956d4″,”x”:117,”y”:349,”wires”:[[“5f4ec201.7bbdac”]]},{“id”:”5f4ec201.7bbdac”,”type”:”function”,”z”:”d5caab33.2a3558″,”name”:”Device to IDX”,”func”:”temp = msg.payload/16;\nrom_id = msg.topic.split(\”/\”)[1];\n\nmsg.payload = {};\nswitch (rom_id) {\n case \”28b8c81d300e5\”:\n msg.payload.idx = 186;\n break;\n case \”28ac871d300e4\”:\n msg.payload.idx = 187;\n break;\n}\nmsg.payload.rom_id = rom_id;\ntemp = temp.toString();\nmsg.payload.svalue = temp;\n\n\nreturn msg;”,”outputs”:1,”noerr”:0,”x”:347,”y”:348,”wires”:[[“71da0e3.d7e8ff”]]},{“id”:”71da0e3.d7e8ff”,”type”:”mqtt out”,”z”:”d5caab33.2a3558″,”name”:””,”topic”:”domoticz/in”,”qos”:””,”retain”:””,”broker”:”66a92c76.9956d4″,”x”:535,”y”:349,”wires”:[]},{“id”:”66a92c76.9956d4″,”type”:”mqtt-broker”,”z”:””,”broker”:””,”port”:”1883″,”clientid”:””,”usetls”:false,”compatmode”:true,”keepalive”:”15″,”cleansession”:true,”willTopic”:””,”willQos”:”0″,”willPayload”:””,”birthTopic”:””,”birthQos”:”0″,”birthPayload”:””}]

In short, this flow subscribes to all messages on temp/#, takes the payload and topic, and formulates a JSON message with the correct IDX. The IDX is the unique ID for a virtual device (in this case, a temperature sensor) in Domoticz. The JSON message is then published on /domoticz/in, where it is consumed by Domoticz and used for its own home automation purposes.

Now, every value of every device in Domoticz is also published on /domoticz/out. I use this for a few MQTT to Python services I run, but I also have another Node-Red flow that takes the Domoticz JSON messages and inserts them into InfluxDB. This flow was taken from here and relies on the node-red-contrib-influxdb node.

The rest is plain sailing really – there’s a Grafana install that is configured to use InfluxDB as a datasource. Grafana can extract the data using the IDX that’s mentioned above, and will display it in a nice fashion.

SELECT mean(“svalue1”) FROM “domoticz” WHERE “idx” = ‘171’ AND $timeFilter GROUP BY time($interval) fill(null)

Job done.

Heating control

Recently I mentioned monitoring the house with wireless sensors dotted around the place. It uses node-red to average the temperatures, and come up with a synthetic value that gets reported back to the home control system, Domoticz.

Next stage is to control the heating.

The heating system in my house is a very old design, and there’s simply a plug for the heating pump, and a plug for the boiler. When the heating is commanded to turn on by the control device (so old it’s not even a thermostat) downstairs, it really just connects these two plugs to a mains supply. The boiler and pump then turns on, and warmth ensues.

My chosen method of automation is simply to keep the heating ‘on’ all the time, and have some sort of device plugged in to the plugs in order to turn them on and off remotely. I want this to be completely retrofittable, so we can remove or change it at a later date without massive amounts of rewiring.

My initial thought was just to use a couple of LightwaveRF appliance modules, but I had a USB controlled dual relay floating around that I long planned to control the TV with, but never quite managed to get around to. Additionally, and conveniently, up the loft there’s a laptop that I use for transcoding the satellite feed to IPTV (with TVHeadend), so it was a simple case of hooking the USB board up to that laptop and getting some software on to it.

Also, to make it a bit safer, and along with the retrofitting feature, I opted to put the relay board into a little dual gang enclosure, and wire in some 13A sockets that I had in the garage.

The end result is a little deamon called mqtt-usb-relay that sits and listens for MQTT messages and then act upon them to turn the USB connected relays on and off. It subscribes to the /raw/`hostname -f`/usb-relay/#, topic, and simply takes the last component of the topic as the relay number to control, and the message as the state to turn the relay to.

Now, doing this ‘correctly’ would involve parsing the JSON output of the 3rd party mqtt.js script for Domoticz, but I decided to keep things simple and to use the On and Off Actions built into Domoticz to trigger simple mosquitto_pub events.

To do this, just create the dummy switch in Domoticz, and in the On/Off Action field, stick in commands similar to this.

script://///usr/bin/mosquitto_pub -h -t /raw/ -m 1

Job done. The heating can now be controlled from Domoticz. It’s not extensive control over zones or power levels of the boiler (although I have an idea for that), but it can certainly command the ‘MORE HEAT’ desire, and maybe one day I’ll install wireless TRVs on the radiators.

Household temperature monitoring

I’ve had it in my mind to control the heating of the house via the computer for a while now, but my first requirement was always to monitor the environment, so the computer can at least make an informed decision about whether the heating is *actually* required.

A while ago I purchased an RFXCom transceiver for my home automation needs, and it’s been one of the best decisions I’ve made with regards to home automation. Not only can it transmit and receive LightwaveRF signals, it can also do Byron, Nexa, X10, Oregon Scientific, and a whole tonne more.

I subsequently discovered these dirt cheap Imagintronix humidity and temperature transmitter devices, which you can buy for £7 each. The temperature sensor needs to be calibrated against a known source, and you then apply the difference to the device as it is picked up in Domoticz. It’s all rather simple, and you immediately have a source of temperature data that can be used. I took a variety of these sensors, and put one in each room, and rather quickly gained an overview of the house from within Domoticz.

Room temperatures

Next up was the desire to average out these temperatures per zone. We have a very simple heating system with only one zone, so it was a simple case of averaging all the temperatures to get one value that we can notionally call the ‘Average house temperature’

The issue here is that Domoticz can’t do that sort of simple calculation. It has a Blockly engine built in to it, but I didn’t see any way of making do simple calculations. However, there was a way around that…

I already use the mqtt.js script from to publish MQTT messages from Domoticz, and Node-Red to do some other MQTT management things, so it was just a case of getting Node-Red to do the work instead, and then to JSONify it and push it back into Domoticz.

[{"id":"b75445a3.48abb8","type":"function","name":"JSONify","func":"msg.payload = '{\"idx\":46,\"svalue\":\"' + msg.payload + ';0;0\"}';\nreturn msg;","outputs":1,"x":495,"y":463,"z":"d5caab33.2a3558","wires":[["a4bce105.5b432"]]}]

Sorted, there’s now a dummy temperature sensor in Domoticz with IDX 46, and Node-Red emits a MQTT message with the appropriate JSON content for Domoticz to pick up and use with the temperature sensor.

Average temperature

Next step is to actually use that data…

ESP8266 Links

What with the recent buzz around the latest ESP8266 chips, I thought I should compile a list of handy links here…

The manufacturer of ESP8266 –
Manufacturer discussion forum –

Community forum –
Lua based firmware –
Discussion regarding MQTT on the ESP8266 –!topic/mqtt/Uy985KUpG64
ESP8266 Github wiki –
Working GCC Toolchain –
Open source SDK –
Native DHT22 and LED I/O using Lua –

Buy one (UK) –