Update WiZ with IP address validation (#66117)

This commit is contained in:
Stephan Traub 2022-02-09 19:53:32 +01:00 committed by GitHub
parent 83a10cca53
commit a6013dc0de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 74 additions and 35 deletions

View file

@ -13,6 +13,7 @@ from homeassistant import config_entries
from homeassistant.components import dhcp
from homeassistant.const import CONF_HOST
from homeassistant.data_entry_flow import FlowResult
from homeassistant.util.network import is_ip_address
from .const import DEFAULT_NAME, DISCOVER_SCAN_TIMEOUT, DOMAIN, WIZ_EXCEPTIONS
from .discovery import async_discover_devices
@ -139,29 +140,32 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
if user_input is not None:
if not (host := user_input[CONF_HOST]):
return await self.async_step_pick_device()
bulb = wizlight(host)
try:
mac = await bulb.getMac()
bulbtype = await bulb.get_bulbtype()
except WizLightTimeOutError:
errors["base"] = "bulb_time_out"
except ConnectionRefusedError:
errors["base"] = "cannot_connect"
except WizLightConnectionError:
errors["base"] = "no_wiz_light"
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
if not is_ip_address(user_input[CONF_HOST]):
errors["base"] = "no_ip"
else:
await self.async_set_unique_id(mac, raise_on_progress=False)
self._abort_if_unique_id_configured(
updates={CONF_HOST: user_input[CONF_HOST]}
)
name = name_from_bulb_type_and_mac(bulbtype, mac)
return self.async_create_entry(
title=name,
data=user_input,
)
bulb = wizlight(host)
try:
bulbtype = await bulb.get_bulbtype()
mac = await bulb.getMac()
except WizLightTimeOutError:
errors["base"] = "bulb_time_out"
except ConnectionRefusedError:
errors["base"] = "cannot_connect"
except WizLightConnectionError:
errors["base"] = "no_wiz_light"
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
await self.async_set_unique_id(mac, raise_on_progress=False)
self._abort_if_unique_id_configured(
updates={CONF_HOST: user_input[CONF_HOST]}
)
name = name_from_bulb_type_and_mac(bulbtype, mac)
return self.async_create_entry(
title=name,
data=user_input,
)
return self.async_show_form(
step_id="user",

View file

@ -4,9 +4,9 @@
"step": {
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]"
"host": "[%key:common::config_flow::data::ip%]"
},
"description": "If you leave the host empty, discovery will be used to find devices."
"description": "If you leave the IP Address empty, discovery will be used to find devices."
},
"discovery_confirm": {
"description": "Do you want to setup {name} ({host})?"
@ -20,8 +20,9 @@
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]",
"bulb_time_out": "Can not connect to the bulb. Maybe the bulb is offline or a wrong IP/host was entered. Please turn on the light and try again!",
"no_wiz_light": "The bulb can not be connected via WiZ Platform integration."
"bulb_time_out": "Can not connect to the bulb. Maybe the bulb is offline or a wrong IP was entered. Please turn on the light and try again!",
"no_wiz_light": "The bulb can not be connected via WiZ Platform integration.",
"no_ip": "Not a valid IP address."
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"

View file

@ -1,20 +1,17 @@
{
"config": {
"abort": {
"already_configured": "Device is already configured",
"no_devices_found": "No devices found on the network"
"already_configured": "Device is already configured"
},
"error": {
"bulb_time_out": "Can not connect to the bulb. Maybe the bulb is offline or a wrong IP/host was entered. Please turn on the light and try again!",
"bulb_time_out": "Can not connect to the bulb. Maybe the bulb is offline or a wrong IP was entered. Please turn on the light and try again!",
"cannot_connect": "Failed to connect",
"no_ip": "Not a valid IP address.",
"no_wiz_light": "The bulb can not be connected via WiZ Platform integration.",
"unknown": "Unexpected error"
},
"flow_title": "{name} ({host})",
"step": {
"confirm": {
"description": "Do you want to start set up?"
},
"discovery_confirm": {
"description": "Do you want to setup {name} ({host})?"
},
@ -25,10 +22,9 @@
},
"user": {
"data": {
"host": "Host",
"name": "Name"
"host": "IP Address"
},
"description": "If you leave the host empty, discovery will be used to find devices."
"description": "If you leave the IP Address empty, discovery will be used to find devices."
}
}
}

View file

@ -114,6 +114,44 @@ async def test_form(hass):
assert len(mock_setup_entry.mock_calls) == 1
async def test_user_flow_enters_dns_name(hass):
"""Test we reject dns names and want ips."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == "form"
assert result["errors"] == {}
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "ip.only"},
)
await hass.async_block_till_done()
assert result2["type"] == RESULT_TYPE_FORM
assert result2["errors"] == {"base": "no_ip"}
with _patch_wizlight(), patch(
"homeassistant.components.wiz.async_setup_entry",
return_value=True,
) as mock_setup_entry, patch(
"homeassistant.components.wiz.async_setup", return_value=True
) as mock_setup:
result3 = await hass.config_entries.flow.async_configure(
result2["flow_id"],
TEST_CONNECTION,
)
await hass.async_block_till_done()
assert result3["type"] == "create_entry"
assert result3["title"] == "WiZ Dimmable White ABCABC"
assert result3["data"] == {
CONF_HOST: "1.1.1.1",
}
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1
@pytest.mark.parametrize(
"side_effect, error_base",
[