This rule is one part of a bundle designed to allow the creation, configuration, and utilization of Bayesian probability calculations for some item states using the MainUI. The three parts are:
- Bayesian Group Activation Rule (this rule)
- Bayesain Group Modification Rule
- Bayesian Group Control Widget
Credit: This is an OH3-ready implementation of @cweitkamp’s awesome Bayesian aggregation design pattern. So, much of the credit goes to him and you will want to read through his post for a more detailed explanation of the underlying concepts and very clear description and example of probability selection.
In short, Bayesian aggregation is a method of determining a binary state (e.g., on/off) from a combination of assumed likelihoods of related states. Often, for complex situations such as room presence, no absolute combination of factors accurately predicts even something as simple as a binary state. Bayesian probability logic takes into account the idea that some combination of factors is a good enough indication of a conglomerate state but has the advantage that not all factors have to contribute every time and some factors contribute more than others.
There are a few changes and updates from Christoph’s original Implementation.
- All the metadata for one group is collected in the group item instead of each individual item. This permits one item to contribute to more than one Bayesian group if required.
- There are many more tests for each likelihood than simple equality, such as
<
and>
or test for list membership. See the Configuration Reference section below for a full description of the available options. - Also included is a limited ability for a likeihood probability to be dynamically defined. For example, when the lights in a room are on, this could be considered a good indicator that someone is present in the room. However, my children tend to leave lights on when they exit rooms so if the lights in a room have just been turned on that is a strong indicator that someone is in the room, but if the lights have been on for more than an hour, that is a much weaker indicator of room occupancy (see
Decay
in the configuration reference for more information). - There are two additional components available in the marketplace, a widget and a rule that works with the widget to help you manage and configure the Bayesian groups (see links above).
Installation and Use
After downloading this rule from the marketplace you only need to create one instance of the rule. The single rule template parameter that you need to input is the name of one Bayesian sensor group. This group item must have the following characteristics:
Bayesian Sensor
non-semantic tag- Properly configured
BayesianSensor
metadata - Member items for each configured Bayesian probability
You can create one of these Bayesian Group items manually or use the widget and widget rule (linked above).
In addition to the group item you will need a proxy item of the appropriate type to receive the command after the probability has been calculated (see Configuration Reference below).
If you have more than one Bayesian sensor group, then you can add each group to the triggers of the same rule using the had a member change
trigger.
Sensor Configuration
All of the configuration for a single Bayesian group sensor is maintained in the BayesianSensor
metadata namespace of the group item. It is recommended that you use the additional two components of this suite (the widget and the rule for the widget) to make management and configuration of the sensors easier. This will allow the automatic creation of the group items with a complete metadata template, shortcut access to the metadata editor, shortcut access to the group item editor, and auditing of the metadata to ensure proper configuration.
Configuration Reference
Main group configuration options
Each of the following options is set in the metadata config
:
Config option | Required | Explanation |
---|---|---|
proxy | yes | The name of the item that will receive commands based on the result of the probability calculation |
threshold | yes | Numerical value between 0 and 1 that defines the boundary between the sensor being probably true and probably false |
trueState | no | The command to be sent to the proxy item when the calculated probability is greater than or equal to the threshold (default = ON ) |
falseState | no | The command to be sent to the proxy item when the calculated probability is less than the threshold (default = OFF ) |
prior | no | The initial likelihood that the sensor is in a true state (default = 0.5 ) |
posterior | no | The name of a item (type: Number:dimensionless) in which to store the calculated posterior probability of the sensor |
sensors | yes | Map of the individual items to be checked to compute the probability with the name of each item as a key (see Observation item configuration options below) |
Audit
If you have used the widget and widget rule to check the metadata configuration then an audit
property will also be found in the config
metadata. You never have to add this property yourself it will be automatically generated. If the configuration contains no errors or warnings then the property will indicate that the configuration passed, otherwise it will show the errors and warnings. You can delete this key and its values if you wish without impacting the function of the Bayesian group, but the widget will not be able to show the results of the most recent audit if you do.
Observation item configuration options
For each item in the sensors
map the following options are available:
Sensors option | Required | Explanation |
---|---|---|
testState | yes | The state relevant for the check of whether the item represents a true or false observation: value type depends on testType |
pTrue | yes | Numerical value from 0 to 1 representing the probability that the main condition is true if this observation is true |
pFalse | yes | Numerical value from 0 to 1 representing the probability that the main condition is true if this observation is false |
testType | no | Short code specifying the kind of test performed on the item state (default test is basic equality) see table below for full list of options |
decay | no | Map of options detailing time-based decrease in pTrue value, see table below for full list of map values |
If testType
is not specified then a basic test of equality between the item state and testState
is performed and the observation is true if the equality is true. Other tests are defined using the testType
as follows:
testType value | testState value | Test performed |
---|---|---|
gt | numerical value | true if item state is greater than testState |
lt | numerical value | true if item state is less then testState |
bt | two-element array of numerical values | true if item state is greater than first array element and less than second array element |
neq | any valid state | true if item state is not equal to testState |
list | array of any length and element type | true if item state is equal to any element in testState |
The decay
property causes the probability if true value (pTrue
) of an observation to decrease over time from some reference time. Usually this will be the last time the item was changed but could be from some absolute time of day or other time point. This requires that there be an additional Type:DateTime Item that holds the timestamp of interest (the timestamp profile being the most obvious way of creating this).
Decay configuration | Required | Explanation |
---|---|---|
decayStep | yes | Numerical value between 0 and 1 to reduce the pTrue value with each timeStep |
timestamp | no | Item name of the DateTime item that holds timestamp value (default is sensor item name with ‘_TS’ appended to the end) |
timeStep | no | Number of minutes between each decrement of the pTrue value (default = 5 minutes) |
decayMin | no | Numerical value between 0 and 1 representing the minimum value that pTrue can be decreased to (default = 0.6) |
Examples
Here is an example of a properly configured BayesianSensor
metadata with some annotations to help understand.
value: " "
config:
proxy: Occupancy_Kitchen
trueState: ON
falseState: OFF
sensors:
Occupancy_Kitchen_Detection: #Item that indicates if the camera that sees kitchen area has detected a person
pFalse: 0.2 #The camera also sees a few other areas such as the backyard through the back door
pTrue: 0.9 #If a person has been detected by the camera it is very likely that there is a person in the kitchen
testState: ON
Speaker_Kitchen_Playing: #Switch indicating if sonos speaker is playing
pFalse: 0.3 #Sometimes kitchen speaker is linked to other speakers in the house
pTrue: 0.75 #Usually if the speaker in the kitchen is playing, someone is in the kitchen
testState: ON
Switch_BreakfastLight_OnOff: #Light over the table in the adjoining breakfast space
pFalse: 0.4
pTrue: 0.9
testState: ON
decay: #Kids have the tendency to leave the light on so over time this decreases the probability that this light correlates with someone in the kitchen area
timestamp: Switch_BreakfastLight_OnOff_TS #Name of the DateTime item that holds the last changed timestamp for the light switch
timeStep: 5 #Decrease every five minutes
decayStep: 0.05 #Decrease probability by 5%
decayMin: 0.4 #If the light has been on long enough it hits a minimum equal to `pFalse` which means this observation has no impact on the final probability
Switch_KitchenLight_OnOff:
pFalse: 0.3
pTrue: 0.9
testState: ON
decay:
timestamp: Switch_KitchenLight_OnOff_TS
timeStep: 5
decayStep: 0.05
decayMin: 0.4
AutomationTime: #My systems time of day item
testType: list #Check if the item state is equal to any of the elements in the given array
pFalse: 0.1
pTrue: 0.5
testState: #Array of times of day we are likely to be in the kitchen (rarely is someone in the kitchen after bedtime or before the start of the morning
- MORNING
- AFTERNOON
- EVENING
prior: 0.3 #Baseline probability that someone is in the kitchen at any one time (my wife likes to cook a lot so someone is in the kitchen often)
audit: #This metadata has been checked by the widget rule
passed: true #The metadata is properly formatted
posterior: Occupancy_Kitchen_Posterior #Each time a new probability is calculated it is stored in this item
threshold: 0.95 #A high level of certainty (95% certain) is required to set the kitchen occupancy to ON
This next example is for a switch that triggers my time of day item to change over from WAKE_UP
to MORNING
. Over the years this has proven to be a very difficult task for the system to work out because of so many different possibilities between me, my wife, kids, weekdays and weekends, but this Bayesian group sensor is exceptionally accurate, even with only simple equality tests for all the different sensor observations.
value: " "
config:
proxy: AutomationTime_Morning_Start
sensors:
AutomationTime:
pFalse: 0.3
pTrue: 0.99
testState: WAKE_UP
Phone_JustinsCell_ChargingState:
pFalse: 0.5
pTrue: 0.75
testState: OFF
Sensor_MasterBath_Motion:
pFalse: 0.5
pTrue: 0.9
testState: ON
Sensor_MasterCloset_Motion:
pFalse: 0.5
pTrue: 0.8
testState: ON
Switch_MasterBedroomFan_OnOff:
pFalse: 0.5
pTrue: 0.9
testState: OFF
prior: 0.5
audit: #This metadata has been checked by the widget rule
warnings: #Two warnings have cropped up with this configuration for values that I have not specified and so are falling back to the default values instead.
number: 2
list:
"0": trueState not set - default ON will be used
"1": falseState not set - default OFF will be used
posterior: AutomationTime_Morning_Start_Posterior
threshold: 0.9
Language:
- JSscripting ECMAScript 2021+
Dependencies:
- JSscripting Add-on
Changelog
Version 0.2
- Fixed template formatting issue
Version 0.1
- initial release