Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove previously deprecated ISY994 YAML support #91575

Merged
merged 2 commits into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 2 additions & 99 deletions homeassistant/components/isy994/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,15 @@
import homeassistant.helpers.device_registry as dr
from homeassistant.helpers.device_registry import DeviceEntryType
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.typing import ConfigType

from .const import (
_LOGGER,
CONF_IGNORE_STRING,
CONF_NETWORK,
CONF_RESTORE_LIGHT_STATE,
CONF_SENSOR_STRING,
CONF_TLS_VER,
CONF_VAR_SENSOR_STRING,
DEFAULT_IGNORE_STRING,
DEFAULT_RESTORE_LIGHT_STATE,
DEFAULT_SENSOR_STRING,
DEFAULT_VAR_SENSOR_STRING,
DOMAIN,
Expand All @@ -55,90 +51,16 @@
from .util import _async_cleanup_registry_entries

CONFIG_SCHEMA = vol.Schema(
vol.All(
cv.deprecated(DOMAIN),
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_HOST): cv.url,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_TLS_VER): vol.Coerce(float),
vol.Optional(
CONF_IGNORE_STRING, default=DEFAULT_IGNORE_STRING
): cv.string,
vol.Optional(
CONF_SENSOR_STRING, default=DEFAULT_SENSOR_STRING
): cv.string,
vol.Optional(
CONF_VAR_SENSOR_STRING, default=DEFAULT_VAR_SENSOR_STRING
): cv.string,
vol.Required(
CONF_RESTORE_LIGHT_STATE, default=DEFAULT_RESTORE_LIGHT_STATE
): bool,
},
)
},
),
cv.deprecated(DOMAIN),
extra=vol.ALLOW_EXTRA,
)


