From ba9daea4b6da96cbb4f66f4e519db13e31ee595a Mon Sep 17 00:00:00 2001 From: Thibaut Date: Fri, 25 Dec 2020 22:37:55 +0100 Subject: [PATCH] Add hourly report (#10) --- custom_components/veolia/__init__.py | 45 ++++++++++++++++++++------ custom_components/veolia/const.py | 4 +++ custom_components/veolia/entity.py | 18 ++++++++--- custom_components/veolia/manifest.json | 2 +- custom_components/veolia/sensor.py | 44 ++++++++++++------------- 5 files changed, 74 insertions(+), 39 deletions(-) diff --git a/custom_components/veolia/__init__.py b/custom_components/veolia/__init__.py index 89696af..9a696cd 100644 --- a/custom_components/veolia/__init__.py +++ b/custom_components/veolia/__init__.py @@ -7,6 +7,7 @@ import asyncio from datetime import datetime, timedelta import logging +import time from homeassistant.config_entries import ConfigEntry from homeassistant.core import Config, HomeAssistant @@ -14,7 +15,6 @@ from homeassistant.helpers import aiohttp_client from homeassistant.helpers.typing import HomeAssistantType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator - from pyolia.client import VeoliaClient from .const import ( @@ -22,11 +22,15 @@ CONF_PASSWORD, CONF_USERNAME, COORDINATOR, + DAILY, DOMAIN, + HOURLY, + LAST_REPORT_TIMESTAMP, PLATFORMS, ) -SCAN_INTERVAL = timedelta(days=1) +SCAN_INTERVAL = timedelta(seconds=30) + _LOGGER = logging.getLogger(__name__) @@ -48,11 +52,34 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): hass.data[DOMAIN][API] = VeoliaClient(username, password, session) async def _get_consumption(): - """Return the water consumption for each day of the current month.""" - now = datetime.now() - if now.day < 4: - now = now - timedelta(days=3) - return await hass.data[DOMAIN][API].get_consumption(now.month, now.year) + """Return the water consumption.""" + api = hass.data[DOMAIN][API] + last_report_date = api.last_report_date + last_report_timestamp = time.mktime( + datetime( + last_report_date.year, last_report_date.month, last_report_date.day + ).timetuple() + ) + + previous_data = hass.data[DOMAIN][COORDINATOR].data + if ( + previous_data + and previous_data[LAST_REPORT_TIMESTAMP] == last_report_timestamp + ): + return previous_data + + daily_consumption = await api.get_consumption( + last_report_date.month, last_report_date.year + ) + + hourly_consumption = await api.get_consumption( + last_report_date.month, last_report_date.year, last_report_date.day + ) + return { + DAILY: daily_consumption, + HOURLY: hourly_consumption, + LAST_REPORT_TIMESTAMP: last_report_timestamp, + } coordinator = DataUpdateCoordinator( hass, @@ -62,13 +89,13 @@ async def _get_consumption(): update_interval=SCAN_INTERVAL, ) + hass.data[DOMAIN][COORDINATOR] = coordinator + await coordinator.async_refresh() if not coordinator.last_update_success: raise ConfigEntryNotReady - hass.data[DOMAIN][COORDINATOR] = coordinator - for platform in PLATFORMS: hass.async_add_job( hass.config_entries.async_forward_entry_setup(entry, platform) diff --git a/custom_components/veolia/const.py b/custom_components/veolia/const.py index 59a06db..58b54fa 100644 --- a/custom_components/veolia/const.py +++ b/custom_components/veolia/const.py @@ -9,3 +9,7 @@ CONF_PASSWORD = "password" API = "api" COORDINATOR = "coordinator" + +DAILY = "daily" +HOURLY = "hourly" +LAST_REPORT_TIMESTAMP = "last_report_timestamp" diff --git a/custom_components/veolia/entity.py b/custom_components/veolia/entity.py index 13d8091..3f3b094 100644 --- a/custom_components/veolia/entity.py +++ b/custom_components/veolia/entity.py @@ -1,9 +1,8 @@ """VeoliaEntity class""" -from datetime import datetime - +from homeassistant.const import VOLUME_LITERS from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DOMAIN, NAME +from .const import DOMAIN, LAST_REPORT_TIMESTAMP, NAME class VeoliaEntity(CoordinatorEntity): @@ -27,7 +26,16 @@ def device_info(self): @property def device_state_attributes(self): """Return the state attributes.""" - last_timestamp = list(self.coordinator.data.keys())[-1] return { - "last_report": datetime.fromtimestamp(last_timestamp), + "last_report": self.coordinator.data[LAST_REPORT_TIMESTAMP], } + + @property + def icon(self) -> str: + """Return the usage icon.""" + return "mdi:water" + + @property + def unit_of_measurement(self) -> str: + """Return liter as the unit measurement for water.""" + return VOLUME_LITERS diff --git a/custom_components/veolia/manifest.json b/custom_components/veolia/manifest.json index 2cbde1f..24c1ff2 100644 --- a/custom_components/veolia/manifest.json +++ b/custom_components/veolia/manifest.json @@ -9,6 +9,6 @@ "@tetienne" ], "requirements": [ - "pyolia==0.1.0" + "pyolia==0.2.0" ] } \ No newline at end of file diff --git a/custom_components/veolia/sensor.py b/custom_components/veolia/sensor.py index f570073..da17d74 100644 --- a/custom_components/veolia/sensor.py +++ b/custom_components/veolia/sensor.py @@ -1,7 +1,7 @@ """Sensor platform for Veolia.""" -from homeassistant.const import VOLUME_LITERS +import datetime -from .const import COORDINATOR, DOMAIN +from .const import COORDINATOR, DAILY, DOMAIN, HOURLY from .entity import VeoliaEntity @@ -10,38 +10,44 @@ async def async_setup_entry(hass, entry, async_add_devices): coordinator = hass.data[DOMAIN][COORDINATOR] async_add_devices( [ + VeoliaHourlyUsageSensor(coordinator, entry), VeoliaDailyUsageSensor(coordinator, entry), VeoliaMonthlyUsageSensor(coordinator, entry), ] ) -class VeoliaDailyUsageSensor(VeoliaEntity): - """Monitors the daily water usage.""" +class VeoliaHourlyUsageSensor(VeoliaEntity): + """Monitors the hourly water usage.""" @property def name(self): """Return the name of the sensor.""" - return "veolia_daily_consumption" + return "veolia_hourly_consumption" @property def state(self): """Return the state of the sensor.""" - return list(self.coordinator.data.values())[-1] + hour = datetime.datetime.now().hour + return self.coordinator.data[HOURLY][hour - 1] + + +class VeoliaDailyUsageSensor(VeoliaEntity): + """Monitors the daily water usage.""" @property - def icon(self) -> str: - """Return the daily usage icon.""" - return "mdi:water" + def name(self): + """Return the name of the sensor.""" + return "veolia_daily_consumption" @property - def unit_of_measurement(self) -> str: - """Return liter as the unit measurement for water.""" - return VOLUME_LITERS + def state(self): + """Return the state of the sensor.""" + return self.coordinator.data[DAILY][-1] class VeoliaMonthlyUsageSensor(VeoliaEntity): - """Monitors the daily water usage.""" + """Monitors the monthly water usage.""" @property def name(self): @@ -51,14 +57,4 @@ def name(self): @property def state(self): """Return the state of the sensor.""" - return sum(self.coordinator.data.values()) - - @property - def icon(self) -> str: - """Return the daily usage icon.""" - return "mdi:water" - - @property - def unit_of_measurement(self) -> str: - """Return liter as the unit measurement for water.""" - return VOLUME_LITERS + return sum(self.coordinator.data[DAILY])