Design Pattern: Multi-Sensor Confidence Aggregation
Problem: You want to derive a reliable result from multiple sensors, e.g., presence detection, window status, light sensors. Individual sensors can be wrong.
Solution:
- Calculate a confidence value for each sensor item.
- Use a rule that makes an aggregated decision based on all sensors (e.g., weighted average or Bayesian).
- Trigger actions only when a certain threshold is exceeded.
Advantages:
- Higher reliability.
- Flexible for any combination of sensors.
1. Concept
Assume we have the following sensors:
| Sensor | Item Name | Weight (Confidence) |
|---|---|---|
| Motion Sensor | MotionSensor | 0.7 |
| Window Contact | WindowSensor | 0.5 |
| Light Sensor | LightSensor | 0.3 |
Goal: If the aggregated confidence > 0.6, then “Presence detected” is considered true.
Note: The illustration contains errors.
2. Implementation in Rule DSL
// Items
// Switch MotionSensor "Motion Sensor" <motion>
// Switch WindowSensor "Window Open" <contact>
// Number LightSensor "Light" <light>
// Rule in Rule DSL
rule "Multi-Sensor Confidence Aggregation"
when
Item MotionSensor changed or
Item WindowSensor changed or
Item LightSensor changed
then
// Individual sensor confidences
var Number motionConfidence = if(MotionSensor.state == ON) 0.7 else 0.0
var Number windowConfidence = if(WindowSensor.state == CLOSED) 0.5 else 0.0
var Number lightConfidence = if((LightSensor.state as Number) > 100) 0.3 else 0.0
// Aggregation (Weighted Sum)
var Number aggregatedConfidence = motionConfidence + windowConfidence + lightConfidence
logInfo("MultiSensor", "Aggregated Confidence: " + aggregatedConfidence)
// Action only if threshold > 0.6
if(aggregatedConfidence > 0.6) {
logInfo("MultiSensor", "Presence detected!")
// e.g., turn on light:
// LightSwitch.sendCommand(ON)
} else {
logInfo("MultiSensor", "No presence detected.")
}
end
Explanation:
if(... == ON)checks the sensor state.aggregatedConfidencecan be more complex (e.g., weighted average, Bayesian).- Actions occur only if a threshold is exceeded.
3. Implementation in Python (Jython Scripting)
from core.rules import rule
from core.triggers import when
from core.log import logging
log = logging.getLogger("MultiSensor")
@rule("Multi-Sensor Confidence Aggregation Python")
@when("Item MotionSensor changed")
@when("Item WindowSensor changed")
@when("Item LightSensor changed")
def multi_sensor_confidence(event):
# Individual sensor confidences
motion_conf = 0.7 if str(items["MotionSensor"]) == "ON" else 0.0
window_conf = 0.5 if str(items["WindowSensor"]) == "CLOSED" else 0.0
light_conf = 0.3 if float(items["LightSensor"]) > 100 else 0.0
# Aggregation
aggregated_conf = motion_conf + window_conf + light_conf
log.info(f"Aggregated Confidence: {aggregated_conf}")
if aggregated_conf > 0.6:
log.info("Presence detected!")
# e.g., turn on light
# events.sendCommand("LightSwitch", "ON")
else:
log.info("No presence detected.")
Explanation:
items["MotionSensor"]returns the current state.- Conditional assignment for confidence.
- Aggregation as the sum of confidences; threshold check.
- Python allows more flexible calculations (e.g., Bayesian, complex formulas).
4. Extensions
- Dynamic weighting: Sensors can have different trust levels.
- Bayesian aggregation:
P(Active | Sensor1, Sensor2)for probabilistic decisions. - Historical data: Average over time to reduce false alarms.
- Flexible thresholds: Different thresholds for actions (e.g., lights, alarms, notifications).
Bayesian Multi-Sensor Confidence Aggregation Example for openHAB in Python (Jython)
1. Idea
We use Bayes’ Theorem:
![]()
- Each sensor provides a probability of correct detection (True Positive / False Positive).
- Aggregation is performed independently over all sensors.
2. Example in Python (Jython)
from core.rules import rule
from core.triggers import when
from core.log import logging
log = logging.getLogger("MultiSensorBayes")
# Sensor metrics (probability of correctness)
SENSOR_CONFIDENCE = {
"MotionSensor": {"tp": 0.9, "fp": 0.1}, # True Positive / False Positive
"WindowSensor": {"tp": 0.8, "fp": 0.2},
"LightSensor": {"tp": 0.7, "fp": 0.3}
}
# Prior probability of presence
PRIOR_PRESENCE = 0.5
@rule("Bayesian Multi-Sensor Aggregation")
@when("Item MotionSensor changed")
@when("Item WindowSensor changed")
@when("Item LightSensor changed")
def bayesian_aggregation(event):
# Read sensor states
states = {
"MotionSensor": str(items["MotionSensor"]) == "ON",
"WindowSensor": str(items["WindowSensor"]) == "CLOSED",
"LightSensor": float(items["LightSensor"]) > 100
}
# Initialize Bayes probability with prior
prob_presence = PRIOR_PRESENCE
prob_absence = 1 - PRIOR_PRESENCE
for sensor, detected in states.items():
tp = SENSOR_CONFIDENCE[sensor]["tp"]
fp = SENSOR_CONFIDENCE[sensor]["fp"]
if detected:
prob_presence *= tp
prob_absence *= fp
else:
prob_presence *= (1 - tp)
prob_absence *= (1 - fp)
# Normalize
total = prob_presence + prob_absence
prob_presence /= total
log.info(f"Bayesian Presence Probability: {prob_presence:.2f}")
# Threshold
if prob_presence > 0.6:
log.info("Presence detected!")
# events.sendCommand("LightSwitch", "ON")
else:
log.info("No presence detected.")
3. Explanation
- SENSOR_CONFIDENCE: Contains how reliable each sensor is (True Positive / False Positive).
- State detection:
Trueif the sensor indicates “presence”. - Bayesian combination: Multiply probabilities for each sensor.
- Normalization: Ensures
P(Presence) + P(Absence) = 1. - Threshold: Action only if, e.g., probability > 0.6.
4. Advantages
- Accounts for sensor uncertainty.
- Scalable to any number of sensors.
- Reduces false alarms.
- Flexible adjustment via
tp/fpvalues.
