mirror of
https://github.com/home-assistant/core.git
synced 2026-09-24 15:31:52 -05:00
Track meteo_france alert departments with a HassKey (#179062)
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
"""Support for Meteo-France weather data."""
|
||||
# pylint: disable=home-assistant-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern
|
||||
|
||||
import logging
|
||||
|
||||
@@ -10,7 +9,7 @@ from requests import RequestException
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
|
||||
from .const import DOMAIN, PLATFORMS
|
||||
from .const import METEO_FRANCE_DATA, PLATFORMS
|
||||
from .coordinator import (
|
||||
MeteoFranceAlertUpdateCoordinator,
|
||||
MeteoFranceConfigEntry,
|
||||
@@ -24,7 +23,8 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: MeteoFranceConfigEntry) -> bool:
|
||||
"""Set up a Meteo-France account from a config entry."""
|
||||
hass.data.setdefault(DOMAIN, {})
|
||||
if (departments_with_alert := hass.data.get(METEO_FRANCE_DATA)) is None:
|
||||
departments_with_alert = hass.data[METEO_FRANCE_DATA] = set()
|
||||
|
||||
client = MeteoFranceClient()
|
||||
|
||||
@@ -55,7 +55,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: MeteoFranceConfigEntry)
|
||||
department,
|
||||
)
|
||||
if department is not None and is_valid_warning_department(department):
|
||||
if not hass.data[DOMAIN].get(department):
|
||||
if department not in departments_with_alert:
|
||||
coordinator_alert = MeteoFranceAlertUpdateCoordinator(
|
||||
hass,
|
||||
entry,
|
||||
@@ -66,7 +66,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: MeteoFranceConfigEntry)
|
||||
await coordinator_alert.async_refresh()
|
||||
|
||||
if coordinator_alert.last_update_success:
|
||||
hass.data[DOMAIN][department] = True
|
||||
departments_with_alert.add(department)
|
||||
else:
|
||||
_LOGGER.warning(
|
||||
(
|
||||
@@ -108,7 +108,7 @@ async def async_unload_entry(
|
||||
"""Unload a config entry."""
|
||||
if entry.runtime_data.alert_coordinator:
|
||||
department = entry.runtime_data.forecast_coordinator.data.position.get("dept")
|
||||
hass.data[DOMAIN][department] = False
|
||||
hass.data[METEO_FRANCE_DATA].discard(department)
|
||||
_LOGGER.debug(
|
||||
(
|
||||
"Weather alert for depatment %s unloaded and released. It can be added"
|
||||
@@ -119,8 +119,8 @@ async def async_unload_entry(
|
||||
|
||||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
if unload_ok:
|
||||
if not hass.data[DOMAIN]:
|
||||
hass.data.pop(DOMAIN)
|
||||
if not hass.data[METEO_FRANCE_DATA]:
|
||||
hass.data.pop(METEO_FRANCE_DATA)
|
||||
|
||||
return unload_ok
|
||||
|
||||
|
||||
@@ -18,9 +18,15 @@ from homeassistant.components.weather import (
|
||||
ATTR_CONDITION_WINDY_VARIANT,
|
||||
)
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.util.hass_dict import HassKey
|
||||
|
||||
DOMAIN = "meteo_france"
|
||||
PLATFORMS = [Platform.SENSOR, Platform.WEATHER]
|
||||
|
||||
# Departments that already have a city providing weather alerts. Only one city
|
||||
# per department may do so, so this is shared between config entries rather than
|
||||
# owned by any one of them.
|
||||
METEO_FRANCE_DATA: HassKey[set[str]] = HassKey(DOMAIN)
|
||||
ATTRIBUTION = "Data provided by Météo-France"
|
||||
MODEL = "Météo-France mobile API"
|
||||
MANUFACTURER = "Météo-France"
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
"""Test Météo France init."""
|
||||
|
||||
from collections.abc import Generator
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.meteo_france.const import (
|
||||
CONF_CITY,
|
||||
DOMAIN,
|
||||
METEO_FRANCE_DATA,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_USER, ConfigEntryState
|
||||
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def override_platforms() -> Generator[None]:
|
||||
"""Override PLATFORMS."""
|
||||
with patch("homeassistant.components.meteo_france.PLATFORMS", []):
|
||||
yield
|
||||
|
||||
|
||||
def _second_city(hass: HomeAssistant) -> MockConfigEntry:
|
||||
"""Return a second entry for a different city in the same department."""
|
||||
entry_data = {
|
||||
CONF_CITY: "Le Grand-Bornand",
|
||||
CONF_LATITUDE: 45.94179,
|
||||
CONF_LONGITUDE: 6.42794,
|
||||
}
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
source=SOURCE_USER,
|
||||
unique_id=f"{entry_data[CONF_LATITUDE], entry_data[CONF_LONGITUDE]}",
|
||||
title=entry_data[CONF_CITY],
|
||||
data=entry_data,
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
return config_entry
|
||||
|
||||
|
||||
async def test_only_one_city_per_department_provides_alerts(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the second city in a department does not also provide alerts."""
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.runtime_data.alert_coordinator is not None
|
||||
|
||||
second_entry = _second_city(hass)
|
||||
await hass.config_entries.async_setup(second_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert second_entry.state is ConfigEntryState.LOADED
|
||||
assert second_entry.runtime_data.alert_coordinator is None
|
||||
|
||||
|
||||
async def test_unload_releases_the_department(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test unloading releases the department so another city can claim it."""
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.data[METEO_FRANCE_DATA]
|
||||
|
||||
assert await hass.config_entries.async_unload(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# The last entry is gone, so the shared registry is cleaned up entirely.
|
||||
assert METEO_FRANCE_DATA not in hass.data
|
||||
|
||||
second_entry = _second_city(hass)
|
||||
await hass.config_entries.async_setup(second_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert second_entry.runtime_data.alert_coordinator is not None
|
||||
Reference in New Issue
Block a user