Move Insteon configuration panel to config entry (#105581)
* Move Insteon panel to the config menu * Bump pyinsteon to 1.5.3 * Undo devcontainer.json changes * Bump Insteon frontend * Update config_flow.py * Code cleanup * Code review changes * Fix failing tests * Fix format * Remove unnecessary exception * codecov * Remove return from try * Fix merge mistake --------- Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
parent
1dfabf34c4
commit
c5c407b3bb
17 changed files with 988 additions and 766 deletions
|
@ -8,38 +8,14 @@ from voluptuous_serialize import convert
|
|||
from homeassistant import config_entries
|
||||
from homeassistant.components import dhcp, usb
|
||||
from homeassistant.components.insteon.config_flow import (
|
||||
STEP_ADD_OVERRIDE,
|
||||
STEP_ADD_X10,
|
||||
STEP_CHANGE_HUB_CONFIG,
|
||||
STEP_CHANGE_PLM_CONFIG,
|
||||
STEP_HUB_V1,
|
||||
STEP_HUB_V2,
|
||||
STEP_PLM,
|
||||
STEP_PLM_MANUALLY,
|
||||
STEP_REMOVE_OVERRIDE,
|
||||
STEP_REMOVE_X10,
|
||||
)
|
||||
from homeassistant.components.insteon.const import (
|
||||
CONF_CAT,
|
||||
CONF_DIM_STEPS,
|
||||
CONF_HOUSECODE,
|
||||
CONF_HUB_VERSION,
|
||||
CONF_OVERRIDE,
|
||||
CONF_SUBCAT,
|
||||
CONF_UNITCODE,
|
||||
CONF_X10,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.components.insteon.const import CONF_HUB_VERSION, DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import (
|
||||
CONF_ADDRESS,
|
||||
CONF_DEVICE,
|
||||
CONF_HOST,
|
||||
CONF_PASSWORD,
|
||||
CONF_PLATFORM,
|
||||
CONF_PORT,
|
||||
CONF_USERNAME,
|
||||
)
|
||||
from homeassistant.const import CONF_DEVICE, CONF_HOST
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
|
@ -52,11 +28,8 @@ from .const import (
|
|||
PATCH_ASYNC_SETUP,
|
||||
PATCH_ASYNC_SETUP_ENTRY,
|
||||
PATCH_CONNECTION,
|
||||
PATCH_CONNECTION_CLOSE,
|
||||
PATCH_DEVICES,
|
||||
PATCH_USB_LIST,
|
||||
)
|
||||
from .mock_devices import MockDevices
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
@ -294,379 +267,6 @@ async def test_failed_connection_hub(hass: HomeAssistant) -> None:
|
|||
assert result2["errors"] == {"base": "cannot_connect"}
|
||||
|
||||
|
||||
async def _options_init_form(hass, entry_id, step):
|
||||
"""Run the init options form."""
|
||||
with patch(PATCH_ASYNC_SETUP_ENTRY, return_value=True):
|
||||
result = await hass.config_entries.options.async_init(entry_id)
|
||||
|
||||
assert result["type"] is FlowResultType.MENU
|
||||
assert result["step_id"] == "init"
|
||||
|
||||
return await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
{"next_step_id": step},
|
||||
)
|
||||
|
||||
|
||||
async def _options_form(
|
||||
hass, flow_id, user_input, connection=mock_successful_connection
|
||||
):
|
||||
"""Test an options form."""
|
||||
mock_devices = MockDevices(connected=True)
|
||||
await mock_devices.async_load()
|
||||
mock_devices.modem = mock_devices["AA.AA.AA"]
|
||||
with (
|
||||
patch(PATCH_CONNECTION, new=connection),
|
||||
patch(PATCH_ASYNC_SETUP_ENTRY, return_value=True) as mock_setup_entry,
|
||||
patch(PATCH_DEVICES, mock_devices),
|
||||
patch(PATCH_CONNECTION_CLOSE),
|
||||
):
|
||||
result = await hass.config_entries.options.async_configure(flow_id, user_input)
|
||||
return result, mock_setup_entry
|
||||
|
||||
|
||||
async def test_options_change_hub_config(hass: HomeAssistant) -> None:
|
||||
"""Test changing Hub v2 config."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="abcde12345",
|
||||
data={**MOCK_USER_INPUT_HUB_V2, CONF_HUB_VERSION: 2},
|
||||
options={},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await _options_init_form(
|
||||
hass, config_entry.entry_id, STEP_CHANGE_HUB_CONFIG
|
||||
)
|
||||
|
||||
user_input = {
|
||||
CONF_HOST: "2.3.4.5",
|
||||
CONF_PORT: 9999,
|
||||
CONF_USERNAME: "new username",
|
||||
CONF_PASSWORD: "new password",
|
||||
}
|
||||
result, _ = await _options_form(hass, result["flow_id"], user_input)
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert config_entry.options == {}
|
||||
assert config_entry.data == {**user_input, CONF_HUB_VERSION: 2}
|
||||
|
||||
|
||||
async def test_options_change_hub_bad_config(hass: HomeAssistant) -> None:
|
||||
"""Test changing Hub v2 with bad config."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="abcde12345",
|
||||
data={**MOCK_USER_INPUT_HUB_V2, CONF_HUB_VERSION: 2},
|
||||
options={},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await _options_init_form(
|
||||
hass, config_entry.entry_id, STEP_CHANGE_HUB_CONFIG
|
||||
)
|
||||
|
||||
user_input = {
|
||||
CONF_HOST: "2.3.4.5",
|
||||
CONF_PORT: 9999,
|
||||
CONF_USERNAME: "new username",
|
||||
CONF_PASSWORD: "new password",
|
||||
}
|
||||
result, _ = await _options_form(
|
||||
hass, result["flow_id"], user_input, mock_failed_connection
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["errors"]["base"] == "cannot_connect"
|
||||
|
||||
|
||||
async def test_options_change_plm_config(hass: HomeAssistant) -> None:
|
||||
"""Test changing PLM config."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="abcde12345",
|
||||
data=MOCK_USER_INPUT_PLM,
|
||||
options={},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await _options_init_form(
|
||||
hass, config_entry.entry_id, STEP_CHANGE_PLM_CONFIG
|
||||
)
|
||||
|
||||
user_input = {CONF_DEVICE: "/dev/ttyUSB0"}
|
||||
result, _ = await _options_form(hass, result["flow_id"], user_input)
|
||||
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert config_entry.options == {}
|
||||
assert config_entry.data == user_input
|
||||
|
||||
|
||||
async def test_options_change_plm_bad_config(hass: HomeAssistant) -> None:
|
||||
"""Test changing PLM config."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="abcde12345",
|
||||
data=MOCK_USER_INPUT_PLM,
|
||||
options={},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await _options_init_form(
|
||||
hass, config_entry.entry_id, STEP_CHANGE_PLM_CONFIG
|
||||
)
|
||||
|
||||
user_input = {CONF_DEVICE: "/dev/ttyUSB0"}
|
||||
result, _ = await _options_form(
|
||||
hass, result["flow_id"], user_input, mock_failed_connection
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["errors"]["base"] == "cannot_connect"
|
||||
|
||||
|
||||
async def test_options_add_device_override(hass: HomeAssistant) -> None:
|
||||
"""Test adding a device override."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="abcde12345",
|
||||
data={**MOCK_USER_INPUT_HUB_V2, CONF_HUB_VERSION: 2},
|
||||
options={},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await _options_init_form(hass, config_entry.entry_id, STEP_ADD_OVERRIDE)
|
||||
|
||||
user_input = {
|
||||
CONF_ADDRESS: "1a2b3c",
|
||||
CONF_CAT: "0x04",
|
||||
CONF_SUBCAT: "0xaa",
|
||||
}
|
||||
result, _ = await _options_form(hass, result["flow_id"], user_input)
|
||||
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert len(config_entry.options[CONF_OVERRIDE]) == 1
|
||||
assert config_entry.options[CONF_OVERRIDE][0][CONF_ADDRESS] == "1A.2B.3C"
|
||||
assert config_entry.options[CONF_OVERRIDE][0][CONF_CAT] == 4
|
||||
assert config_entry.options[CONF_OVERRIDE][0][CONF_SUBCAT] == 170
|
||||
|
||||
result2 = await _options_init_form(hass, config_entry.entry_id, STEP_ADD_OVERRIDE)
|
||||
|
||||
user_input = {
|
||||
CONF_ADDRESS: "4d5e6f",
|
||||
CONF_CAT: "05",
|
||||
CONF_SUBCAT: "bb",
|
||||
}
|
||||
result3, _ = await _options_form(hass, result2["flow_id"], user_input)
|
||||
|
||||
assert len(config_entry.options[CONF_OVERRIDE]) == 2
|
||||
assert config_entry.options[CONF_OVERRIDE][1][CONF_ADDRESS] == "4D.5E.6F"
|
||||
assert config_entry.options[CONF_OVERRIDE][1][CONF_CAT] == 5
|
||||
assert config_entry.options[CONF_OVERRIDE][1][CONF_SUBCAT] == 187
|
||||
|
||||
# If result1 eq result2 the changes will not save
|
||||
assert result["data"] != result3["data"]
|
||||
|
||||
|
||||
async def test_options_remove_device_override(hass: HomeAssistant) -> None:
|
||||
"""Test removing a device override."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="abcde12345",
|
||||
data={**MOCK_USER_INPUT_HUB_V2, CONF_HUB_VERSION: 2},
|
||||
options={
|
||||
CONF_OVERRIDE: [
|
||||
{CONF_ADDRESS: "1A.2B.3C", CONF_CAT: 6, CONF_SUBCAT: 100},
|
||||
{CONF_ADDRESS: "4D.5E.6F", CONF_CAT: 7, CONF_SUBCAT: 200},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await _options_init_form(hass, config_entry.entry_id, STEP_REMOVE_OVERRIDE)
|
||||
|
||||
user_input = {CONF_ADDRESS: "1A.2B.3C"}
|
||||
result, _ = await _options_form(hass, result["flow_id"], user_input)
|
||||
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert len(config_entry.options[CONF_OVERRIDE]) == 1
|
||||
|
||||
|
||||
async def test_options_remove_device_override_with_x10(hass: HomeAssistant) -> None:
|
||||
"""Test removing a device override when an X10 device is configured."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="abcde12345",
|
||||
data={**MOCK_USER_INPUT_HUB_V2, CONF_HUB_VERSION: 2},
|
||||
options={
|
||||
CONF_OVERRIDE: [
|
||||
{CONF_ADDRESS: "1A.2B.3C", CONF_CAT: 6, CONF_SUBCAT: 100},
|
||||
{CONF_ADDRESS: "4D.5E.6F", CONF_CAT: 7, CONF_SUBCAT: 200},
|
||||
],
|
||||
CONF_X10: [
|
||||
{
|
||||
CONF_HOUSECODE: "d",
|
||||
CONF_UNITCODE: 5,
|
||||
CONF_PLATFORM: "light",
|
||||
CONF_DIM_STEPS: 22,
|
||||
}
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await _options_init_form(hass, config_entry.entry_id, STEP_REMOVE_OVERRIDE)
|
||||
|
||||
user_input = {CONF_ADDRESS: "1A.2B.3C"}
|
||||
result, _ = await _options_form(hass, result["flow_id"], user_input)
|
||||
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert len(config_entry.options[CONF_OVERRIDE]) == 1
|
||||
assert len(config_entry.options[CONF_X10]) == 1
|
||||
|
||||
|
||||
async def test_options_add_x10_device(hass: HomeAssistant) -> None:
|
||||
"""Test adding an X10 device."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="abcde12345",
|
||||
data={**MOCK_USER_INPUT_HUB_V2, CONF_HUB_VERSION: 2},
|
||||
options={},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await _options_init_form(hass, config_entry.entry_id, STEP_ADD_X10)
|
||||
|
||||
user_input = {
|
||||
CONF_HOUSECODE: "c",
|
||||
CONF_UNITCODE: 12,
|
||||
CONF_PLATFORM: "light",
|
||||
CONF_DIM_STEPS: 18,
|
||||
}
|
||||
result2, _ = await _options_form(hass, result["flow_id"], user_input)
|
||||
|
||||
assert result2["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert len(config_entry.options[CONF_X10]) == 1
|
||||
assert config_entry.options[CONF_X10][0][CONF_HOUSECODE] == "c"
|
||||
assert config_entry.options[CONF_X10][0][CONF_UNITCODE] == 12
|
||||
assert config_entry.options[CONF_X10][0][CONF_PLATFORM] == "light"
|
||||
assert config_entry.options[CONF_X10][0][CONF_DIM_STEPS] == 18
|
||||
|
||||
result = await _options_init_form(hass, config_entry.entry_id, STEP_ADD_X10)
|
||||
user_input = {
|
||||
CONF_HOUSECODE: "d",
|
||||
CONF_UNITCODE: 10,
|
||||
CONF_PLATFORM: "binary_sensor",
|
||||
CONF_DIM_STEPS: 15,
|
||||
}
|
||||
result3, _ = await _options_form(hass, result["flow_id"], user_input)
|
||||
|
||||
assert result3["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert len(config_entry.options[CONF_X10]) == 2
|
||||
assert config_entry.options[CONF_X10][1][CONF_HOUSECODE] == "d"
|
||||
assert config_entry.options[CONF_X10][1][CONF_UNITCODE] == 10
|
||||
assert config_entry.options[CONF_X10][1][CONF_PLATFORM] == "binary_sensor"
|
||||
assert config_entry.options[CONF_X10][1][CONF_DIM_STEPS] == 15
|
||||
|
||||
# If result2 eq result3 the changes will not save
|
||||
assert result2["data"] != result3["data"]
|
||||
|
||||
|
||||
async def test_options_remove_x10_device(hass: HomeAssistant) -> None:
|
||||
"""Test removing an X10 device."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="abcde12345",
|
||||
data={**MOCK_USER_INPUT_HUB_V2, CONF_HUB_VERSION: 2},
|
||||
options={
|
||||
CONF_X10: [
|
||||
{
|
||||
CONF_HOUSECODE: "C",
|
||||
CONF_UNITCODE: 4,
|
||||
CONF_PLATFORM: "light",
|
||||
CONF_DIM_STEPS: 18,
|
||||
},
|
||||
{
|
||||
CONF_HOUSECODE: "D",
|
||||
CONF_UNITCODE: 10,
|
||||
CONF_PLATFORM: "binary_sensor",
|
||||
CONF_DIM_STEPS: 15,
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await _options_init_form(hass, config_entry.entry_id, STEP_REMOVE_X10)
|
||||
|
||||
user_input = {CONF_DEVICE: "Housecode: C, Unitcode: 4"}
|
||||
result, _ = await _options_form(hass, result["flow_id"], user_input)
|
||||
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert len(config_entry.options[CONF_X10]) == 1
|
||||
|
||||
|
||||
async def test_options_remove_x10_device_with_override(hass: HomeAssistant) -> None:
|
||||
"""Test removing an X10 device when a device override is configured."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="abcde12345",
|
||||
data={**MOCK_USER_INPUT_HUB_V2, CONF_HUB_VERSION: 2},
|
||||
options={
|
||||
CONF_X10: [
|
||||
{
|
||||
CONF_HOUSECODE: "C",
|
||||
CONF_UNITCODE: 4,
|
||||
CONF_PLATFORM: "light",
|
||||
CONF_DIM_STEPS: 18,
|
||||
},
|
||||
{
|
||||
CONF_HOUSECODE: "D",
|
||||
CONF_UNITCODE: 10,
|
||||
CONF_PLATFORM: "binary_sensor",
|
||||
CONF_DIM_STEPS: 15,
|
||||
},
|
||||
],
|
||||
CONF_OVERRIDE: [{CONF_ADDRESS: "1A.2B.3C", CONF_CAT: 1, CONF_SUBCAT: 18}],
|
||||
},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await _options_init_form(hass, config_entry.entry_id, STEP_REMOVE_X10)
|
||||
|
||||
user_input = {CONF_DEVICE: "Housecode: C, Unitcode: 4"}
|
||||
result, _ = await _options_form(hass, result["flow_id"], user_input)
|
||||
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert len(config_entry.options[CONF_X10]) == 1
|
||||
assert len(config_entry.options[CONF_OVERRIDE]) == 1
|
||||
|
||||
|
||||
async def test_options_override_bad_data(hass: HomeAssistant) -> None:
|
||||
"""Test for bad data in a device override."""
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
entry_id="abcde12345",
|
||||
data={**MOCK_USER_INPUT_HUB_V2, CONF_HUB_VERSION: 2},
|
||||
options={},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
result = await _options_init_form(hass, config_entry.entry_id, STEP_ADD_OVERRIDE)
|
||||
|
||||
user_input = {
|
||||
CONF_ADDRESS: "zzzzzz",
|
||||
CONF_CAT: "bad",
|
||||
CONF_SUBCAT: "data",
|
||||
}
|
||||
result, _ = await _options_form(hass, result["flow_id"], user_input)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["errors"] == {"base": "input_error"}
|
||||
|
||||
|
||||
async def test_discovery_via_usb(hass: HomeAssistant) -> None:
|
||||
"""Test usb flow."""
|
||||
discovery_info = usb.UsbServiceInfo(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue