The new Bayesian Binary Sensor - Any additional examples?

Would love to see some more examples if you have a chance

I’ve got two examples that are working ok, I’m still tinkering with them and figuring out how the logic of it works. Any thoughts on how to improve welcome.

- platform: bayesian
  prior: 0.5
  name: 'Bayesian Sleeping'
  probability_threshold: 0.8
  observations:
      - entity_id: 'group.tracked_users'
        prob_given_true: 1.0
        prob_given_false: 0.5
        platform: 'state'
        to_state: 'home'
      - entity_id: 'sensor.sun'
        prob_given_true: 1.0
        prob_given_false: 0.2
        platform: 'state'
        to_state: 'below_horizon'
      - entity_id: 'group.all_lights'
        prob_given_true: 1.0
        prob_given_false: 0.4
        platform: 'state'
        to_state: 'off'
      - entity_id: 'sensor.coffeemaker'
        prob_given_true: 0.6
        prob_given_false: 0.3
        platform: 'state'
        to_state: 'Ready'
      - entity_id: 'sensor.motion_last30'
        prob_given_true: 0.8
        prob_given_false: 0.5
        platform: 'state'
        to_state: 'off'
      - entity_id: 'variable.last_motion'
        prob_given_true: 0.8
        prob_given_false: 0.3
        platform: 'state'
        to_state: 'Bathroom Motion'
      - entity_id: 'binary_sensor.brad_phone_pluggedin'
        prob_given_true: 0.95
        prob_given_false: 0.5
        platform: 'state'
        to_state: 'on'


I think I need to raise the probability_threshold on this one a little to eliminate the few blips, and then you can see it gets confused during my morning routine after the ‘on’ block for when I was sleeping (in and out of bathroom - change variablee.last_motion’s prob_given true a little lower?).

The one thing this gets wrong is watching a movie, but that’s easy enough to filter out with an automation condition.

- platform: bayesian
  prior: 0.5
  name: 'Bayesian Presence'
  probability_threshold: 0.9
  observations:
    - entity_id: 'device_tracker.brad_ping'
      prob_given_true: 0.7
      prob_given_false: 0.4
      platform: 'state'
      to_state: 'home'
    - entity_id: 'device_tracker.brad_ios'
      prob_given_true: 0.9
      prob_given_false: 0.2
      platform: 'state'
      to_state: 'home'
    - entity_id: 'device_tracker.brad_owntracks'
      prob_given_true: 0.9
      prob_given_false: 0.2
      platform: 'state'
      to_state: 'home'
    - entity_id: 'biary_sensor.motion_last30'
      prob_given_true: 0.7
      prob_given_false: 0.5
      platform: 'state'
      to_state: 'on'
    - entity_id: 'binary_sensor.motion_last10'
      prob_given_true: 0.8
      prob_given_false: 0.2
      platform: 'state'
      to_state: 'on'

This one is working pretty well for me so far.

2 Likes

Weird, given that there’s a typo in it. :stuck_out_tongue: In the last30 motion sensor, you have it written as “biary.”

Do you know how you’d use this to specify a time? i similarly want to have one for whether or not I’m in bed, and would like to have an observation related to what time of day it is.

I think maybe I need to add the time_date platform?

I’m working on a tool to automate some of my hass tasks. One part of it will test all combinations of the Bayesian binary sensor and output combos that evaluate to true/false. It will also allow you to scope the output to a single observation entity, so you can say “show me all combinations that evaluate to true and include sensor.bedroom_motion”. Hope to have this ready next week.

1 Like

Woops you are right, still works with a typo in there. Thanks

To specify a time I would add a template binary_sensor. For example here is mine that I made for my bayesian presence sensor above, to calculate if there has been motion in the last 10 minutes.

- platform: template
  sensors:
    motion_last10:
      value_template: '{{(as_timestamp(now())-as_timestamp(states.variable.last_motion.last_changed)) < 600 }}'
      friendly_name: Motion in Last 10min
      device_class: motion

You would need a template that returned true if time is between X or Y.

I have added another observation for my sleeping sensor based on a binary template - my phone is always plugged in when I’m in bed. So return false if ‘unplugged’ otherwise 'true

- platform: template
  sensors:
    brad_phone_pluggedin:
      friendly_name: Phone Plugged In?
      value_template: "{% if is_state('sensor.bradphone_battery_state', 'Unplugged') %} false {%- else -%} true  {%- endif %}"

It would seem the more observations you add, the better the bayesian sensing gets.

1 Like

