Add HomeKit discovery for iSmartGate (#39702)

This commit is contained in:
J. Nick Koston 2020-09-06 12:56:38 -05:00 committed by GitHub
parent f29154011e
commit d7e471e244
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 112 additions and 5 deletions

View File

@ -29,12 +29,32 @@ class Gogogate2FlowHandler(ConfigFlow, domain=DOMAIN):
VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL
def __init__(self):
"""Initialize the config flow."""
self._ip_address = None
self._device_type = None
async def async_step_import(self, config_data: dict = None):
"""Handle importing of configuration."""
result = await self.async_step_user(config_data)
self._abort_if_unique_id_configured()
return result
async def async_step_homekit(self, discovery_info):
"""Handle homekit discovery."""
await self.async_set_unique_id(discovery_info["properties"]["id"])
self._abort_if_unique_id_configured({CONF_IP_ADDRESS: discovery_info["host"]})
ip_address = discovery_info["host"]
for entry in self._async_current_entries():
if entry.data.get(CONF_IP_ADDRESS) == ip_address:
return self.async_abort(reason="already_configured")
self._ip_address = ip_address
self._device_type = DEVICE_TYPE_ISMARTGATE
return await self.async_step_user()
async def async_step_user(self, user_input: dict = None):
"""Handle user initiated flow."""
user_input = user_input or {}
@ -88,10 +108,12 @@ class Gogogate2FlowHandler(ConfigFlow, domain=DOMAIN):
{
vol.Required(
CONF_DEVICE,
default=user_input.get(CONF_DEVICE, DEVICE_TYPE_GOGOGATE2),
default=self._device_type
or user_input.get(CONF_DEVICE, DEVICE_TYPE_GOGOGATE2),
): vol.In((DEVICE_TYPE_GOGOGATE2, DEVICE_TYPE_ISMARTGATE)),
vol.Required(
CONF_IP_ADDRESS, default=user_input.get(CONF_IP_ADDRESS, "")
CONF_IP_ADDRESS,
default=user_input.get(CONF_IP_ADDRESS, self._ip_address),
): str,
vol.Required(
CONF_USERNAME, default=user_input.get(CONF_USERNAME, "")

View File

@ -4,5 +4,10 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/gogogate2",
"requirements": ["gogogate2-api==2.0.0"],
"codeowners": ["@vangorra"]
"codeowners": ["@vangorra"],
"homekit": {
"models": [
"iSmartGate"
]
}
}

View File

@ -92,5 +92,6 @@ HOMEKIT = {
"TRADFRI": "tradfri",
"Welcome": "netatmo",
"Wemo": "wemo",
"iSmartGate": "gogogate2",
"tado": "tado"
}

View File

@ -3,7 +3,12 @@ from gogogate2_api import GogoGate2Api
from gogogate2_api.common import ApiError
from gogogate2_api.const import GogoGate2ApiErrorCode
from homeassistant.components.gogogate2.const import DEVICE_TYPE_GOGOGATE2
from homeassistant import config_entries, setup
from homeassistant.components.gogogate2.const import (
DEVICE_TYPE_GOGOGATE2,
DEVICE_TYPE_ISMARTGATE,
DOMAIN,
)
from homeassistant.config_entries import SOURCE_USER
from homeassistant.const import (
CONF_DEVICE,
@ -12,9 +17,12 @@ from homeassistant.const import (
CONF_USERNAME,
)
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import RESULT_TYPE_FORM
from homeassistant.data_entry_flow import RESULT_TYPE_ABORT, RESULT_TYPE_FORM
from tests.async_mock import MagicMock, patch
from tests.common import MockConfigEntry
MOCK_MAC_ADDR = "AA:BB:CC:DD:EE:FF"
@patch("homeassistant.components.gogogate2.async_setup", return_value=True)
@ -64,3 +72,74 @@ async def test_auth_fail(
assert result
assert result["type"] == RESULT_TYPE_FORM
assert result["errors"] == {"base": "cannot_connect"}
async def test_form_homekit_unique_id_already_setup(hass):
"""Test that we abort from homekit if gogogate2 is already setup."""
await setup.async_setup_component(hass, "persistent_notification", {})
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_HOMEKIT},
data={"host": "1.2.3.4", "properties": {"id": MOCK_MAC_ADDR}},
)
assert result["type"] == RESULT_TYPE_FORM
assert result["errors"] == {}
flow = next(
flow
for flow in hass.config_entries.flow.async_progress()
if flow["flow_id"] == result["flow_id"]
)
assert flow["context"]["unique_id"] == MOCK_MAC_ADDR
entry = MockConfigEntry(
domain=DOMAIN,
data={CONF_IP_ADDRESS: "1.2.3.4", CONF_USERNAME: "mock", CONF_PASSWORD: "mock"},
)
entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_HOMEKIT},
data={"host": "1.2.3.4", "properties": {"id": MOCK_MAC_ADDR}},
)
assert result["type"] == RESULT_TYPE_ABORT
async def test_form_homekit_ip_address_already_setup(hass):
"""Test that we abort from homekit if gogogate2 is already setup."""
await setup.async_setup_component(hass, "persistent_notification", {})
entry = MockConfigEntry(
domain=DOMAIN,
data={CONF_IP_ADDRESS: "1.2.3.4", CONF_USERNAME: "mock", CONF_PASSWORD: "mock"},
)
entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_HOMEKIT},
data={"host": "1.2.3.4", "properties": {"id": MOCK_MAC_ADDR}},
)
assert result["type"] == RESULT_TYPE_ABORT
async def test_form_homekit_ip_address(hass):
"""Test homekit includes the defaults ip address."""
await setup.async_setup_component(hass, "persistent_notification", {})
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_HOMEKIT},
data={"host": "1.2.3.4", "properties": {"id": MOCK_MAC_ADDR}},
)
assert result["type"] == RESULT_TYPE_FORM
assert result["errors"] == {}
data_schema = result["data_schema"]
assert data_schema({CONF_USERNAME: "username", CONF_PASSWORD: "password"}) == {
CONF_DEVICE: DEVICE_TYPE_ISMARTGATE,
CONF_IP_ADDRESS: "1.2.3.4",
CONF_PASSWORD: "password",
CONF_USERNAME: "username",
}