1
mirror of https://github.com/home-assistant/core synced 2024-10-04 07:58:43 +02:00
ha-core/homeassistant/components/compensation/__init__.py
Petro31 545fe7a7be
Add Compensation Integration (#41675)
* Add Compensation Integration

Adds the Compensation Integration

* Add Requirements

add missing requirements to compensation integration

* Fix for tests

Fix files after tests

* Fix isort

ran isort

* Handle ADR-0007

Change the configuration to deal with ADR-0007

* fix flake8

Fix flake8

* Added Error Trapping

Catch errors.
Raise Rank Warnings but continue.
Fixed bad imports

* fix flake8 & pylint

* fix isort.... again

* fix tests & comments

fix tests and comments

* fix flake8

* remove discovery message

* Fixed Review changes

* Fixed review requests.
* Added test to test get more coverage.

* Roll back numpy requirement

Roll back numpy requirement to match other integrations.

* Fix flake8

* Fix requested changes

Removed some necessary comments.
Changed a test case to be more readable.

* Fix doc strings and continue

* Fixed a few test case doc strings
* Removed a continue/else

* Remove periods from logger

Removed periods from _LOGGER errors.

* Fixes

changed name to unqiue_id.
implemented suggested changes.

* Add name and fix unique_id

* removed conf name and auto construct it
2021-04-03 22:42:09 +02:00

121 lines
3.5 KiB
Python

"""The Compensation integration."""
import logging
import warnings
import numpy as np
import voluptuous as vol
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.const import (
CONF_ATTRIBUTE,
CONF_SOURCE,
CONF_UNIQUE_ID,
CONF_UNIT_OF_MEASUREMENT,
)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.discovery import async_load_platform
from .const import (
CONF_COMPENSATION,
CONF_DATAPOINTS,
CONF_DEGREE,
CONF_POLYNOMIAL,
CONF_PRECISION,
DATA_COMPENSATION,
DEFAULT_DEGREE,
DEFAULT_PRECISION,
DOMAIN,
)
_LOGGER = logging.getLogger(__name__)
def datapoints_greater_than_degree(value: dict) -> dict:
"""Validate data point list is greater than polynomial degrees."""
if len(value[CONF_DATAPOINTS]) <= value[CONF_DEGREE]:
raise vol.Invalid(
f"{CONF_DATAPOINTS} must have at least {value[CONF_DEGREE]+1} {CONF_DATAPOINTS}"
)
return value
COMPENSATION_SCHEMA = vol.Schema(
{
vol.Required(CONF_SOURCE): cv.entity_id,
vol.Required(CONF_DATAPOINTS): [
vol.ExactSequence([vol.Coerce(float), vol.Coerce(float)])
],
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_ATTRIBUTE): cv.string,
vol.Optional(CONF_PRECISION, default=DEFAULT_PRECISION): cv.positive_int,
vol.Optional(CONF_DEGREE, default=DEFAULT_DEGREE): vol.All(
vol.Coerce(int),
vol.Range(min=1, max=7),
),
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
}
)
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{cv.slug: vol.All(COMPENSATION_SCHEMA, datapoints_greater_than_degree)}
)
},
extra=vol.ALLOW_EXTRA,
)
async def async_setup(hass, config):
"""Set up the Compensation sensor."""
hass.data[DATA_COMPENSATION] = {}
for compensation, conf in config.get(DOMAIN).items():
_LOGGER.debug("Setup %s.%s", DOMAIN, compensation)
degree = conf[CONF_DEGREE]
# get x values and y values from the x,y point pairs
x_values, y_values = zip(*conf[CONF_DATAPOINTS])
# try to get valid coefficients for a polynomial
coefficients = None
with np.errstate(all="raise"):
with warnings.catch_warnings(record=True) as all_warnings:
warnings.simplefilter("always")
try:
coefficients = np.polyfit(x_values, y_values, degree)
except FloatingPointError as error:
_LOGGER.error(
"Setup of %s encountered an error, %s",
compensation,
error,
)
for warning in all_warnings:
_LOGGER.warning(
"Setup of %s encountered a warning, %s",
compensation,
str(warning.message).lower(),
)
if coefficients is not None:
data = {
k: v for k, v in conf.items() if k not in [CONF_DEGREE, CONF_DATAPOINTS]
}
data[CONF_POLYNOMIAL] = np.poly1d(coefficients)
hass.data[DATA_COMPENSATION][compensation] = data
hass.async_create_task(
async_load_platform(
hass,
SENSOR_DOMAIN,
DOMAIN,
{CONF_COMPENSATION: compensation},
config,
)
)
return True