Dynalite listener for config entry update (#32116)
* added entry listener that reloads the component * fixed update with existing entry * fixed import in test * fixes * library version * removed unique_id * fix * fixed for no entries in hass.data * fixed return value on abort * moved to use async_entries * removed unused importpull/32368/head
parent
b9fa32444a
commit
02c170b961
|
@ -108,22 +108,28 @@ async def async_setup(hass, config):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def async_entry_changed(hass, entry):
|
||||||
|
"""Reload entry since the data has changed."""
|
||||||
|
LOGGER.debug("Reconfiguring entry %s", entry.data)
|
||||||
|
bridge = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
await bridge.reload_config(entry.data)
|
||||||
|
LOGGER.debug("Reconfiguring entry finished %s", entry.data)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass, entry):
|
async def async_setup_entry(hass, entry):
|
||||||
"""Set up a bridge from a config entry."""
|
"""Set up a bridge from a config entry."""
|
||||||
LOGGER.debug("Setting up entry %s", entry.data)
|
LOGGER.debug("Setting up entry %s", entry.data)
|
||||||
|
|
||||||
bridge = DynaliteBridge(hass, entry.data)
|
bridge = DynaliteBridge(hass, entry.data)
|
||||||
|
hass.data[DOMAIN][entry.entry_id] = bridge
|
||||||
|
entry.add_update_listener(async_entry_changed)
|
||||||
if not await bridge.async_setup():
|
if not await bridge.async_setup():
|
||||||
LOGGER.error("Could not set up bridge for entry %s", entry.data)
|
LOGGER.error("Could not set up bridge for entry %s", entry.data)
|
||||||
|
hass.data[DOMAIN].pop(entry.entry_id)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not await bridge.try_connection():
|
if not await bridge.try_connection():
|
||||||
LOGGER.errot("Could not connect with entry %s", entry)
|
LOGGER.error("Could not connect with entry %s", entry)
|
||||||
|
hass.data[DOMAIN].pop(entry.entry_id)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady
|
||||||
|
|
||||||
hass.data[DOMAIN][entry.entry_id] = bridge
|
|
||||||
|
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
hass.config_entries.async_forward_entry_setup(entry, "light")
|
hass.config_entries.async_forward_entry_setup(entry, "light")
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,16 +25,22 @@ class DynaliteBridge:
|
||||||
self.host = config[CONF_HOST]
|
self.host = config[CONF_HOST]
|
||||||
# Configure the dynalite devices
|
# Configure the dynalite devices
|
||||||
self.dynalite_devices = DynaliteDevices(
|
self.dynalite_devices = DynaliteDevices(
|
||||||
config=config,
|
|
||||||
newDeviceFunc=self.add_devices_when_registered,
|
newDeviceFunc=self.add_devices_when_registered,
|
||||||
updateDeviceFunc=self.update_device,
|
updateDeviceFunc=self.update_device,
|
||||||
)
|
)
|
||||||
|
self.dynalite_devices.configure(config)
|
||||||
|
|
||||||
async def async_setup(self):
|
async def async_setup(self):
|
||||||
"""Set up a Dynalite bridge."""
|
"""Set up a Dynalite bridge."""
|
||||||
# Configure the dynalite devices
|
# Configure the dynalite devices
|
||||||
|
LOGGER.debug("Setting up bridge - host %s", self.host)
|
||||||
return await self.dynalite_devices.async_setup()
|
return await self.dynalite_devices.async_setup()
|
||||||
|
|
||||||
|
async def reload_config(self, config):
|
||||||
|
"""Reconfigure a bridge when config changes."""
|
||||||
|
LOGGER.debug("Setting up bridge - host %s, config %s", self.host, config)
|
||||||
|
self.dynalite_devices.configure(config)
|
||||||
|
|
||||||
def update_signal(self, device=None):
|
def update_signal(self, device=None):
|
||||||
"""Create signal to use to trigger entity update."""
|
"""Create signal to use to trigger entity update."""
|
||||||
if device:
|
if device:
|
||||||
|
|
|
@ -22,8 +22,11 @@ class DynaliteFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
"""Import a new bridge as a config entry."""
|
"""Import a new bridge as a config entry."""
|
||||||
LOGGER.debug("Starting async_step_import - %s", import_info)
|
LOGGER.debug("Starting async_step_import - %s", import_info)
|
||||||
host = import_info[CONF_HOST]
|
host = import_info[CONF_HOST]
|
||||||
await self.async_set_unique_id(host)
|
for entry in self.hass.config_entries.async_entries(DOMAIN):
|
||||||
self._abort_if_unique_id_configured(import_info)
|
if entry.data[CONF_HOST] == host:
|
||||||
|
if entry.data != import_info:
|
||||||
|
self.hass.config_entries.async_update_entry(entry, data=import_info)
|
||||||
|
return self.async_abort(reason="already_configured")
|
||||||
# New entry
|
# New entry
|
||||||
bridge = DynaliteBridge(self.hass, import_info)
|
bridge = DynaliteBridge(self.hass, import_info)
|
||||||
if not await bridge.async_setup():
|
if not await bridge.async_setup():
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
"documentation": "https://www.home-assistant.io/integrations/dynalite",
|
"documentation": "https://www.home-assistant.io/integrations/dynalite",
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": ["@ziv1234"],
|
"codeowners": ["@ziv1234"],
|
||||||
"requirements": ["dynalite_devices==0.1.22"]
|
"requirements": ["dynalite_devices==0.1.26"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -460,7 +460,7 @@ dsmr_parser==0.18
|
||||||
dweepy==0.3.0
|
dweepy==0.3.0
|
||||||
|
|
||||||
# homeassistant.components.dynalite
|
# homeassistant.components.dynalite
|
||||||
dynalite_devices==0.1.22
|
dynalite_devices==0.1.26
|
||||||
|
|
||||||
# homeassistant.components.rainforest_eagle
|
# homeassistant.components.rainforest_eagle
|
||||||
eagle200_reader==0.2.1
|
eagle200_reader==0.2.1
|
||||||
|
|
|
@ -171,7 +171,7 @@ distro==1.4.0
|
||||||
dsmr_parser==0.18
|
dsmr_parser==0.18
|
||||||
|
|
||||||
# homeassistant.components.dynalite
|
# homeassistant.components.dynalite
|
||||||
dynalite_devices==0.1.22
|
dynalite_devices==0.1.26
|
||||||
|
|
||||||
# homeassistant.components.ee_brightbox
|
# homeassistant.components.ee_brightbox
|
||||||
eebrightbox==0.0.4
|
eebrightbox==0.0.4
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
"""Common functions for the Dynalite tests."""
|
||||||
|
|
||||||
|
from homeassistant.components import dynalite
|
||||||
|
|
||||||
|
|
||||||
|
def get_bridge_from_hass(hass_obj):
|
||||||
|
"""Get the bridge from hass.data."""
|
||||||
|
key = next(iter(hass_obj.data[dynalite.DOMAIN]))
|
||||||
|
return hass_obj.data[dynalite.DOMAIN][key]
|
|
@ -2,7 +2,7 @@
|
||||||
from unittest.mock import Mock, call
|
from unittest.mock import Mock, call
|
||||||
|
|
||||||
from asynctest import patch
|
from asynctest import patch
|
||||||
from dynalite_lib import CONF_ALL
|
from dynalite_devices_lib import CONF_ALL
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components import dynalite
|
from homeassistant.components import dynalite
|
||||||
|
|
|
@ -4,6 +4,8 @@ from asynctest import patch
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.components import dynalite
|
from homeassistant.components import dynalite
|
||||||
|
|
||||||
|
from .common import get_bridge_from_hass
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,21 +72,29 @@ async def test_existing(hass):
|
||||||
async def test_existing_update(hass):
|
async def test_existing_update(hass):
|
||||||
"""Test when the entry exists with the same config."""
|
"""Test when the entry exists with the same config."""
|
||||||
host = "1.2.3.4"
|
host = "1.2.3.4"
|
||||||
mock_entry = MockConfigEntry(
|
port1 = 7777
|
||||||
domain=dynalite.DOMAIN, unique_id=host, data={dynalite.CONF_HOST: host}
|
port2 = 8888
|
||||||
)
|
|
||||||
mock_entry.add_to_hass(hass)
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.dynalite.bridge.DynaliteDevices.async_setup",
|
"homeassistant.components.dynalite.bridge.DynaliteDevices.async_setup",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.dynalite.bridge.DynaliteDevices.available", True
|
"homeassistant.components.dynalite.bridge.DynaliteDevices.available", True
|
||||||
):
|
):
|
||||||
|
assert await hass.config_entries.flow.async_init(
|
||||||
|
dynalite.DOMAIN,
|
||||||
|
context={"source": config_entries.SOURCE_IMPORT},
|
||||||
|
data={dynalite.CONF_HOST: host, dynalite.CONF_PORT: port1},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
old_bridge = get_bridge_from_hass(hass)
|
||||||
|
assert old_bridge.dynalite_devices.port == port1
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
dynalite.DOMAIN,
|
dynalite.DOMAIN,
|
||||||
context={"source": config_entries.SOURCE_IMPORT},
|
context={"source": config_entries.SOURCE_IMPORT},
|
||||||
data={dynalite.CONF_HOST: host, "aaa": "bbb"},
|
data={dynalite.CONF_HOST: host, dynalite.CONF_PORT: port2},
|
||||||
)
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
assert result["type"] == "abort"
|
assert result["type"] == "abort"
|
||||||
assert result["reason"] == "already_configured"
|
assert result["reason"] == "already_configured"
|
||||||
assert mock_entry.data.get("aaa") == "bbb"
|
bridge = get_bridge_from_hass(hass)
|
||||||
|
assert bridge.dynalite_devices.port == port2
|
||||||
|
|
Loading…
Reference in New Issue