mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Ensure lutron caseta imports set the unique id (#66754)
This commit is contained in:
parent
90a0d5518d
commit
64277058b5
@ -1,4 +1,6 @@
|
|||||||
"""Config flow for Lutron Caseta."""
|
"""Config flow for Lutron Caseta."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@ -17,6 +19,7 @@ from homeassistant.data_entry_flow import FlowResult
|
|||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ABORT_REASON_CANNOT_CONNECT,
|
ABORT_REASON_CANNOT_CONNECT,
|
||||||
|
BRIDGE_DEVICE_ID,
|
||||||
BRIDGE_TIMEOUT,
|
BRIDGE_TIMEOUT,
|
||||||
CONF_CA_CERTS,
|
CONF_CA_CERTS,
|
||||||
CONF_CERTFILE,
|
CONF_CERTFILE,
|
||||||
@ -101,7 +104,7 @@ class LutronCasetaFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
if (
|
if (
|
||||||
not self.attempted_tls_validation
|
not self.attempted_tls_validation
|
||||||
and await self.hass.async_add_executor_job(self._tls_assets_exist)
|
and await self.hass.async_add_executor_job(self._tls_assets_exist)
|
||||||
and await self.async_validate_connectable_bridge_config()
|
and await self.async_get_lutron_id()
|
||||||
):
|
):
|
||||||
self.tls_assets_validated = True
|
self.tls_assets_validated = True
|
||||||
self.attempted_tls_validation = True
|
self.attempted_tls_validation = True
|
||||||
@ -177,7 +180,7 @@ class LutronCasetaFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
self.data[CONF_CERTFILE] = import_info[CONF_CERTFILE]
|
self.data[CONF_CERTFILE] = import_info[CONF_CERTFILE]
|
||||||
self.data[CONF_CA_CERTS] = import_info[CONF_CA_CERTS]
|
self.data[CONF_CA_CERTS] = import_info[CONF_CA_CERTS]
|
||||||
|
|
||||||
if not await self.async_validate_connectable_bridge_config():
|
if not (lutron_id := await self.async_get_lutron_id()):
|
||||||
# Ultimately we won't have a dedicated step for import failure, but
|
# Ultimately we won't have a dedicated step for import failure, but
|
||||||
# in order to keep configuration.yaml-based configs transparently
|
# in order to keep configuration.yaml-based configs transparently
|
||||||
# working without requiring further actions from the user, we don't
|
# working without requiring further actions from the user, we don't
|
||||||
@ -189,6 +192,8 @@ class LutronCasetaFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
# will require users to go through a confirmation flow for imports).
|
# will require users to go through a confirmation flow for imports).
|
||||||
return await self.async_step_import_failed()
|
return await self.async_step_import_failed()
|
||||||
|
|
||||||
|
await self.async_set_unique_id(lutron_id, raise_on_progress=False)
|
||||||
|
self._abort_if_unique_id_configured()
|
||||||
return self.async_create_entry(title=ENTRY_DEFAULT_TITLE, data=self.data)
|
return self.async_create_entry(title=ENTRY_DEFAULT_TITLE, data=self.data)
|
||||||
|
|
||||||
async def async_step_import_failed(self, user_input=None):
|
async def async_step_import_failed(self, user_input=None):
|
||||||
@ -204,10 +209,8 @@ class LutronCasetaFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
|
|
||||||
return self.async_abort(reason=ABORT_REASON_CANNOT_CONNECT)
|
return self.async_abort(reason=ABORT_REASON_CANNOT_CONNECT)
|
||||||
|
|
||||||
async def async_validate_connectable_bridge_config(self):
|
async def async_get_lutron_id(self) -> str | None:
|
||||||
"""Check if we can connect to the bridge with the current config."""
|
"""Check if we can connect to the bridge with the current config."""
|
||||||
bridge = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bridge = Smartbridge.create_tls(
|
bridge = Smartbridge.create_tls(
|
||||||
hostname=self.data[CONF_HOST],
|
hostname=self.data[CONF_HOST],
|
||||||
@ -220,18 +223,23 @@ class LutronCasetaFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
"Invalid certificate used to connect to bridge at %s",
|
"Invalid certificate used to connect to bridge at %s",
|
||||||
self.data[CONF_HOST],
|
self.data[CONF_HOST],
|
||||||
)
|
)
|
||||||
return False
|
return None
|
||||||
|
|
||||||
connected_ok = False
|
|
||||||
try:
|
try:
|
||||||
async with async_timeout.timeout(BRIDGE_TIMEOUT):
|
async with async_timeout.timeout(BRIDGE_TIMEOUT):
|
||||||
await bridge.connect()
|
await bridge.connect()
|
||||||
connected_ok = bridge.is_connected()
|
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Timeout while trying to connect to bridge at %s",
|
"Timeout while trying to connect to bridge at %s",
|
||||||
self.data[CONF_HOST],
|
self.data[CONF_HOST],
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
if not bridge.is_connected():
|
||||||
|
return None
|
||||||
|
devices = bridge.get_devices()
|
||||||
|
bridge_device = devices[BRIDGE_DEVICE_ID]
|
||||||
|
return hex(bridge_device["serial"])[2:].zfill(8)
|
||||||
|
finally:
|
||||||
await bridge.close()
|
await bridge.close()
|
||||||
return connected_ok
|
|
||||||
|
return None
|
||||||
|
@ -56,6 +56,10 @@ class MockBridge:
|
|||||||
"""Return whether the mock bridge is connected."""
|
"""Return whether the mock bridge is connected."""
|
||||||
return self.is_currently_connected
|
return self.is_currently_connected
|
||||||
|
|
||||||
|
def get_devices(self):
|
||||||
|
"""Return devices on the bridge."""
|
||||||
|
return {"1": {"serial": 1234}}
|
||||||
|
|
||||||
async def close(self):
|
async def close(self):
|
||||||
"""Close the mock bridge connection."""
|
"""Close the mock bridge connection."""
|
||||||
self.is_currently_connected = False
|
self.is_currently_connected = False
|
||||||
@ -90,6 +94,8 @@ async def test_bridge_import_flow(hass):
|
|||||||
assert result["type"] == "create_entry"
|
assert result["type"] == "create_entry"
|
||||||
assert result["title"] == CasetaConfigFlow.ENTRY_DEFAULT_TITLE
|
assert result["title"] == CasetaConfigFlow.ENTRY_DEFAULT_TITLE
|
||||||
assert result["data"] == entry_mock_data
|
assert result["data"] == entry_mock_data
|
||||||
|
assert result["result"].unique_id == "000004d2"
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user