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 import
pull/32368/head
Ziv 2020-02-28 01:05:55 -05:00 committed by GitHub
parent b9fa32444a
commit 02c170b961
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 54 additions and 20 deletions

View File

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

View File

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

View File

@ -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():

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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