Merge onvif host/auth step, allow skipping scan (#49660)
parent
fd1d110b80
commit
3a5ee00081
|
@ -91,10 +91,15 @@ class OnvifFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
|
||||
async def async_step_user(self, user_input=None):
|
||||
"""Handle user flow."""
|
||||
if user_input is not None:
|
||||
return await self.async_step_device()
|
||||
if user_input:
|
||||
if user_input["auto"]:
|
||||
return await self.async_step_device()
|
||||
return await self.async_step_configure()
|
||||
|
||||
return self.async_show_form(step_id="user")
|
||||
return self.async_show_form(
|
||||
step_id="user",
|
||||
data_schema=vol.Schema({vol.Required("auto", default=True): bool}),
|
||||
)
|
||||
|
||||
async def async_step_device(self, user_input=None):
|
||||
"""Handle WS-Discovery.
|
||||
|
@ -105,7 +110,7 @@ class OnvifFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
if user_input:
|
||||
|
||||
if CONF_MANUAL_INPUT == user_input[CONF_HOST]:
|
||||
return await self.async_step_manual_input()
|
||||
return await self.async_step_configure()
|
||||
|
||||
for device in self.devices:
|
||||
name = f"{device[CONF_NAME]} ({device[CONF_HOST]})"
|
||||
|
@ -116,7 +121,7 @@ class OnvifFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
CONF_HOST: device[CONF_HOST],
|
||||
CONF_PORT: device[CONF_PORT],
|
||||
}
|
||||
return await self.async_step_auth()
|
||||
return await self.async_step_configure()
|
||||
|
||||
discovery = await async_discovery(self.hass)
|
||||
for device in discovery:
|
||||
|
@ -142,44 +147,33 @@ class OnvifFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
data_schema=vol.Schema({vol.Optional(CONF_HOST): vol.In(names)}),
|
||||
)
|
||||
|
||||
return await self.async_step_manual_input()
|
||||
return await self.async_step_configure()
|
||||
|
||||
async def async_step_manual_input(self, user_input=None):
|
||||
"""Manual configuration."""
|
||||
async def async_step_configure(self, user_input=None, errors=None):
|
||||
"""Device configuration."""
|
||||
if user_input:
|
||||
self.onvif_config = user_input
|
||||
return await self.async_step_auth()
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="manual_input",
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_NAME): str,
|
||||
vol.Required(CONF_HOST): str,
|
||||
vol.Required(CONF_PORT, default=DEFAULT_PORT): int,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
async def async_step_auth(self, user_input=None):
|
||||
"""Username and Password configuration for ONVIF device."""
|
||||
if user_input:
|
||||
self.onvif_config[CONF_USERNAME] = user_input[CONF_USERNAME]
|
||||
self.onvif_config[CONF_PASSWORD] = user_input[CONF_PASSWORD]
|
||||
return await self.async_step_profiles()
|
||||
|
||||
def conf(name, default=None):
|
||||
return self.onvif_config.get(name, default)
|
||||
|
||||
# Username and Password are optional and default empty
|
||||
# due to some cameras not allowing you to change ONVIF user settings.
|
||||
# See https://github.com/home-assistant/core/issues/39182
|
||||
# and https://github.com/home-assistant/core/issues/35904
|
||||
return self.async_show_form(
|
||||
step_id="auth",
|
||||
step_id="configure",
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_USERNAME, default=""): str,
|
||||
vol.Optional(CONF_PASSWORD, default=""): str,
|
||||
vol.Required(CONF_NAME, default=conf(CONF_NAME)): str,
|
||||
vol.Required(CONF_HOST, default=conf(CONF_HOST)): str,
|
||||
vol.Required(CONF_PORT, default=conf(CONF_PORT, DEFAULT_PORT)): int,
|
||||
vol.Optional(CONF_USERNAME, default=conf(CONF_USERNAME, "")): str,
|
||||
vol.Optional(CONF_PASSWORD, default=conf(CONF_PASSWORD, "")): str,
|
||||
}
|
||||
),
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
async def async_step_profiles(self, user_input=None):
|
||||
|
@ -268,7 +262,7 @@ class OnvifFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
finally:
|
||||
await device.close()
|
||||
|
||||
return self.async_show_form(step_id="auth", errors=errors)
|
||||
return await self.async_step_configure(errors=errors)
|
||||
|
||||
async def async_step_import(self, user_input):
|
||||
"""Handle import."""
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"auto": "Search automatically"
|
||||
},
|
||||
"title": "ONVIF device setup",
|
||||
"description": "By clicking submit, we will search your network for ONVIF devices that support Profile S.\n\nSome manufacturers have started to disable ONVIF by default. Please ensure ONVIF is enabled in your camera's configuration."
|
||||
},
|
||||
|
@ -21,20 +24,15 @@
|
|||
},
|
||||
"title": "Select ONVIF device"
|
||||
},
|
||||
"manual_input": {
|
||||
"configure": {
|
||||
"data": {
|
||||
"name": "[%key:common::config_flow::data::name%]",
|
||||
"host": "[%key:common::config_flow::data::host%]",
|
||||
"port": "[%key:common::config_flow::data::port%]"
|
||||
},
|
||||
"title": "Configure ONVIF device"
|
||||
},
|
||||
"auth": {
|
||||
"title": "Configure authentication",
|
||||
"data": {
|
||||
"port": "[%key:common::config_flow::data::port%]",
|
||||
"username": "[%key:common::config_flow::data::username%]",
|
||||
"password": "[%key:common::config_flow::data::password%]"
|
||||
}
|
||||
},
|
||||
"title": "Configure ONVIF device"
|
||||
},
|
||||
"configure_profile": {
|
||||
"description": "Create camera entity for {profile} at {resolution} resolution?",
|
||||
|
|
|
@ -11,12 +11,15 @@
|
|||
"cannot_connect": "Failed to connect"
|
||||
},
|
||||
"step": {
|
||||
"auth": {
|
||||
"configure": {
|
||||
"data": {
|
||||
"host": "Host",
|
||||
"name": "Name",
|
||||
"password": "Password",
|
||||
"port": "Port",
|
||||
"username": "Username"
|
||||
},
|
||||
"title": "Configure authentication"
|
||||
"title": "Configure ONVIF device"
|
||||
},
|
||||
"configure_profile": {
|
||||
"data": {
|
||||
|
@ -31,15 +34,10 @@
|
|||
},
|
||||
"title": "Select ONVIF device"
|
||||
},
|
||||
"manual_input": {
|
||||
"data": {
|
||||
"host": "Host",
|
||||
"name": "Name",
|
||||
"port": "Port"
|
||||
},
|
||||
"title": "Configure ONVIF device"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
"auto": "Search automatically"
|
||||
},
|
||||
"description": "By clicking submit, we will search your network for ONVIF devices that support Profile S.\n\nSome manufacturers have started to disable ONVIF by default. Please ensure ONVIF is enabled in your camera's configuration.",
|
||||
"title": "ONVIF device setup"
|
||||
}
|
||||
|
|
|
@ -203,7 +203,7 @@ async def test_flow_discovered_devices(hass):
|
|||
setup_mock_device(mock_device)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
result["flow_id"], user_input={"auto": True}
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
|
@ -215,7 +215,7 @@ async def test_flow_discovered_devices(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "auth"
|
||||
assert result["step_id"] == "configure"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.onvif.async_setup", return_value=True
|
||||
|
@ -268,7 +268,7 @@ async def test_flow_discovered_devices_ignore_configured_manual_input(hass):
|
|||
setup_mock_device(mock_device)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
result["flow_id"], user_input={"auto": True}
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
|
@ -281,7 +281,37 @@ async def test_flow_discovered_devices_ignore_configured_manual_input(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "manual_input"
|
||||
assert result["step_id"] == "configure"
|
||||
|
||||
|
||||
async def test_flow_discovered_no_device(hass):
|
||||
"""Test that config flow discovery no device."""
|
||||
await setup_onvif_integration(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
config_flow.DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.onvif.config_flow.get_device"
|
||||
) as mock_onvif_camera, patch(
|
||||
"homeassistant.components.onvif.config_flow.wsdiscovery"
|
||||
) as mock_discovery, patch(
|
||||
"homeassistant.components.onvif.ONVIFDevice"
|
||||
) as mock_device:
|
||||
setup_mock_onvif_camera(mock_onvif_camera)
|
||||
mock_discovery.return_value = []
|
||||
setup_mock_device(mock_device)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={"auto": True}
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "configure"
|
||||
|
||||
|
||||
async def test_flow_discovery_ignore_existing_and_abort(hass):
|
||||
|
@ -319,12 +349,12 @@ async def test_flow_discovery_ignore_existing_and_abort(hass):
|
|||
setup_mock_device(mock_device)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
result["flow_id"], user_input={"auto": True}
|
||||
)
|
||||
|
||||
# It should skip to manual entry if the only devices are already configured
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "manual_input"
|
||||
assert result["step_id"] == "configure"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
|
@ -332,15 +362,6 @@ async def test_flow_discovery_ignore_existing_and_abort(hass):
|
|||
config_flow.CONF_NAME: NAME,
|
||||
config_flow.CONF_HOST: HOST,
|
||||
config_flow.CONF_PORT: PORT,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "auth"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
config_flow.CONF_USERNAME: USERNAME,
|
||||
config_flow.CONF_PASSWORD: PASSWORD,
|
||||
},
|
||||
|
@ -373,23 +394,11 @@ async def test_flow_manual_entry(hass):
|
|||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={},
|
||||
user_input={"auto": False},
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "manual_input"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
config_flow.CONF_NAME: NAME,
|
||||
config_flow.CONF_HOST: HOST,
|
||||
config_flow.CONF_PORT: PORT,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "auth"
|
||||
assert result["step_id"] == "configure"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.onvif.async_setup", return_value=True
|
||||
|
@ -399,6 +408,9 @@ async def test_flow_manual_entry(hass):
|
|||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
config_flow.CONF_NAME: NAME,
|
||||
config_flow.CONF_HOST: HOST,
|
||||
config_flow.CONF_PORT: PORT,
|
||||
config_flow.CONF_USERNAME: USERNAME,
|
||||
config_flow.CONF_PASSWORD: PASSWORD,
|
||||
},
|
||||
|
@ -598,7 +610,7 @@ async def test_flow_import_onvif_auth_error(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "auth"
|
||||
assert result["step_id"] == "configure"
|
||||
assert result["errors"]["base"] == "cannot_connect"
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue