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
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.