mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Add entity descriptions to Plugwise switch platform (#66174)
This commit is contained in:
parent
1f4ee3c265
commit
aa95150360
@ -62,6 +62,5 @@ FLAME_ICON = "mdi:fire"
|
|||||||
FLOW_OFF_ICON = "mdi:water-pump-off"
|
FLOW_OFF_ICON = "mdi:water-pump-off"
|
||||||
FLOW_ON_ICON = "mdi:water-pump"
|
FLOW_ON_ICON = "mdi:water-pump"
|
||||||
IDLE_ICON = "mdi:circle-off-outline"
|
IDLE_ICON = "mdi:circle-off-outline"
|
||||||
SWITCH_ICON = "mdi:electric-switch"
|
|
||||||
NO_NOTIFICATION_ICON = "mdi:mailbox-outline"
|
NO_NOTIFICATION_ICON = "mdi:mailbox-outline"
|
||||||
NOTIFICATION_ICON = "mdi:mailbox-up-outline"
|
NOTIFICATION_ICON = "mdi:mailbox-up-outline"
|
||||||
|
@ -2,16 +2,19 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from plugwise.exceptions import InvalidAuthentication, PlugwiseException
|
from plugwise.exceptions import InvalidAuthentication, PlugwiseException
|
||||||
from plugwise.smile import Smile
|
from plugwise.smile import Smile
|
||||||
|
|
||||||
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME
|
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers import device_registry as dr
|
from homeassistant.helpers import device_registry as dr
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
from homeassistant.helpers.entity_registry import RegistryEntry, async_migrate_entries
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
DEFAULT_PORT,
|
DEFAULT_PORT,
|
||||||
@ -26,6 +29,8 @@ from .coordinator import PlugwiseDataUpdateCoordinator
|
|||||||
|
|
||||||
async def async_setup_entry_gw(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry_gw(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up Plugwise Smiles from a config entry."""
|
"""Set up Plugwise Smiles from a config entry."""
|
||||||
|
await async_migrate_entries(hass, entry.entry_id, async_migrate_entity_entry)
|
||||||
|
|
||||||
websession = async_get_clientsession(hass, verify_ssl=False)
|
websession = async_get_clientsession(hass, verify_ssl=False)
|
||||||
api = Smile(
|
api = Smile(
|
||||||
host=entry.data[CONF_HOST],
|
host=entry.data[CONF_HOST],
|
||||||
@ -88,3 +93,16 @@ async def async_unload_entry_gw(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
):
|
):
|
||||||
hass.data[DOMAIN].pop(entry.entry_id)
|
hass.data[DOMAIN].pop(entry.entry_id)
|
||||||
return unload_ok
|
return unload_ok
|
||||||
|
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def async_migrate_entity_entry(entry: RegistryEntry) -> dict[str, Any] | None:
|
||||||
|
"""Migrate Plugwise entity entries.
|
||||||
|
|
||||||
|
- Migrates unique ID from old relay switches to the new unique ID
|
||||||
|
"""
|
||||||
|
if entry.domain == SWITCH_DOMAIN and entry.unique_id.endswith("-plug"):
|
||||||
|
return {"new_unique_id": entry.unique_id.replace("-plug", "-relay")}
|
||||||
|
|
||||||
|
# No migration needed
|
||||||
|
return None
|
||||||
|
@ -5,15 +5,23 @@ from typing import Any
|
|||||||
|
|
||||||
from plugwise.exceptions import PlugwiseException
|
from plugwise.exceptions import PlugwiseException
|
||||||
|
|
||||||
from homeassistant.components.switch import SwitchEntity
|
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from .const import DOMAIN, LOGGER, SWITCH_ICON
|
from .const import DOMAIN, LOGGER
|
||||||
from .coordinator import PlugwiseDataUpdateCoordinator
|
from .coordinator import PlugwiseDataUpdateCoordinator
|
||||||
from .entity import PlugwiseEntity
|
from .entity import PlugwiseEntity
|
||||||
|
|
||||||
|
SWITCHES: tuple[SwitchEntityDescription, ...] = (
|
||||||
|
SwitchEntityDescription(
|
||||||
|
key="relay",
|
||||||
|
name="Relay",
|
||||||
|
icon="mdi:electric-switch",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@ -22,35 +30,38 @@ async def async_setup_entry(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the Smile switches from a config entry."""
|
"""Set up the Smile switches from a config entry."""
|
||||||
coordinator = hass.data[DOMAIN][config_entry.entry_id]
|
coordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
async_add_entities(
|
entities: list[PlugwiseSwitchEntity] = []
|
||||||
PlugwiseSwitchEntity(coordinator, device_id)
|
for device_id, device in coordinator.data.devices.items():
|
||||||
for device_id, device in coordinator.data.devices.items()
|
for description in SWITCHES:
|
||||||
if "switches" in device and "relay" in device["switches"]
|
if "switches" not in device or description.key not in device["switches"]:
|
||||||
)
|
continue
|
||||||
|
entities.append(PlugwiseSwitchEntity(coordinator, device_id, description))
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
class PlugwiseSwitchEntity(PlugwiseEntity, SwitchEntity):
|
class PlugwiseSwitchEntity(PlugwiseEntity, SwitchEntity):
|
||||||
"""Representation of a Plugwise plug."""
|
"""Representation of a Plugwise plug."""
|
||||||
|
|
||||||
_attr_icon = SWITCH_ICON
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
coordinator: PlugwiseDataUpdateCoordinator,
|
coordinator: PlugwiseDataUpdateCoordinator,
|
||||||
device_id: str,
|
device_id: str,
|
||||||
|
description: SwitchEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the Plugwise API."""
|
"""Set up the Plugwise API."""
|
||||||
super().__init__(coordinator, device_id)
|
super().__init__(coordinator, device_id)
|
||||||
self._attr_unique_id = f"{device_id}-plug"
|
self.entity_description = description
|
||||||
self._members = coordinator.data.devices[device_id].get("members")
|
self._attr_unique_id = f"{device_id}-{description.key}"
|
||||||
self._attr_is_on = False
|
|
||||||
self._attr_name = coordinator.data.devices[device_id].get("name")
|
self._attr_name = coordinator.data.devices[device_id].get("name")
|
||||||
|
|
||||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
"""Turn the device on."""
|
"""Turn the device on."""
|
||||||
try:
|
try:
|
||||||
state_on = await self.coordinator.api.set_switch_state(
|
state_on = await self.coordinator.api.set_switch_state(
|
||||||
self._dev_id, self._members, "relay", "on"
|
self._dev_id,
|
||||||
|
self.coordinator.data.devices[self._dev_id].get("members"),
|
||||||
|
self.entity_description.key,
|
||||||
|
"on",
|
||||||
)
|
)
|
||||||
except PlugwiseException:
|
except PlugwiseException:
|
||||||
LOGGER.error("Error while communicating to device")
|
LOGGER.error("Error while communicating to device")
|
||||||
@ -63,7 +74,10 @@ class PlugwiseSwitchEntity(PlugwiseEntity, SwitchEntity):
|
|||||||
"""Turn the device off."""
|
"""Turn the device off."""
|
||||||
try:
|
try:
|
||||||
state_off = await self.coordinator.api.set_switch_state(
|
state_off = await self.coordinator.api.set_switch_state(
|
||||||
self._dev_id, self._members, "relay", "off"
|
self._dev_id,
|
||||||
|
self.coordinator.data.devices[self._dev_id].get("members"),
|
||||||
|
self.entity_description.key,
|
||||||
|
"off",
|
||||||
)
|
)
|
||||||
except PlugwiseException:
|
except PlugwiseException:
|
||||||
LOGGER.error("Error while communicating to device")
|
LOGGER.error("Error while communicating to device")
|
||||||
@ -80,5 +94,5 @@ class PlugwiseSwitchEntity(PlugwiseEntity, SwitchEntity):
|
|||||||
super()._handle_coordinator_update()
|
super()._handle_coordinator_update()
|
||||||
return
|
return
|
||||||
|
|
||||||
self._attr_is_on = data["switches"].get("relay")
|
self._attr_is_on = data["switches"].get(self.entity_description.key)
|
||||||
super()._handle_coordinator_update()
|
super()._handle_coordinator_update()
|
||||||
|
@ -2,8 +2,12 @@
|
|||||||
|
|
||||||
from plugwise.exceptions import PlugwiseException
|
from plugwise.exceptions import PlugwiseException
|
||||||
|
|
||||||
|
from homeassistant.components.plugwise.const import DOMAIN
|
||||||
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
from tests.components.plugwise.common import async_init_integration
|
from tests.components.plugwise.common import async_init_integration
|
||||||
|
|
||||||
|
|
||||||
@ -121,3 +125,45 @@ async def test_stretch_switch_changes(hass, mock_stretch):
|
|||||||
)
|
)
|
||||||
state = hass.states.get("switch.droger_52559")
|
state = hass.states.get("switch.droger_52559")
|
||||||
assert str(state.state) == "on"
|
assert str(state.state) == "on"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_unique_id_migration_plug_relay(hass, mock_smile_adam):
|
||||||
|
"""Test unique ID migration of -plugs to -relay."""
|
||||||
|
entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN, data={"host": "1.1.1.1", "password": "test-password"}
|
||||||
|
)
|
||||||
|
entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
registry = er.async_get(hass)
|
||||||
|
# Entry to migrate
|
||||||
|
registry.async_get_or_create(
|
||||||
|
SWITCH_DOMAIN,
|
||||||
|
DOMAIN,
|
||||||
|
"21f2b542c49845e6bb416884c55778d6-plug",
|
||||||
|
config_entry=entry,
|
||||||
|
suggested_object_id="playstation_smart_plug",
|
||||||
|
disabled_by=None,
|
||||||
|
)
|
||||||
|
# Entry not needing migration
|
||||||
|
registry.async_get_or_create(
|
||||||
|
SWITCH_DOMAIN,
|
||||||
|
DOMAIN,
|
||||||
|
"675416a629f343c495449970e2ca37b5-relay",
|
||||||
|
config_entry=entry,
|
||||||
|
suggested_object_id="router",
|
||||||
|
disabled_by=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get("switch.playstation_smart_plug") is not None
|
||||||
|
assert hass.states.get("switch.router") is not None
|
||||||
|
|
||||||
|
entity_entry = registry.async_get("switch.playstation_smart_plug")
|
||||||
|
assert entity_entry
|
||||||
|
assert entity_entry.unique_id == "21f2b542c49845e6bb416884c55778d6-relay"
|
||||||
|
|
||||||
|
entity_entry = registry.async_get("switch.router")
|
||||||
|
assert entity_entry
|
||||||
|
assert entity_entry.unique_id == "675416a629f343c495449970e2ca37b5-relay"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user