mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Enable co-existence of two IPMA weather entities for the same location (#40354)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
parent
6a59e79bc6
commit
1f850f6374
@ -25,7 +25,8 @@ from homeassistant.const import (
|
|||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.core import callback
|
||||||
|
from homeassistant.helpers import config_validation as cv, entity_registry
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.util import Throttle
|
from homeassistant.util import Throttle
|
||||||
from homeassistant.util.dt import now, parse_datetime
|
from homeassistant.util.dt import now, parse_datetime
|
||||||
@ -89,10 +90,33 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
"""Add a weather entity from a config_entry."""
|
"""Add a weather entity from a config_entry."""
|
||||||
latitude = config_entry.data[CONF_LATITUDE]
|
latitude = config_entry.data[CONF_LATITUDE]
|
||||||
longitude = config_entry.data[CONF_LONGITUDE]
|
longitude = config_entry.data[CONF_LONGITUDE]
|
||||||
|
mode = config_entry.data[CONF_MODE]
|
||||||
|
|
||||||
api = await async_get_api(hass)
|
api = await async_get_api(hass)
|
||||||
location = await async_get_location(hass, api, latitude, longitude)
|
location = await async_get_location(hass, api, latitude, longitude)
|
||||||
|
|
||||||
|
# Migrate old unique_id
|
||||||
|
@callback
|
||||||
|
def _async_migrator(entity_entry: entity_registry.RegistryEntry):
|
||||||
|
# Reject if new unique_id
|
||||||
|
if entity_entry.unique_id.count(",") == 2:
|
||||||
|
return None
|
||||||
|
|
||||||
|
new_unique_id = (
|
||||||
|
f"{location.station_latitude}, {location.station_longitude}, {mode}"
|
||||||
|
)
|
||||||
|
|
||||||
|
_LOGGER.info(
|
||||||
|
"Migrating unique_id from [%s] to [%s]",
|
||||||
|
entity_entry.unique_id,
|
||||||
|
new_unique_id,
|
||||||
|
)
|
||||||
|
return {"new_unique_id": new_unique_id}
|
||||||
|
|
||||||
|
await entity_registry.async_migrate_entries(
|
||||||
|
hass, config_entry.entry_id, _async_migrator
|
||||||
|
)
|
||||||
|
|
||||||
async_add_entities([IPMAWeather(location, api, config_entry.data)], True)
|
async_add_entities([IPMAWeather(location, api, config_entry.data)], True)
|
||||||
|
|
||||||
|
|
||||||
@ -157,7 +181,7 @@ class IPMAWeather(WeatherEntity):
|
|||||||
@property
|
@property
|
||||||
def unique_id(self) -> str:
|
def unique_id(self) -> str:
|
||||||
"""Return a unique id."""
|
"""Return a unique id."""
|
||||||
return f"{self._location.station_latitude}, {self._location.station_longitude}"
|
return f"{self._location.station_latitude}, {self._location.station_longitude}, {self._mode}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def attribution(self):
|
def attribution(self):
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
"""Tests for IPMA config flow."""
|
"""Tests for IPMA config flow."""
|
||||||
|
|
||||||
from homeassistant.components.ipma import config_flow
|
from homeassistant.components.ipma import DOMAIN, config_flow
|
||||||
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE
|
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_MODE
|
||||||
|
from homeassistant.helpers import entity_registry
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
from .test_weather import MockLocation
|
||||||
|
|
||||||
from tests.async_mock import Mock, patch
|
from tests.async_mock import Mock, patch
|
||||||
|
from tests.common import MockConfigEntry, mock_registry
|
||||||
|
|
||||||
|
|
||||||
async def test_show_config_form():
|
async def test_show_config_form():
|
||||||
@ -116,3 +121,53 @@ async def test_flow_entry_config_entry_already_exists():
|
|||||||
assert len(config_form.mock_calls) == 1
|
assert len(config_form.mock_calls) == 1
|
||||||
assert len(config_entries.mock_calls) == 1
|
assert len(config_entries.mock_calls) == 1
|
||||||
assert len(flow._errors) == 1
|
assert len(flow._errors) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_config_entry_migration(hass):
|
||||||
|
"""Tests config entry without mode in unique_id can be migrated."""
|
||||||
|
ipma_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title="Home",
|
||||||
|
data={CONF_LATITUDE: 0, CONF_LONGITUDE: 0, CONF_MODE: "daily"},
|
||||||
|
)
|
||||||
|
ipma_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
ipma_entry2 = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title="Home",
|
||||||
|
data={CONF_LATITUDE: 0, CONF_LONGITUDE: 0, CONF_MODE: "hourly"},
|
||||||
|
)
|
||||||
|
ipma_entry2.add_to_hass(hass)
|
||||||
|
|
||||||
|
mock_registry(
|
||||||
|
hass,
|
||||||
|
{
|
||||||
|
"weather.hometown": entity_registry.RegistryEntry(
|
||||||
|
entity_id="weather.hometown",
|
||||||
|
unique_id="0, 0",
|
||||||
|
platform="ipma",
|
||||||
|
config_entry_id=ipma_entry.entry_id,
|
||||||
|
),
|
||||||
|
"weather.hometown_2": entity_registry.RegistryEntry(
|
||||||
|
entity_id="weather.hometown_2",
|
||||||
|
unique_id="0, 0, hourly",
|
||||||
|
platform="ipma",
|
||||||
|
config_entry_id=ipma_entry.entry_id,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.ipma.weather.async_get_location",
|
||||||
|
return_value=MockLocation(),
|
||||||
|
):
|
||||||
|
assert await async_setup_component(hass, DOMAIN, {})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
ent_reg = await entity_registry.async_get_registry(hass)
|
||||||
|
|
||||||
|
weather_home = ent_reg.async_get("weather.hometown")
|
||||||
|
assert weather_home.unique_id == "0, 0, daily"
|
||||||
|
|
||||||
|
weather_home2 = ent_reg.async_get("weather.hometown_2")
|
||||||
|
assert weather_home2.unique_id == "0, 0, hourly"
|
||||||
|
@ -24,7 +24,12 @@ from homeassistant.util.dt import now
|
|||||||
from tests.async_mock import patch
|
from tests.async_mock import patch
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
TEST_CONFIG = {"name": "HomeTown", "latitude": "40.00", "longitude": "-8.00"}
|
TEST_CONFIG = {
|
||||||
|
"name": "HomeTown",
|
||||||
|
"latitude": "40.00",
|
||||||
|
"longitude": "-8.00",
|
||||||
|
"mode": "daily",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class MockLocation:
|
class MockLocation:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user