Dear # JudoWill thanks to share, but I have a question for your excel file… For the Probalility formula, I think that have an error, the formula say:
=INDEX(L:L,COUNTA(L:L),1)
In my opinion this formula don’t take into account the last row, any value for this row show the same result. I think that the correct formula should be:
@uezezs It seems in his example above he put house is occupied at 12 hours and not 14 hours (as in the spreadsheet). So it’s 4/12=~0.33 whereas 4/14=0.29. I’m guessing it’s a typo/mistake in the yaml saying 10 hours (as it’s 10 hours away not home). Example said 12 hours, but spreadsheet has 14 (to make 10+14=24)
I’d go with the spreadsheet as it seems the most accurate (with the fix mentioned above for the Index).
Another thanks for the original post - I’m still don’t really understand this but the spreadsheet was really helpful together with the explanation. Thanks!
I created a few boolean input selectors and made a bayesian sensor based on these. It helped me better understand the explanation above when I could easily toggle the selectors and see how that affected the probability, instead of waiting for real life sensors to trigger, cool down and so forth.
I’m using most of my sensors (motion + a custom for my media players, to see if anything is playing) and two template sensors with delay_off setup like in one of the entries in this thread. Works great so far!
Also, how can we handle multiple device_trackers, particularly to ignore them if they are not on the same page ?
Example : I’ve got two gps device_trackers but both can occasionnaly be thrown off… I would like the bayesian sensor to make them “cancel each other” when they disagree, and rely on other signals until they agree. Is that doable ?
Edit:
Well, I found a way to do that but the probabilities cannot be defined by hours true/false. Here is a minimum working example :
platform: bayesian
name: home
prior: 0.8
probability_threshold: 0.8
observations:
platform: state
entity_id: device_tracker.gps1
to_state: “home”
prob_given_true: 0.6
prob_given_false: 0.4
platform: state
entity_id: device_tracker.gps1
to_state: “not_home”
prob_given_true: 0.4
prob_given_false: 0.6
platform: state
entity_id: device_tracker.gps2
to_state: “home”
prob_given_true: 0.6
prob_given_false: 0.4
platform: state
entity_id: device_tracker.gps2
to_state: “not_home”
prob_given_true: 0.4
prob_given_false: 0.6
platform: state
entity_id: light.xxx
to_state: “on”
prob_given_true: 0.6
prob_given_false: 0.4
platform: state
entity_id: light.xxx
to_state: “off”
prob_given_true: 0.4
prob_given_false: 0.6
non-contradictory GPS takes priority over light status:
home with light → 0.93 HOME
home without light → 0.86 HOME
not home with light → 0.73 NOT_HOME
not home without light → 0.54 NOT_HOME
light status takes priority over contradictory GPS:
contradictory gps with light → 0.86 HOME
contradictory gps without light → 0.73 NOT_HOME
I’m going to try adding other observations and see if it holds
You sir are a legend and definitely a great professor, no doubt. That was very clear. I was looking for more information on how this is implemented in HA and your write-up was excellent. I am trying to set up a sensor to estimate whether all of the household is in bed or not, could you please check if the below code makes sense for that.
- platform: bayesian
prior: 0.32
name: 'Bedtime'
probability_threshold: 0.9
observations:
- entity_id: group.alarmo_device_tracker
prob_given_true: 0.99 # If I'm in bed then I have to be home - hence 100% probability
prob_given_false: 0.7 # I could be home and not in bed 70% of the time during any given day
platform: 'state'
to_state: 'home'
- entity_id: group.alarmo_device_tracker
prob_given_true: 0.009 # If I'm in bed, then I can't be not home
prob_given_false: 0.5 # I'm not in bed and not home (i.e. at work or school etc.)
platform: 'state'
to_state: 'not_home'
- entity_id: 'sensor.sun'
prob_given_true: 0.97
prob_given_false: 0.33
platform: 'state'
to_state: 'below_horizon'
- entity_id: 'sensor.sun'
prob_given_true: 0.03
prob_given_false: 0.99
platform: 'state'
to_state: 'above_horizon'
- entity_id: group.interior_lights
prob_given_true: 0.99 # I never go to bed with lights on
prob_given_false: 0.8 # Lights off when I'm not in bed, which is true for most of the DAY, but excluding some lights (e.g. bathroom, garage, pantry)
platform: 'state'
to_state: 'off'
- entity_id: group.interior_lights
prob_given_true: 0.001 # reverse of the above
prob_given_false: 0.2 # reverse of the above
platform: 'state'
to_state: 'on'
- entity_id: binary_sensor.master_door_contact
prob_given_true: 0.98
prob_given_false: 0.3
platform: 'state'
to_state: 'off'
- entity_id: binary_sensor.master_door_contact
prob_given_true: 0.02
prob_given_false: 0.7
platform: 'state'
to_state: 'on'
- entity_id: 'variable.last_motion'
prob_given_true: 0.95
prob_given_false: 0.15
platform: 'state'
to_state: 'Bedroom Zooz Sensor motion'
- entity_id: binary_sensor.abhi_pixel_is_charging
prob_given_true: 0.9
prob_given_false: 0.4
platform: 'state'
to_state: 'on'
- entity_id: binary_sensor.abhi_pixel_is_charging
prob_given_true: 0.1
prob_given_false: 0.6
platform: 'state'
to_state: 'off'
- entity_id: alarm_control_panel.alarmo
prob_given_true: 0.99
prob_given_false: 0.01
platform: 'state'
to_state: 'armed_night'
- entity_id: alarm_control_panel.alarmo
prob_given_true: 0.01
prob_given_false: 0.99
platform: 'state'
to_state: 'disarmed'
- platform: "template"
prob_given_true: 0.95
prob_given_false: 0.1
value_template: >-
{% if is_state('binary_sensor.device_tracker.gps1', 'home')
and is_state('binary_sensor.device_tracker.gps1', 'home') %}
true
{% elif is_state('binary_sensor.device_tracker.gps1', 'not_home')
and is_state('binary_sensor.device_tracker.gps1', 'not_home') %}
false
{% endif %}
And because you have to give the inverse until my PR is merged
- platform: "template"
prob_given_true: 0.9
prob_given_false: 0.05
value_template: >-
{% if is_state('binary_sensor.device_tracker.gps1', 'home')
and is_state('binary_sensor.device_tracker.gps1', 'home') %}
false
{% elif is_state('binary_sensor.device_tracker.gps1', 'not_home')
and is_state('binary_sensor.device_tracker.gps1', 'not_home') %}
true
{% endif %}
If they disagree they will evaluate to null and so should be ignored by Bayesian.
P.S your probabilities look too conservative - so I’ve tweaked them in my example. Assumes they will both accidentally read ‘home’ when you are away 5% of the time and that they will both read “not_home” when you are home 10% of the time, which is probably still too conservative
Looks good, but mathematically the inverse probabilities should sum to 1.
- entity_id: group.alarmo_device_tracker
prob_given_true: 0.99 # If I'm in bed then I have to be home - hence 100% probability
prob_given_false: 0.7 # I could be home and not in bed 70% of the time during any given day
platform: 'state'
to_state: 'home'
- entity_id: group.alarmo_device_tracker
prob_given_true: 0.01 # If I'm in bed, then I can't be not home
prob_given_false: 0.3 # I'm not in bed and not home (i.e. at work or school etc.)
platform: 'state'
to_state: 'not_home'
I’d love to see some of yours as further examples.
I’m attempting to do room occupancy based on tod, motion, room power usage and other room occupancy and power usage but feel I’m missing the mark in having it only move a few points rather than the current drastic changes I see.
I think I would like to see a bit of groundswell behind this proposal - the negated state should have consequence for the calculation. Implementing this would encourage my Bayes sensors to “turn off” / “dial down” the probability when their contributing inputs are false
I just need to improve the tests, unfortunately I am a bit pressed for time at the moment
Edit: PR is reviewer approved and awaiting merge.
Edit2: @teskanoo the PR is now merged, not sure what release it will be in. Hopefully 2022.10
Edit3: Released in 2022.10 - this is a breaking change but I also included some repairs which should detect and notify for most broken configs.