Motion Blinds dhcp discovery (#68809)

Co-authored-by: J. Nick Koston <nick@koston.org>
pull/67672/head^2
starkillerOG 2022-03-29 01:01:17 +02:00 committed by GitHub
parent 8eb2e131e5
commit 98ca9754d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 3 deletions

View File

@ -5,9 +5,11 @@ from motionblinds import AsyncMotionMulticast, MotionDiscovery
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,
@ -72,6 +74,21 @@ class MotionBlindsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""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 = {}
@ -137,7 +154,7 @@ class MotionBlindsFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
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,

View File

@ -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"]

View File

@ -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",

View File

@ -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": {

View File

@ -55,6 +55,8 @@ DHCP: list[dict[str, str | bool]] = [
{'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*'},

View File

@ -5,6 +5,7 @@ from unittest.mock import Mock, patch
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
@ -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(