the examples of @etsinko helped me a great deal to sort the bayesian thing out:

most importantly rephrasing the observation in plain speech helped me understand which probability-values should be set (65% chance that if shower is on humidity is > 94). with that in mind i managed to get the probabilities sorted out. you still need some solid observations, but this bayesian sensor tells me reliably when the shower is on, based on humidity, temperature and occupancy. formerly i only measured humidity, which led to much too long measurements — because of the rather long time it takes to normalize the humidity. this combination of sensor data works great now.

(my humidity sensor is mounted at the ceiling, which makes it rather sensitive to humidity and temperature changes. but this serves its purpose, to switch on ventilation, as soon as the shower is on. a sensor at the other side of the room will probably have a decent lag until it indicates changed humidity or temperature.)

platform: 'bayesian'
name: 'shower aon bayesian'
device_class: humidity
prior: 0.25
probability_threshold: 0.5
observations:
    # shower on -> high probability if humidity > 94
  - entity_id: sensor.lf_bad
    platform: numeric_state
    above: 94
    prob_given_true: 0.65 # 65% chance that if shower is on humidity is > 94
    prob_given_false: 0.10 # 10% chance that if shower is off humidity is > 94

    # shower on -> high probability if temperature > 23.5
  - entity_id: sensor.temperatur_bad
    platform: numeric_state
    above: 23.5
    prob_given_true: 0.9 # 90% chance that if shower is on t is > 23.5
    prob_given_false: 0.3 # 30% chance that if shower is off t is > 23.5

    # shower on -> probable if humidity > 80
  - entity_id: sensor.lf_bad
    platform: numeric_state
    below: 80
    prob_given_true: 0.3 # 30% chance that if shower is on humidity is < 80
    prob_given_false: 0.8 # 80% chance that if shower is off humidity is < 80

    # shower on -> probable if bathroom light is on
  - entity_id: binary_sensor.licht_bad
    platform: state
    to_state: 'on'
    prob_given_true: 0.9 # 90% chance that if shower is on light is on
    prob_given_false: 0.8 # 80% chance that if shower is off light is on

    # shower on -> probable if bathroom occupied
  - entity_id: input_boolean.occupied_bad
    platform: state
    to_state: 'on'
    prob_given_true: 0.9 # 90% chance that if shower is on bathroom is occupied
    prob_given_false: 0.8 # 80% chance that if shower is off bathroom is occupied

6 Likes

Working on getting a few of my tools that I think are useful for my hass setup, first real feature is Bayesian Binary introspection: https://github.com/jlmcgehee21/smart_hass

Example usage to see how cases vary based on time of day: https://github.com/jlmcgehee21/smart_hass/blob/master/examples/Smass%20Examples.ipynb

4 Likes

I’m currrently using an input_select to manually tag events (e.g. going to bed) which will hopefully allow me to determine the optimum parameters for a Bayesian_sensor for said events. Interested to see any analysis along these lines.
Cheers

Interesting, so you will use that input as a label, then analyze your data via pandas, etc?

I’m not committed enough manually label my events… at least not yet.

Thinking ahead, it would definitely be possible to build an add-on that is configured to train many classifiers (agents if we wanted to take a reinforcement learning approach) based on binary sensors that are manually triggered and corresponding entities to observe.

Yes pandas/saleranno. Am interested in collaborating on that add-on

Wow, those examples helped me a lot! I tried tinkering with the bayesian sensor for presence, but couldn’t really wrap my head around the probability numbers. Now I think I’ve done a much better job, but I guess time will tell. I guess it will come down to keeping track of how it does and then fine tuning as I go.
If it turns out well I will probably exchange my normal presence in all automations to this sensor. But then I will lose the ability to track other zones for example? Anyone has an idea of how to combine the bayesian for presence with zones? Or maybe just keep them separate? Bayesian for home/not home-automations and device_tracker for the rest?

I also just thought about making a history graph with all the entities that I’m using in the bayesian for troubleshooting purposes! Easier to see whats wrong.

My own bayesian ‘in bed bayesian sensor’ is working nicely now. I found that the ‘sun below horizon’ input wasn’t particularly useful, since in the UK at this time of year the sun is setting before 5pm.! Instead I’m using a template sensor which is ON at ‘late night’.

- platform: template
  sensors:
    late_night_sensor:
      value_template: >-
          {{ strptime("22:00", "%H%M")  < now().strftime("%H:%M")
             or now().strftime("%H:%M") < strptime("07:00", "%H%M") }}

