mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 11:47:06 +00:00
Motion Blinds auto interface (#68852)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
c6e2bdcea0
commit
4dade9668a
@ -113,9 +113,22 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
|
|
||||||
entry.async_on_unload(entry.add_update_listener(update_listener))
|
entry.async_on_unload(entry.add_update_listener(update_listener))
|
||||||
|
|
||||||
|
# check multicast interface
|
||||||
|
check_multicast_class = ConnectMotionGateway(hass, interface=multicast_interface)
|
||||||
|
working_interface = await check_multicast_class.async_check_interface(host, key)
|
||||||
|
if working_interface != multicast_interface:
|
||||||
|
data = {**entry.data, CONF_INTERFACE: working_interface}
|
||||||
|
hass.config_entries.async_update_entry(entry, data=data)
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Motion Blinds interface updated from %s to %s, "
|
||||||
|
"this should only occur after a network change",
|
||||||
|
multicast_interface,
|
||||||
|
working_interface,
|
||||||
|
)
|
||||||
|
|
||||||
# Create multicast Listener
|
# Create multicast Listener
|
||||||
if KEY_MULTICAST_LISTENER not in hass.data[DOMAIN]:
|
if KEY_MULTICAST_LISTENER not in hass.data[DOMAIN]:
|
||||||
multicast = AsyncMotionMulticast(interface=multicast_interface)
|
multicast = AsyncMotionMulticast(interface=working_interface)
|
||||||
hass.data[DOMAIN][KEY_MULTICAST_LISTENER] = multicast
|
hass.data[DOMAIN][KEY_MULTICAST_LISTENER] = multicast
|
||||||
# start listening for local pushes (only once)
|
# start listening for local pushes (only once)
|
||||||
await multicast.Start_listen()
|
await multicast.Start_listen()
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
"""Config flow to configure Motion Blinds using their WLAN API."""
|
"""Config flow to configure Motion Blinds using their WLAN API."""
|
||||||
from socket import gaierror
|
from motionblinds import MotionDiscovery
|
||||||
|
|
||||||
from motionblinds import AsyncMotionMulticast, MotionDiscovery
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.components import dhcp, network
|
from homeassistant.components import dhcp
|
||||||
from homeassistant.const import CONF_API_KEY, CONF_HOST
|
from homeassistant.const import CONF_API_KEY, CONF_HOST
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
@ -131,27 +129,20 @@ class MotionBlindsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
errors = {}
|
errors = {}
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
key = user_input[CONF_API_KEY]
|
key = user_input[CONF_API_KEY]
|
||||||
multicast_interface = user_input[CONF_INTERFACE]
|
|
||||||
|
|
||||||
# check socket interface
|
connect_gateway_class = ConnectMotionGateway(self.hass)
|
||||||
if multicast_interface != DEFAULT_INTERFACE:
|
|
||||||
motion_multicast = AsyncMotionMulticast(interface=multicast_interface)
|
|
||||||
try:
|
|
||||||
await motion_multicast.Start_listen()
|
|
||||||
motion_multicast.Stop_listen()
|
|
||||||
except gaierror:
|
|
||||||
errors[CONF_INTERFACE] = "invalid_interface"
|
|
||||||
return self.async_show_form(
|
|
||||||
step_id="connect",
|
|
||||||
data_schema=self._config_settings,
|
|
||||||
errors=errors,
|
|
||||||
)
|
|
||||||
|
|
||||||
connect_gateway_class = ConnectMotionGateway(self.hass, multicast=None)
|
|
||||||
if not await connect_gateway_class.async_connect_gateway(self._host, key):
|
if not await connect_gateway_class.async_connect_gateway(self._host, key):
|
||||||
return self.async_abort(reason="connection_error")
|
return self.async_abort(reason="connection_error")
|
||||||
motion_gateway = connect_gateway_class.gateway_device
|
motion_gateway = connect_gateway_class.gateway_device
|
||||||
|
|
||||||
|
# check socket interface
|
||||||
|
check_multicast_class = ConnectMotionGateway(
|
||||||
|
self.hass, interface=DEFAULT_INTERFACE
|
||||||
|
)
|
||||||
|
multicast_interface = await check_multicast_class.async_check_interface(
|
||||||
|
self._host, key
|
||||||
|
)
|
||||||
|
|
||||||
mac_address = motion_gateway.mac
|
mac_address = motion_gateway.mac
|
||||||
|
|
||||||
await self.async_set_unique_id(mac_address, raise_on_progress=False)
|
await self.async_set_unique_id(mac_address, raise_on_progress=False)
|
||||||
@ -172,38 +163,12 @@ class MotionBlindsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
(interfaces, default_interface) = await self.async_get_interfaces()
|
|
||||||
|
|
||||||
self._config_settings = vol.Schema(
|
self._config_settings = vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Required(CONF_API_KEY): vol.All(str, vol.Length(min=16, max=16)),
|
vol.Required(CONF_API_KEY): vol.All(str, vol.Length(min=16, max=16)),
|
||||||
vol.Optional(CONF_INTERFACE, default=default_interface): vol.In(
|
|
||||||
interfaces
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id="connect", data_schema=self._config_settings, errors=errors
|
step_id="connect", data_schema=self._config_settings, errors=errors
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_get_interfaces(self):
|
|
||||||
"""Get list of interface to use."""
|
|
||||||
interfaces = [DEFAULT_INTERFACE, "0.0.0.0"]
|
|
||||||
enabled_interfaces = []
|
|
||||||
default_interface = DEFAULT_INTERFACE
|
|
||||||
|
|
||||||
adapters = await network.async_get_adapters(self.hass)
|
|
||||||
for adapter in adapters:
|
|
||||||
if ipv4s := adapter["ipv4"]:
|
|
||||||
ip4 = ipv4s[0]["address"]
|
|
||||||
interfaces.append(ip4)
|
|
||||||
if adapter["enabled"]:
|
|
||||||
enabled_interfaces.append(ip4)
|
|
||||||
if adapter["default"]:
|
|
||||||
default_interface = ip4
|
|
||||||
|
|
||||||
if len(enabled_interfaces) == 1:
|
|
||||||
default_interface = enabled_interfaces[0]
|
|
||||||
|
|
||||||
return (interfaces, default_interface)
|
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
"""Code to handle a Motion Gateway."""
|
"""Code to handle a Motion Gateway."""
|
||||||
|
import contextlib
|
||||||
import logging
|
import logging
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
from motionblinds import MotionGateway
|
from motionblinds import AsyncMotionMulticast, MotionGateway
|
||||||
|
|
||||||
|
from homeassistant.components import network
|
||||||
|
|
||||||
|
from .const import DEFAULT_INTERFACE
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -10,11 +15,12 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
class ConnectMotionGateway:
|
class ConnectMotionGateway:
|
||||||
"""Class to async connect to a Motion Gateway."""
|
"""Class to async connect to a Motion Gateway."""
|
||||||
|
|
||||||
def __init__(self, hass, multicast):
|
def __init__(self, hass, multicast=None, interface=None):
|
||||||
"""Initialize the entity."""
|
"""Initialize the entity."""
|
||||||
self._hass = hass
|
self._hass = hass
|
||||||
self._multicast = multicast
|
self._multicast = multicast
|
||||||
self._gateway_device = None
|
self._gateway_device = None
|
||||||
|
self._interface = interface
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gateway_device(self):
|
def gateway_device(self):
|
||||||
@ -48,3 +54,78 @@ class ConnectMotionGateway:
|
|||||||
self.gateway_device.protocol,
|
self.gateway_device.protocol,
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def check_interface(self):
|
||||||
|
"""Check if the current interface supports multicast."""
|
||||||
|
with contextlib.suppress(socket.timeout):
|
||||||
|
return self.gateway_device.Check_gateway_multicast()
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def async_get_interfaces(self):
|
||||||
|
"""Get list of interface to use."""
|
||||||
|
interfaces = [DEFAULT_INTERFACE, "0.0.0.0"]
|
||||||
|
enabled_interfaces = []
|
||||||
|
default_interface = DEFAULT_INTERFACE
|
||||||
|
|
||||||
|
adapters = await network.async_get_adapters(self._hass)
|
||||||
|
for adapter in adapters:
|
||||||
|
if ipv4s := adapter["ipv4"]:
|
||||||
|
ip4 = ipv4s[0]["address"]
|
||||||
|
interfaces.append(ip4)
|
||||||
|
if adapter["enabled"]:
|
||||||
|
enabled_interfaces.append(ip4)
|
||||||
|
if adapter["default"]:
|
||||||
|
default_interface = ip4
|
||||||
|
|
||||||
|
if len(enabled_interfaces) == 1:
|
||||||
|
default_interface = enabled_interfaces[0]
|
||||||
|
interfaces.remove(default_interface)
|
||||||
|
interfaces.insert(0, default_interface)
|
||||||
|
|
||||||
|
if self._interface is not None:
|
||||||
|
interfaces.remove(self._interface)
|
||||||
|
interfaces.insert(0, self._interface)
|
||||||
|
|
||||||
|
return interfaces
|
||||||
|
|
||||||
|
async def async_check_interface(self, host, key):
|
||||||
|
"""Connect to the Motion Gateway."""
|
||||||
|
interfaces = await self.async_get_interfaces()
|
||||||
|
for interface in interfaces:
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Checking Motion Blinds interface '%s' with host %s", interface, host
|
||||||
|
)
|
||||||
|
# initialize multicast listener
|
||||||
|
check_multicast = AsyncMotionMulticast(interface=interface)
|
||||||
|
try:
|
||||||
|
await check_multicast.Start_listen()
|
||||||
|
except socket.gaierror:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# trigger test multicast
|
||||||
|
self._gateway_device = MotionGateway(
|
||||||
|
ip=host, key=key, multicast=check_multicast
|
||||||
|
)
|
||||||
|
result = await self._hass.async_add_executor_job(self.check_interface)
|
||||||
|
|
||||||
|
# close multicast listener again
|
||||||
|
try:
|
||||||
|
check_multicast.Stop_listen()
|
||||||
|
except socket.gaierror:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if result:
|
||||||
|
# successfully received multicast
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Success using Motion Blinds interface '%s' with host %s",
|
||||||
|
interface,
|
||||||
|
host,
|
||||||
|
)
|
||||||
|
return interface
|
||||||
|
|
||||||
|
_LOGGER.error(
|
||||||
|
"Could not find working interface for Motion Blinds host %s, using interface '%s'",
|
||||||
|
host,
|
||||||
|
self._interface,
|
||||||
|
)
|
||||||
|
return self._interface
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Motion Blinds",
|
"name": "Motion Blinds",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/motion_blinds",
|
"documentation": "https://www.home-assistant.io/integrations/motion_blinds",
|
||||||
"requirements": ["motionblinds==0.6.2"],
|
"requirements": ["motionblinds==0.6.4"],
|
||||||
"dependencies": ["network"],
|
"dependencies": ["network"],
|
||||||
"dhcp": [
|
"dhcp": [
|
||||||
{ "registered_devices": true },
|
{ "registered_devices": true },
|
||||||
|
@ -11,8 +11,7 @@
|
|||||||
"connect": {
|
"connect": {
|
||||||
"description": "You will need the 16 character API Key, see https://www.home-assistant.io/integrations/motion_blinds/#retrieving-the-key for instructions",
|
"description": "You will need the 16 character API Key, see https://www.home-assistant.io/integrations/motion_blinds/#retrieving-the-key for instructions",
|
||||||
"data": {
|
"data": {
|
||||||
"api_key": "[%key:common::config_flow::data::api_key%]",
|
"api_key": "[%key:common::config_flow::data::api_key%]"
|
||||||
"interface": "The network interface to use"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"select": {
|
"select": {
|
||||||
@ -24,8 +23,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"discovery_error": "Failed to discover a Motion Gateway",
|
"discovery_error": "Failed to discover a Motion Gateway"
|
||||||
"invalid_interface": "Invalid network interface"
|
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%], connection settings are updated",
|
"already_configured": "[%key:common::config_flow::abort::already_configured_device%], connection settings are updated",
|
||||||
|
@ -6,15 +6,13 @@
|
|||||||
"connection_error": "Failed to connect"
|
"connection_error": "Failed to connect"
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"discovery_error": "Failed to discover a Motion Gateway",
|
"discovery_error": "Failed to discover a Motion Gateway"
|
||||||
"invalid_interface": "Invalid network interface"
|
|
||||||
},
|
},
|
||||||
"flow_title": "{short_mac} ({ip_address})",
|
"flow_title": "{short_mac} ({ip_address})",
|
||||||
"step": {
|
"step": {
|
||||||
"connect": {
|
"connect": {
|
||||||
"data": {
|
"data": {
|
||||||
"api_key": "API Key",
|
"api_key": "API Key"
|
||||||
"interface": "The network interface to use"
|
|
||||||
},
|
},
|
||||||
"description": "You will need the 16 character API Key, see https://www.home-assistant.io/integrations/motion_blinds/#retrieving-the-key for instructions",
|
"description": "You will need the 16 character API Key, see https://www.home-assistant.io/integrations/motion_blinds/#retrieving-the-key for instructions",
|
||||||
"title": "Motion Blinds"
|
"title": "Motion Blinds"
|
||||||
|
@ -1020,7 +1020,7 @@ mitemp_bt==0.0.5
|
|||||||
moehlenhoff-alpha2==1.1.2
|
moehlenhoff-alpha2==1.1.2
|
||||||
|
|
||||||
# homeassistant.components.motion_blinds
|
# homeassistant.components.motion_blinds
|
||||||
motionblinds==0.6.2
|
motionblinds==0.6.4
|
||||||
|
|
||||||
# homeassistant.components.motioneye
|
# homeassistant.components.motioneye
|
||||||
motioneye-client==0.3.12
|
motioneye-client==0.3.12
|
||||||
|
@ -688,7 +688,7 @@ minio==5.0.10
|
|||||||
moehlenhoff-alpha2==1.1.2
|
moehlenhoff-alpha2==1.1.2
|
||||||
|
|
||||||
# homeassistant.components.motion_blinds
|
# homeassistant.components.motion_blinds
|
||||||
motionblinds==0.6.2
|
motionblinds==0.6.4
|
||||||
|
|
||||||
# homeassistant.components.motioneye
|
# homeassistant.components.motioneye
|
||||||
motioneye-client==0.3.12
|
motioneye-client==0.3.12
|
||||||
|
@ -76,6 +76,9 @@ def motion_blinds_connect_fixture(mock_get_source_ip):
|
|||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.motion_blinds.gateway.MotionGateway.Update",
|
"homeassistant.components.motion_blinds.gateway.MotionGateway.Update",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.motion_blinds.gateway.MotionGateway.Check_gateway_multicast",
|
||||||
|
return_value=True,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.motion_blinds.gateway.MotionGateway.device_list",
|
"homeassistant.components.motion_blinds.gateway.MotionGateway.device_list",
|
||||||
TEST_DEVICE_LIST,
|
TEST_DEVICE_LIST,
|
||||||
@ -86,13 +89,13 @@ def motion_blinds_connect_fixture(mock_get_source_ip):
|
|||||||
"homeassistant.components.motion_blinds.config_flow.MotionDiscovery.discover",
|
"homeassistant.components.motion_blinds.config_flow.MotionDiscovery.discover",
|
||||||
return_value=TEST_DISCOVERY_1,
|
return_value=TEST_DISCOVERY_1,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.motion_blinds.config_flow.AsyncMotionMulticast.Start_listen",
|
"homeassistant.components.motion_blinds.gateway.AsyncMotionMulticast.Start_listen",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.motion_blinds.config_flow.AsyncMotionMulticast.Stop_listen",
|
"homeassistant.components.motion_blinds.gateway.AsyncMotionMulticast.Stop_listen",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.motion_blinds.config_flow.network.async_get_adapters",
|
"homeassistant.components.motion_blinds.gateway.network.async_get_adapters",
|
||||||
return_value=TEST_INTERFACES,
|
return_value=TEST_INTERFACES,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.motion_blinds.async_setup_entry", return_value=True
|
"homeassistant.components.motion_blinds.async_setup_entry", return_value=True
|
||||||
@ -129,7 +132,7 @@ async def test_config_flow_manual_host_success(hass):
|
|||||||
assert result["data"] == {
|
assert result["data"] == {
|
||||||
CONF_HOST: TEST_HOST,
|
CONF_HOST: TEST_HOST,
|
||||||
CONF_API_KEY: TEST_API_KEY,
|
CONF_API_KEY: TEST_API_KEY,
|
||||||
const.CONF_INTERFACE: TEST_HOST_HA,
|
const.CONF_INTERFACE: TEST_HOST_ANY,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -152,17 +155,21 @@ async def test_config_flow_discovery_1_success(hass):
|
|||||||
assert result["step_id"] == "connect"
|
assert result["step_id"] == "connect"
|
||||||
assert result["errors"] == {}
|
assert result["errors"] == {}
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
with patch(
|
||||||
result["flow_id"],
|
"homeassistant.components.motion_blinds.gateway.AsyncMotionMulticast.Stop_listen",
|
||||||
{CONF_API_KEY: TEST_API_KEY},
|
side_effect=socket.gaierror,
|
||||||
)
|
):
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{CONF_API_KEY: TEST_API_KEY},
|
||||||
|
)
|
||||||
|
|
||||||
assert result["type"] == "create_entry"
|
assert result["type"] == "create_entry"
|
||||||
assert result["title"] == DEFAULT_GATEWAY_NAME
|
assert result["title"] == DEFAULT_GATEWAY_NAME
|
||||||
assert result["data"] == {
|
assert result["data"] == {
|
||||||
CONF_HOST: TEST_HOST,
|
CONF_HOST: TEST_HOST,
|
||||||
CONF_API_KEY: TEST_API_KEY,
|
CONF_API_KEY: TEST_API_KEY,
|
||||||
const.CONF_INTERFACE: TEST_HOST_HA,
|
const.CONF_INTERFACE: TEST_HOST_ANY,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -202,17 +209,21 @@ async def test_config_flow_discovery_2_success(hass):
|
|||||||
assert result["step_id"] == "connect"
|
assert result["step_id"] == "connect"
|
||||||
assert result["errors"] == {}
|
assert result["errors"] == {}
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
with patch(
|
||||||
result["flow_id"],
|
"homeassistant.components.motion_blinds.gateway.MotionGateway.Check_gateway_multicast",
|
||||||
{CONF_API_KEY: TEST_API_KEY},
|
side_effect=socket.timeout,
|
||||||
)
|
):
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{CONF_API_KEY: TEST_API_KEY},
|
||||||
|
)
|
||||||
|
|
||||||
assert result["type"] == "create_entry"
|
assert result["type"] == "create_entry"
|
||||||
assert result["title"] == DEFAULT_GATEWAY_NAME
|
assert result["title"] == DEFAULT_GATEWAY_NAME
|
||||||
assert result["data"] == {
|
assert result["data"] == {
|
||||||
CONF_HOST: TEST_HOST2,
|
CONF_HOST: TEST_HOST2,
|
||||||
CONF_API_KEY: TEST_API_KEY,
|
CONF_API_KEY: TEST_API_KEY,
|
||||||
const.CONF_INTERFACE: TEST_HOST_HA,
|
const.CONF_INTERFACE: TEST_HOST_ANY,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -272,39 +283,6 @@ async def test_config_flow_discovery_fail(hass):
|
|||||||
assert result["errors"] == {"base": "discovery_error"}
|
assert result["errors"] == {"base": "discovery_error"}
|
||||||
|
|
||||||
|
|
||||||
async def test_config_flow_interface(hass):
|
|
||||||
"""Successful flow manually initialized by the user with interface specified."""
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
const.DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == "form"
|
|
||||||
assert result["step_id"] == "user"
|
|
||||||
assert result["errors"] == {}
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
|
||||||
result["flow_id"],
|
|
||||||
{CONF_HOST: TEST_HOST},
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == "form"
|
|
||||||
assert result["step_id"] == "connect"
|
|
||||||
assert result["errors"] == {}
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
|
||||||
result["flow_id"],
|
|
||||||
{CONF_API_KEY: TEST_API_KEY, const.CONF_INTERFACE: TEST_HOST_HA},
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == "create_entry"
|
|
||||||
assert result["title"] == DEFAULT_GATEWAY_NAME
|
|
||||||
assert result["data"] == {
|
|
||||||
CONF_HOST: TEST_HOST,
|
|
||||||
CONF_API_KEY: TEST_API_KEY,
|
|
||||||
const.CONF_INTERFACE: TEST_HOST_HA,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async def test_config_flow_invalid_interface(hass):
|
async def test_config_flow_invalid_interface(hass):
|
||||||
"""Failed flow manually initialized by the user with invalid interface."""
|
"""Failed flow manually initialized by the user with invalid interface."""
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
@ -325,17 +303,21 @@ async def test_config_flow_invalid_interface(hass):
|
|||||||
assert result["errors"] == {}
|
assert result["errors"] == {}
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.motion_blinds.config_flow.AsyncMotionMulticast.Start_listen",
|
"homeassistant.components.motion_blinds.gateway.AsyncMotionMulticast.Start_listen",
|
||||||
side_effect=socket.gaierror,
|
side_effect=socket.gaierror,
|
||||||
):
|
):
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
{CONF_API_KEY: TEST_API_KEY, const.CONF_INTERFACE: TEST_HOST_HA},
|
{CONF_API_KEY: TEST_API_KEY},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == "form"
|
assert result["type"] == "create_entry"
|
||||||
assert result["step_id"] == "connect"
|
assert result["title"] == DEFAULT_GATEWAY_NAME
|
||||||
assert result["errors"] == {const.CONF_INTERFACE: "invalid_interface"}
|
assert result["data"] == {
|
||||||
|
CONF_HOST: TEST_HOST,
|
||||||
|
CONF_API_KEY: TEST_API_KEY,
|
||||||
|
const.CONF_INTERFACE: TEST_HOST_ANY,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_dhcp_flow(hass):
|
async def test_dhcp_flow(hass):
|
||||||
@ -364,7 +346,7 @@ async def test_dhcp_flow(hass):
|
|||||||
assert result["data"] == {
|
assert result["data"] == {
|
||||||
CONF_HOST: TEST_HOST,
|
CONF_HOST: TEST_HOST,
|
||||||
CONF_API_KEY: TEST_API_KEY,
|
CONF_API_KEY: TEST_API_KEY,
|
||||||
const.CONF_INTERFACE: TEST_HOST_HA,
|
const.CONF_INTERFACE: TEST_HOST_ANY,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -433,7 +415,7 @@ async def test_change_connection_settings(hass):
|
|||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
{CONF_API_KEY: TEST_API_KEY2, const.CONF_INTERFACE: TEST_HOST_ANY},
|
{CONF_API_KEY: TEST_API_KEY2},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == "abort"
|
assert result["type"] == "abort"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user