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 http://e.verything.co/post/62163759361/bridging-two-mqtt-brokers and http://owntracks.org/booklet/guide/bridge/ 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 http://home-assistant.io with native Owntracks support, but it might prove useful.

Geofencing, with node-red

[{“id”:”ceb5e9b3.255318″,”type”:”mqtt-broker”,”z”:””,”broker”:”homeauto.vpn.glasgownet.com”,”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.lat + ‘,’ + 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”:”location.lat”,”x”:265,”y”:248,”wires”:[]}]

 

Attached Files:

The Old Backnet

Spurred on by the Twitter discussion regarding the old Backnet network and Electron Club founding, I went for a rummage through some backups.

Fond memories of the Backnet Assigned Names And Number Authority, BANANA. Whilst I still use 172.24.32.0, I’ve expanded somewhat from the /27 to /24. My home network won’t fit on a /27 these days! Gordon is on 172.24.33.0/24, my parents on 172.24.34.0/24. The legacy lives on a little, and still technically within the allocated BANANA range 🙂

Archive.org to the rescue! https://web.archive.org/web/20050421022318/http://wiki.backnet.org/BANANA/Addresses

Like I say, these are from backups. The file this came from was last modified in 2004!

Current Address Allocations

The majority of these addresses also route to the Backnet network

GlasgowNet currently runs on the IP range 172.24.32.0/21, and we have 172.24.40.0/21 as well for overflow usage.

We also use AS numbers 65088 – 65103 from the private AS numbers range defined by IANA

You can see the current routing table on one of the routers at the looking glass

172.24.32.000/27 – AS65089 – Kyle Gordon
172.24.32.032/27 – AS65096 – Justin Hayes
172.24.32.064/27 – AS65090 – Neil McKillop
172.24.32.096/27 – ICM
172.24.32.128/27 – AS65092 – Colin Petrie
172.24.32.160/28 – Kenny Duffus
172.24.32.176/30 – Andrew Elwell
172.24.32.180/30 – AS65094 – William Anderson
172.24.32.184/30 – AS65091 – Gordon Pearce
172.24.32.188/28 – AS65093 – Stinkpad
172.24.32.204/27 – AS65095 – Matthew Keay

ESP8266 notes

So I finally got around to using my two ESP8266 modules. This is just some notes that I’ve collected whilst working on them.

If you’re interested in the boot data, it uses a different baud rate from the main interface. It might be briefly caught if the right baud rate is chosen, ie http://vogelchr.blogspot.co.uk/2014/12/esp8266-firmware-upgrade-odd-baudrate.html

The esp-open-sdk from https://github.com/pfalcon/esp-open-sdk is perfectly functional, and all it takes is a ‘make STANDALONE=y’
Once compiled, ensure that esp-open-sdk/bin is in your $PATH, ie /home/bagpuss/src/esp-open-sdk/xtensa-lx106-elf/bin

To flash the ESP8266 from Linux, esptool.py from https://github.com/themadinventor/esptool works great. Just ensure you have sufficient privileges to write to the serial port.

Whilst nodemcu-firmware could be pulled from https://github.com/nodemcu/nodemcu-firmware it’s just easier to grab the precompiled firmware from https://github.com/nodemcu/nodemcu-firmware/raw/master/pre_build/latest/nodemcu_latest.bin

Good pinout diagram here http://www.electrodragon.com/w/File:ESP8266_V091.png
Keep CH_PD pulled high all the time.
Pull GPIO0 to GND in order to enter flashing mode.
Power it up
./esptool.py –port /dev/ttyUSB0 write_flash 0x00000 ../nodemcu_latest.bin
Reboot it when done

When talking to it, at least with the original firmware, you need a serial terminal that does newlines and carriage returns. The Arduino serial monitor works well for this. With nodemcu installed, /usr/bin/screen works just fine.

After a flash of nodemcu, do a file.format() to clear the flash

Use luatool from https://github.com/4refr0nt/luatool to upload lua scripts to the device.

If the device isn’t responding, wipe and start again… this set of commands have repeatedly gotten out of a ‘bricked’ device state.

./esptool.py –port /dev/ttyUSB0 write_flash 0x00000 ../esp-open-sdk/esp_iot_sdk_v1.0.1/bin/boot_v1.2.bin
./esptool.py –port /dev/ttyUSB0 write_flash 0x00000 ../esp-open-sdk/esp_iot_sdk_v1.0.1/bin/at/user1.1024.new.bin
./esptool.py –port /dev/ttyUSB0 write_flash 0x01000 ../esp-open-sdk/esp_iot_sdk_v1.0.1/bin/at/user1.1024.new.bin
./esptool.py –port /dev/ttyUSB0 write_flash 0x7e000 ../esp-open-sdk/esp_iot_sdk_v1.0.1/bin/blank.bin
./esptool.py –port /dev/ttyUSB0 write_flash 0xfe000 ../esp-open-sdk/esp_iot_sdk_v1.0.1/bin/blank.bin
./esptool.py –port /dev/ttyUSB0 write_flash 0x00000 ../nodemcu_latest.bin

L8 Lateness

Since the very beginning of https://www.kickstarter.com/projects/l8smartlight/l8-smartlight-the-soundless-speaker/ the founders of this project/company have been appalingly slow in responding to *anything*.

The product was delivered close to 2 years behind schedule, and in many cases backers had to plead for updates, and would often get one update every 2 to 3 months.

Suffice to say, the final product is somewhat lacking. But hey, it’s Kickstarter, so I’m not expecting an Apple class product. I am expecting decent communications from a company that has a Marketing and PR expert as a Co-Founder though.

One of my units was defective, so I emailed them for replacement guidance. A month and half later they emailed me with instructions…

It was subsequently posted, and I heard nothing. A month later I emailed to ask if they’d received it. Nothing. A month and a half later again, I email to demand a response. Still nothing.

So here’s my solution, there’s three co-founders, and they have a somewhat limited public presence. The best that I can glean is what’s listed below.

I’ve messaged 2 of them several weeks ago regarding my replacement unit, and they’ve not bothered to reply. What other L8 victims do with this information is now up to them.

Carlos Kuchkovsky – Co-founder – Software Design
http://www.linkedin.com/profile/view?id=6785213
https://www.facebook.com/kuchkovsky

Carlos Conejero – Co-founder – Industrial Design
http://www.linkedin.com/profile/view?id=47816711

Alvaro Martinez Esteve – Co-founder – Marketing & PR
http://www.linkedin.com/profile/view?id=45109590
https://www.facebook.com/alvarome

Compiling boblightd on Ubuntu Trusty

Some notes regarding the installation of Boblightd on Ubuntu Trusty

mkdir ~/src/
sudo apt-get install portaudio19-dev libusb-dev libusb-1.0-0-dev libx11-dev libxrender-dev libxext-dev libgl1-mesa-dev
svn checkout http://boblight.googlecode.com/svn/trunk/ ~/src/boblight
cd ~/src/boblight/
./configure –prefix=/usr
make
make install

Restore /etc/init.d/boblightd from backups
chmod +x /etc/init.d/boblightd
update-rc.d boblightd defaults

Restore /etc/boblight.conf from backups