Add reconfigure flow to homeworks (#112419)

* Add reconfigure flow to homeworks

* Fix tests

* Use async_update_reload_and_abort helper

* Try to fix test shutdown
This commit is contained in:
Erik Montnemery 2024-03-12 08:47:44 +01:00 committed by GitHub
parent 6c35ae06a0
commit d039bd654b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 208 additions and 1 deletions

View file

@ -430,6 +430,7 @@ DATA_SCHEMA_ADD_CONTROLLER = vol.Schema(
**CONTROLLER_EDIT,
}
)
DATA_SCHEMA_EDIT_CONTROLLER = vol.Schema(CONTROLLER_EDIT)
DATA_SCHEMA_ADD_LIGHT = vol.Schema(
{
vol.Optional(CONF_NAME, default=DEFAULT_LIGHT_NAME): TextSelector(),
@ -643,6 +644,66 @@ class HomeworksConfigFlowHandler(ConfigFlow, domain=DOMAIN):
return self.async_show_form(step_id="import_finish", data_schema=vol.Schema({}))
async def _validate_edit_controller(
self, user_input: dict[str, Any]
) -> dict[str, Any]:
"""Validate controller setup."""
user_input[CONF_PORT] = int(user_input[CONF_PORT])
our_entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
assert our_entry
other_entries = self._async_current_entries()
for entry in other_entries:
if entry.entry_id == our_entry.entry_id:
continue
if (
user_input[CONF_HOST] == entry.options[CONF_HOST]
and user_input[CONF_PORT] == entry.options[CONF_PORT]
):
raise SchemaFlowError("duplicated_host_port")
await _try_connection(user_input)
return user_input
async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle a reconfigure flow."""
entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
assert entry
errors = {}
suggested_values = {
CONF_HOST: entry.options[CONF_HOST],
CONF_PORT: entry.options[CONF_PORT],
}
if user_input:
suggested_values = {
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
}
try:
await self._validate_edit_controller(user_input)
except SchemaFlowError as err:
errors["base"] = str(err)
else:
new_options = entry.options | {
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
}
return self.async_update_reload_and_abort(
entry, options=new_options, reason="reconfigure_successful"
)
return self.async_show_form(
step_id="reconfigure",
data_schema=self.add_suggested_values_to_schema(
DATA_SCHEMA_EDIT_CONTROLLER, suggested_values
),
errors=errors,
)
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:

View file

@ -19,6 +19,13 @@
"name": "[%key:component::homeworks::config::step::user::data_description::name%]"
}
},
"reconfigure": {
"data": {
"host": "[%key:common::config_flow::data::host%]",
"port": "[%key:common::config_flow::data::port%]"
},
"description": "Modify a Lutron Homeworks controller connection settings"
},
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]",

View file

@ -18,7 +18,7 @@ from homeassistant.components.homeworks.const import (
DOMAIN,
)
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_RECONFIGURE, SOURCE_USER
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
@ -261,6 +261,145 @@ async def test_import_flow_controller_id_exists(
assert result["errors"] == {"base": "duplicated_controller_id"}
async def test_reconfigure_flow(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_homeworks: MagicMock
) -> None:
"""Test reconfigure flow."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_RECONFIGURE, "entry_id": mock_config_entry.entry_id},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "reconfigure"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "192.168.0.2",
CONF_PORT: 1234,
},
)
await hass.async_block_till_done()
assert result["type"] == FlowResultType.ABORT
assert result["reason"] == "reconfigure_successful"
assert mock_config_entry.options == {
"controller_id": "main_controller",
"dimmers": [
{"addr": "[02:08:01:01]", "name": "Foyer Sconces", "rate": 1.0},
],
"host": "192.168.0.2",
"keypads": [
{
"addr": "[02:08:02:01]",
"buttons": [
{
"name": "Morning",
"number": 1,
"release_delay": None,
},
{"name": "Relax", "number": 2, "release_delay": None},
{"name": "Dim up", "number": 3, "release_delay": 0.2},
],
"name": "Foyer Keypad",
},
],
"port": 1234,
}
async def test_reconfigure_flow_flow_duplicate(
hass: HomeAssistant, mock_homeworks: MagicMock
) -> None:
"""Test reconfigure flow."""
entry1 = MockConfigEntry(
domain=DOMAIN,
data={},
options={
"controller_id": "controller_1",
"host": "192.168.0.1",
"port": 1234,
},
)
entry1.add_to_hass(hass)
entry2 = MockConfigEntry(
domain=DOMAIN,
data={},
options={
"controller_id": "controller_2",
"host": "192.168.0.2",
"port": 1234,
},
)
entry2.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_RECONFIGURE, "entry_id": entry1.entry_id},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "reconfigure"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "192.168.0.2",
CONF_PORT: 1234,
},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "reconfigure"
assert result["errors"] == {"base": "duplicated_host_port"}
async def test_reconfigure_flow_flow_no_change(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_homeworks: MagicMock
) -> None:
"""Test reconfigure flow."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_RECONFIGURE, "entry_id": mock_config_entry.entry_id},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "reconfigure"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "192.168.0.1",
CONF_PORT: 1234,
},
)
assert result["type"] == FlowResultType.ABORT
assert result["reason"] == "reconfigure_successful"
assert mock_config_entry.options == {
"controller_id": "main_controller",
"dimmers": [
{"addr": "[02:08:01:01]", "name": "Foyer Sconces", "rate": 1.0},
],
"host": "192.168.0.1",
"keypads": [
{
"addr": "[02:08:02:01]",
"buttons": [
{
"name": "Morning",
"number": 1,
"release_delay": None,
},
{"name": "Relax", "number": 2, "release_delay": None},
{"name": "Dim up", "number": 3, "release_delay": 0.2},
],
"name": "Foyer Keypad",
}
],
"port": 1234,
}
async def test_options_add_light_flow(
hass: HomeAssistant,
mock_empty_config_entry: MockConfigEntry,