Use ConfigEntry runtime_data in easyEnergy (#133053)

This commit is contained in:
Klaas Schoute
2024-12-12 20:13:41 +01:00
committed by GitHub
parent 40c3dd2095
commit ce70cb9e33
6 changed files with 49 additions and 50 deletions

View File

@@ -2,7 +2,6 @@
from __future__ import annotations from __future__ import annotations
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform from homeassistant.const import Platform
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryNotReady
@@ -10,10 +9,10 @@ from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from .const import DOMAIN from .const import DOMAIN
from .coordinator import EasyEnergyDataUpdateCoordinator from .coordinator import EasyEnergyConfigEntry, EasyEnergyDataUpdateCoordinator
from .services import async_setup_services from .services import async_setup_services
PLATFORMS = [Platform.SENSOR] PLATFORMS: list[Platform] = [Platform.SENSOR]
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
@@ -25,25 +24,22 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
return True return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: EasyEnergyConfigEntry) -> bool:
"""Set up easyEnergy from a config entry.""" """Set up easyEnergy from a config entry."""
coordinator = EasyEnergyDataUpdateCoordinator(hass) coordinator = EasyEnergyDataUpdateCoordinator(hass, entry)
try: try:
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
except ConfigEntryNotReady: except ConfigEntryNotReady:
await coordinator.easyenergy.close() await coordinator.easyenergy.close()
raise raise
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_unload_entry(hass: HomeAssistant, entry: EasyEnergyConfigEntry) -> bool:
"""Unload easyEnergy config entry.""" """Unload easyEnergy config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok

View File

@@ -21,6 +21,8 @@ from homeassistant.util import dt as dt_util
from .const import DOMAIN, LOGGER, SCAN_INTERVAL, THRESHOLD_HOUR from .const import DOMAIN, LOGGER, SCAN_INTERVAL, THRESHOLD_HOUR
type EasyEnergyConfigEntry = ConfigEntry[EasyEnergyDataUpdateCoordinator]
class EasyEnergyData(NamedTuple): class EasyEnergyData(NamedTuple):
"""Class for defining data in dict.""" """Class for defining data in dict."""
@@ -33,15 +35,16 @@ class EasyEnergyData(NamedTuple):
class EasyEnergyDataUpdateCoordinator(DataUpdateCoordinator[EasyEnergyData]): class EasyEnergyDataUpdateCoordinator(DataUpdateCoordinator[EasyEnergyData]):
"""Class to manage fetching easyEnergy data from single endpoint.""" """Class to manage fetching easyEnergy data from single endpoint."""
config_entry: ConfigEntry config_entry: EasyEnergyConfigEntry
def __init__(self, hass: HomeAssistant) -> None: def __init__(self, hass: HomeAssistant, entry: EasyEnergyConfigEntry) -> None:
"""Initialize global easyEnergy data updater.""" """Initialize global easyEnergy data updater."""
super().__init__( super().__init__(
hass, hass,
LOGGER, LOGGER,
name=DOMAIN, name=DOMAIN,
update_interval=SCAN_INTERVAL, update_interval=SCAN_INTERVAL,
config_entry=entry,
) )
self.easyenergy = EasyEnergy(session=async_get_clientsession(hass)) self.easyenergy = EasyEnergy(session=async_get_clientsession(hass))

View File

@@ -5,12 +5,9 @@ from __future__ import annotations
from datetime import timedelta from datetime import timedelta
from typing import Any from typing import Any
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from . import EasyEnergyDataUpdateCoordinator from .coordinator import EasyEnergyConfigEntry, EasyEnergyData
from .const import DOMAIN
from .coordinator import EasyEnergyData
def get_gas_price(data: EasyEnergyData, hours: int) -> float | None: def get_gas_price(data: EasyEnergyData, hours: int) -> float | None:
@@ -32,41 +29,42 @@ def get_gas_price(data: EasyEnergyData, hours: int) -> float | None:
async def async_get_config_entry_diagnostics( async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: ConfigEntry hass: HomeAssistant, entry: EasyEnergyConfigEntry
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Return diagnostics for a config entry.""" """Return diagnostics for a config entry."""
coordinator: EasyEnergyDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] coordinator_data = entry.runtime_data.data
energy_today = coordinator_data.energy_today
return { return {
"entry": { "entry": {
"title": entry.title, "title": entry.title,
}, },
"energy_usage": { "energy_usage": {
"current_hour_price": coordinator.data.energy_today.current_usage_price, "current_hour_price": energy_today.current_usage_price,
"next_hour_price": coordinator.data.energy_today.price_at_time( "next_hour_price": energy_today.price_at_time(
coordinator.data.energy_today.utcnow() + timedelta(hours=1) energy_today.utcnow() + timedelta(hours=1)
), ),
"average_price": coordinator.data.energy_today.average_usage_price, "average_price": energy_today.average_usage_price,
"max_price": coordinator.data.energy_today.extreme_usage_prices[1], "max_price": energy_today.extreme_usage_prices[1],
"min_price": coordinator.data.energy_today.extreme_usage_prices[0], "min_price": energy_today.extreme_usage_prices[0],
"highest_price_time": coordinator.data.energy_today.highest_usage_price_time, "highest_price_time": energy_today.highest_usage_price_time,
"lowest_price_time": coordinator.data.energy_today.lowest_usage_price_time, "lowest_price_time": energy_today.lowest_usage_price_time,
"percentage_of_max": coordinator.data.energy_today.pct_of_max_usage, "percentage_of_max": energy_today.pct_of_max_usage,
}, },
"energy_return": { "energy_return": {
"current_hour_price": coordinator.data.energy_today.current_return_price, "current_hour_price": energy_today.current_return_price,
"next_hour_price": coordinator.data.energy_today.price_at_time( "next_hour_price": energy_today.price_at_time(
coordinator.data.energy_today.utcnow() + timedelta(hours=1), "return" energy_today.utcnow() + timedelta(hours=1), "return"
), ),
"average_price": coordinator.data.energy_today.average_return_price, "average_price": energy_today.average_return_price,
"max_price": coordinator.data.energy_today.extreme_return_prices[1], "max_price": energy_today.extreme_return_prices[1],
"min_price": coordinator.data.energy_today.extreme_return_prices[0], "min_price": energy_today.extreme_return_prices[0],
"highest_price_time": coordinator.data.energy_today.highest_return_price_time, "highest_price_time": energy_today.highest_return_price_time,
"lowest_price_time": coordinator.data.energy_today.lowest_return_price_time, "lowest_price_time": energy_today.lowest_return_price_time,
"percentage_of_max": coordinator.data.energy_today.pct_of_max_return, "percentage_of_max": energy_today.pct_of_max_return,
}, },
"gas": { "gas": {
"current_hour_price": get_gas_price(coordinator.data, 0), "current_hour_price": get_gas_price(coordinator_data, 0),
"next_hour_price": get_gas_price(coordinator.data, 1), "next_hour_price": get_gas_price(coordinator_data, 1),
}, },
} }

