mirror of
https://github.com/home-assistant/core.git
synced 2025-07-10 23:07:09 +00:00
Refactor eheimdigital platform async_setup_entry (#136745)
This commit is contained in:
parent
d83c335ed6
commit
cde59613a5
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from eheimdigital.device import EheimDigitalDevice
|
||||||
from eheimdigital.heater import EheimDigitalHeater
|
from eheimdigital.heater import EheimDigitalHeater
|
||||||
from eheimdigital.types import EheimDigitalClientError, HeaterMode, HeaterUnit
|
from eheimdigital.types import EheimDigitalClientError, HeaterMode, HeaterUnit
|
||||||
|
|
||||||
@ -39,17 +40,23 @@ async def async_setup_entry(
|
|||||||
"""Set up the callbacks for the coordinator so climate entities can be added as devices are found."""
|
"""Set up the callbacks for the coordinator so climate entities can be added as devices are found."""
|
||||||
coordinator = entry.runtime_data
|
coordinator = entry.runtime_data
|
||||||
|
|
||||||
async def async_setup_device_entities(device_address: str) -> None:
|
def async_setup_device_entities(
|
||||||
"""Set up the light entities for a device."""
|
device_address: str | dict[str, EheimDigitalDevice],
|
||||||
device = coordinator.hub.devices[device_address]
|
) -> None:
|
||||||
|
"""Set up the climate entities for one or multiple devices."""
|
||||||
|
entities: list[EheimDigitalHeaterClimate] = []
|
||||||
|
if isinstance(device_address, str):
|
||||||
|
device_address = {device_address: coordinator.hub.devices[device_address]}
|
||||||
|
for device in device_address.values():
|
||||||
if isinstance(device, EheimDigitalHeater):
|
if isinstance(device, EheimDigitalHeater):
|
||||||
async_add_entities([EheimDigitalHeaterClimate(coordinator, device)])
|
entities.append(EheimDigitalHeaterClimate(coordinator, device))
|
||||||
|
coordinator.known_devices.add(device.mac_address)
|
||||||
|
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
coordinator.add_platform_callback(async_setup_device_entities)
|
coordinator.add_platform_callback(async_setup_device_entities)
|
||||||
|
|
||||||
for device_address in entry.runtime_data.hub.devices:
|
async_setup_device_entities(coordinator.hub.devices)
|
||||||
await async_setup_device_entities(device_address)
|
|
||||||
|
|
||||||
|
|
||||||
class EheimDigitalHeaterClimate(EheimDigitalEntity[EheimDigitalHeater], ClimateEntity):
|
class EheimDigitalHeaterClimate(EheimDigitalEntity[EheimDigitalHeater], ClimateEntity):
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Callable, Coroutine
|
from collections.abc import Callable
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from aiohttp import ClientError
|
from aiohttp import ClientError
|
||||||
from eheimdigital.device import EheimDigitalDevice
|
from eheimdigital.device import EheimDigitalDevice
|
||||||
@ -19,7 +18,9 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda
|
|||||||
|
|
||||||
from .const import DOMAIN, LOGGER
|
from .const import DOMAIN, LOGGER
|
||||||
|
|
||||||
type AsyncSetupDeviceEntitiesCallback = Callable[[str], Coroutine[Any, Any, None]]
|
type AsyncSetupDeviceEntitiesCallback = Callable[
|
||||||
|
[str | dict[str, EheimDigitalDevice]], None
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class EheimDigitalUpdateCoordinator(
|
class EheimDigitalUpdateCoordinator(
|
||||||
@ -61,7 +62,7 @@ class EheimDigitalUpdateCoordinator(
|
|||||||
|
|
||||||
if device_address not in self.known_devices:
|
if device_address not in self.known_devices:
|
||||||
for platform_callback in self.platform_callbacks:
|
for platform_callback in self.platform_callbacks:
|
||||||
await platform_callback(device_address)
|
platform_callback(device_address)
|
||||||
|
|
||||||
async def _async_receive_callback(self) -> None:
|
async def _async_receive_callback(self) -> None:
|
||||||
self.async_set_updated_data(self.hub.devices)
|
self.async_set_updated_data(self.hub.devices)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from eheimdigital.classic_led_ctrl import EheimDigitalClassicLEDControl
|
from eheimdigital.classic_led_ctrl import EheimDigitalClassicLEDControl
|
||||||
|
from eheimdigital.device import EheimDigitalDevice
|
||||||
from eheimdigital.types import EheimDigitalClientError, LightMode
|
from eheimdigital.types import EheimDigitalClientError, LightMode
|
||||||
|
|
||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
@ -37,24 +38,28 @@ async def async_setup_entry(
|
|||||||
"""Set up the callbacks for the coordinator so lights can be added as devices are found."""
|
"""Set up the callbacks for the coordinator so lights can be added as devices are found."""
|
||||||
coordinator = entry.runtime_data
|
coordinator = entry.runtime_data
|
||||||
|
|
||||||
async def async_setup_device_entities(device_address: str) -> None:
|
def async_setup_device_entities(
|
||||||
"""Set up the light entities for a device."""
|
device_address: str | dict[str, EheimDigitalDevice],
|
||||||
device = coordinator.hub.devices[device_address]
|
) -> None:
|
||||||
|
"""Set up the light entities for one or multiple devices."""
|
||||||
entities: list[EheimDigitalClassicLEDControlLight] = []
|
entities: list[EheimDigitalClassicLEDControlLight] = []
|
||||||
|
if isinstance(device_address, str):
|
||||||
|
device_address = {device_address: coordinator.hub.devices[device_address]}
|
||||||
|
for device in device_address.values():
|
||||||
if isinstance(device, EheimDigitalClassicLEDControl):
|
if isinstance(device, EheimDigitalClassicLEDControl):
|
||||||
for channel in range(2):
|
for channel in range(2):
|
||||||
if len(device.tankconfig[channel]) > 0:
|
if len(device.tankconfig[channel]) > 0:
|
||||||
entities.append(
|
entities.append(
|
||||||
EheimDigitalClassicLEDControlLight(coordinator, device, channel)
|
EheimDigitalClassicLEDControlLight(
|
||||||
|
coordinator, device, channel
|
||||||
|
)
|
||||||
)
|
)
|
||||||
coordinator.known_devices.add(device.mac_address)
|
coordinator.known_devices.add(device.mac_address)
|
||||||
|
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
coordinator.add_platform_callback(async_setup_device_entities)
|
coordinator.add_platform_callback(async_setup_device_entities)
|
||||||
|
async_setup_device_entities(coordinator.hub.devices)
|
||||||
for device_address in entry.runtime_data.hub.devices:
|
|
||||||
await async_setup_device_entities(device_address)
|
|
||||||
|
|
||||||
|
|
||||||
class EheimDigitalClassicLEDControlLight(
|
class EheimDigitalClassicLEDControlLight(
|
||||||
|
@ -1,4 +1,80 @@
|
|||||||
# serializer version: 1
|
# serializer version: 1
|
||||||
|
# name: test_dynamic_new_devices[climate.mock_heater_none-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': dict({
|
||||||
|
'hvac_modes': list([
|
||||||
|
<HVACMode.OFF: 'off'>,
|
||||||
|
<HVACMode.AUTO: 'auto'>,
|
||||||
|
]),
|
||||||
|
'max_temp': 32,
|
||||||
|
'min_temp': 18,
|
||||||
|
'preset_modes': list([
|
||||||
|
'none',
|
||||||
|
'bio_mode',
|
||||||
|
'smart_mode',
|
||||||
|
]),
|
||||||
|
'target_temp_step': 0.5,
|
||||||
|
}),
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'climate',
|
||||||
|
'entity_category': None,
|
||||||
|
'entity_id': 'climate.mock_heater_none',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': None,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': None,
|
||||||
|
'platform': 'eheimdigital',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': <ClimateEntityFeature: 401>,
|
||||||
|
'translation_key': 'heater',
|
||||||
|
'unique_id': '00:00:00:00:00:02',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_dynamic_new_devices[climate.mock_heater_none-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'current_temperature': 24.2,
|
||||||
|
'friendly_name': 'Mock Heater None',
|
||||||
|
'hvac_action': <HVACAction.HEATING: 'heating'>,
|
||||||
|
'hvac_modes': list([
|
||||||
|
<HVACMode.OFF: 'off'>,
|
||||||
|
<HVACMode.AUTO: 'auto'>,
|
||||||
|
]),
|
||||||
|
'max_temp': 32,
|
||||||
|
'min_temp': 18,
|
||||||
|
'preset_mode': 'none',
|
||||||
|
'preset_modes': list([
|
||||||
|
'none',
|
||||||
|
'bio_mode',
|
||||||
|
'smart_mode',
|
||||||
|
]),
|
||||||
|
'supported_features': <ClimateEntityFeature: 401>,
|
||||||
|
'target_temp_step': 0.5,
|
||||||
|
'temperature': 25.5,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'climate.mock_heater_none',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': 'auto',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
# name: test_setup_heater[climate.mock_heater_none-entry]
|
# name: test_setup_heater[climate.mock_heater_none-entry]
|
||||||
EntityRegistryEntrySnapshot({
|
EntityRegistryEntrySnapshot({
|
||||||
'aliases': set({
|
'aliases': set({
|
||||||
|
@ -56,6 +56,41 @@ async def test_setup_heater(
|
|||||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_dynamic_new_devices(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
eheimdigital_hub_mock: MagicMock,
|
||||||
|
heater_mock: MagicMock,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test light platform setup with at first no devices and dynamically adding a device."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
eheimdigital_hub_mock.return_value.devices = {}
|
||||||
|
|
||||||
|
with patch("homeassistant.components.eheimdigital.PLATFORMS", [Platform.CLIMATE]):
|
||||||
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
len(
|
||||||
|
entity_registry.entities.get_entries_for_config_entry_id(
|
||||||
|
mock_config_entry.entry_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
== 0
|
||||||
|
)
|
||||||
|
|
||||||
|
eheimdigital_hub_mock.return_value.devices = {"00:00:00:00:00:02": heater_mock}
|
||||||
|
|
||||||
|
await eheimdigital_hub_mock.call_args.kwargs["device_found_callback"](
|
||||||
|
"00:00:00:00:00:02", EheimDeviceType.VERSION_EHEIM_EXT_HEATER
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("preset_mode", "heater_mode"),
|
("preset_mode", "heater_mode"),
|
||||||
[
|
[
|
||||||
|
Loading…
x
Reference in New Issue
Block a user