From de407709262c8476745e26b95c0c3e94a7f4a545 Mon Sep 17 00:00:00 2001 From: Klaas Schoute Date: Thu, 24 Mar 2022 13:18:19 +0100 Subject: [PATCH] Add diagnostics support to Forecast.Solar (#65063) Co-authored-by: Franck Nijhof --- .../components/forecast_solar/__init__.py | 4 +- .../components/forecast_solar/diagnostics.py | 58 +++++++++++++++++++ tests/components/forecast_solar/conftest.py | 13 +++++ .../forecast_solar/test_diagnostics.py | 58 +++++++++++++++++++ 4 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 homeassistant/components/forecast_solar/diagnostics.py create mode 100644 tests/components/forecast_solar/test_diagnostics.py diff --git a/homeassistant/components/forecast_solar/__init__.py b/homeassistant/components/forecast_solar/__init__.py index d4e8e3af969..18d542c1d3b 100644 --- a/homeassistant/components/forecast_solar/__init__.py +++ b/homeassistant/components/forecast_solar/__init__.py @@ -4,7 +4,7 @@ from __future__ import annotations from datetime import timedelta import logging -from forecast_solar import ForecastSolar +from forecast_solar import Estimate, ForecastSolar from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, Platform @@ -54,7 +54,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: if api_key is not None: update_interval = timedelta(minutes=30) - coordinator: DataUpdateCoordinator = DataUpdateCoordinator( + coordinator: DataUpdateCoordinator[Estimate] = DataUpdateCoordinator( hass, logging.getLogger(__name__), name=DOMAIN, diff --git a/homeassistant/components/forecast_solar/diagnostics.py b/homeassistant/components/forecast_solar/diagnostics.py new file mode 100644 index 00000000000..7fdcd22d0fc --- /dev/null +++ b/homeassistant/components/forecast_solar/diagnostics.py @@ -0,0 +1,58 @@ +"""Diagnostics support for Forecast.Solar integration.""" +from __future__ import annotations + +from typing import Any + +from forecast_solar import Estimate + +from homeassistant.components.diagnostics import async_redact_data +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE +from homeassistant.core import HomeAssistant +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator + +from .const import DOMAIN + +TO_REDACT = { + CONF_API_KEY, + CONF_LATITUDE, + CONF_LONGITUDE, +} + + +async def async_get_config_entry_diagnostics( + hass: HomeAssistant, entry: ConfigEntry +) -> dict[str, Any]: + """Return diagnostics for a config entry.""" + coordinator: DataUpdateCoordinator[Estimate] = hass.data[DOMAIN][entry.entry_id] + + return { + "entry": { + "title": entry.title, + "data": async_redact_data(entry.data, TO_REDACT), + "options": async_redact_data(entry.options, TO_REDACT), + }, + "data": { + "energy_production_today": coordinator.data.energy_production_today, + "energy_production_tomorrow": coordinator.data.energy_production_tomorrow, + "energy_current_hour": coordinator.data.energy_current_hour, + "power_production_now": coordinator.data.power_production_now, + "watts": { + watt_datetime.isoformat(): watt_value + for watt_datetime, watt_value in coordinator.data.watts.items() + }, + "wh_days": { + wh_datetime.isoformat(): wh_value + for wh_datetime, wh_value in coordinator.data.wh_days.items() + }, + "wh_hours": { + wh_datetime.isoformat(): wh_value + for wh_datetime, wh_value in coordinator.data.wh_hours.items() + }, + }, + "account": { + "type": coordinator.data.account_type.value, + "rate_limit": coordinator.data.api_rate_limit, + "timezone": coordinator.data.timezone, + }, + } diff --git a/tests/components/forecast_solar/conftest.py b/tests/components/forecast_solar/conftest.py index 0d9f76b367e..31256c95866 100644 --- a/tests/components/forecast_solar/conftest.py +++ b/tests/components/forecast_solar/conftest.py @@ -59,6 +59,7 @@ def mock_forecast_solar(hass) -> Generator[None, MagicMock, None]: estimate = MagicMock(spec=models.Estimate) estimate.now.return_value = now estimate.timezone = "Europe/Amsterdam" + estimate.api_rate_limit = 60 estimate.account_type.value = "public" estimate.energy_production_today = 100000 estimate.energy_production_tomorrow = 200000 @@ -80,6 +81,18 @@ def mock_forecast_solar(hass) -> Generator[None, MagicMock, None]: estimate.sum_energy_production.side_effect = { 1: 900000, }.get + estimate.watts = { + datetime(2021, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 10, + datetime(2022, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 100, + } + estimate.wh_days = { + datetime(2021, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 20, + datetime(2022, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 200, + } + estimate.wh_hours = { + datetime(2021, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 30, + datetime(2022, 6, 27, 13, 0, tzinfo=dt_util.DEFAULT_TIME_ZONE): 300, + } forecast_solar.estimate.return_value = estimate yield forecast_solar diff --git a/tests/components/forecast_solar/test_diagnostics.py b/tests/components/forecast_solar/test_diagnostics.py new file mode 100644 index 00000000000..3c388951009 --- /dev/null +++ b/tests/components/forecast_solar/test_diagnostics.py @@ -0,0 +1,58 @@ +"""Tests for the diagnostics data provided by the Forecast.Solar integration.""" +from aiohttp import ClientSession + +from homeassistant.components.diagnostics import REDACTED +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry +from tests.components.diagnostics import get_diagnostics_for_config_entry + + +async def test_diagnostics( + hass: HomeAssistant, + hass_client: ClientSession, + init_integration: MockConfigEntry, +): + """Test diagnostics.""" + assert await get_diagnostics_for_config_entry( + hass, hass_client, init_integration + ) == { + "entry": { + "title": "Green House", + "data": { + "latitude": REDACTED, + "longitude": REDACTED, + }, + "options": { + "api_key": REDACTED, + "declination": 30, + "azimuth": 190, + "modules power": 5100, + "damping": 0.5, + "inverter_size": 2000, + }, + }, + "data": { + "energy_production_today": 100000, + "energy_production_tomorrow": 200000, + "energy_current_hour": 800000, + "power_production_now": 300000, + "watts": { + "2021-06-27T13:00:00-07:00": 10, + "2022-06-27T13:00:00-07:00": 100, + }, + "wh_days": { + "2021-06-27T13:00:00-07:00": 20, + "2022-06-27T13:00:00-07:00": 200, + }, + "wh_hours": { + "2021-06-27T13:00:00-07:00": 30, + "2022-06-27T13:00:00-07:00": 300, + }, + }, + "account": { + "type": "public", + "rate_limit": 60, + "timezone": "Europe/Amsterdam", + }, + }