1 """The Compensation integration."""
4 from operator
import itemgetter
7 import voluptuous
as vol
16 CONF_UNIT_OF_MEASUREMENT,
37 _LOGGER = logging.getLogger(__name__)
41 """Validate data point list is greater than polynomial degrees."""
42 if len(value[CONF_DATAPOINTS]) <= value[CONF_DEGREE]:
44 f
"{CONF_DATAPOINTS} must have at least"
45 f
" {value[CONF_DEGREE]+1} {CONF_DATAPOINTS}"
51 COMPENSATION_SCHEMA = vol.Schema(
53 vol.Required(CONF_SOURCE): cv.entity_id,
54 vol.Required(CONF_DATAPOINTS): [
55 vol.ExactSequence([vol.Coerce(float), vol.Coerce(float)])
57 vol.Optional(CONF_UNIQUE_ID): cv.string,
58 vol.Optional(CONF_ATTRIBUTE): cv.string,
59 vol.Optional(CONF_UPPER_LIMIT, default=
False): cv.boolean,
60 vol.Optional(CONF_LOWER_LIMIT, default=
False): cv.boolean,
61 vol.Optional(CONF_PRECISION, default=DEFAULT_PRECISION): cv.positive_int,
62 vol.Optional(CONF_DEGREE, default=DEFAULT_DEGREE): vol.All(
64 vol.Range(min=1, max=7),
66 vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
70 CONFIG_SCHEMA = vol.Schema(
73 {cv.slug: vol.All(COMPENSATION_SCHEMA, datapoints_greater_than_degree)}
76 extra=vol.ALLOW_EXTRA,
80 async
def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
81 """Set up the Compensation sensor."""
82 hass.data[DATA_COMPENSATION] = {}
84 for compensation, conf
in config[DOMAIN].items():
85 _LOGGER.debug(
"Setup %s.%s", DOMAIN, compensation)
87 degree = conf[CONF_DEGREE]
89 initial_coefficients: list[tuple[float, float]] = conf[CONF_DATAPOINTS]
90 sorted_coefficients = sorted(initial_coefficients, key=itemgetter(0))
93 x_values, y_values = zip(*initial_coefficients, strict=
False)
97 with np.errstate(all=
"raise"):
99 coefficients = np.polyfit(x_values, y_values, degree)
100 except FloatingPointError
as error:
102 "Setup of %s encountered an error, %s",
107 if coefficients
is not None:
109 k: v
for k, v
in conf.items()
if k
not in [CONF_DEGREE, CONF_DATAPOINTS]
111 data[CONF_POLYNOMIAL] = np.poly1d(coefficients)
113 if data[CONF_LOWER_LIMIT]:
114 data[CONF_MINIMUM] = sorted_coefficients[0]
116 data[CONF_MINIMUM] =
None
118 if data[CONF_UPPER_LIMIT]:
119 data[CONF_MAXIMUM] = sorted_coefficients[-1]
121 data[CONF_MAXIMUM] =
None
123 hass.data[DATA_COMPENSATION][compensation] = data
125 hass.async_create_task(
130 {CONF_COMPENSATION: compensation},
dict datapoints_greater_than_degree(dict value)
bool async_setup(HomeAssistant hass, ConfigType config)
None async_load_platform(core.HomeAssistant hass, Platform|str component, str platform, DiscoveryInfoType|None discovered, ConfigType hass_config)