architecture
architecture copied to clipboard
Logic for combining device_trackers for PERSON component
Since the person component is now ready, it is now a good time to think about how should multiple device_trackers entities be combined. Based on the multiple threads on the forums and my own experience playing with 5 different device_trackers, here is the approach that I use that gives me 100% reliable presence detection. The logic relies on two assumptions:
- Use most recent information wherever possible (see exceptions below)
- GPS trackers are generally more accurate than wifi or BT trackers
So, here's one approach to combine different trackers:
- Any new information from a GPS tracker should be updated in the person component
- Wifi and BT trackers don't scan reliably (e.g., Google Home tracker does not even work on iOS) or have other issues (e.g., wifi sleeping), we should not act upon them immediately to mark
not_home. They are far more reliable for markinghome. - So, for
hometonot_home, GPS trackers will typically update first and they should be used to updateperson. Wifi/BT trackers should be acted upon with some delay to avoid false alarms, i.e., they should benot_homefor some time before we markpersonasnot_home. This can be taken care using a slightly larger value forconsider_home(about 10 minutes seems to work fine). Thus, in most cases,not_homewill be marked based on GPS based trackers. Worst case scenario, if none of the GPS trackers are working,personwill be markednot_homeafter theconsider_homeinterval. - For
not_hometohome, we can use any tracker that updates first to set the state. Since wifi/BT trackers are quite reliable in this case, we don't need to delay them.
We can probably provide a config option to reverse the logic if someone wants to prioritize Wifi/BT trackers over GPS trackers (not preferred IMHO).
I'd like us to avoid config options if at all possible. Besides that, I think the above sounds good. But let's hear what others think.
I agree...we can leave the config options out as I don't think we should ever prioritize wifi/BT over updated GPS.
As I can understand, consider_home affects only change of state from hometo not_home. If it really so, I think, that in multi-tracker configuration consider_home must be set as low as possible. In this case home from stationary tracker is reliable and must be prioritized. When no any stationary tracker shows home, then GPS must be prioritized.
We don't have to prioritize a particular tracker, we are prioritizing based on what provides the most recent information. Presence is the fundamental aspect of home automation and I am opposed to the idea of prioritizing any particular tracker as it can mess things up if it misbehaves. That is the reason I have 5 trackers :)
In your example, for home, wifi trackers will automatically be used as we are not delaying them (due to consider_home). Thus, it handles your use case as well.
In my experience with the Unifi presence tracker, it's very accurate for determining when a device arrives at home. However, the device timeout on the Unifi controller (external to HA) is long and not obviously configurable, leaving devices marked as home far after other trackers have updated.
Situation with Unifi is almost alike to situation with consider_home. This makes stationary trackers reliable to detection of arriving home but not being home. Relying on GPS gives us another problem - false detections of not_home in case of fluctuations of GPS (my example with Google Maps). I don't see ideal solution without additional parameters to config of Person.
I can see two things people may want here: presets and advanced configuration. Presets are nice, but there will be people with very specific needs not covered by them. With the advanced configuration scenario, I can see a per person, per device tracker setting. This would require an alternate schema for the device_tracker list though. Advanced config and presets can even be mutually exclusive to help keep things simple.
When more likely configurations are figured out, then I think would be time to pre-configure things with presets.
ie (added some random keys for demonstration purposes):
person:
- id: me
name: Me
device_trackers:
- entity_id: device_tracker.track_me_1
consider_not_home: 5
consider_home: 30
priority: 2
force_if_not_home: true
- entity_id: device_tracker.track_me_2
@Chris-V While it will be great to have such fine-grained control, we should weigh it against the complexities and move gradually towards such options. As a first step, we should try things out without any config options as @MartinHjelmare suggested.
Something to consider, though, is that we are talking about moving or remaking the consider_home option from the device tracker component as part of that refactor. Maybe it has a place in the person component?
I still think we should be careful before adding config options, but it's good to consider the big picture and changes we are planning.
If we move all the "intelligence" to the person component such that the device_tracker just collects the information and passes it on to person, we can include options like consider_home and consider_not_home in person component. Given that person will be the primary presence detection (including room detection at some point), I am sure we will need config options here. In which case, it may not be a bad idea to move them to person during the refactor.
I'm not sure that makes sense in all situations. It makes sense when all you are trying to keep track are people but what about object detection or animal detection?
For example, I could have multiple device trackers in my car that I may or may not want to combine. In that scenario I'd certainly want the ability to adjust consider_home and consider_not_home depending on the tracker but I wouldn't want to create a person entity for that.
The same with a dog for example, if I had a smart dog door and tracking collar, I'd want to customize consider_home and consider_not_home but it would feel odd to set up a person entity, especially since a dog would never login to Home Assistant.
Currently Person combines two functions - trackable entity and (potential) subject of authentication. Maybe it worth to split this functions and make Trackable as independent entity with Person as subclass? Or make metatracker, containing all logic of combining device trackers, as a platform for device_tracker?
I'm glad we are getting this discussion going.
The config example by @Chris-V is great, but out of scope for now, and we should not further discuss that in the current issue. Our config format is capable of expanding to it in the future, if necessary.
@rohankapoorcom I think that we should focus on tracking humans for now, and so we should not consider supporting alternative tracking approaches for cars/dogs. I think that we can consider expanding scope or add a new component to track objects/animals/etc in the future. Also note, you can create persons that are not connected to a user, so you could still track your dog without giving them login credentials.
Things like consider_home should be deprecated from device tracker and be added to the person component. The device tracker should, just like all our other integrations, present the data as-is as we receive from the source. An entity is either a raw data representation, or a synthetic/processed representation of various raw data entities. (video explaining some more info about the difference)
May I propose that when people suggest algorithms, let's describe how the algorithm should work in pseudo-code, and not sentences. That will make it easer to compare results.
Proposal based on what I have seen so far:
Person to adopt latest updated state for which any of these checks is true:
- Device Tracker is type
wifi/btand state ishome - Device Tracker is type
wifi/bt, state isnot_homeand it has been this state for 5 minutes - Device Tracker is type
gps
Person to adopt battery level attribute of latest updated state that contains battery_level.
When a tracked device tracker state of the type wifi/bt changes to the state not_home, set an interval to update the person state again in 5 minutes.
That is an excellent summary. I am assuming 5 minutes should be sufficient time for wifi/bt devices to wakeup.
Hi team,
So from my own personal use case point of view, the "Person" component is rather binary for my liking. I had the same issues with device_trackers in that a person could only be home, and not home.
Underneath the hood, I think that the current implementation of using device trackers for a person is fine. However, I would also like the ability to have this expanded, to perhaps binary sensors. After all, most of the status is just on/home, not home/off. For this reason, it would be good to allow a Bayesian sensor (or any other binary_sensor) to be able to mark a person as home or away. This way, people can use their own logic to dictate when they should be marked as home etc.
The reason I mention the bayesian sensor, is my current feeling towards the person entity. Right now, if my phone is connected to wifi and bluetooth, if I turn off my bluetooth, but my phone stays connected to the Wifi, I am marked as away, as that was the last entity to be updated. (I may be wrong here, if I am please accept my most humble apologies). For me, I would like the ability to "fine tune" the way in which the person component knows if I am home or away. Not based on a device tracker updating, which could change frequently if I move in and out of Bluetooth range.
Now what I would love to see in the person component, is an implementation of my Not so binary presence. I would love the person to have two kinds of states, home and not_home, which is just binary. Current logic. And also another state, where the person could be either Just Arrived, Just Left, or Extended Away. Bonus points if the rules and logic for this person could be defined against the person.
person:
name: Phil
states:
Just Arrived:
state: home
for:
seconds: 0
Home:
state: home
for:
minutes: 15
Just Left:
state: not_home
for:
seconds: 0
Away
state: not_home
for:
minutes: 10
extended_away:
state: not_home
for:
hours: 24
As mentioned I use this logic currently based on templates and dropdowns, which allows me to do some automations which trigger as a person gets home for the first time, and then move into another mode etc.
Just my 2c
Although 5 min seems like a sane timeout, some trackers update when leaving a zone much faster than that. Requiring a wifi/bt tracker to timeout first to not_home will limit the potential overall responsiveness.
Zone exits seem inherently unreliable for wifi/bt/ibeacon tracking methods. Perhaps they can be given top priority for arriving but relied on far less for remaining in or exiting the zone?
My logic is quite simple.
If any non gps tracker is home, the person is home else set same state as gps tracker unless gps tracker did not report new data in an hour so we dont get stuck Home if we are away a long time.
This works most reliable of any logic I tried. I imolemented a appdaemon app to use it. In the Swedish community quite a few people use it and are happy with it.
Non gps trackers are normally reliable on home state but can be false positive in not_home state due to battery savings in mobiles. With this logic and use 3 trackers , gps, BT and WiFi(router) it is very acccurate.
Not so binary logic I also implement with just arrived and just left logic. I tend to do automations on when just arrived. I suggest we wait to implement the "not so binary" logic. Better to manage the device prio first. Let’s Make it stable before next step.
Currently state of device_tracker or person is spatial. In approach of 'not so binary logic' the state is spatial-temporal, what from my point of view makes things more complex. My proposal is to add attribute since to person, which will show time of last status change (opposite to last_updated, which shows last status check). With this attribute and Template Sensor it will be easy to implement any kind of 'not so binary logic'. Or we can make separate sensor type for this.
One more thought to tracker state combining: not only routers have time, when they doesn't update state after device is disconnected. GPS is also not immediate and makes update not every second. So we always have periods of time, when state of our sensors not reflect real things. I think that we should assume that we always have some delay between reality and it's representation in Home Assistant, but our task is simply to make this delay as low as possible. I believe that it can be done by manipulating with consider_home on device tracker level (because such kind of timeout mostly makes sense for device as a whole, not for every single entity) with possible addidtonal fine-tuning on the level of person's device tracker eitities). Something like:
device_tracker:
- platform: traccar
- platform: fritz
consider_home: 60
person:
- id: me
name: Me
device_trackers:
- entity: device_tracker.track_me_traccar
consider_home: 30
- device_tracker.track_me_fritz
2. GPS trackers are generally more accurate than wifi or BT trackers
Except... I find the opposite. My GPS tracker will take 10 to 15 minutes (or so) to mark me as home or away.
That's why I'm using much the same approach as @helto4real (and also make use of much of @philhawthorne's awesome non-binary logic - except for my extended away logic being based on distance from home). As long as one of BT or WiFi shows me at home, they win over GPS. Indeed, GPS showing somebody at home, but WiFi and BT not probably means that they're at the neighbours.
As a non-coder, mere user, my feedback is simple: Please give us the ability to make our own decisions. We're using open-source software for a reason: flexibility. Let us establish our own rules, our own priorities, and then you guys guide us on the pros/cons of each option if we're getting it wrong. That's what the docs are supposed to be for.
What is the most intuitive way of doing that? IMHO, priority should be given in the order that the trackers or sensors are listed in the config. Don't second guess us. Doing so is most peoples' complaints about Google: your logic and AI don't always mesh with our expectations as users, and the decision that you (Devs) make in this thread have to be consistent for the rest of HA's life or until you have this debate again. A new device tracker is released that is killer accurate in 5 years from now, integrated immediately into HA, but it's not GPS-based so it falls to the end of the logic - now you guys have to update the logic and have this debate again. I set up my system to use Wifi with appropriate timeouts, notwithstanding that Google Maps integration is available? Let me override the GPS-heavy logic - I've built in the necessary delays in my automations already.
You guys are knocking it out of the park with this project. Don't over think it. Users can learn from tools that are too flexible. Users stop using tools that become inflexible.
@databoy2k, seems to be that your idea comes to simply iterating through device trackers in order, in which they're appearing in config, and searching for first tracker, which returns something different than 'not_home', right?
One more potential problem with prioritizing BT/router/etc tracker sources is when using non-home zones. Perhaps I have a GPS tracker that marks me at my Office zone. If something causes the router device_tracker entity to update (attribute change?) or HA is restarted, the person entity could be updated to not_home which will be technically correct but not the most accurate option.
@jjlawren, restart of HA is always the special case. After restart reliable status will be only atfer all (or almost all) device trackers got updates. GPS trackers usually make updates with bigger intervals to lower battery consumption and probably will be last.
@databoy2k, seems to be that your idea comes to simply iterating through device trackers in order, in which they're appearing in config, and searching for first tracker, which returns something different than 'not_home', right?
I think so, yes. Or prefer marked Zones to deal with @jjlawren's comment. I'm mostly responding to the suggestion that there needs to be an overarching logic that can't be configured; on the flip side, rather than creating some arcane set of rules that we might start cussing in 5 years time, I'm advocating for allocating complete manual control of priority to the users via config.
@databoy2k, I think that it quite good idea to make priority by config order. I want only to expand and evolve it.
So, I think, that it would be too complicated to config such order for each person. From my point of view it will be better to configure such things at component level and set order of platforms:
person:
platform_priorities:
- unifi_direct
- buetooth_le_tracker
- google_maps
- traccar
But this will require, that every device tracker entity should have attribute platform or maybe even every device tracker platform should have custom tag attribute, which will be propagated to entities on creation.
device_tracker:
- platform: unifi_direct
priority_tag: wifi
- platform: buetooth_le_tracker
priority_tag: ble
- platform: google_maps
priority_tag: gps
- platform: traccar
priority_tag: gps
person:
priority:
- ble
- wifi
- gps
@databoy2k, I think that it quite good idea to make priority by config order. I want only to expand and evolve it. So, I think, that it would be too complicated to config such order for each
person. From my point of view it will be better to configure such things at component level and set order of platforms:
FWIW (and again, coming from strictly a user standpoint, and just one of the many at that) I don't think per-user is a bad idea or undesirable. I can think of lots of use cases where defining priorities based on the person, rather than globally, is a better alternative. Besides: you have to define trackers by person anyway, so the only use case for setting priorities by platforms is where you have multiple persons (perhaps significant numbers) and you're experimenting with the different orders. The cost of that is the loss of individuality; maybe GPS is the correct priority for my wife and my phones, but if I want the alarm system to shut off when the inlaws come in then Wifi is the best priority for them.
Again, I'm probably not the best guy to be engaging in this discussion too deeply as a non-dev, but when the decision gets made, I seriously hope that flexibility remains the guiding principle, even if it is at the expense of a few extra keystrokes. Better to have a truly flexible system that allows full user control, even if it means that the users have to think about the best priority order that works for their respective systems.
I just got triggered by a sentence in one of the above comments:
We're using open-source software for a reason: flexibility.
Our flexibility offering is that you can just copy our component into the custom component folder and make any changes that you want. By doing so, your flexibility does not come at the expense of offering a sane and usable defaults that will be enough for 90% of the users or at the expense of our developers time.
So right now, we should be discussing default behavior for person component. Going all in on per-person configuration is out of scope, as I mentioned in my initial response https://github.com/home-assistant/architecture/issues/163#issuecomment-468475096 . If we don't have sane defaults, we can't even start to offer config options.
As I haven't seen any other algorithm suggestions since mine at https://github.com/home-assistant/architecture/issues/163#issuecomment-468475096 , I suggest that we just implement that and consider this issue closed.
Small edit: this doesn't mean it's the final feature set, it just means that we have some default that works pretty ok out of the box.
Flexibility doesn't just always come at the expense of "a few keystrokes". It can also cause a much more complex logic to make sure you keep undesired effects out and the worst side effect can be a less robust component with a lot of things that can go wrong. It can also make bug reporting and finding bugs a lot harder.
For me open source is not necessarily the same as a super flexible solution, and not even that everyone gets the thing they think is best, there are still developers that has to make the decisions of what's best for the project in terms of maintainability and robustness.
@balloob I would suggest one addition to your logic above, that if you have multiple trackers of wifi or bt, that maybe at least two has to be not home for 5 min. Otherwise, and also without this suggestion, I think it sounds great and will be really useful.
As I haven't seen any other algorithm suggestions since mine at #163 (comment) , I suggest that we just implement that and consider this issue closed.
Small edit: this doesn't mean it's the final feature set, it just means that we have some default that works pretty ok out of the box.
I can only suggest to make check of wifi/ble is not_home for 5 minutes, only if no any gps in status zone. From my point of view all zones (except home) should have priority over not_home.
And maybe not constant 5 min but some consider_home parameter on component level of person.