From bb4e014feb49f764e0ae918c2ce6fd01c7ef79a0 Mon Sep 17 00:00:00 2001 From: Rany Date: Sun, 9 Jun 2024 20:16:51 +0300 Subject: [PATCH] Provide detailed forecast in sensor attribute (#12) Fixes #1 Signed-off-by: rany --- .../open_meteo_solar_forecast/const.py | 5 ++- .../open_meteo_solar_forecast/recorder.py | 13 ++++++ .../open_meteo_solar_forecast/sensor.py | 40 ++++++++++++++++++- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 custom_components/open_meteo_solar_forecast/recorder.py diff --git a/custom_components/open_meteo_solar_forecast/const.py b/custom_components/open_meteo_solar_forecast/const.py index 9b24073..901d034 100644 --- a/custom_components/open_meteo_solar_forecast/const.py +++ b/custom_components/open_meteo_solar_forecast/const.py @@ -12,4 +12,7 @@ CONF_AZIMUTH = "azimuth" CONF_MODULES_POWER = "modules_power" CONF_INVERTER_POWER = "inverter_power" -CONF_EFFICIENCY_FACTOR = "efficiency_factor" \ No newline at end of file +CONF_EFFICIENCY_FACTOR = "efficiency_factor" + +ATTR_WATTS = "watts" +ATTR_WH_PERIOD = "wh_period" diff --git a/custom_components/open_meteo_solar_forecast/recorder.py b/custom_components/open_meteo_solar_forecast/recorder.py new file mode 100644 index 0000000..657623c --- /dev/null +++ b/custom_components/open_meteo_solar_forecast/recorder.py @@ -0,0 +1,13 @@ +"""Integration platform for recorder.""" + +from __future__ import annotations + +from homeassistant.core import HomeAssistant, callback + +from .const import ATTR_WATTS, ATTR_WH_PERIOD + + +@callback +def exclude_attributes(hass: HomeAssistant) -> set[str]: + """Exclude potentially large attributes from being recorded in the database.""" + return {ATTR_WATTS, ATTR_WH_PERIOD} diff --git a/custom_components/open_meteo_solar_forecast/sensor.py b/custom_components/open_meteo_solar_forecast/sensor.py index b3d46a6..fc0a90a 100644 --- a/custom_components/open_meteo_solar_forecast/sensor.py +++ b/custom_components/open_meteo_solar_forecast/sensor.py @@ -27,7 +27,7 @@ from open_meteo_solar_forecast.models import Estimate -from .const import DOMAIN +from .const import ATTR_WATTS, ATTR_WH_PERIOD, DOMAIN from .coordinator import OpenMeteoSolarForecastDataUpdateCoordinator @@ -290,3 +290,41 @@ def native_value(self) -> datetime | StateType: state = self.entity_description.state(self.coordinator.data) return state + + @property + def extra_state_attributes(self) -> dict[str, Any] | None: + """Return the state attributes.""" + if self.entity_description.key.startswith( + "energy_production_d" + ) or self.entity_description.key in ( + "energy_production_today", + "energy_production_tomorrow", + ): + target_date = self.coordinator.data.now().date() + if self.entity_description.key == "energy_production_tomorrow": + target_date += timedelta(days=1) + elif self.entity_description.key.startswith("energy_production_d"): + target_date += timedelta( + days=int(self.entity_description.key[len("energy_production_d") :]) + ) + elif self.entity_description.key == "energy_production_today": + pass # target_date is already set to today + else: + raise ValueError( + f"Unexpected key {self.entity_description.key} for extra_state_attributes" + ) + + return { + ATTR_WATTS: { + watt_datetime.isoformat(): watt_value + for watt_datetime, watt_value in self.coordinator.data.watts.items() + if watt_datetime.date() == target_date + }, + ATTR_WH_PERIOD: { + wh_datetime.isoformat(): wh_value + for wh_datetime, wh_value in self.coordinator.data.wh_period.items() + if wh_datetime.date() == target_date + }, + } + + return None