Design Pattern: Bayesian Sensor Aggregation

Bayesian Sensor Aggregation

Yesterday I announced a community post about my talk on the topic “Bayesian Sensor Aggregation” to share my example and open the topic for further discussion and improvements. Note: The slides will be published later together with the rest of the Virtual Meetup 2020 in an official post. I will add the link afterwards.

Here you can find a link to my personal Gist containing my code and example configuration. It should be possible to use the demo setup out-of-the-box by dropping it into your OPENHAB_CONF folder. Requirements: Map Transformation and Jython.

Some additional words to the content of my slides:

Theorie

Based on the alternative form of the Bayesian Theorem I created a weighted aggregation function for openHAB. A Bayesian sensor attempts to guess whether something is true or not based on a series of observations.

Simple Form

grafik

Alernative Form

What do we need in openHAB to define a Bayesian (binary) Sensor?

  • A Rule for doing the math - I have written this Rule in Jython.

  • Several Items including Metadata configuration

    • A proxy Switch - representing the target Item and final sensor state (the sensor)
    • A proxy Number - (optionally) for visualization of the resulting posterior probability
    • A Group - to collect all Items for observations as members and allow iteration over them
    • One or more Items - representing different observations

The Rule in Pseudocode

see bayesian.py

update_probability(prior, prob_given_true, prob_given_false)
    numerator = prob_given_true * prior
    denominator = numerator + prob_given_false * (1 - prior)
    return numerator / denominator

bayesianSensorAggregation()
    prior = initial_prior
    foreach item in group do
        if item.state == state_given then
            prior = update_probability(prior, prob_given_true, prob_given_false)
    targetItem.state = prior >= treshold ? state_given_true : state_given_false

The Group

see bayesian.items

Defining the Metadata of the Group, namespace - bayesian

value - name of the target Item representing the sensor. This Item in general can have every item type of your choice be aware to define a state_given_true and state_given_false respectively (see below).

prior - the overall probability at any point in time (ignoring all external influences) of the event being true

threshold - the limit above which the sensor should be trigger ON

state_given_true - (optionally) target state of the sensor if posterior probability is greater than or equals to threshold, state_given_false otherwise (default: ON and OFF)

Example

Group gBAYESIAN “Bayesian Sleep Sensor” {
    bayesian="proxySwitch" [ prior=0.5, threshold=0.85, state_given_true=”ON”, state_given_false=”OFF” ]
}

The Items

see bayesian.items

Metadata for each Item, namespace - bayesian. Do not forget to add all Items to the Group defined above

value - state of the Item to be considered as given. The Item will be skipped in the calculation if this state is not detected.

prob_given_true - the probability the observed state is occurring, given the event is true

prob_given_false - (optionally) the probability the observation is occurring, given the event is false (default: 1 - prob_given_true)

Example

Switch myObservation1 “My First Observation” (gBAYESIAN) {
    bayesian="ON" [ prob_given_true=0.99, prob_given_false=0.5 ]
}
String myObservation2 "My Second Observation" (gBAYESIAN) {
    bayesian="NIGHT" [ prob_given_true=0.75 ]
}

Bayesian Binary Sleep Sensor

Sleep is something we cannot detect directly but it would be nice to know to trigger different rules/scenes/stuff based on it. That is the reason why I created my example to guess when I am not awake anymore. None of these observations individually are very helpful for knowing whether I am asleep or not. Taken together, it is very accurate. Think creatively about the data you already are tracking with openHAB, how those values could possibly indicate something you want to detect. All values shown below are fictitious and tweaked for the demo.

The Group

prior - the overall probability that I am asleep: 50%. Let’s say roughly a half of the time I am home. Okay, currently this is not true. Due to COVID-19 pandemic I am at home for nearly 24 hours per day.

threshold - how sure should we be before guessing true? 85% - pretty sure

Observation 1 - Presence Sensor

prob_given_true - the likelihood I am at home if I am sleeping: 99% - obviously, I need to be home to go to my bed.

prob_given_false - I am present but not asleep half the time: 50%

Observation 2 - Time of Day

prob_given_true - usually it is night (after sunset and dark outside) when I am sleeping: 75%

prob_given_false - but in winter it is dark earlier: 30%

Observation 3 - Lights

prob_given_true - another strong indicator if the lights are turned off: 90%

prob_given_false - 40% … or I am watching a movie

Observation 4 - “Do Not Disturb” (DND) Mode of Mobile Phone

prob_given_true - I always mute my mobile phone when I go to bed: 95%

prob_given_false - but I do it in other situations as well: 50%

Appendix

I am happy to answer your questions. Please do not hesitate to tweak my example, share your own ideas and solutions and post ports of approaches in different JSR322 based languages. As already mentioned this is not a proof of concept but rather a draft of an ideas spinning around in my mind for a long time. It might not be the final approach, I am open for extensions or improvements.

10 Likes

reserved

Thanks for this ! Any proper implementation will leapfrog reliability in smarthomes for automated tasks
(not sure how obvious that is to the audience).

Have you thought about turning this into some sort of general-purpose “toolset” binding like the one below?

I’d think that some mid-term day you could make extensions like e.g. add a neural net to the list of computation mechanisms. That sort you wouldn’t want to implement in rules DSL.

1 Like

Thank you for the feedback.

Yes, of course. My plan is to provide it in a more user-friendly way. In the short term I will try to migrate my rule into Javascript and/or a JSON code snippet which can be imported via new UI.

In the long run I like to provide this as an openHAB Core feature (e.g. Group Aggregation Function would fit bats - I guess).

Even if neural net or other machine learning stuff would be indeed very nice. But a simple Bayesian Sensor Aggregation like suggested above could solve a lot different requirements of on its own.

1 Like

+1 for the core implementation as a group aggregation function (why not right away?)

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.