Remove YAML configuration from Somfy MyLink (#50359)
* Remove YAML configuration from Somfy MyLink * Keep deprecation warningpull/50399/head
parent
f581616064
commit
1c98df5d18
homeassistant/components/somfy_mylink
tests/components/somfy_mylink
|
@ -3,89 +3,25 @@ import asyncio
|
|||
import logging
|
||||
|
||||
from somfy_mylink_synergy import SomfyMyLinkSynergy
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.cover import ENTITY_ID_FORMAT
|
||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.util import slugify
|
||||
|
||||
from .const import (
|
||||
CONF_DEFAULT_REVERSE,
|
||||
CONF_ENTITY_CONFIG,
|
||||
CONF_REVERSE,
|
||||
CONF_REVERSED_TARGET_IDS,
|
||||
CONF_SYSTEM_ID,
|
||||
DATA_SOMFY_MYLINK,
|
||||
DEFAULT_PORT,
|
||||
DOMAIN,
|
||||
MYLINK_STATUS,
|
||||
PLATFORMS,
|
||||
)
|
||||
from .const import CONF_SYSTEM_ID, DATA_SOMFY_MYLINK, DOMAIN, MYLINK_STATUS, PLATFORMS
|
||||
|
||||
CONFIG_OPTIONS = (CONF_DEFAULT_REVERSE, CONF_ENTITY_CONFIG)
|
||||
UNDO_UPDATE_LISTENER = "undo_update_listener"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def validate_entity_config(values):
|
||||
"""Validate config entry for CONF_ENTITY."""
|
||||
entity_config_schema = vol.Schema({vol.Optional(CONF_REVERSE): cv.boolean})
|
||||
if not isinstance(values, dict):
|
||||
raise vol.Invalid("expected a dictionary")
|
||||
entities = {}
|
||||
for entity_id, config in values.items():
|
||||
entity = cv.entity_id(entity_id)
|
||||
config = entity_config_schema(config)
|
||||
entities[entity] = config
|
||||
return entities
|
||||
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
vol.All(
|
||||
cv.deprecated(DOMAIN),
|
||||
{
|
||||
DOMAIN: vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_SYSTEM_ID): cv.string,
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||
vol.Optional(CONF_DEFAULT_REVERSE, default=False): cv.boolean,
|
||||
vol.Optional(
|
||||
CONF_ENTITY_CONFIG, default={}
|
||||
): validate_entity_config,
|
||||
}
|
||||
)
|
||||
},
|
||||
),
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
|
||||
|
||||
async def async_setup(hass, config):
|
||||
"""Set up the MyLink platform."""
|
||||
|
||||
conf = config.get(DOMAIN)
|
||||
hass.data.setdefault(DOMAIN, {})
|
||||
|
||||
if not conf:
|
||||
return True
|
||||
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_IMPORT}, data=conf
|
||||
)
|
||||
)
|
||||
return True
|
||||
CONFIG_SCHEMA = cv.deprecated(DOMAIN)
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
"""Set up Somfy MyLink from a config entry."""
|
||||
_async_import_options_from_data_if_missing(hass, entry)
|
||||
hass.data.setdefault(DOMAIN, {})
|
||||
|
||||
config = entry.data
|
||||
somfy_mylink = SomfyMyLinkSynergy(
|
||||
|
@ -111,8 +47,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
if "result" not in mylink_status:
|
||||
raise ConfigEntryNotReady("The Somfy MyLink device returned an empty result")
|
||||
|
||||
_async_migrate_entity_config(hass, entry, mylink_status)
|
||||
|
||||
undo_listener = entry.add_update_listener(_async_update_listener)
|
||||
|
||||
hass.data[DOMAIN][entry.entry_id] = {
|
||||
|
@ -131,49 +65,6 @@ async def _async_update_listener(hass: HomeAssistant, entry: ConfigEntry):
|
|||
await hass.config_entries.async_reload(entry.entry_id)
|
||||
|
||||
|
||||
@callback
|
||||
def _async_import_options_from_data_if_missing(hass: HomeAssistant, entry: ConfigEntry):
|
||||
options = dict(entry.options)
|
||||
data = dict(entry.data)
|
||||
modified = False
|
||||
|
||||
for importable_option in CONFIG_OPTIONS:
|
||||
if importable_option not in options and importable_option in data:
|
||||
options[importable_option] = data.pop(importable_option)
|
||||
modified = True
|
||||
|
||||
if modified:
|
||||
hass.config_entries.async_update_entry(entry, data=data, options=options)
|
||||
|
||||
|
||||
@callback
|
||||
def _async_migrate_entity_config(
|
||||
hass: HomeAssistant, entry: ConfigEntry, mylink_status: dict
|
||||
):
|
||||
if CONF_ENTITY_CONFIG not in entry.options:
|
||||
return
|
||||
|
||||
options = dict(entry.options)
|
||||
|
||||
reversed_target_ids = options[CONF_REVERSED_TARGET_IDS] = {}
|
||||
legacy_entry_config = options[CONF_ENTITY_CONFIG]
|
||||
default_reverse = options.get(CONF_DEFAULT_REVERSE)
|
||||
|
||||
for cover in mylink_status["result"]:
|
||||
legacy_entity_id = ENTITY_ID_FORMAT.format(slugify(cover["name"]))
|
||||
target_id = cover["targetID"]
|
||||
|
||||
entity_config = legacy_entry_config.get(legacy_entity_id, {})
|
||||
if entity_config.get(CONF_REVERSE, default_reverse):
|
||||
reversed_target_ids[target_id] = True
|
||||
|
||||
for legacy_key in (CONF_DEFAULT_REVERSE, CONF_ENTITY_CONFIG):
|
||||
if legacy_key in options:
|
||||
del options[legacy_key]
|
||||
|
||||
hass.config_entries.async_update_entry(entry, data=entry.data, options=options)
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
"""Unload a config entry."""
|
||||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
"""Component for the Somfy MyLink device supporting the Synergy API."""
|
||||
|
||||
CONF_ENTITY_CONFIG = "entity_config"
|
||||
CONF_SYSTEM_ID = "system_id"
|
||||
CONF_REVERSE = "reverse"
|
||||
CONF_DEFAULT_REVERSE = "default_reverse"
|
||||
CONF_TARGET_NAME = "target_name"
|
||||
CONF_REVERSED_TARGET_IDS = "reversed_target_ids"
|
||||
CONF_TARGET_ID = "target_id"
|
||||
|
|
|
@ -7,9 +7,6 @@ import pytest
|
|||
from homeassistant import config_entries, data_entry_flow, setup
|
||||
from homeassistant.components.dhcp import HOSTNAME, IP_ADDRESS, MAC_ADDRESS
|
||||
from homeassistant.components.somfy_mylink.const import (
|
||||
CONF_DEFAULT_REVERSE,
|
||||
CONF_ENTITY_CONFIG,
|
||||
CONF_REVERSE,
|
||||
CONF_REVERSED_TARGET_IDS,
|
||||
CONF_SYSTEM_ID,
|
||||
DOMAIN,
|
||||
|
@ -32,8 +29,6 @@ async def test_form_user(hass):
|
|||
"homeassistant.components.somfy_mylink.config_flow.SomfyMyLinkSynergy.status_info",
|
||||
return_value={"any": "data"},
|
||||
), patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup", return_value=True
|
||||
) as mock_setup, patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
|
@ -54,7 +49,6 @@ async def test_form_user(hass):
|
|||
CONF_PORT: 1234,
|
||||
CONF_SYSTEM_ID: "456",
|
||||
}
|
||||
assert len(mock_setup.mock_calls) == 1
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
|
@ -77,8 +71,6 @@ async def test_form_user_already_configured(hass):
|
|||
"homeassistant.components.somfy_mylink.config_flow.SomfyMyLinkSynergy.status_info",
|
||||
return_value={"any": "data"},
|
||||
), patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup", return_value=True
|
||||
) as mock_setup, patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
|
@ -93,116 +85,6 @@ async def test_form_user_already_configured(hass):
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert result2["type"] == "abort"
|
||||
assert len(mock_setup.mock_calls) == 0
|
||||
assert len(mock_setup_entry.mock_calls) == 0
|
||||
|
||||
|
||||
async def test_form_import(hass):
|
||||
"""Test we get the form with import source."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.somfy_mylink.config_flow.SomfyMyLinkSynergy.status_info",
|
||||
return_value={"any": "data"},
|
||||
), patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup", return_value=True
|
||||
) as mock_setup, patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_IMPORT},
|
||||
data={
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_PORT: 1234,
|
||||
CONF_SYSTEM_ID: 456,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == "MyLink 1.1.1.1"
|
||||
assert result["data"] == {
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_PORT: 1234,
|
||||
CONF_SYSTEM_ID: 456,
|
||||
}
|
||||
assert len(mock_setup.mock_calls) == 1
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_form_import_with_entity_config(hass):
|
||||
"""Test we can import entity config."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.somfy_mylink.config_flow.SomfyMyLinkSynergy.status_info",
|
||||
return_value={"any": "data"},
|
||||
), patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup", return_value=True
|
||||
) as mock_setup, patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_IMPORT},
|
||||
data={
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_PORT: 1234,
|
||||
CONF_SYSTEM_ID: 456,
|
||||
CONF_DEFAULT_REVERSE: True,
|
||||
CONF_ENTITY_CONFIG: {"cover.xyz": {CONF_REVERSE: False}},
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == "MyLink 1.1.1.1"
|
||||
assert result["data"] == {
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_PORT: 1234,
|
||||
CONF_SYSTEM_ID: 456,
|
||||
CONF_DEFAULT_REVERSE: True,
|
||||
CONF_ENTITY_CONFIG: {"cover.xyz": {CONF_REVERSE: False}},
|
||||
}
|
||||
assert len(mock_setup.mock_calls) == 1
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_form_import_already_exists(hass):
|
||||
"""Test we get the form with import source."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={CONF_HOST: "1.1.1.1", CONF_PORT: 12, CONF_SYSTEM_ID: 46},
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.somfy_mylink.config_flow.SomfyMyLinkSynergy.status_info",
|
||||
return_value={"any": "data"},
|
||||
), patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup", return_value=True
|
||||
) as mock_setup, patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_IMPORT},
|
||||
data={
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_PORT: 1234,
|
||||
CONF_SYSTEM_ID: "456",
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == "abort"
|
||||
assert len(mock_setup.mock_calls) == 0
|
||||
assert len(mock_setup_entry.mock_calls) == 0
|
||||
|
||||
|
||||
|
@ -354,77 +236,6 @@ async def test_options_with_targets(hass, reversed):
|
|||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("reversed", [True, False])
|
||||
async def test_form_import_with_entity_config_modify_options(hass, reversed):
|
||||
"""Test we can import entity config and modify options."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
||||
mock_imported_config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_PORT: 1234,
|
||||
CONF_SYSTEM_ID: "456",
|
||||
CONF_DEFAULT_REVERSE: True,
|
||||
CONF_ENTITY_CONFIG: {"cover.xyz": {CONF_REVERSE: False}},
|
||||
},
|
||||
)
|
||||
mock_imported_config_entry.add_to_hass(hass)
|
||||
|
||||
mock_status_info = {
|
||||
"result": [
|
||||
{"targetID": "1.1", "name": "xyz"},
|
||||
{"targetID": "1.2", "name": "zulu"},
|
||||
]
|
||||
}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.somfy_mylink.SomfyMyLinkSynergy.status_info",
|
||||
return_value=mock_status_info,
|
||||
):
|
||||
assert await hass.config_entries.async_setup(
|
||||
mock_imported_config_entry.entry_id
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_imported_config_entry.options == {
|
||||
"reversed_target_ids": {"1.2": True}
|
||||
}
|
||||
|
||||
result = await hass.config_entries.options.async_init(
|
||||
mock_imported_config_entry.entry_id
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "init"
|
||||
|
||||
result2 = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={"target_id": "1.2"},
|
||||
)
|
||||
|
||||
assert result2["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
result3 = await hass.config_entries.options.async_configure(
|
||||
result2["flow_id"],
|
||||
user_input={"reverse": reversed},
|
||||
)
|
||||
|
||||
assert result3["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
|
||||
result4 = await hass.config_entries.options.async_configure(
|
||||
result3["flow_id"],
|
||||
user_input={"target_id": None},
|
||||
)
|
||||
assert result4["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
|
||||
# Will not be altered if nothing changes
|
||||
assert mock_imported_config_entry.options == {
|
||||
CONF_REVERSED_TARGET_IDS: {"1.2": reversed},
|
||||
}
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
async def test_form_user_already_configured_from_dhcp(hass):
|
||||
"""Test we abort if already configured from dhcp."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
|
@ -439,8 +250,6 @@ async def test_form_user_already_configured_from_dhcp(hass):
|
|||
"homeassistant.components.somfy_mylink.config_flow.SomfyMyLinkSynergy.status_info",
|
||||
return_value={"any": "data"},
|
||||
), patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup", return_value=True
|
||||
) as mock_setup, patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
|
@ -457,7 +266,6 @@ async def test_form_user_already_configured_from_dhcp(hass):
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == "abort"
|
||||
assert len(mock_setup.mock_calls) == 0
|
||||
assert len(mock_setup_entry.mock_calls) == 0
|
||||
|
||||
|
||||
|
@ -501,8 +309,6 @@ async def test_dhcp_discovery(hass):
|
|||
"homeassistant.components.somfy_mylink.config_flow.SomfyMyLinkSynergy.status_info",
|
||||
return_value={"any": "data"},
|
||||
), patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup", return_value=True
|
||||
) as mock_setup, patch(
|
||||
"homeassistant.components.somfy_mylink.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
|
@ -523,5 +329,4 @@ async def test_dhcp_discovery(hass):
|
|||
CONF_PORT: 1234,
|
||||
CONF_SYSTEM_ID: "456",
|
||||
}
|
||||
assert len(mock_setup.mock_calls) == 1
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
|
Loading…
Reference in New Issue