In my previous post about presence detection, I showed how you can combine multiple device trackers into one highly accurate Bayesian sensor.
In Home Assistant, this new binary_sensor that I created is either on or off. It would be a little nicer if it were a device_tracker entity instead that was either home or not home.
With Node-Red that’s easy enough, but what if we take it a step further and create our own custom device_tracker based on a different set of rules altogether?
CONVERT BINARY SENSOR TO DEVICE TRACKER
The input is an inject node, set to send a message once every minute. It then gets the state of the binary_sensor.brad_presence entity and returns it’s state as the message. The switch evaluates that message: on goes up to set my new device_tracker home, off goes down to a different service call to set it away.
I am using the device_tracker.see service call in the output, configured like so:
This creates a device_tracker.brad_bayesian entity to use like any other.
Copy the JSON below to import this flow into your Node-Red.
[{"id":"763070f9.0c571","type":"switch","z":"4056fc4f.0baa64","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","outputs":2,"x":1316.9999771118164,"y":301.00000381469727,"wires":[["57b903a4.bd2f6c"],["a080246.03d5ed8"]]},{"id":"57b903a4.bd2f6c","type":"api-call-service","z":"4056fc4f.0baa64","name":"Set Presence Home","server":"8ac3cd7f.58d3e","service_domain":"device_tracker","service":"see","data":"{\"dev_id\":\"brad_bayesian\",\"location_name\":\"home\"}","x":1510.3333740234375,"y":272.6667175292969,"wires":[]},{"id":"a080246.03d5ed8","type":"api-call-service","z":"4056fc4f.0baa64","name":"Set Presence Not Home","server":"8ac3cd7f.58d3e","service_domain":"device_tracker","service":"see","data":"{\"dev_id\":\"brad_bayesian\",\"location_name\":\"not_home\"}","x":1520.3333282470703,"y":335.99999380111694,"wires":[]},{"id":"afb02bc5.351e68","type":"comment","z":"4056fc4f.0baa64","name":"Convert Bayesian Sensor into Device Tracker","info":"","x":1015.0000381469727,"y":252.00008296966553,"wires":[]},{"id":"a86ac3f0.00c67","type":"inject","z":"4056fc4f.0baa64","name":"","topic":"","payload":"","payloadType":"date","repeat":"10","crontab":"","once":false,"x":942.3333129882812,"y":300.6665403842926,"wires":[["d43007ca.720b78"]]},{"id":"d43007ca.720b78","type":"api-current-state","z":"4056fc4f.0baa64","name":"Bayesian Presence","server":"8ac3cd7f.58d3e","halt_if":"","entity_id":"binary_sensor.bayesian_presence","x":1142.3333892822266,"y":300.66639733314514,"wires":[["763070f9.0c571"]]},{"id":"8ac3cd7f.58d3e","type":"server","z":"","name":"Home Assistant","url":"http://HASSIP:8123","pass":"XXX"}]
CREATING AN IMPROVED DEVICE TRACKER
I walk my dog over to a park close by a few times a day. This was causing my house to shut down, turn the music off, etc. and then turn everything back on to a blank slate every time I walked out.
I tried a few work arounds with delays and iBeacons, but really I just wanted my bayesian sensor to weight it’s probability slightly more towards home if I was walking to the park.
On the left as inputs, I have 3 different GPS tracking platforms – the Home Assistant iOS app, my Tile tracker, and Owntracks. I format the GPS signal, and then send it into two geofence nodes.
The last function node in the flow marked “GPS” formats the GPS signal into data that Home Assistant can use, so our new device_tracker also contains the GPS data of the original source (our inputs, on the left). Anything sent in the “data” container like this will override the “data” field in the Home Assistant service output node.
Copy the JSON below to import into your Node-Red to see for yourself:
[{"id":"274f638d.ec8f8c","type":"api-call-service","z":"4056fc4f.0baa64","name":"Node Red Presence not_home","server":"8ac3cd7f.58d3e","service_domain":"device_tracker","service":"see","data":"{\"dev_id\":\"you_nodered\",\"location_name\":\"not_home\"}","x":1467.8095474243164,"y":403.9643292427063,"wires":[]},{"id":"b72e2804.d59b08","type":"api-call-service","z":"4056fc4f.0baa64","name":"Node Red Presence home","server":"8ac3cd7f.58d3e","service_domain":"device_tracker","service":"see","data":"{\"dev_id\":\"you_nodered\",\"location_name\":\"home\"}","x":1457.8094329833984,"y":333.2976927757263,"wires":[]},{"id":"be995292.1ddc4","type":"comment","z":"4056fc4f.0baa64","name":"Create Device Tracker","info":"","x":1460.8095932006836,"y":293.9643611907959,"wires":[]},{"id":"e63f1260.978e2","type":"comment","z":"4056fc4f.0baa64","name":"Home or Not?","info":"","x":1031.3452911376953,"y":372.33337688446045,"wires":[]},{"id":"d4e1c95c.1f67e8","type":"function","z":"4056fc4f.0baa64","name":"GPS","func":"newmsg = {};\nnewmsg.payload = { data: {'gps': [msg.payload.lat,msg.payload.lon] } };\nreturn newmsg;","outputs":1,"noerr":0,"x":1258.6432456970215,"y":334.2023983001709,"wires":[["b72e2804.d59b08"]]},{"id":"2d1f97bf.d24a98","type":"function","z":"4056fc4f.0baa64","name":"GPS","func":"newmsg = {};\nnewmsg.payload = { data: {'gps': [msg.payload.lat,msg.payload.lon] } };\nreturn newmsg;","outputs":1,"noerr":0,"x":1257.8097114562988,"y":403.8691101074219,"wires":[["274f638d.ec8f8c"]]},{"id":"739a62d6.c7e47c","type":"geofence","z":"4056fc4f.0baa64","name":"Inside Home Zone","mode":"circle","inside":"true","rad":0,"points":[],"centre":{"latitude":0,"longitude":0},"x":1025.625015258789,"y":322.5000047683716,"wires":[["d4e1c95c.1f67e8"]]},{"id":"f52b241a.4d2f78","type":"geofence","z":"4056fc4f.0baa64","name":"Outside Home Zone","mode":"circle","inside":"false","rad":0,"points":[],"centre":{"latitude":0,"longitude":0},"x":1034.9999961853027,"y":418.7499952316284,"wires":[["2d1f97bf.d24a98"]]},{"id":"8ac3cd7f.58d3e","type":"server","z":"","name":"Home Assistant","url":"http://HASSIP:8123","pass":"XXXXX"}]
In this way we create yet another piece of presence data for our Bayesian sensor to evaluate, so that a quick walk around to the nearby park doesn’t arm the house like we’re gone for good.
[…] Node-Red – A custom GPS tracker using Node-Red, see blog post […]
Hi,
Great articles! Really helping me get a hold of Node Red. I’ve tried creating the flow above using my own device trackers but for some reason they never created a new device tracker in HassIO.
I’ve copied your flow json and modified it for me but no joy.
Hey Jay, in the Home Assistant developer tools, go to the Service Call page and try running the device_tracker.see service manually and see if you can get it to work there. Whatever works there is what you should use in the output node. If that doesn’t work, put some debug nodes on your flow and you should be able to see what’s going on. Good luck!
Just noticed that in your explanation that you say ” I format the GPS signal, and then send it into two geofence nodes.” But the device tracker nodes feed directly into the geofence nodes. Is that correct? How do the geofence nodes know how to treat the output from the device tracker nodes when they output things like “home”, “not_home” or “work”?
Thanks!
If your device_tracker platform supports GPS the coordinates will be an attribute to the payload. Use a debug node to examine the message it’s sending, you should see more information than just the “home” or “not_home” in the msg.
If you look at the geofence node info, it looks for the GPS coordinates in a particular format.
In my example, the iOS app outputs in this format already so needs no modification – connect straight to the geofence node. For Owntracks, the message comes from MQTT and needs to go through an Owntracks node to modify it into a usable format. For Tile, I had to manually reformat the msg with a function node.
Ok, my HASS iOS app creates a device tracker named device_tracker.jiphone.
I’ve put a debug node on that device tracker node but the only output I get is:
device_tracker.jiphone : msg.payload : string[4]
“home”
No GPS coordinates that I can find.
You need to set the debug node to show the whole message, not just msg.payload.
Strange, all I”m getting is:
object
topic: “device_tracker.owntracks_jiphone”
payload: “Work”
data: object
_msgid: “f8d8152d.b25398”
Will have to do some more digging.
Thanks!
[…] Diyfuturism – my inspiration to start very. Check out all his posts on the topic, especially about Presence management […]
Hi, I’m also using the node-red add-on via hassio. My problem is the MQTT connection is very very terrible. Its status turns to “connected” almost every 20 seconds. The MQTT setting in node-red is totally the same with the one in configuration.yaml.
Do you have any idea?
Which MQTT broker are you using? I have not had any issues at all with MQTT, it is a pretty simple service. I am using the Hassio addon.
To troubleshoot, you could subscribe to all topics on your broker and see if there is something strange going on. Or check the logs for why it may be crashing.
Hi Brad,
Thanks for your very interesting articles in your blog.
I’m new to node-red and probably that is the reason why I’m struggling so much about something that is probably simple. After trying so solve by myself with no sucess, I will ask you.
I am trying to pass to geofence a gps position that I receive like this:
msg.payload : Object
object
data: object
dev_id: “abc”
gps: array[2]
0: 30.265015
1: -82.852281
Geofence is supposed to receive gps position in format “msg.location.lat & msg.location.lon”.
I pulled my hair out to get it to work. Could you please help me on this?
THANKS!
Hello,
First, good article. Second, I am trying to configure this like you have and I have run into an issue. I have owntracks setup and working just fine, but when I try to connect up my home assistant app and use it’s gps, it doesn’t get past the geofence node. Debugging it shows nothing after the geofence node. I can see the gps packet come into the goefence node, but then nothing comes out. I can see the full packet and the payload that has the gps coordinates in it come from the app, but it seems the geofence node doesn’t like the input or something. What am I missing? Did something change recently? I am using home assistant 80.0 and the latest version of the app. Thanks for any help or insight you might have.
Just started using life360 and it works great but trying to develop some of the gps flows. they data is in home -assistant but is there a way to use that entity data in Node-Red. Still pretty new to this but love the info in your blog.
Hey Zach glad you found it useful. If you use a “debug” node and set it to show the “complete msg” in it’s options you will see the HA attribute info.
Hi Brad,
Is there a reason why you inject a timestamp every minute instead of just detecting the state change with an “events state” node?
Great article, got it working and its all good in properly detecting presence of people in the house. However now all that’s done how do we get it to display the locations as listed in the ZONES section.
I have two states only, home and not_home
[…] Node-Red – En tilpasset GPS tracker der bruger Node-Red. […]
Problem with node output:
10/13/2022, 1:03:25 AM node: Set Presence Home
msg : string[67]
“Custom Ouput Error (msg:): Invalid property expression: zero-length
{
“id”: “57b03a45.bd2f6c”,
“type”: “api-call-service”,
“z”: “0ef9154a5d6da2c8”,
“name”: “Set Presence Home”,
“server”: “5c543aa4.6c05aa”,
“version”: 5,
“debugenabled”: false,
“domain”: “device_tracker”,
“service”: “see”,
“areaId”: [],
“deviceId”: [],
“entityId”: [],
“data”: “{\”dev_id\”:\”ben_presence\”,\”host_name\”:\”Ben presence\”,\”location_name\”:\”home\”}”,
“dataType”: “json”,
“mergeContext”: “”,
“mustacheAltTags”: false,
“outputProperties”: [
{
“property”: “”,
“propertyType”: “msg”,
“value”: “”,
“valueType”: “data”
}
],
“queue”: “none”,
“x”: 713.3333969116211,
“y”: 176.6667137145996,
“wires”: [
[]
]
},