Skip to content

Commit

Permalink
Motion Blinds dhcp discovery (#68809)
Browse files Browse the repository at this point in the history
Co-authored-by: J. Nick Koston <nick@koston.org>
  • Loading branch information
starkillerOG and bdraco committed Mar 28, 2022
1 parent 8eb2e13 commit 98ca975
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 3 deletions.
21 changes: 19 additions & 2 deletions homeassistant/components/motion_blinds/config_flow.py
Expand Up @@ -5,9 +5,11 @@
import voluptuous as vol

from homeassistant import config_entries
from homeassistant.components import network
from homeassistant.components import dhcp, network
from homeassistant.const import CONF_API_KEY, CONF_HOST
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers.device_registry import format_mac

from .const import (
CONF_INTERFACE,
Expand Down Expand Up @@ -72,6 +74,21 @@ def async_get_options_flow(config_entry) -> OptionsFlowHandler:
"""Get the options flow."""
return OptionsFlowHandler(config_entry)

async def async_step_dhcp(self, discovery_info: dhcp.DhcpServiceInfo) -> FlowResult:
"""Handle discovery via dhcp."""
mac_address = format_mac(discovery_info.macaddress).replace(":", "")
await self.async_set_unique_id(mac_address)
self._abort_if_unique_id_configured(updates={CONF_HOST: discovery_info.ip})

short_mac = mac_address[-6:].upper()
self.context["title_placeholders"] = {
"short_mac": short_mac,
"ip_address": discovery_info.ip,
}

self._host = discovery_info.ip
return await self.async_step_connect()

async def async_step_user(self, user_input=None):
"""Handle a flow initialized by the user."""
errors = {}
Expand Down Expand Up @@ -137,7 +154,7 @@ async def async_step_connect(self, user_input=None):

mac_address = motion_gateway.mac

await self.async_set_unique_id(mac_address)
await self.async_set_unique_id(mac_address, raise_on_progress=False)
self._abort_if_unique_id_configured(
updates={
CONF_HOST: self._host,
Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/motion_blinds/manifest.json
Expand Up @@ -5,6 +5,12 @@
"documentation": "https://www.home-assistant.io/integrations/motion_blinds",
"requirements": ["motionblinds==0.6.2"],
"dependencies": ["network"],
"dhcp": [
{"registered_devices": true},
{
"hostname": "motion_*"
}
],
"codeowners": ["@starkillerOG"],
"iot_class": "local_push",
"loggers": ["motionblinds"]
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/motion_blinds/strings.json
@@ -1,5 +1,6 @@
{
"config": {
"flow_title": "{short_mac} ({ip_address})",
"step": {
"user": {
"description": "Connect to your Motion Gateway, if the IP address is not set, auto-discovery is used",
Expand Down
Expand Up @@ -9,7 +9,7 @@
"discovery_error": "Failed to discover a Motion Gateway",
"invalid_interface": "Invalid network interface"
},
"flow_title": "Motion Blinds",
"flow_title": "{short_mac} ({ip_address})",
"step": {
"connect": {
"data": {
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/generated/dhcp.py
Expand Up @@ -55,6 +55,8 @@
{'domain': 'lyric', 'hostname': 'lyric-*', 'macaddress': '48A2E6*'},
{'domain': 'lyric', 'hostname': 'lyric-*', 'macaddress': 'B82CA0*'},
{'domain': 'lyric', 'hostname': 'lyric-*', 'macaddress': '00D02D*'},
{'domain': 'motion_blinds', 'registered_devices': True},
{'domain': 'motion_blinds', 'hostname': 'motion_*'},
{'domain': 'myq', 'macaddress': '645299*'},
{'domain': 'nest', 'macaddress': '18B430*'},
{'domain': 'nest', 'macaddress': '641666*'},
Expand Down
31 changes: 31 additions & 0 deletions tests/components/motion_blinds/test_config_flow.py
Expand Up @@ -5,6 +5,7 @@
import pytest

from homeassistant import config_entries, data_entry_flow
from homeassistant.components import dhcp
from homeassistant.components.motion_blinds import const
from homeassistant.components.motion_blinds.config_flow import DEFAULT_GATEWAY_NAME
from homeassistant.const import CONF_API_KEY, CONF_HOST
Expand Down Expand Up @@ -337,6 +338,36 @@ async def test_config_flow_invalid_interface(hass):
assert result["errors"] == {const.CONF_INTERFACE: "invalid_interface"}


async def test_dhcp_flow(hass):
"""Successful flow from DHCP discovery."""
dhcp_data = dhcp.DhcpServiceInfo(
ip=TEST_HOST,
hostname="MOTION_abcdef",
macaddress=TEST_MAC,
)

result = await hass.config_entries.flow.async_init(
const.DOMAIN, context={"source": config_entries.SOURCE_DHCP}, data=dhcp_data
)

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},
)

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_options_flow(hass):
"""Test specifying non default settings using options flow."""
config_entry = MockConfigEntry(
Expand Down

0 comments on commit 98ca975

Please sign in to comment.