mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Update plugwise module to 0.16.9 (#68255)
Co-authored-by: Franck Nijhof <frenck@frenck.nl>
This commit is contained in:
parent
94fde3bf23
commit
4d607b2eb5
@ -7,22 +7,27 @@ 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, callback
|
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, entity_registry as er
|
||||||
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 DEFAULT_PORT, DEFAULT_USERNAME, DOMAIN, LOGGER, PLATFORMS_GATEWAY
|
from .const import (
|
||||||
|
DEFAULT_PORT,
|
||||||
|
DEFAULT_USERNAME,
|
||||||
|
DOMAIN,
|
||||||
|
LOGGER,
|
||||||
|
PLATFORMS_GATEWAY,
|
||||||
|
Platform,
|
||||||
|
)
|
||||||
from .coordinator import PlugwiseDataUpdateCoordinator
|
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)
|
await er.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(
|
||||||
@ -57,6 +62,7 @@ async def async_setup_entry_gw(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
|
|
||||||
coordinator = PlugwiseDataUpdateCoordinator(hass, api)
|
coordinator = PlugwiseDataUpdateCoordinator(hass, api)
|
||||||
await coordinator.async_config_entry_first_refresh()
|
await coordinator.async_config_entry_first_refresh()
|
||||||
|
migrate_sensor_entities(hass, coordinator)
|
||||||
|
|
||||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
|
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
|
||||||
|
|
||||||
@ -85,13 +91,39 @@ async def async_unload_entry_gw(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_migrate_entity_entry(entry: RegistryEntry) -> dict[str, Any] | None:
|
def async_migrate_entity_entry(entry: er.RegistryEntry) -> dict[str, Any] | None:
|
||||||
"""Migrate Plugwise entity entries.
|
"""Migrate Plugwise entity entries.
|
||||||
|
|
||||||
- Migrates unique ID from old relay switches to the new unique ID
|
- Migrates unique ID from old relay switches to the new unique ID
|
||||||
"""
|
"""
|
||||||
if entry.domain == SWITCH_DOMAIN and entry.unique_id.endswith("-plug"):
|
if entry.domain == Platform.SWITCH and entry.unique_id.endswith("-plug"):
|
||||||
return {"new_unique_id": entry.unique_id.replace("-plug", "-relay")}
|
return {"new_unique_id": entry.unique_id.replace("-plug", "-relay")}
|
||||||
|
|
||||||
# No migration needed
|
# No migration needed
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_sensor_entities(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
coordinator: PlugwiseDataUpdateCoordinator,
|
||||||
|
) -> None:
|
||||||
|
"""Migrate Sensors if needed."""
|
||||||
|
ent_reg = er.async_get(hass)
|
||||||
|
|
||||||
|
# Migrating opentherm_outdoor_temperature to opentherm_outdoor_air_temperature sensor
|
||||||
|
for device_id, device in coordinator.data.devices.items():
|
||||||
|
if device["class"] != "heater_central":
|
||||||
|
continue
|
||||||
|
|
||||||
|
old_unique_id = f"{device_id}-outdoor_temperature"
|
||||||
|
if entity_id := ent_reg.async_get_entity_id(
|
||||||
|
Platform.SENSOR, DOMAIN, old_unique_id
|
||||||
|
):
|
||||||
|
new_unique_id = f"{device_id}-outdoor_air_temperature"
|
||||||
|
LOGGER.debug(
|
||||||
|
"Migrating entity %s from old unique ID '%s' to new unique ID '%s'",
|
||||||
|
entity_id,
|
||||||
|
old_unique_id,
|
||||||
|
new_unique_id,
|
||||||
|
)
|
||||||
|
ent_reg.async_update_entity(entity_id, new_unique_id=new_unique_id)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"domain": "plugwise",
|
"domain": "plugwise",
|
||||||
"name": "Plugwise",
|
"name": "Plugwise",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/plugwise",
|
"documentation": "https://www.home-assistant.io/integrations/plugwise",
|
||||||
"requirements": ["plugwise==0.16.8"],
|
"requirements": ["plugwise==0.16.9"],
|
||||||
"codeowners": ["@CoMPaTech", "@bouwew", "@brefra", "@frenck"],
|
"codeowners": ["@CoMPaTech", "@bouwew", "@brefra", "@frenck"],
|
||||||
"zeroconf": ["_plugwise._tcp.local."],
|
"zeroconf": ["_plugwise._tcp.local."],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
|
@ -60,6 +60,13 @@ SENSORS: tuple[SensorEntityDescription, ...] = (
|
|||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="outdoor_air_temperature",
|
||||||
|
name="Outdoor Air Temperature",
|
||||||
|
native_unit_of_measurement=TEMP_CELSIUS,
|
||||||
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
SensorEntityDescription(
|
SensorEntityDescription(
|
||||||
key="water_temperature",
|
key="water_temperature",
|
||||||
name="Water Temperature",
|
name="Water Temperature",
|
||||||
|
@ -1222,7 +1222,7 @@ plexauth==0.0.6
|
|||||||
plexwebsocket==0.0.13
|
plexwebsocket==0.0.13
|
||||||
|
|
||||||
# homeassistant.components.plugwise
|
# homeassistant.components.plugwise
|
||||||
plugwise==0.16.8
|
plugwise==0.16.9
|
||||||
|
|
||||||
# homeassistant.components.plum_lightpad
|
# homeassistant.components.plum_lightpad
|
||||||
plumlightpad==0.0.11
|
plumlightpad==0.0.11
|
||||||
|
@ -816,7 +816,7 @@ plexauth==0.0.6
|
|||||||
plexwebsocket==0.0.13
|
plexwebsocket==0.0.13
|
||||||
|
|
||||||
# homeassistant.components.plugwise
|
# homeassistant.components.plugwise
|
||||||
plugwise==0.16.8
|
plugwise==0.16.9
|
||||||
|
|
||||||
# homeassistant.components.plum_lightpad
|
# homeassistant.components.plum_lightpad
|
||||||
plumlightpad==0.0.11
|
plumlightpad==0.0.11
|
||||||
|
@ -25,12 +25,12 @@
|
|||||||
"flame_state": false
|
"flame_state": false
|
||||||
},
|
},
|
||||||
"sensors": {
|
"sensors": {
|
||||||
"outdoor_temperature": 3.0,
|
|
||||||
"water_temperature": 29.1,
|
"water_temperature": 29.1,
|
||||||
"intended_boiler_temperature": 0.0,
|
"intended_boiler_temperature": 0.0,
|
||||||
"modulation_level": 52,
|
"modulation_level": 52,
|
||||||
"return_temperature": 25.1,
|
"return_temperature": 25.1,
|
||||||
"water_pressure": 1.57
|
"water_pressure": 1.57,
|
||||||
|
"outdoor_air_temperature": 3.0
|
||||||
},
|
},
|
||||||
"switches": {
|
"switches": {
|
||||||
"dhw_cm_switch": false
|
"dhw_cm_switch": false
|
||||||
|
@ -10,11 +10,17 @@ from plugwise.exceptions import (
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.plugwise.const import DOMAIN
|
from homeassistant.components.plugwise.const import DOMAIN
|
||||||
|
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||||
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
HEATER_ID = "1cbf783bb11e4a7c8a6843dee3a86927" # Opentherm device_id for migration
|
||||||
|
PLUG_ID = "cd0ddb54ef694e11ac18ed1cbce5dbbd" # VCR device_id for migration
|
||||||
|
|
||||||
|
|
||||||
async def test_load_unload_config_entry(
|
async def test_load_unload_config_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@ -60,3 +66,85 @@ async def test_config_entry_not_ready(
|
|||||||
|
|
||||||
assert len(mock_smile_anna.connect.mock_calls) == 1
|
assert len(mock_smile_anna.connect.mock_calls) == 1
|
||||||
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"entitydata,old_unique_id,new_unique_id",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
{
|
||||||
|
"domain": SENSOR_DOMAIN,
|
||||||
|
"platform": DOMAIN,
|
||||||
|
"unique_id": f"{HEATER_ID}-outdoor_temperature",
|
||||||
|
"suggested_object_id": f"{HEATER_ID}-outdoor_temperature",
|
||||||
|
"disabled_by": None,
|
||||||
|
},
|
||||||
|
f"{HEATER_ID}-outdoor_temperature",
|
||||||
|
f"{HEATER_ID}-outdoor_air_temperature",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_migrate_unique_id_temperature(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_smile_anna: MagicMock,
|
||||||
|
entitydata: dict,
|
||||||
|
old_unique_id: str,
|
||||||
|
new_unique_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test migration of unique_id."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
entity_registry = er.async_get(hass)
|
||||||
|
entity: er.RegistryEntry = entity_registry.async_get_or_create(
|
||||||
|
**entitydata,
|
||||||
|
config_entry=mock_config_entry,
|
||||||
|
)
|
||||||
|
assert entity.unique_id == old_unique_id
|
||||||
|
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity_migrated = entity_registry.async_get(entity.entity_id)
|
||||||
|
assert entity_migrated
|
||||||
|
assert entity_migrated.unique_id == new_unique_id
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"entitydata,old_unique_id,new_unique_id",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
{
|
||||||
|
"domain": SWITCH_DOMAIN,
|
||||||
|
"platform": DOMAIN,
|
||||||
|
"unique_id": f"{PLUG_ID}-plug",
|
||||||
|
"suggested_object_id": f"{PLUG_ID}-plug",
|
||||||
|
"disabled_by": None,
|
||||||
|
},
|
||||||
|
f"{PLUG_ID}-plug",
|
||||||
|
f"{PLUG_ID}-relay",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_migrate_unique_id_relay(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_smile_adam: MagicMock,
|
||||||
|
entitydata: dict,
|
||||||
|
old_unique_id: str,
|
||||||
|
new_unique_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test migration of unique_id."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
entity_registry = er.async_get(hass)
|
||||||
|
entity: er.RegistryEntry = entity_registry.async_get_or_create(
|
||||||
|
**entitydata,
|
||||||
|
config_entry=mock_config_entry,
|
||||||
|
)
|
||||||
|
assert entity.unique_id == old_unique_id
|
||||||
|
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity_migrated = entity_registry.async_get(entity.entity_id)
|
||||||
|
assert entity_migrated
|
||||||
|
assert entity_migrated.unique_id == new_unique_id
|
||||||
|
@ -39,7 +39,7 @@ async def test_anna_as_smt_climate_sensor_entities(
|
|||||||
hass: HomeAssistant, mock_smile_anna: MagicMock, init_integration: MockConfigEntry
|
hass: HomeAssistant, mock_smile_anna: MagicMock, init_integration: MockConfigEntry
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test creation of climate related sensor entities."""
|
"""Test creation of climate related sensor entities."""
|
||||||
state = hass.states.get("sensor.opentherm_outdoor_temperature")
|
state = hass.states.get("sensor.opentherm_outdoor_air_temperature")
|
||||||
assert state
|
assert state
|
||||||
assert float(state.state) == 3.0
|
assert float(state.state) == 3.0
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ async def test_anna_climate_sensor_entities(
|
|||||||
hass: HomeAssistant, mock_smile_anna: MagicMock, init_integration: MockConfigEntry
|
hass: HomeAssistant, mock_smile_anna: MagicMock, init_integration: MockConfigEntry
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test creation of climate related sensor entities."""
|
"""Test creation of climate related sensor entities."""
|
||||||
state = hass.states.get("sensor.opentherm_outdoor_temperature")
|
state = hass.states.get("sensor.opentherm_outdoor_air_temperature")
|
||||||
assert state
|
assert state
|
||||||
assert float(state.state) == 3.0
|
assert float(state.state) == 3.0
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user