73 lines
2.2 KiB
Python
73 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
|
|
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
|