Remove geniushub yaml support after 6 months of deprecation (#130285)

* Remove geniushub YAML import after 6 moths of deprecation

* Update homeassistant/components/geniushub/__init__.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
Jan Bouwhuis 2024-11-10 14:58:44 +01:00 committed by GitHub
parent 70211ab78e
commit de391fa98b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 3 additions and 273 deletions

View File

@ -9,7 +9,6 @@ import aiohttp
from geniushubclient import GeniusHub from geniushubclient import GeniusHub
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
@ -21,20 +20,12 @@ from homeassistant.const import (
CONF_USERNAME, CONF_USERNAME,
Platform, Platform,
) )
from homeassistant.core import ( from homeassistant.core import HomeAssistant, ServiceCall, callback
DOMAIN as HOMEASSISTANT_DOMAIN,
HomeAssistant,
ServiceCall,
callback,
)
from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers import config_validation as cv, 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.dispatcher import async_dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.event import async_track_time_interval from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.service import verify_domain_control from homeassistant.helpers.service import verify_domain_control
from homeassistant.helpers.typing import ConfigType
from .const import DOMAIN from .const import DOMAIN
@ -45,27 +36,6 @@ SCAN_INTERVAL = timedelta(seconds=60)
MAC_ADDRESS_REGEXP = r"^([0-9A-F]{2}:){5}([0-9A-F]{2})$" MAC_ADDRESS_REGEXP = r"^([0-9A-F]{2}:){5}([0-9A-F]{2})$"
CLOUD_API_SCHEMA = vol.Schema(
{
vol.Required(CONF_TOKEN): cv.string,
vol.Required(CONF_MAC): vol.Match(MAC_ADDRESS_REGEXP),
}
)
LOCAL_API_SCHEMA = vol.Schema(
{
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_MAC): vol.Match(MAC_ADDRESS_REGEXP),
}
)
CONFIG_SCHEMA = vol.Schema(
{DOMAIN: vol.Any(LOCAL_API_SCHEMA, CLOUD_API_SCHEMA)}, extra=vol.ALLOW_EXTRA
)
ATTR_ZONE_MODE = "mode" ATTR_ZONE_MODE = "mode"
ATTR_DURATION = "duration" ATTR_DURATION = "duration"
@ -100,56 +70,6 @@ PLATFORMS = [
] ]
async def _async_import(hass: HomeAssistant, base_config: ConfigType) -> None:
"""Import a config entry from configuration.yaml."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=base_config[DOMAIN],
)
if (
result["type"] is FlowResultType.CREATE_ENTRY
or result["reason"] == "already_configured"
):
async_create_issue(
hass,
HOMEASSISTANT_DOMAIN,
f"deprecated_yaml_{DOMAIN}",
breaks_in_ha_version="2024.12.0",
is_fixable=False,
issue_domain=DOMAIN,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "Genius Hub",
},
)
return
async_create_issue(
hass,
DOMAIN,
f"deprecated_yaml_import_issue_{result['reason']}",
breaks_in_ha_version="2024.12.0",
is_fixable=False,
issue_domain=DOMAIN,
severity=IssueSeverity.WARNING,
translation_key=f"deprecated_yaml_import_issue_{result['reason']}",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "Genius Hub",
},
)
async def async_setup(hass: HomeAssistant, base_config: ConfigType) -> bool:
"""Set up a Genius Hub system."""
if DOMAIN in base_config:
hass.async_create_task(_async_import(hass, base_config))
return True
type GeniusHubConfigEntry = ConfigEntry[GeniusBroker] type GeniusHubConfigEntry = ConfigEntry[GeniusBroker]

View File

@ -13,7 +13,6 @@ import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_TOKEN, CONF_USERNAME from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_TOKEN, CONF_USERNAME
from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DOMAIN from .const import DOMAIN
@ -123,14 +122,3 @@ class GeniusHubConfigFlow(ConfigFlow, domain=DOMAIN):
return self.async_show_form( return self.async_show_form(
step_id="cloud_api", errors=errors, data_schema=CLOUD_API_SCHEMA step_id="cloud_api", errors=errors, data_schema=CLOUD_API_SCHEMA
) )
async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult:
"""Import the yaml config."""
if CONF_HOST in import_data:
result = await self.async_step_local_api(import_data)
else:
result = await self.async_step_cloud_api(import_data)
if result["type"] is FlowResultType.FORM:
assert result["errors"]
return self.async_abort(reason=result["errors"]["base"])
return result

View File

@ -2,21 +2,14 @@
from http import HTTPStatus from http import HTTPStatus
import socket import socket
from typing import Any
from unittest.mock import AsyncMock from unittest.mock import AsyncMock
from aiohttp import ClientConnectionError, ClientResponseError from aiohttp import ClientConnectionError, ClientResponseError
import pytest import pytest
from homeassistant.components.geniushub import DOMAIN from homeassistant.components.geniushub import DOMAIN
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER from homeassistant.config_entries import SOURCE_USER
from homeassistant.const import ( from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_TOKEN, CONF_USERNAME
CONF_HOST,
CONF_MAC,
CONF_PASSWORD,
CONF_TOKEN,
CONF_USERNAME,
)
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType from homeassistant.data_entry_flow import FlowResultType
@ -309,174 +302,3 @@ async def test_cloud_duplicate(
) )
assert result["type"] is FlowResultType.ABORT assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured" assert result["reason"] == "already_configured"
@pytest.mark.parametrize(
("data"),
[
{
CONF_HOST: "10.0.0.130",
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
},
{
CONF_HOST: "10.0.0.130",
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
CONF_MAC: "aa:bb:cc:dd:ee:ff",
},
],
)
async def test_import_local_flow(
hass: HomeAssistant,
mock_setup_entry: AsyncMock,
mock_geniushub_client: AsyncMock,
data: dict[str, Any],
) -> None:
"""Test full local import flow."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=data,
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "10.0.0.130"
assert result["data"] == data
assert result["result"].unique_id == "aa:bb:cc:dd:ee:ff"
@pytest.mark.parametrize(
("data"),
[
{
CONF_TOKEN: "abcdef",
},
{
CONF_TOKEN: "abcdef",
CONF_MAC: "aa:bb:cc:dd:ee:ff",
},
],
)
async def test_import_cloud_flow(
hass: HomeAssistant,
mock_setup_entry: AsyncMock,
mock_geniushub_client: AsyncMock,
data: dict[str, Any],
) -> None:
"""Test full cloud import flow."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=data,
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "Genius hub"
assert result["data"] == data
@pytest.mark.parametrize(
("data"),
[
{
CONF_HOST: "10.0.0.130",
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
},
{
CONF_HOST: "10.0.0.130",
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
CONF_MAC: "aa:bb:cc:dd:ee:ff",
},
{
CONF_TOKEN: "abcdef",
},
{
CONF_TOKEN: "abcdef",
CONF_MAC: "aa:bb:cc:dd:ee:ff",
},
],
)
@pytest.mark.parametrize(
("exception", "reason"),
[
(socket.gaierror, "invalid_host"),
(
ClientResponseError(AsyncMock(), (), status=HTTPStatus.UNAUTHORIZED),
"invalid_auth",
),
(
ClientResponseError(AsyncMock(), (), status=HTTPStatus.NOT_FOUND),
"invalid_host",
),
(TimeoutError, "cannot_connect"),
(ClientConnectionError, "cannot_connect"),
(Exception, "unknown"),
],
)
async def test_import_flow_exceptions(
hass: HomeAssistant,
mock_geniushub_client: AsyncMock,
data: dict[str, Any],
exception: Exception,
reason: str,
) -> None:
"""Test import flow exceptions."""
mock_geniushub_client.request.side_effect = exception
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=data,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == reason
@pytest.mark.parametrize(
("data"),
[
{
CONF_HOST: "10.0.0.130",
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
},
{
CONF_HOST: "10.0.0.131",
CONF_USERNAME: "test-username1",
CONF_PASSWORD: "test-password",
},
],
)
async def test_import_flow_local_duplicate(
hass: HomeAssistant,
mock_geniushub_client: AsyncMock,
mock_local_config_entry: MockConfigEntry,
data: dict[str, Any],
) -> None:
"""Test import flow aborts on local duplicate data."""
mock_local_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=data,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_import_flow_cloud_duplicate(
hass: HomeAssistant,
mock_geniushub_client: AsyncMock,
mock_cloud_config_entry: MockConfigEntry,
) -> None:
"""Test import flow aborts on cloud duplicate data."""
mock_cloud_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data={
CONF_TOKEN: "abcdef",
},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"