As a couple of others have done I also have a sensor to detect when there has been no motion in the house for 5 minutes. I implemented that using an input_select and an automation:

- id: '1513346519354'
  alias: House_idle
  trigger:
  - entity_id: binary_sensor.motion_at_home
    for:
      minutes: 5
    from: 'on'
    platform: state
    to: 'off'
  action:
  - data:
      entity_id: input_boolean.house_idle
    service: input_boolean.turn_on

Finally the bayesian sensor is:

- platform: 'bayesian'
  name: 'in_bed_bayesian'
  prior: 0.25
  probability_threshold: 0.5
  observations:
    - entity_id: 'group.all_lights'
      prob_given_true: 0.4
      platform: 'state'
      to_state: 'off'
    - entity_id: 'input_boolean.house_idle'
      prob_given_true: 0.6
      platform: 'state'
      to_state: 'on'
    - entity_id: 'binary_sensor.late_night_sensor'
      prob_given_true: 0.7
      platform: 'state'
      to_state: 'on'
    - entity_id: 'switch.macbook_power'
      prob_given_true: 0.1
      platform: 'state'
      to_state: 'on'

I am using the history statistics component and a template sensor to display the number of hours I spent in bed last night.

- platform: history_stats
  name: Time in bed
  entity_id: binary_sensor.in_bed_bayesian
  state: 'on'
  type: time
  end: '{{ now() }}'
  duration:
    hours: 24

And the template sensor:

- platform: template
  sensors:
    time_in_bed_template:
      friendly_name: 'Time in bed'
      value_template: '{{states.sensor.time_in_bed.attributes.value}}'

Lastly, I wrote a notebook discussing the ideas behind the bayesian sensor, and many thanks to @jlmcgehee21 for his edits:


If theres sufficient interest, I will format this for a blog post, so let me know.
Cheers!
13 Likes

Just wanted to say thank you for the amazing tool – Used it to quickly tweak my probability inputs on my bayesian sensor setup and it was fantastic.

I’m still not 100% sure of how this works. Here is one I created, but have not done extensive testing.

- platform: bayesian
  prior: 0.6
  name: 'Paul Presence'
  probability_threshold: 0.9
  observations:
    - entity_id: 'binary_sensor.ping_paul_iphone'
      prob_given_true: 0.9
      prob_given_false: 0.1
      platform: 'state'
      to_state: 'on'
    - entity_id: 'device_tracker.pauls_iphone'
      prob_given_true: 0.9
      prob_given_false: 0.2
      platform: 'state'
      to_state: 'home'
    - entity_id: 'device_tracker.paul_iphone'
      prob_given_true: 0.9
      prob_given_false: 0.4
      platform: 'state'
      to_state: 'home'

So my question is, what has to happen for this to be ‘On’

So the ping is accurate, but often off, only works on my iPhone if the iPhone is awake. The other two are using owntracks, and the IOS home assistant app (and also asuswrt, which combines into a single sensor using some magic,( ie mac address of the device I believe)

So I guess my normal situation is that the owntracks is a little slower at proviing a home status, but quicker at an away status.

I guess I don’t understand the full math. Do you just add the prob give true if something is true, and subtract the prob given false if an item is false and he total of all numbers must match the prob threshold?

So If I came home, and HA Ios app said I was home, but others were false

ping -.1
HA +.9
Owntracks -.4
Total = .4 so switch is off

Is that basically how it works?

@ptdalen For info on how the sensor works see the notebook link I posted

1 Like

Wow, lots of words! :slight_smile:

Thanks for such a detailed description. I will definitely give this a full read tonight

Can anyone tell me what is wrong with my formatting above

I keep getting

expected , but found ‘’ for the first line

  • platform: bayesian

Great article, thanks for the work. I’m still a bit confused. I admit that I skimmed down to the examples near the bottom, but here is where I’m confused.

At the bottom you mentioned turning on the kitchen light, but the probability value looked like it was for the bedroom light (.25 vs .6), then of course the part that I just did not get was when you turned on both lights, the total was .45, both were true. I could not figure out how .45 was the output. I could not see a true or false situation that would provide that value.

Sorry, i’m sure its right in my face. I’m just missing it. I do have a sensor created for presence, and it’s working, but I admit I just guessed and threw some numbers together. I’d like to understand a bit better so I can really benefit from this powerful sensor.

Hi @ptdalen I suggest you could either clone the notebook and run yourself through all the steps, or you could just to the calculations by hand or in excel. It is just the repeated calculation of Bayes formula with different inputs, nothing too computationally complex. Let me know how you get on.
Cheers