View File

@@ -13,7 +13,6 @@ from homeassistant.components.sensor import (
SensorEntityDescription, SensorEntityDescription,
SensorStateClass, SensorStateClass,
) )
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
CURRENCY_EURO, CURRENCY_EURO,
PERCENTAGE, PERCENTAGE,
@@ -27,7 +26,11 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN, SERVICE_TYPE_DEVICE_NAMES from .const import DOMAIN, SERVICE_TYPE_DEVICE_NAMES
from .coordinator import EasyEnergyData, EasyEnergyDataUpdateCoordinator from .coordinator import (
EasyEnergyConfigEntry,
EasyEnergyData,
EasyEnergyDataUpdateCoordinator,
)
@dataclass(frozen=True, kw_only=True) @dataclass(frozen=True, kw_only=True)
@@ -208,10 +211,12 @@ def get_gas_price(data: EasyEnergyData, hours: int) -> float | None:
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant,
entry: EasyEnergyConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None: ) -> None:
"""Set up easyEnergy sensors based on a config entry.""" """Set up easyEnergy sensors based on a config entry."""
coordinator: EasyEnergyDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] coordinator = entry.runtime_data
async_add_entities( async_add_entities(
EasyEnergySensorEntity(coordinator=coordinator, description=description) EasyEnergySensorEntity(coordinator=coordinator, description=description)
for description in SENSORS for description in SENSORS

View File

@@ -10,7 +10,7 @@ from typing import Final
from easyenergy import Electricity, Gas, VatOption from easyenergy import Electricity, Gas, VatOption
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import ConfigEntry, ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import ( from homeassistant.core import (
HomeAssistant, HomeAssistant,
ServiceCall, ServiceCall,
@@ -23,7 +23,7 @@ from homeassistant.helpers import selector
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from .const import DOMAIN from .const import DOMAIN
from .coordinator import EasyEnergyDataUpdateCoordinator from .coordinator import EasyEnergyConfigEntry, EasyEnergyDataUpdateCoordinator
ATTR_CONFIG_ENTRY: Final = "config_entry" ATTR_CONFIG_ENTRY: Final = "config_entry"
ATTR_START: Final = "start" ATTR_START: Final = "start"
@@ -91,7 +91,7 @@ def __get_coordinator(
) -> EasyEnergyDataUpdateCoordinator: ) -> EasyEnergyDataUpdateCoordinator:
"""Get the coordinator from the entry.""" """Get the coordinator from the entry."""
entry_id: str = call.data[ATTR_CONFIG_ENTRY] entry_id: str = call.data[ATTR_CONFIG_ENTRY]
entry: ConfigEntry | None = hass.config_entries.async_get_entry(entry_id) entry: EasyEnergyConfigEntry | None = hass.config_entries.async_get_entry(entry_id)
if not entry: if not entry:
raise ServiceValidationError( raise ServiceValidationError(
@@ -110,8 +110,7 @@ def __get_coordinator(
}, },
) )
coordinator: EasyEnergyDataUpdateCoordinator = hass.data[DOMAIN][entry_id] return entry.runtime_data
return coordinator
async def __get_prices( async def __get_prices(

View File

@@ -4,7 +4,6 @@ from unittest.mock import MagicMock, patch
from easyenergy import EasyEnergyConnectionError from easyenergy import EasyEnergyConnectionError
from homeassistant.components.easyenergy.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@@ -24,7 +23,6 @@ async def test_load_unload_config_entry(
await hass.config_entries.async_unload(mock_config_entry.entry_id) await hass.config_entries.async_unload(mock_config_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
assert not hass.data.get(DOMAIN)
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED assert mock_config_entry.state is ConfigEntryState.NOT_LOADED