diff --git a/homeassistant/components/ambee/__init__.py b/homeassistant/components/ambee/__init__.py index ee311df75fa..dbc503928c4 100644 --- a/homeassistant/components/ambee/__init__.py +++ b/homeassistant/components/ambee/__init__.py @@ -3,10 +3,16 @@ from __future__ import annotations from ambee import AirQuality, Ambee, AmbeeAuthenticationError, Pollen +from homeassistant.components.repairs import ( + IssueSeverity, + async_create_issue, + async_delete_issue, +) from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed +from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import DOMAIN, LOGGER, SCAN_INTERVAL, SERVICE_AIR_QUALITY, SERVICE_POLLEN @@ -14,6 +20,20 @@ from .const import DOMAIN, LOGGER, SCAN_INTERVAL, SERVICE_AIR_QUALITY, SERVICE_P PLATFORMS = [Platform.SENSOR] +async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: + """Set up the Ambee integration.""" + async_create_issue( + hass, + DOMAIN, + "pending_removal", + breaks_in_ha_version="2022.10.0", + is_fixable=False, + severity=IssueSeverity.WARNING, + translation_key="pending_removal", + ) + return True + + async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Ambee from a config entry.""" hass.data.setdefault(DOMAIN, {}).setdefault(entry.entry_id, {}) @@ -67,4 +87,6 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) if unload_ok: del hass.data[DOMAIN][entry.entry_id] + if not hass.data[DOMAIN]: + async_delete_issue(hass, DOMAIN, "pending_removal") return unload_ok diff --git a/homeassistant/components/ambee/manifest.json b/homeassistant/components/ambee/manifest.json index 3226e9de3a3..f74832100cd 100644 --- a/homeassistant/components/ambee/manifest.json +++ b/homeassistant/components/ambee/manifest.json @@ -4,6 +4,7 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/ambee", "requirements": ["ambee==0.4.0"], + "dependencies": ["repairs"], "codeowners": ["@frenck"], "quality_scale": "platinum", "iot_class": "cloud_polling" diff --git a/homeassistant/components/ambee/strings.json b/homeassistant/components/ambee/strings.json index e3c306788dd..7d0e75877c9 100644 --- a/homeassistant/components/ambee/strings.json +++ b/homeassistant/components/ambee/strings.json @@ -24,5 +24,11 @@ "abort": { "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" } + }, + "issues": { + "pending_removal": { + "title": "The Ambee integration is being removed", + "description": "The Ambee integration is pending removal from Home Assistant and will no longer be available as of Home Assistant 2022.10.\n\nThe integration is being removed, because Ambee removed their free (limited) accounts and doesn't provide a way for regular users to sign up for a paid plan anymore.\n\nRemove the Ambee integration entry from your instance to fix this issue." + } } } diff --git a/homeassistant/components/ambee/translations/en.json b/homeassistant/components/ambee/translations/en.json index 433580e8023..03f4c3241b6 100644 --- a/homeassistant/components/ambee/translations/en.json +++ b/homeassistant/components/ambee/translations/en.json @@ -24,5 +24,11 @@ "description": "Set up Ambee to integrate with Home Assistant." } } + }, + "issues": { + "pending_removal": { + "description": "The Ambee integration is pending removal from Home Assistant and will no longer be available as of Home Assistant 2022.10.\n\nThe integration is being removed, because Ambee removed their free (limited) accounts and doesn't provide a way for regular users to sign up for a paid plan anymore.\n\nRemove the Ambee integration entry from your instance to fix this issue.", + "title": "The Ambee integration is being removed" + } } } \ No newline at end of file diff --git a/tests/components/ambee/test_init.py b/tests/components/ambee/test_init.py index c6ad45735ff..059c58da803 100644 --- a/tests/components/ambee/test_init.py +++ b/tests/components/ambee/test_init.py @@ -1,6 +1,8 @@ """Tests for the Ambee integration.""" +from collections.abc import Awaitable, Callable from unittest.mock import AsyncMock, MagicMock, patch +from aiohttp import ClientWebSocketResponse from ambee import AmbeeConnectionError from ambee.exceptions import AmbeeAuthenticationError import pytest @@ -10,12 +12,14 @@ from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState from homeassistant.core import HomeAssistant from tests.common import MockConfigEntry +from tests.components.repairs import get_repairs async def test_load_unload_config_entry( hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_ambee: AsyncMock, + hass_ws_client: Callable[[HomeAssistant], Awaitable[ClientWebSocketResponse]], ) -> None: """Test the Ambee configuration entry loading/unloading.""" mock_config_entry.add_to_hass(hass) @@ -24,9 +28,16 @@ async def test_load_unload_config_entry( assert mock_config_entry.state is ConfigEntryState.LOADED + issues = await get_repairs(hass, hass_ws_client) + assert len(issues) == 1 + assert issues[0]["issue_id"] == "pending_removal" + await hass.config_entries.async_unload(mock_config_entry.entry_id) await hass.async_block_till_done() + issues = await get_repairs(hass, hass_ws_client) + assert len(issues) == 0 + assert not hass.data.get(DOMAIN) diff --git a/tests/components/repairs/__init__.py b/tests/components/repairs/__init__.py index b0d26f49ee4..77971d0284b 100644 --- a/tests/components/repairs/__init__.py +++ b/tests/components/repairs/__init__.py @@ -1 +1,30 @@ """Tests for the repairs integration.""" +from collections.abc import Awaitable, Callable + +from aiohttp import ClientWebSocketResponse + +from homeassistant.core import HomeAssistant +from homeassistant.setup import async_setup_component + + +async def get_repairs( + hass: HomeAssistant, + hass_ws_client: Callable[[HomeAssistant], Awaitable[ClientWebSocketResponse]], +): + """Return the repairs list of issues.""" + assert await async_setup_component(hass, "repairs", {}) + + client = await hass_ws_client(hass) + await hass.async_block_till_done() + + await client.send_json({"id": 1, "type": "repairs/list_issues"}) + msg = await client.receive_json() + + client = await hass_ws_client(hass) + await hass.async_block_till_done() + + assert msg["id"] == 1 + assert msg["success"] + assert msg["result"] + + return msg["result"]["issues"]