From 8a72e8df79883897c42ac9a1a6a743b64be654f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Hjelseth=20H=C3=B8yer?= Date: Wed, 21 Jul 2021 07:41:08 +0200 Subject: [PATCH] Convert Mill consumption attributes to sensors (#52311) --- .coveragerc | 1 + homeassistant/components/mill/__init__.py | 21 +++++- homeassistant/components/mill/climate.py | 21 +----- homeassistant/components/mill/const.py | 4 +- homeassistant/components/mill/sensor.py | 85 +++++++++++++++++++++++ 5 files changed, 111 insertions(+), 21 deletions(-) create mode 100644 homeassistant/components/mill/sensor.py diff --git a/.coveragerc b/.coveragerc index 3b6c140c0f1..84577e99197 100644 --- a/.coveragerc +++ b/.coveragerc @@ -622,6 +622,7 @@ omit = homeassistant/components/mill/__init__.py homeassistant/components/mill/climate.py homeassistant/components/mill/const.py + homeassistant/components/mill/sensor.py homeassistant/components/minecraft_server/__init__.py homeassistant/components/minecraft_server/binary_sensor.py homeassistant/components/minecraft_server/const.py diff --git a/homeassistant/components/mill/__init__.py b/homeassistant/components/mill/__init__.py index 115bb5eb33c..75422cd26e1 100644 --- a/homeassistant/components/mill/__init__.py +++ b/homeassistant/components/mill/__init__.py @@ -1,10 +1,29 @@ """The mill component.""" +from mill import Mill -PLATFORMS = ["climate"] +from homeassistant.const import CONF_PASSWORD, CONF_USERNAME +from homeassistant.exceptions import ConfigEntryNotReady +from homeassistant.helpers.aiohttp_client import async_get_clientsession + +from .const import DOMAIN + +PLATFORMS = ["climate", "sensor"] async def async_setup_entry(hass, entry): """Set up the Mill heater.""" + mill_data_connection = Mill( + entry.data[CONF_USERNAME], + entry.data[CONF_PASSWORD], + websession=async_get_clientsession(hass), + ) + if not await mill_data_connection.connect(): + raise ConfigEntryNotReady + + await mill_data_connection.find_all_heaters() + + hass.data[DOMAIN] = mill_data_connection + hass.config_entries.async_setup_platforms(entry, PLATFORMS) return True diff --git a/homeassistant/components/mill/climate.py b/homeassistant/components/mill/climate.py index 2d591c67668..16c78329b0b 100644 --- a/homeassistant/components/mill/climate.py +++ b/homeassistant/components/mill/climate.py @@ -1,5 +1,4 @@ """Support for mill wifi-enabled home heaters.""" -from mill import Mill import voluptuous as vol from homeassistant.components.climate import ClimateEntity @@ -12,15 +11,8 @@ from homeassistant.components.climate.const import ( SUPPORT_FAN_MODE, SUPPORT_TARGET_TEMPERATURE, ) -from homeassistant.const import ( - ATTR_TEMPERATURE, - CONF_PASSWORD, - CONF_USERNAME, - TEMP_CELSIUS, -) -from homeassistant.exceptions import ConfigEntryNotReady +from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import ( ATTR_AWAY_TEMP, @@ -48,15 +40,8 @@ SET_ROOM_TEMP_SCHEMA = vol.Schema( async def async_setup_entry(hass, entry, async_add_entities): """Set up the Mill climate.""" - mill_data_connection = Mill( - entry.data[CONF_USERNAME], - entry.data[CONF_PASSWORD], - websession=async_get_clientsession(hass), - ) - if not await mill_data_connection.connect(): - raise ConfigEntryNotReady - await mill_data_connection.find_all_heaters() + mill_data_connection = hass.data[DOMAIN] dev = [] for heater in mill_data_connection.heaters.values(): @@ -109,8 +94,6 @@ class MillHeater(ClimateEntity): "heating": self._heater.is_heating, "controlled_by_tibber": self._heater.tibber_control, "heater_generation": 1 if self._heater.is_gen1 else 2, - "consumption_today": self._heater.day_consumption, - "consumption_total": self._heater.year_consumption, } if self._heater.room: res["room"] = self._heater.room.name diff --git a/homeassistant/components/mill/const.py b/homeassistant/components/mill/const.py index b0ba7065e0a..61171420e44 100644 --- a/homeassistant/components/mill/const.py +++ b/homeassistant/components/mill/const.py @@ -4,8 +4,10 @@ ATTR_AWAY_TEMP = "away_temp" ATTR_COMFORT_TEMP = "comfort_temp" ATTR_ROOM_NAME = "room_name" ATTR_SLEEP_TEMP = "sleep_temp" +CONSUMPTION_TODAY = "consumption_today" +CONSUMPTION_YEAR = "consumption_year" +DOMAIN = "mill" MANUFACTURER = "Mill" MAX_TEMP = 35 MIN_TEMP = 5 -DOMAIN = "mill" SERVICE_SET_ROOM_TEMP = "set_room_temperature" diff --git a/homeassistant/components/mill/sensor.py b/homeassistant/components/mill/sensor.py new file mode 100644 index 00000000000..5b0cf7efd73 --- /dev/null +++ b/homeassistant/components/mill/sensor.py @@ -0,0 +1,85 @@ +"""Support for mill wifi-enabled home heaters.""" + +from homeassistant.components.sensor import ( + DEVICE_CLASS_ENERGY, + STATE_CLASS_MEASUREMENT, + SensorEntity, +) +from homeassistant.const import ENERGY_KILO_WATT_HOUR, STATE_UNKNOWN +from homeassistant.util import dt as dt_util + +from .const import CONSUMPTION_TODAY, CONSUMPTION_YEAR, DOMAIN, MANUFACTURER + + +async def async_setup_entry(hass, entry, async_add_entities): + """Set up the Mill sensor.""" + + mill_data_connection = hass.data[DOMAIN] + + dev = [] + for heater in mill_data_connection.heaters.values(): + for sensor_type in [CONSUMPTION_TODAY, CONSUMPTION_YEAR]: + dev.append( + MillHeaterEnergySensor(heater, mill_data_connection, sensor_type) + ) + async_add_entities(dev) + + +class MillHeaterEnergySensor(SensorEntity): + """Representation of a Mill Sensor device.""" + + def __init__(self, heater, mill_data_connection, sensor_type): + """Initialize the sensor.""" + self._id = heater.device_id + self._conn = mill_data_connection + self._sensor_type = sensor_type + + self._attr_device_class = DEVICE_CLASS_ENERGY + self._attr_name = f"{heater.name} {sensor_type.replace('_', ' ')}" + self._attr_unique_id = f"{heater.device_id}_{sensor_type}" + self._attr_unit_of_measurement = ENERGY_KILO_WATT_HOUR + self._attr_state_class = STATE_CLASS_MEASUREMENT + self._attr_device_info = { + "identifiers": {(DOMAIN, heater.device_id)}, + "name": self.name, + "manufacturer": MANUFACTURER, + "model": f"generation {1 if heater.is_gen1 else 2}", + } + if self._sensor_type == CONSUMPTION_TODAY: + self._attr_last_reset = dt_util.as_utc( + dt_util.now().replace(hour=0, minute=0, second=0, microsecond=0) + ) + elif self._sensor_type == CONSUMPTION_YEAR: + self._attr_last_reset = dt_util.as_utc( + dt_util.now().replace( + month=1, day=1, hour=0, minute=0, second=0, microsecond=0 + ) + ) + + async def async_update(self): + """Retrieve latest state.""" + heater = await self._conn.update_device(self._id) + self._attr_available = heater.available + + if self._sensor_type == CONSUMPTION_TODAY: + _state = heater.day_consumption + elif self._sensor_type == CONSUMPTION_YEAR: + _state = heater.year_consumption + else: + _state = None + if _state is None: + self._attr_state = _state + return + + if self.state not in [STATE_UNKNOWN, None] and _state < self.state: + if self._sensor_type == CONSUMPTION_TODAY: + self._attr_last_reset = dt_util.as_utc( + dt_util.now().replace(hour=0, minute=0, second=0, microsecond=0) + ) + elif self._sensor_type == CONSUMPTION_YEAR: + self._attr_last_reset = dt_util.as_utc( + dt_util.now().replace( + month=1, day=1, hour=0, minute=0, second=0, microsecond=0 + ) + ) + self._attr_state = _state