Handle unique WLED device using zeroconf properties (#32897)
parent
c1ceab09e5
commit
4517f0d59a
|
@ -44,7 +44,12 @@ class WLEDFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||||
|
|
||||||
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
|
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
|
||||||
self.context.update(
|
self.context.update(
|
||||||
{CONF_HOST: host, CONF_NAME: name, "title_placeholders": {"name": name}}
|
{
|
||||||
|
CONF_HOST: host,
|
||||||
|
CONF_NAME: name,
|
||||||
|
CONF_MAC: user_input["properties"].get(CONF_MAC),
|
||||||
|
"title_placeholders": {"name": name},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Prepare configuration flow
|
# Prepare configuration flow
|
||||||
|
@ -72,23 +77,22 @@ class WLEDFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||||
if source == SOURCE_ZEROCONF:
|
if source == SOURCE_ZEROCONF:
|
||||||
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
|
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
|
||||||
user_input[CONF_HOST] = self.context.get(CONF_HOST)
|
user_input[CONF_HOST] = self.context.get(CONF_HOST)
|
||||||
|
user_input[CONF_MAC] = self.context.get(CONF_MAC)
|
||||||
|
|
||||||
errors = {}
|
if user_input.get(CONF_MAC) is None or not prepare:
|
||||||
session = async_get_clientsession(self.hass)
|
session = async_get_clientsession(self.hass)
|
||||||
wled = WLED(user_input[CONF_HOST], session=session)
|
wled = WLED(user_input[CONF_HOST], session=session)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
device = await wled.update()
|
device = await wled.update()
|
||||||
except WLEDConnectionError:
|
except WLEDConnectionError:
|
||||||
if source == SOURCE_ZEROCONF:
|
if source == SOURCE_ZEROCONF:
|
||||||
return self.async_abort(reason="connection_error")
|
return self.async_abort(reason="connection_error")
|
||||||
errors["base"] = "connection_error"
|
return self._show_setup_form({"base": "connection_error"})
|
||||||
return self._show_setup_form(errors)
|
user_input[CONF_MAC] = device.info.mac_address
|
||||||
|
|
||||||
# Check if already configured
|
# Check if already configured
|
||||||
mac_address = device.info.mac_address
|
await self.async_set_unique_id(user_input[CONF_MAC])
|
||||||
await self.async_set_unique_id(device.info.mac_address)
|
self._abort_if_unique_id_configured(updates={CONF_HOST: user_input[CONF_HOST]})
|
||||||
self._abort_if_unique_id_configured()
|
|
||||||
|
|
||||||
title = user_input[CONF_HOST]
|
title = user_input[CONF_HOST]
|
||||||
if source == SOURCE_ZEROCONF:
|
if source == SOURCE_ZEROCONF:
|
||||||
|
@ -99,7 +103,8 @@ class WLEDFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||||
return await self.async_step_zeroconf_confirm()
|
return await self.async_step_zeroconf_confirm()
|
||||||
|
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
title=title, data={CONF_HOST: user_input[CONF_HOST], CONF_MAC: mac_address}
|
title=title,
|
||||||
|
data={CONF_HOST: user_input[CONF_HOST], CONF_MAC: user_input[CONF_MAC]},
|
||||||
)
|
)
|
||||||
|
|
||||||
def _show_setup_form(self, errors: Optional[Dict] = None) -> Dict[str, Any]:
|
def _show_setup_form(self, errors: Optional[Dict] = None) -> Dict[str, Any]:
|
||||||
|
|
|
@ -48,7 +48,9 @@ async def test_show_zerconf_form(
|
||||||
flow = config_flow.WLEDFlowHandler()
|
flow = config_flow.WLEDFlowHandler()
|
||||||
flow.hass = hass
|
flow.hass = hass
|
||||||
flow.context = {"source": SOURCE_ZEROCONF}
|
flow.context = {"source": SOURCE_ZEROCONF}
|
||||||
result = await flow.async_step_zeroconf({"hostname": "example.local."})
|
result = await flow.async_step_zeroconf(
|
||||||
|
{"hostname": "example.local.", "properties": {}}
|
||||||
|
)
|
||||||
|
|
||||||
assert flow.context[CONF_HOST] == "example.local"
|
assert flow.context[CONF_HOST] == "example.local"
|
||||||
assert flow.context[CONF_NAME] == "example"
|
assert flow.context[CONF_NAME] == "example"
|
||||||
|
@ -83,7 +85,7 @@ async def test_zeroconf_connection_error(
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
config_flow.DOMAIN,
|
config_flow.DOMAIN,
|
||||||
context={"source": SOURCE_ZEROCONF},
|
context={"source": SOURCE_ZEROCONF},
|
||||||
data={"hostname": "example.local."},
|
data={"hostname": "example.local.", "properties": {}},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["reason"] == "connection_error"
|
assert result["reason"] == "connection_error"
|
||||||
|
@ -103,7 +105,7 @@ async def test_zeroconf_confirm_connection_error(
|
||||||
CONF_HOST: "example.com",
|
CONF_HOST: "example.com",
|
||||||
CONF_NAME: "test",
|
CONF_NAME: "test",
|
||||||
},
|
},
|
||||||
data={"hostname": "example.com."},
|
data={"hostname": "example.com.", "properties": {}},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["reason"] == "connection_error"
|
assert result["reason"] == "connection_error"
|
||||||
|
@ -147,7 +149,23 @@ async def test_zeroconf_device_exists_abort(
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
config_flow.DOMAIN,
|
config_flow.DOMAIN,
|
||||||
context={"source": SOURCE_ZEROCONF},
|
context={"source": SOURCE_ZEROCONF},
|
||||||
data={"hostname": "example.local."},
|
data={"hostname": "example.local.", "properties": {}},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_zeroconf_with_mac_device_exists_abort(
|
||||||
|
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
||||||
|
) -> None:
|
||||||
|
"""Test we abort zeroconf flow if WLED device already configured."""
|
||||||
|
await init_integration(hass, aioclient_mock)
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
config_flow.DOMAIN,
|
||||||
|
context={"source": SOURCE_ZEROCONF},
|
||||||
|
data={"hostname": "example.local.", "properties": {CONF_MAC: "aabbccddeeff"}},
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
|
@ -194,7 +212,9 @@ async def test_full_zeroconf_flow_implementation(
|
||||||
flow = config_flow.WLEDFlowHandler()
|
flow = config_flow.WLEDFlowHandler()
|
||||||
flow.hass = hass
|
flow.hass = hass
|
||||||
flow.context = {"source": SOURCE_ZEROCONF}
|
flow.context = {"source": SOURCE_ZEROCONF}
|
||||||
result = await flow.async_step_zeroconf({"hostname": "example.local."})
|
result = await flow.async_step_zeroconf(
|
||||||
|
{"hostname": "example.local.", "properties": {}}
|
||||||
|
)
|
||||||
|
|
||||||
assert flow.context[CONF_HOST] == "example.local"
|
assert flow.context[CONF_HOST] == "example.local"
|
||||||
assert flow.context[CONF_NAME] == "example"
|
assert flow.context[CONF_NAME] == "example"
|
||||||
|
|
Loading…
Reference in New Issue