diff --git a/homeassistant/components/energyzero/diagnostics.py b/homeassistant/components/energyzero/diagnostics.py new file mode 100644 index 00000000000..5e3e402efbf --- /dev/null +++ b/homeassistant/components/energyzero/diagnostics.py @@ -0,0 +1,58 @@ +"""Diagnostics support for EnergyZero.""" +from __future__ import annotations + +from datetime import timedelta +from typing import Any + +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant + +from . import EnergyZeroDataUpdateCoordinator +from .const import DOMAIN +from .coordinator import EnergyZeroData + + +def get_gas_price(data: EnergyZeroData, hours: int) -> float | None: + """Get the gas price for a given hour. + + Args: + data: The data object. + hours: The number of hours to add to the current time. + + Returns: + The gas market price value. + """ + if not data.gas_today: + return None + return data.gas_today.price_at_time( + data.gas_today.utcnow() + timedelta(hours=hours) + ) + + +async def async_get_config_entry_diagnostics( + hass: HomeAssistant, entry: ConfigEntry +) -> dict[str, Any]: + """Return diagnostics for a config entry.""" + coordinator: EnergyZeroDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + + return { + "entry": { + "title": entry.title, + }, + "energy": { + "current_hour_price": coordinator.data.energy_today.current_price, + "next_hour_price": coordinator.data.energy_today.price_at_time( + coordinator.data.energy_today.utcnow() + timedelta(hours=1) + ), + "average_price": coordinator.data.energy_today.average_price, + "max_price": coordinator.data.energy_today.extreme_prices[1], + "min_price": coordinator.data.energy_today.extreme_prices[0], + "highest_price_time": coordinator.data.energy_today.highest_price_time, + "lowest_price_time": coordinator.data.energy_today.lowest_price_time, + "percentage_of_max": coordinator.data.energy_today.pct_of_max_price, + }, + "gas": { + "current_hour_price": get_gas_price(coordinator.data, 0), + "next_hour_price": get_gas_price(coordinator.data, 1), + }, + } diff --git a/homeassistant/components/energyzero/manifest.json b/homeassistant/components/energyzero/manifest.json index d3f29d6a026..f0a76ab3baf 100644 --- a/homeassistant/components/energyzero/manifest.json +++ b/homeassistant/components/energyzero/manifest.json @@ -5,5 +5,6 @@ "documentation": "https://www.home-assistant.io/integrations/energyzero", "requirements": ["energyzero==0.3.1"], "codeowners": ["@klaasnicolaas"], - "iot_class": "cloud_polling" + "iot_class": "cloud_polling", + "quality_scale": "platinum" } diff --git a/tests/components/energyzero/test_diagnostics.py b/tests/components/energyzero/test_diagnostics.py new file mode 100644 index 00000000000..e58ca9bc0bf --- /dev/null +++ b/tests/components/energyzero/test_diagnostics.py @@ -0,0 +1,86 @@ +"""Tests for the diagnostics data provided by the EnergyZero integration.""" +from unittest.mock import MagicMock + +from aiohttp import ClientSession +from energyzero import EnergyZeroNoDataError +import pytest + +from homeassistant.components.homeassistant import SERVICE_UPDATE_ENTITY +from homeassistant.const import ATTR_ENTITY_ID +from homeassistant.core import HomeAssistant +from homeassistant.setup import async_setup_component + +from tests.common import MockConfigEntry +from tests.components.diagnostics import get_diagnostics_for_config_entry + + +@pytest.mark.freeze_time("2022-12-07 15:00:00") +async def test_diagnostics( + hass: HomeAssistant, + hass_client: ClientSession, + init_integration: MockConfigEntry, +) -> None: + """Test diagnostics.""" + assert await get_diagnostics_for_config_entry( + hass, hass_client, init_integration + ) == { + "entry": { + "title": "energy", + }, + "energy": { + "current_hour_price": 0.49, + "next_hour_price": 0.55, + "average_price": 0.37, + "max_price": 0.55, + "min_price": 0.26, + "highest_price_time": "2022-12-07T16:00:00+00:00", + "lowest_price_time": "2022-12-07T02:00:00+00:00", + "percentage_of_max": 89.09, + }, + "gas": { + "current_hour_price": 1.47, + "next_hour_price": 1.47, + }, + } + + +@pytest.mark.freeze_time("2022-12-07 15:00:00") +async def test_diagnostics_no_gas_today( + hass: HomeAssistant, + hass_client: ClientSession, + mock_energyzero: MagicMock, + init_integration: MockConfigEntry, +) -> None: + """Test diagnostics, no gas sensors available.""" + await async_setup_component(hass, "homeassistant", {}) + mock_energyzero.gas_prices.side_effect = EnergyZeroNoDataError + + await hass.services.async_call( + "homeassistant", + SERVICE_UPDATE_ENTITY, + {ATTR_ENTITY_ID: ["sensor.energyzero_today_gas_current_hour_price"]}, + blocking=True, + ) + await hass.async_block_till_done() + + assert await get_diagnostics_for_config_entry( + hass, hass_client, init_integration + ) == { + "entry": { + "title": "energy", + }, + "energy": { + "current_hour_price": 0.49, + "next_hour_price": 0.55, + "average_price": 0.37, + "max_price": 0.55, + "min_price": 0.26, + "highest_price_time": "2022-12-07T16:00:00+00:00", + "lowest_price_time": "2022-12-07T02:00:00+00:00", + "percentage_of_max": 89.09, + }, + "gas": { + "current_hour_price": None, + "next_hour_price": None, + }, + }