# Design Pattern(?): Multi-Sensor Confidence Aggregation

**URL:** <https://community.openhab.org/t/design-pattern-multi-sensor-confidence-aggregation/166259>\
**Category:** Tutorials & Examples\
**Tags:** designpattern\
**Created:** [September 14, 2025, 4:40pm UTC](https://community.openhab.org/t/design-pattern-multi-sensor-confidence-aggregation/166259 "2025-09-14T16:40:03Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michdo93](https://community.openhab.org/user_avatar/community.openhab.org/michdo93/32/193581_2.png) [@Michdo93](https://community.openhab.org/u/Michdo93)\
**Post date:** [September 14, 2025, 4:40pm UTC](https://community.openhab.org/t/design-pattern-multi-sensor-confidence-aggregation/166259/1 "2025-09-14T16:40:03Z")

</div>

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

 ![multisensor](https://community-openhab-org.s3.dualstack.eu-central-1.amazonaws.com/original/3X/4/6/469a5048d51778069b7fbb3c619198c25b80db42.jpeg)

Note: The illustration contains errors.

* * *

## **2. Implementation in Rule DSL**

```java
// 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.
- `aggregatedConfidence` can be more complex (e.g., weighted average, Bayesian).
- Actions occur only if a threshold is exceeded.

* * *

## **3. Implementation in Python (Jython Scripting)**

```python
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**

1. **Dynamic weighting:** Sensors can have different trust levels.
2. **Bayesian aggregation:** `P(Active | Sensor1, Sensor2)` for probabilistic decisions.
3. **Historical data:** Average over time to reduce false alarms.
4. **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** :

![bayes theorem](https://community-openhab-org.s3.dualstack.eu-central-1.amazonaws.com/original/3X/b/1/b12931678e450fceda04d575c54323a95d5a3471.png)

- Each sensor provides a **probability of correct detection** (True Positive / False Positive).
- Aggregation is performed independently over all sensors.

* * *

### **2. Example in Python (Jython)**

```python
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**

1. **SENSOR\_CONFIDENCE:** Contains how reliable each sensor is (True Positive / False Positive).
2. **State detection:** `True` if the sensor indicates “presence”.
3. **Bayesian combination:** Multiply probabilities for each sensor.
4. **Normalization:** Ensures `P(Presence) + P(Absence) = 1`.
5. **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` / `fp` values.

---

<div class="post-metadata">

**Author:** ![rlkoshak](https://community.openhab.org/user_avatar/community.openhab.org/rlkoshak/32/75251_2.png) [@rlkoshak](https://community.openhab.org/u/rlkoshak)\
**Post date:** [September 15, 2025, 2:57pm UTC](https://community.openhab.org/t/design-pattern-multi-sensor-confidence-aggregation/166259/2 "2025-09-15T14:57:31Z")

</div>

There is a Baysean implantation of this approach on the marketplace as a rule template. [Bayesian Sensors - Activation Rule [4.0.0;5.0.0)](https://community.openhab.org/t/bayesian-sensors-activation-rule-4-0-0-5-0-0/155681). There’s a MainUI widget to help adjust the weights and such without changing the rule. [Bayesian Sensors - Details Widget [4.0.0;5.0.0)](https://community.openhab.org/t/bayesian-sensors-details-widget-4-0-0-5-0-0/155685). Full documentation can be found at [Bayesian Sensors in OH4](https://community.openhab.org/t/bayesian-sensors-in-oh4/155686).

The original implementation in Jython can be found at [Design Pattern: Bayesian Sensor Aggregation](https://community.openhab.org/t/design-pattern-bayesian-sensor-aggregation/109627).

---

<div class="post-metadata">

**Author:** ![system](https://community-openhab-org.s3-eu-central-1.amazonaws.com/original/2X/6/6a52f2ac5d00e4c7b50471a354b3a9221188be90.png) [@system](https://community.openhab.org/u/system)\
**Post date:** [October 27, 2025, 6:57am UTC](https://community.openhab.org/t/design-pattern-multi-sensor-confidence-aggregation/166259/3 "2025-10-27T06:57:51Z")

</div>

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