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
>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
Decayin 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).
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 Sensornon-semantic tag
- Properly configured
- 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.
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.
Main group configuration options
Each of the following options is set in the metadata
|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
|falseState||no||The command to be sent to the
|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)|
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:
|testState||yes||The state relevant for the check of whether the item represents a true or false observation: value type depends on
|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
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
|lt||numerical value||true if item state is less then
|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
|list||array of any length and element type||true if item state is equal to any element in
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).
|decayStep||yes||Numerical value between 0 and 1 to reduce the
|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
|decayMin||no||Numerical value between 0 and 1 representing the minimum value that
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
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
- JSscripting ECMAScript 2021+
- JSscripting Add-on
- Fixed template formatting issue
- initial release