Bump pydaikin 2.10.5 (#95656)
This commit is contained in:
parent
b2e708834f
commit
f028d1a1ca
7 changed files with 216 additions and 7 deletions
|
@ -182,7 +182,6 @@ omit =
|
|||
homeassistant/components/crownstone/listeners.py
|
||||
homeassistant/components/cups/sensor.py
|
||||
homeassistant/components/currencylayer/sensor.py
|
||||
homeassistant/components/daikin/__init__.py
|
||||
homeassistant/components/daikin/climate.py
|
||||
homeassistant/components/daikin/sensor.py
|
||||
homeassistant/components/daikin/switch.py
|
||||
|
|
|
@ -15,8 +15,9 @@ from homeassistant.const import (
|
|||
CONF_UUID,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
|
||||
|
@ -52,6 +53,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
if not daikin_api:
|
||||
return False
|
||||
|
||||
await async_migrate_unique_id(hass, entry, daikin_api)
|
||||
|
||||
hass.data.setdefault(DOMAIN, {}).update({entry.entry_id: daikin_api})
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
return True
|
||||
|
@ -67,7 +70,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
return unload_ok
|
||||
|
||||
|
||||
async def daikin_api_setup(hass, host, key, uuid, password):
|
||||
async def daikin_api_setup(hass: HomeAssistant, host, key, uuid, password):
|
||||
"""Create a Daikin instance only once."""
|
||||
|
||||
session = async_get_clientsession(hass)
|
||||
|
@ -127,3 +130,82 @@ class DaikinApi:
|
|||
name=info.get("name"),
|
||||
sw_version=info.get("ver", "").replace("_", "."),
|
||||
)
|
||||
|
||||
|
||||
async def async_migrate_unique_id(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry, api: DaikinApi
|
||||
) -> None:
|
||||
"""Migrate old entry."""
|
||||
dev_reg = dr.async_get(hass)
|
||||
old_unique_id = config_entry.unique_id
|
||||
new_unique_id = api.device.mac
|
||||
new_name = api.device.values["name"]
|
||||
|
||||
@callback
|
||||
def _update_unique_id(entity_entry: er.RegistryEntry) -> dict[str, str] | None:
|
||||
"""Update unique ID of entity entry."""
|
||||
return update_unique_id(entity_entry, new_unique_id)
|
||||
|
||||
if new_unique_id == old_unique_id:
|
||||
return
|
||||
|
||||
# Migrate devices
|
||||
for device_entry in dr.async_entries_for_config_entry(
|
||||
dev_reg, config_entry.entry_id
|
||||
):
|
||||
for connection in device_entry.connections:
|
||||
if connection[1] == old_unique_id:
|
||||
new_connections = {
|
||||
(CONNECTION_NETWORK_MAC, dr.format_mac(new_unique_id))
|
||||
}
|
||||
|
||||
_LOGGER.debug(
|
||||
"Migrating device %s connections to %s",
|
||||
device_entry.name,
|
||||
new_connections,
|
||||
)
|
||||
dev_reg.async_update_device(
|
||||
device_entry.id,
|
||||
merge_connections=new_connections,
|
||||
)
|
||||
|
||||
if device_entry.name is None:
|
||||
_LOGGER.debug(
|
||||
"Migrating device name to %s",
|
||||
new_name,
|
||||
)
|
||||
dev_reg.async_update_device(
|
||||
device_entry.id,
|
||||
name=new_name,
|
||||
)
|
||||
|
||||
# Migrate entities
|
||||
await er.async_migrate_entries(hass, config_entry.entry_id, _update_unique_id)
|
||||
|
||||
new_data = {**config_entry.data, KEY_MAC: dr.format_mac(new_unique_id)}
|
||||
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry, unique_id=new_unique_id, data=new_data
|
||||
)
|
||||
|
||||
|
||||
@callback
|
||||
def update_unique_id(
|
||||
entity_entry: er.RegistryEntry, unique_id: str
|
||||
) -> dict[str, str] | None:
|
||||
"""Update unique ID of entity entry."""
|
||||
if entity_entry.unique_id.startswith(unique_id):
|
||||
# Already correct, nothing to do
|
||||
return None
|
||||
|
||||
unique_id_parts = entity_entry.unique_id.split("-")
|
||||
unique_id_parts[0] = unique_id
|
||||
entity_new_unique_id = "-".join(unique_id_parts)
|
||||
|
||||
_LOGGER.debug(
|
||||
"Migrating entity %s from %s to new id %s",
|
||||
entity_entry.entity_id,
|
||||
entity_entry.unique_id,
|
||||
entity_new_unique_id,
|
||||
)
|
||||
return {"new_unique_id": entity_new_unique_id}
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
"iot_class": "local_polling",
|
||||
"loggers": ["pydaikin"],
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["pydaikin==2.9.0"],
|
||||
"requirements": ["pydaikin==2.10.5"],
|
||||
"zeroconf": ["_dkapi._tcp.local."]
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ async def async_setup_entry(
|
|||
[
|
||||
DaikinZoneSwitch(daikin_api, zone_id)
|
||||
for zone_id, zone in enumerate(zones)
|
||||
if zone != ("-", "0")
|
||||
if zone[0] != "-"
|
||||
]
|
||||
)
|
||||
if daikin_api.device.support_advanced_modes:
|
||||
|
|
|
@ -1618,7 +1618,7 @@ pycsspeechtts==1.0.8
|
|||
# pycups==1.9.73
|
||||
|
||||
# homeassistant.components.daikin
|
||||
pydaikin==2.9.0
|
||||
pydaikin==2.10.5
|
||||
|
||||
# homeassistant.components.danfoss_air
|
||||
pydanfossair==0.1.0
|
||||
|
|
|
@ -1200,7 +1200,7 @@ pycoolmasternet-async==0.1.5
|
|||
pycsspeechtts==1.0.8
|
||||
|
||||
# homeassistant.components.daikin
|
||||
pydaikin==2.9.0
|
||||
pydaikin==2.10.5
|
||||
|
||||
# homeassistant.components.deconz
|
||||
pydeconz==113
|
||||
|
|
128
tests/components/daikin/test_init.py
Normal file
128
tests/components/daikin/test_init.py
Normal file
|
@ -0,0 +1,128 @@
|
|||
"""Define tests for the Daikin init."""
|
||||
import asyncio
|
||||
from unittest.mock import AsyncMock, PropertyMock, patch
|
||||
|
||||
from aiohttp import ClientConnectionError
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.daikin import update_unique_id
|
||||
from homeassistant.components.daikin.const import DOMAIN, KEY_MAC
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from .test_config_flow import HOST, MAC
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_daikin():
|
||||
"""Mock pydaikin."""
|
||||
|
||||
async def mock_daikin_factory(*args, **kwargs):
|
||||
"""Mock the init function in pydaikin."""
|
||||
return Appliance
|
||||
|
||||
with patch("homeassistant.components.daikin.Appliance") as Appliance:
|
||||
Appliance.factory.side_effect = mock_daikin_factory
|
||||
type(Appliance).update_status = AsyncMock()
|
||||
type(Appliance).inside_temperature = PropertyMock(return_value=22)
|
||||
type(Appliance).target_temperature = PropertyMock(return_value=22)
|
||||
type(Appliance).zones = PropertyMock(return_value=[("Zone 1", "0", 0)])
|
||||
type(Appliance).fan_rate = PropertyMock(return_value=[])
|
||||
type(Appliance).swing_modes = PropertyMock(return_value=[])
|
||||
yield Appliance
|
||||
|
||||
|
||||
DATA = {
|
||||
"ver": "1_1_8",
|
||||
"name": "DaikinAP00000",
|
||||
"mac": MAC,
|
||||
"model": "NOTSUPPORT",
|
||||
}
|
||||
|
||||
|
||||
INVALID_DATA = {**DATA, "name": None, "mac": HOST}
|
||||
|
||||
|
||||
async def test_unique_id_migrate(hass: HomeAssistant, mock_daikin) -> None:
|
||||
"""Test unique id migration."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=HOST,
|
||||
title=None,
|
||||
data={CONF_HOST: HOST, KEY_MAC: HOST},
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
entity_registry = er.async_get(hass)
|
||||
device_registry = dr.async_get(hass)
|
||||
|
||||
type(mock_daikin).mac = PropertyMock(return_value=HOST)
|
||||
type(mock_daikin).values = PropertyMock(return_value=INVALID_DATA)
|
||||
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.unique_id == HOST
|
||||
|
||||
assert device_registry.async_get_device({}, {(KEY_MAC, HOST)}).name is None
|
||||
|
||||
entity = entity_registry.async_get("climate.daikin_127_0_0_1")
|
||||
assert entity.unique_id == HOST
|
||||
assert update_unique_id(entity, MAC) is not None
|
||||
|
||||
assert entity_registry.async_get("switch.none_zone_1").unique_id.startswith(HOST)
|
||||
|
||||
type(mock_daikin).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_daikin).values = PropertyMock(return_value=DATA)
|
||||
|
||||
assert config_entry.unique_id != MAC
|
||||
|
||||
assert await hass.config_entries.async_reload(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.unique_id == MAC
|
||||
|
||||
assert (
|
||||
device_registry.async_get_device({}, {(KEY_MAC, MAC)}).name == "DaikinAP00000"
|
||||
)
|
||||
|
||||
entity = entity_registry.async_get("climate.daikin_127_0_0_1")
|
||||
assert entity.unique_id == MAC
|
||||
assert update_unique_id(entity, MAC) is None
|
||||
|
||||
assert entity_registry.async_get("switch.none_zone_1").unique_id.startswith(MAC)
|
||||
|
||||
|
||||
async def test_client_connection_error(hass: HomeAssistant, mock_daikin) -> None:
|
||||
"""Test unique id migration."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=MAC,
|
||||
data={CONF_HOST: HOST, KEY_MAC: MAC},
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
mock_daikin.factory.side_effect = ClientConnectionError
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state == ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
async def test_timeout_error(hass: HomeAssistant, mock_daikin) -> None:
|
||||
"""Test unique id migration."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=MAC,
|
||||
data={CONF_HOST: HOST, KEY_MAC: MAC},
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
mock_daikin.factory.side_effect = asyncio.TimeoutError
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state == ConfigEntryState.SETUP_RETRY
|
Loading…
Add table
Reference in a new issue