mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 18:27:51 +00:00

* test driven delevopment * test driven development - multi numeric state * better multi-state processing * when state==below return true * adds test for a bad state * improve codecov * value error already handled in async_numeric_state * remove whitespace * remove async_get * linting * test_driven dev for error handling * make tests fail correctly * ensure tests fail correctly * prevent bad numeric entries * ensure no overlapping ranges * fix tests, as error caught in validation * remove redundant er call * remove reddundant arg * improves code coverage * filter for numeric states before testing overlap * adress code review * skip non numeric configs but continue * wait to avoid race condition * Better tuples name and better guard clause * better test description * more accurate description * Add comments to calculations * using typing not collections as per ruff * Apply suggestions from code review Co-authored-by: Erik Montnemery <erik@montnemery.com> * follow on from suggestions * Lazy evaluation Co-authored-by: Erik Montnemery <erik@montnemery.com> * update error text in tests * fix broken tests * move validation function call * fixes return type of above_greater_than_below. * improves codecov * fixes validation --------- Co-authored-by: Erik Montnemery <erik@montnemery.com>
75 lines
2.2 KiB
Python
75 lines
2.2 KiB
Python
"""Helpers to deal with bayesian observations."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
import uuid
|
|
|
|
from homeassistant.const import (
|
|
CONF_ABOVE,
|
|
CONF_BELOW,
|
|
CONF_ENTITY_ID,
|
|
CONF_PLATFORM,
|
|
CONF_VALUE_TEMPLATE,
|
|
)
|
|
from homeassistant.helpers.template import Template
|
|
|
|
from .const import CONF_P_GIVEN_F, CONF_P_GIVEN_T, CONF_TO_STATE
|
|
|
|
|
|
@dataclass
|
|
class Observation:
|
|
"""Representation of a sensor or template observation.
|
|
|
|
Either entity_id or value_template should be non-None.
|
|
"""
|
|
|
|
entity_id: str | None
|
|
platform: str
|
|
prob_given_true: float
|
|
prob_given_false: float
|
|
to_state: str | None
|
|
above: float | None
|
|
below: float | None
|
|
value_template: Template | None
|
|
observed: bool | None = None
|
|
multi: bool = False
|
|
id: uuid.UUID = field(default_factory=uuid.uuid4)
|
|
|
|
def to_dict(self) -> dict[str, str | float | bool | None]:
|
|
"""Represent Class as a Dict for easier serialization."""
|
|
|
|
# Needed because dataclasses asdict() can't serialize Templates and ignores Properties.
|
|
dic = {
|
|
CONF_PLATFORM: self.platform,
|
|
CONF_ENTITY_ID: self.entity_id,
|
|
CONF_VALUE_TEMPLATE: self.template,
|
|
CONF_TO_STATE: self.to_state,
|
|
CONF_ABOVE: self.above,
|
|
CONF_BELOW: self.below,
|
|
CONF_P_GIVEN_T: self.prob_given_true,
|
|
CONF_P_GIVEN_F: self.prob_given_false,
|
|
"observed": self.observed,
|
|
}
|
|
|
|
for key, value in dic.copy().items():
|
|
if value is None:
|
|
del dic[key]
|
|
|
|
return dic
|
|
|
|
def is_mirror(self, other: Observation) -> bool:
|
|
"""Dectects whether given observation is a mirror of this one."""
|
|
return (
|
|
self.platform == other.platform
|
|
and round(self.prob_given_true + other.prob_given_true, 1) == 1
|
|
and round(self.prob_given_false + other.prob_given_false, 1) == 1
|
|
)
|
|
|
|
@property
|
|
def template(self) -> str | None:
|
|
"""Not all observations have templates and we want to get template strings."""
|
|
if self.value_template is not None:
|
|
return self.value_template.template
|
|
return None
|