async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the isy994 integration from YAML."""
isy_config: ConfigType | None = config.get(DOMAIN)
hass.data.setdefault(DOMAIN, {})

if not isy_config:
return True

async_create_issue(
hass,
DOMAIN,
"deprecated_yaml",
breaks_in_ha_version="2023.5.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml",
)

# Only import if we haven't before.
config_entry = _async_find_matching_config_entry(hass)
if not config_entry:
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=dict(isy_config),
)
)
return True

# Update the entry based on the YAML configuration, in case it changed.
hass.config_entries.async_update_entry(config_entry, data=dict(isy_config))
return True


@callback
def _async_find_matching_config_entry(
hass: HomeAssistant,
) -> config_entries.ConfigEntry | None:
for entry in hass.config_entries.async_entries(DOMAIN):
if entry.source == config_entries.SOURCE_IMPORT:
return entry
return None


async def async_setup_entry(
hass: HomeAssistant, entry: config_entries.ConfigEntry
) -> bool:
"""Set up the ISY 994 integration."""
# As there currently is no way to import options from yaml
# when setting up a config entry, we fallback to adding
# the options to the config entry and pull them out here if
# they are missing from the options
_async_import_options_from_data_if_missing(hass, entry)

hass.data.setdefault(DOMAIN, {})
isy_data = hass.data[DOMAIN][entry.entry_id] = IsyData()

isy_config = entry.data
Expand Down Expand Up @@ -268,25 +190,6 @@ async def _async_update_listener(
await hass.config_entries.async_reload(entry.entry_id)


@callback
def _async_import_options_from_data_if_missing(
hass: HomeAssistant, entry: config_entries.ConfigEntry
) -> None:
options = dict(entry.options)
modified = False
for importable_option in (
CONF_IGNORE_STRING,
CONF_SENSOR_STRING,
CONF_RESTORE_LIGHT_STATE,
):
if importable_option not in entry.options and importable_option in entry.data:
options[importable_option] = entry.data[importable_option]
modified = True

if modified:
hass.config_entries.async_update_entry(entry, options=options)


@callback
def _async_get_or_create_isy_device_in_registry(
hass: HomeAssistant, entry: config_entries.ConfigEntry, isy: ISY
Expand Down
4 changes: 0 additions & 4 deletions homeassistant/components/isy994/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,6 @@ async def async_step_user(
errors=errors,
)

async def async_step_import(self, user_input: dict[str, Any]) -> FlowResult:
"""Handle import."""
return await self.async_step_user(user_input)

async def _async_set_unique_id_or_update(
self, isy_mac: str, ip_address: str, port: int | None
) -> None:
Expand Down
17 changes: 0 additions & 17 deletions homeassistant/components/isy994/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,5 @@
"last_heartbeat": "Last Heartbeat Time",
"websocket_status": "Event Socket Status"
}
},
"issues": {
"deprecated_service": {
"title": "The {deprecated_service} service will be removed",
"fix_flow": {
"step": {
"confirm": {
"title": "The {deprecated_service} service will be removed",
"description": "Update any automations or scripts that use this service to instead use the `{alternate_service}` service with a target entity ID of `{alternate_target}`."
},
"deprecated_yaml": {
"title": "The ISY/IoX YAML configuration is being removed",
"description": "Configuring Universal Devices ISY/IoX using YAML is being removed.\n\nYour existing YAML configuration has been imported into the UI automatically.\n\nRemove the `isy994` YAML configuration from your configuration.yaml file and restart Home Assistant to fix this issue."
}
}
}
}
}
}
113 changes: 1 addition & 112 deletions tests/components/isy994/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,12 @@
from homeassistant import config_entries, data_entry_flow
from homeassistant.components import dhcp, ssdp
from homeassistant.components.isy994.const import (
CONF_IGNORE_STRING,
CONF_RESTORE_LIGHT_STATE,
CONF_SENSOR_STRING,
CONF_TLS_VER,
CONF_VAR_SENSOR_STRING,
DOMAIN,
ISY_URL_POSTFIX,
UDN_UUID_PREFIX,
)
from homeassistant.config_entries import (
SOURCE_DHCP,
SOURCE_IGNORE,
SOURCE_IMPORT,
SOURCE_SSDP,
)
from homeassistant.config_entries import SOURCE_DHCP, SOURCE_IGNORE, SOURCE_SSDP
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant

Expand Down Expand Up @@ -51,27 +42,6 @@
CONF_PASSWORD: MOCK_PASSWORD,
CONF_TLS_VER: MOCK_TLS_VERSION,
}
MOCK_IMPORT_WITH_SSL = {
CONF_HOST: f"https://{MOCK_HOSTNAME}",
CONF_USERNAME: MOCK_USERNAME,
CONF_PASSWORD: MOCK_PASSWORD,
CONF_TLS_VER: MOCK_TLS_VERSION,
}
MOCK_IMPORT_BASIC_CONFIG = {
CONF_HOST: f"http://{MOCK_HOSTNAME}",
CONF_USERNAME: MOCK_USERNAME,
CONF_PASSWORD: MOCK_PASSWORD,
}
MOCK_IMPORT_FULL_CONFIG = {
CONF_HOST: f"http://{MOCK_HOSTNAME}",
CONF_USERNAME: MOCK_USERNAME,
CONF_PASSWORD: MOCK_PASSWORD,
CONF_IGNORE_STRING: MOCK_IGNORE_STRING,
CONF_RESTORE_LIGHT_STATE: MOCK_RESTORE_LIGHT_STATE,
CONF_SENSOR_STRING: MOCK_SENSOR_STRING,
CONF_TLS_VER: MOCK_TLS_VERSION,
CONF_VAR_SENSOR_STRING: MOCK_VARIABLE_SENSOR_STRING,
}

MOCK_DEVICE_NAME = "Name of the device"
MOCK_UUID = "ce:fb:72:31:b7:b9"
Expand Down Expand Up @@ -121,8 +91,6 @@ async def test_form(hass: HomeAssistant) -> None:
assert result["errors"] == {}

with patch(PATCH_CONNECTION, return_value=MOCK_CONFIG_RESPONSE), patch(
PATCH_ASYNC_SETUP, return_value=True
) as mock_setup, patch(
PATCH_ASYNC_SETUP_ENTRY,
return_value=True,
) as mock_setup_entry:
Expand All @@ -135,7 +103,6 @@ async def test_form(hass: HomeAssistant) -> None:
assert result2["title"] == f"{MOCK_DEVICE_NAME} ({MOCK_HOSTNAME})"
assert result2["result"].unique_id == MOCK_UUID
assert result2["data"] == MOCK_USER_INPUT
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1


Expand Down Expand Up @@ -271,72 +238,6 @@ async def test_form_existing_config_entry(hass: HomeAssistant) -> None:
assert result2["type"] == data_entry_flow.FlowResultType.ABORT


async def test_import_flow_some_fields(hass: HomeAssistant) -> None:
"""Test import config flow with just the basic fields."""
with patch(PATCH_CONNECTION, return_value=MOCK_CONFIG_RESPONSE), patch(
PATCH_ASYNC_SETUP, return_value=True
), patch(
PATCH_ASYNC_SETUP_ENTRY,
return_value=True,
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=MOCK_IMPORT_BASIC_CONFIG,
)

assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
assert result["data"][CONF_HOST] == f"http://{MOCK_HOSTNAME}"
assert result["data"][CONF_USERNAME] == MOCK_USERNAME
assert result["data"][CONF_PASSWORD] == MOCK_PASSWORD


async def test_import_flow_with_https(hass: HomeAssistant) -> None:
"""Test import config with https."""

with patch(PATCH_CONNECTION, return_value=MOCK_CONFIG_RESPONSE), patch(
PATCH_ASYNC_SETUP, return_value=True
), patch(
PATCH_ASYNC_SETUP_ENTRY,
return_value=True,
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=MOCK_IMPORT_WITH_SSL,
)

assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
assert result["data"][CONF_HOST] == f"https://{MOCK_HOSTNAME}"
assert result["data"][CONF_USERNAME] == MOCK_USERNAME
assert result["data"][CONF_PASSWORD] == MOCK_PASSWORD


async def test_import_flow_all_fields(hass: HomeAssistant) -> None:
"""Test import config flow with all fields."""
with patch(PATCH_CONNECTION, return_value=MOCK_CONFIG_RESPONSE), patch(
PATCH_ASYNC_SETUP, return_value=True
), patch(
PATCH_ASYNC_SETUP_ENTRY,
return_value=True,
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=MOCK_IMPORT_FULL_CONFIG,
)

assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
assert result["data"][CONF_HOST] == f"http://{MOCK_HOSTNAME}"
assert result["data"][CONF_USERNAME] == MOCK_USERNAME
assert result["data"][CONF_PASSWORD] == MOCK_PASSWORD
assert result["data"][CONF_IGNORE_STRING] == MOCK_IGNORE_STRING
assert result["data"][CONF_RESTORE_LIGHT_STATE] == MOCK_RESTORE_LIGHT_STATE
assert result["data"][CONF_SENSOR_STRING] == MOCK_SENSOR_STRING
assert result["data"][CONF_VAR_SENSOR_STRING] == MOCK_VARIABLE_SENSOR_STRING
assert result["data"][CONF_TLS_VER] == MOCK_TLS_VERSION


async def test_form_ssdp_already_configured(hass: HomeAssistant) -> None:
"""Test ssdp abort when the serial number is already configured."""

Expand Down Expand Up @@ -383,8 +284,6 @@ async def test_form_ssdp(hass: HomeAssistant) -> None:
assert result["errors"] == {}

with patch(PATCH_CONNECTION, return_value=MOCK_CONFIG_RESPONSE), patch(
PATCH_ASYNC_SETUP, return_value=True
) as mock_setup, patch(
PATCH_ASYNC_SETUP_ENTRY,
return_value=True,
) as mock_setup_entry:
Expand All @@ -398,7 +297,6 @@ async def test_form_ssdp(hass: HomeAssistant) -> None:
assert result2["title"] == f"{MOCK_DEVICE_NAME} ({MOCK_HOSTNAME})"
assert result2["result"].unique_id == MOCK_UUID
assert result2["data"] == MOCK_USER_INPUT
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1


Expand Down Expand Up @@ -545,8 +443,6 @@ async def test_form_dhcp(hass: HomeAssistant) -> None:
assert result["errors"] == {}

with patch(PATCH_CONNECTION, return_value=MOCK_CONFIG_RESPONSE), patch(
PATCH_ASYNC_SETUP, return_value=True
) as mock_setup, patch(
PATCH_ASYNC_SETUP_ENTRY,
return_value=True,
) as mock_setup_entry:
Expand All @@ -560,7 +456,6 @@ async def test_form_dhcp(hass: HomeAssistant) -> None:
assert result2["title"] == f"{MOCK_DEVICE_NAME} ({MOCK_HOSTNAME})"
assert result2["result"].unique_id == MOCK_UUID
assert result2["data"] == MOCK_USER_INPUT
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1


Expand All @@ -585,8 +480,6 @@ async def test_form_dhcp_with_polisy(hass: HomeAssistant) -> None:
)

with patch(PATCH_CONNECTION, return_value=MOCK_CONFIG_RESPONSE), patch(
PATCH_ASYNC_SETUP, return_value=True
) as mock_setup, patch(
PATCH_ASYNC_SETUP_ENTRY,
return_value=True,
) as mock_setup_entry:
Expand All @@ -600,7 +493,6 @@ async def test_form_dhcp_with_polisy(hass: HomeAssistant) -> None:
assert result2["title"] == f"{MOCK_DEVICE_NAME} ({MOCK_HOSTNAME})"
assert result2["result"].unique_id == MOCK_UUID
assert result2["data"] == MOCK_IOX_USER_INPUT
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1


Expand All @@ -625,8 +517,6 @@ async def test_form_dhcp_with_eisy(hass: HomeAssistant) -> None:
)

with patch(PATCH_CONNECTION, return_value=MOCK_CONFIG_RESPONSE), patch(
PATCH_ASYNC_SETUP, return_value=True
) as mock_setup, patch(
PATCH_ASYNC_SETUP_ENTRY,
return_value=True,
) as mock_setup_entry:
Expand All @@ -640,7 +530,6 @@ async def test_form_dhcp_with_eisy(hass: HomeAssistant) -> None:
assert result2["title"] == f"{MOCK_DEVICE_NAME} ({MOCK_HOSTNAME})"
assert result2["result"].unique_id == MOCK_UUID
assert result2["data"] == MOCK_IOX_USER_INPUT
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1


Expand Down