diff --git a/homeassistant/components/binary_sensor/point.py b/homeassistant/components/binary_sensor/point.py index 90a8b0b5813..29488d08130 100644 --- a/homeassistant/components/binary_sensor/point.py +++ b/homeassistant/components/binary_sensor/point.py @@ -7,10 +7,11 @@ https://home-assistant.io/components/binary_sensor.point/ import logging -from homeassistant.components.binary_sensor import BinarySensorDevice +from homeassistant.components.binary_sensor import ( + DOMAIN as PARENT_DOMAIN, BinarySensorDevice) from homeassistant.components.point import MinutPointEntity from homeassistant.components.point.const import ( - DOMAIN as POINT_DOMAIN, NEW_DEVICE, SIGNAL_WEBHOOK) + DOMAIN as POINT_DOMAIN, POINT_DISCOVERY_NEW, SIGNAL_WEBHOOK) from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -40,10 +41,16 @@ EVENTS = { async def async_setup_entry(hass, config_entry, async_add_entities): """Set up a Point's binary sensors based on a config entry.""" - device_id = config_entry.data[NEW_DEVICE] - client = hass.data[POINT_DOMAIN][config_entry.entry_id] - async_add_entities((MinutPointBinarySensor(client, device_id, device_class) - for device_class in EVENTS), True) + async def async_discover_sensor(device_id): + """Discover and add a discovered sensor.""" + client = hass.data[POINT_DOMAIN][config_entry.entry_id] + async_add_entities( + (MinutPointBinarySensor(client, device_id, device_class) + for device_class in EVENTS), True) + + async_dispatcher_connect( + hass, POINT_DISCOVERY_NEW.format(PARENT_DOMAIN, POINT_DOMAIN), + async_discover_sensor) class MinutPointBinarySensor(MinutPointEntity, BinarySensorDevice): diff --git a/homeassistant/components/point/__init__.py b/homeassistant/components/point/__init__.py index 36215da7893..6616d6b24ec 100644 --- a/homeassistant/components/point/__init__.py +++ b/homeassistant/components/point/__init__.py @@ -4,6 +4,7 @@ Support for Minut Point. For more details about this component, please refer to the documentation at https://home-assistant.io/components/point/ """ +import asyncio import logging import voluptuous as vol @@ -22,8 +23,8 @@ from homeassistant.util.dt import as_local, parse_datetime, utc_from_timestamp from . import config_flow # noqa pylint_disable=unused-import from .const import ( - CONF_WEBHOOK_URL, DOMAIN, EVENT_RECEIVED, NEW_DEVICE, SCAN_INTERVAL, - SIGNAL_UPDATE_ENTITY, SIGNAL_WEBHOOK) + CONF_WEBHOOK_URL, DOMAIN, EVENT_RECEIVED, POINT_DISCOVERY_NEW, + SCAN_INTERVAL, SIGNAL_UPDATE_ENTITY, SIGNAL_WEBHOOK) REQUIREMENTS = ['pypoint==1.0.6'] DEPENDENCIES = ['webhook'] @@ -33,6 +34,9 @@ _LOGGER = logging.getLogger(__name__) CONF_CLIENT_ID = 'client_id' CONF_CLIENT_SECRET = 'client_secret' +DATA_CONFIG_ENTRY_LOCK = 'point_config_entry_lock' +CONFIG_ENTRY_IS_SETUP = 'point_config_entry_is_setup' + CONFIG_SCHEMA = vol.Schema( { DOMAIN: @@ -87,6 +91,9 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry): _LOGGER.error('Authentication Error') return False + hass.data[DATA_CONFIG_ENTRY_LOCK] = asyncio.Lock() + hass.data[CONFIG_ENTRY_IS_SETUP] = set() + await async_setup_webhook(hass, entry, session) client = MinutPointClient(hass, entry, session) hass.data.setdefault(DOMAIN, {}).update({entry.entry_id: client}) @@ -111,7 +118,7 @@ async def async_setup_webhook(hass: HomeAssistantType, entry: ConfigEntry, **entry.data, }) session.update_webhook(entry.data[CONF_WEBHOOK_URL], - entry.data[CONF_WEBHOOK_ID]) + entry.data[CONF_WEBHOOK_ID], events=['*']) hass.components.webhook.async_register( DOMAIN, 'Point', entry.data[CONF_WEBHOOK_ID], handle_webhook) @@ -153,7 +160,7 @@ class MinutPointClient(): def __init__(self, hass: HomeAssistantType, config_entry: ConfigEntry, session): """Initialize the Minut data object.""" - self._known_devices = [] + self._known_devices = set() self._hass = hass self._config_entry = config_entry self._is_available = True @@ -172,18 +179,27 @@ class MinutPointClient(): _LOGGER.warning("Device is unavailable") return + async def new_device(device_id, component): + """Load new device.""" + config_entries_key = '{}.{}'.format(component, DOMAIN) + async with self._hass.data[DATA_CONFIG_ENTRY_LOCK]: + if config_entries_key not in self._hass.data[ + CONFIG_ENTRY_IS_SETUP]: + await self._hass.config_entries.async_forward_entry_setup( + self._config_entry, component) + self._hass.data[CONFIG_ENTRY_IS_SETUP].add( + config_entries_key) + + async_dispatcher_send( + self._hass, POINT_DISCOVERY_NEW.format(component, DOMAIN), + device_id) + self._is_available = True for device in self._client.devices: if device.device_id not in self._known_devices: - # A way to communicate the device_id to entry_setup, - # can this be done nicer? - self._config_entry.data[NEW_DEVICE] = device.device_id - await self._hass.config_entries.async_forward_entry_setup( - self._config_entry, 'sensor') - await self._hass.config_entries.async_forward_entry_setup( - self._config_entry, 'binary_sensor') - self._known_devices.append(device.device_id) - del self._config_entry.data[NEW_DEVICE] + for component in ('sensor', 'binary_sensor'): + await new_device(device.device_id, component) + self._known_devices.add(device.device_id) async_dispatcher_send(self._hass, SIGNAL_UPDATE_ENTITY) def device(self, device_id): diff --git a/homeassistant/components/point/const.py b/homeassistant/components/point/const.py index 4ef21b57cd9..c6ba69a8083 100644 --- a/homeassistant/components/point/const.py +++ b/homeassistant/components/point/const.py @@ -12,4 +12,5 @@ CONF_WEBHOOK_URL = 'webhook_url' EVENT_RECEIVED = 'point_webhook_received' SIGNAL_UPDATE_ENTITY = 'point_update' SIGNAL_WEBHOOK = 'point_webhook' -NEW_DEVICE = 'new_device' + +POINT_DISCOVERY_NEW = 'point_new_{}_{}' diff --git a/homeassistant/components/sensor/point.py b/homeassistant/components/sensor/point.py index 0c099c8873e..1bb46827602 100644 --- a/homeassistant/components/sensor/point.py +++ b/homeassistant/components/sensor/point.py @@ -6,13 +6,15 @@ https://home-assistant.io/components/sensor.point/ """ import logging -from homeassistant.components.point import MinutPointEntity +from homeassistant.components.point import ( + DOMAIN as PARENT_DOMAIN, MinutPointEntity) from homeassistant.components.point.const import ( - DOMAIN as POINT_DOMAIN, NEW_DEVICE) + DOMAIN as POINT_DOMAIN, POINT_DISCOVERY_NEW) from homeassistant.const import ( DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_PRESSURE, DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS) from homeassistant.core import callback +from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.util.dt import parse_datetime _LOGGER = logging.getLogger(__name__) @@ -29,10 +31,15 @@ SENSOR_TYPES = { async def async_setup_entry(hass, config_entry, async_add_entities): """Set up a Point's sensors based on a config entry.""" - device_id = config_entry.data[NEW_DEVICE] - client = hass.data[POINT_DOMAIN][config_entry.entry_id] - async_add_entities((MinutPointSensor(client, device_id, sensor_type) - for sensor_type in SENSOR_TYPES), True) + async def async_discover_sensor(device_id): + """Discover and add a discovered sensor.""" + client = hass.data[POINT_DOMAIN][config_entry.entry_id] + async_add_entities((MinutPointSensor(client, device_id, sensor_type) + for sensor_type in SENSOR_TYPES), True) + + async_dispatcher_connect( + hass, POINT_DISCOVERY_NEW.format(PARENT_DOMAIN, POINT_DOMAIN), + async_discover_sensor) class MinutPointSensor(MinutPointEntity):