core/homeassistant/components/dynalite/bridge.py

119 lines
4.0 KiB
Python
Executable File

"""Code to handle a Dynalite bridge."""
from dynalite_devices_lib import DynaliteDevices
from dynalite_lib import CONF_ALL
from homeassistant.const import CONF_HOST
from homeassistant.core import callback
from .const import DATA_CONFIGS, DOMAIN, LOGGER
from .light import DynaliteLight
class BridgeError(Exception):
"""Class to throw exceptions from DynaliteBridge."""
def __init__(self, message):
"""Initialize the exception."""
super().__init__()
self.message = message
class DynaliteBridge:
"""Manages a single Dynalite bridge."""
def __init__(self, hass, config_entry):
"""Initialize the system based on host parameter."""
self.config_entry = config_entry
self.hass = hass
self.area = {}
self.async_add_entities = None
self.waiting_entities = []
self.all_entities = {}
self.config = None
self.host = config_entry.data[CONF_HOST]
if self.host not in hass.data[DOMAIN][DATA_CONFIGS]:
LOGGER.info("invalid host - %s", self.host)
raise BridgeError(f"invalid host - {self.host}")
self.config = hass.data[DOMAIN][DATA_CONFIGS][self.host]
# Configure the dynalite devices
self.dynalite_devices = DynaliteDevices(
config=self.config,
newDeviceFunc=self.add_devices,
updateDeviceFunc=self.update_device,
)
async def async_setup(self, tries=0):
"""Set up a Dynalite bridge."""
# Configure the dynalite devices
await self.dynalite_devices.async_setup()
self.hass.async_create_task(
self.hass.config_entries.async_forward_entry_setup(
self.config_entry, "light"
)
)
return True
@callback
def add_devices(self, devices):
"""Call when devices should be added to home assistant."""
added_entities = []
for device in devices:
if device.category == "light":
entity = DynaliteLight(device, self)
else:
LOGGER.debug("Illegal device category %s", device.category)
continue
added_entities.append(entity)
self.all_entities[entity.unique_id] = entity
if added_entities:
self.add_entities_when_registered(added_entities)
@callback
def update_device(self, device):
"""Call when a device or all devices should be updated."""
if device == CONF_ALL:
# This is used to signal connection or disconnection, so all devices may become available or not.
if self.dynalite_devices.available:
LOGGER.info("Connected to dynalite host")
else:
LOGGER.info("Disconnected from dynalite host")
for uid in self.all_entities:
self.all_entities[uid].try_schedule_ha()
else:
uid = device.unique_id
if uid in self.all_entities:
self.all_entities[uid].try_schedule_ha()
@callback
def register_add_entities(self, async_add_entities):
"""Add an async_add_entities for a category."""
self.async_add_entities = async_add_entities
if self.waiting_entities:
self.async_add_entities(self.waiting_entities)
def add_entities_when_registered(self, entities):
"""Add the entities to HA if async_add_entities was registered, otherwise queue until it is."""
if not entities:
return
if self.async_add_entities:
self.async_add_entities(entities)
else: # handle it later when it is registered
self.waiting_entities.extend(entities)
async def async_reset(self):
"""Reset this bridge to default state.
Will cancel any scheduled setup retry and will unload
the config entry.
"""
result = await self.hass.config_entries.async_forward_entry_unload(
self.config_entry, "light"
)
# None and True are OK
return result