Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add observed entities to bayesian sensor #27721

Merged
merged 9 commits into from
Feb 25, 2020
16 changes: 16 additions & 0 deletions homeassistant/components/bayesian/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from homeassistant.helpers.event import async_track_state_change

ATTR_OBSERVATIONS = "observations"
ATTR_ENTITIES = "observed_entities"
paolog89 marked this conversation as resolved.
Show resolved Hide resolved
ATTR_PROBABILITY = "probability"
ATTR_PROBABILITY_THRESHOLD = "probability_threshold"

Expand Down Expand Up @@ -126,6 +127,7 @@ def __init__(self, name, prior, observations, probability_threshold, device_clas
self.probability = prior

self.current_obs = OrderedDict({})
self.current_ent = OrderedDict({})

to_observe = set()
for obs in self._observations:
Expand Down Expand Up @@ -184,13 +186,24 @@ def _update_current_obs(self, entity_observation, should_trigger):
prob_true = entity_observation["prob_given_true"]
prob_false = entity_observation.get("prob_given_false", 1 - prob_true)

if "entity_id" in entity_observation:
entity_id = entity_observation.get("entity_id")
if "value_template" in entity_observation:
entity_id = entity_observation.get(
CONF_VALUE_TEMPLATE
).extract_entities()

self.current_obs[obs_id] = {
"prob_true": prob_true,
"prob_false": prob_false,
}
self.current_ent[obs_id] = {
paolog89 marked this conversation as resolved.
Show resolved Hide resolved
"entity_id": entity_id,
}

else:
self.current_obs.pop(obs_id, None)
self.current_ent.pop(obs_id, None)

def _process_numeric_state(self, entity_observation):
"""Add entity to current_obs if numeric state conditions are met."""
Expand Down Expand Up @@ -251,6 +264,9 @@ def device_state_attributes(self):
"""Return the state attributes of the sensor."""
return {
ATTR_OBSERVATIONS: list(self.current_obs.values()),
ATTR_ENTITIES: list(
self.current_ent[ent]["entity_id"] for ent in self.current_ent
),
ATTR_PROBABILITY: round(self.probability, 2),
ATTR_PROBABILITY_THRESHOLD: self._probability_threshold,
}
Expand Down
38 changes: 36 additions & 2 deletions tests/components/bayesian/test_binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""The test for the bayesian sensor platform."""
import unittest

from homeassistant.setup import setup_component
from homeassistant.components.bayesian import binary_sensor as bayesian
from homeassistant.setup import setup_component

from tests.common import get_test_home_assistant

Expand Down Expand Up @@ -149,7 +149,7 @@ def test_sensor_state(self):
assert state.state == "off"

def test_threshold(self):
"""Test sensor on probabilty threshold limits."""
"""Test sensor on probability threshold limits."""
config = {
"binary_sensor": {
"name": "Test_Binary",
Expand Down Expand Up @@ -259,3 +259,37 @@ def test_probability_updates(self):
prior = bayesian.update_probability(prior, pt, pf)

assert round(abs(0.9130434782608695 - prior), 7) == 0

def test_observed_entities(self):
"""Test sensor on observed entities."""
config = {
"binary_sensor": {
"name": "Test_Binary",
"platform": "bayesian",
"observations": [
{
"platform": "state",
"entity_id": "sensor.test_monitored",
"to_state": "off",
"prob_given_true": 0.8,
"prob_given_false": 0.4,
}
],
"prior": 0.2,
"probability_threshold": 0.32,
}
}

assert setup_component(self.hass, "binary_sensor", config)

self.hass.states.set("sensor.test_monitored", "on")
self.hass.block_till_done()

state = self.hass.states.get("binary_sensor.test_binary")
assert [] == state.attributes.get("observed_entities")

self.hass.states.set("sensor.test_monitored", "off")
self.hass.block_till_done()

state = self.hass.states.get("binary_sensor.test_binary")
assert ["sensor.test_monitored"] == state.attributes.get("observed_entities")