def async_setup(hass, config): """Set up ZHA. Will automatically load components to support devices found on the network. """ global APPLICATION_CONTROLLER import bellows.ezsp from bellows.zigbee.application import ControllerApplication ezsp_ = bellows.ezsp.EZSP() usb_path = config[DOMAIN].get(CONF_USB_PATH) yield from ezsp_.connect(usb_path) database = config[DOMAIN].get(CONF_DATABASE) APPLICATION_CONTROLLER = ControllerApplication(ezsp_, database) listener = ApplicationListener(hass, config) APPLICATION_CONTROLLER.add_listener(listener) yield from APPLICATION_CONTROLLER.startup(auto_form=True) for device in APPLICATION_CONTROLLER.devices.values(): hass.async_add_job(listener.async_device_initialized(device, False)) @asyncio.coroutine def permit(service): """Allow devices to join this network.""" duration = service.data.get(ATTR_DURATION) _LOGGER.info("Permitting joins for %ss", duration) yield from APPLICATION_CONTROLLER.permit(duration) hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit, SERVICE_DESCRIPTIONS[SERVICE_PERMIT], SERVICE_SCHEMAS[SERVICE_PERMIT]) return True
async def async_setup(hass, config): """Set up ZHA. Will automatically load components to support devices found on the network. """ global APPLICATION_CONTROLLER usb_path = config[DOMAIN].get(CONF_USB_PATH) baudrate = config[DOMAIN].get(CONF_BAUDRATE) radio_type = config[DOMAIN].get(CONF_RADIO_TYPE) if radio_type == RadioType.ezsp: import bellows.ezsp from bellows.zigbee.application import ControllerApplication radio = bellows.ezsp.EZSP() elif radio_type == RadioType.xbee: import zigpy_xbee.api from zigpy_xbee.zigbee.application import ControllerApplication radio = zigpy_xbee.api.XBee() await radio.connect(usb_path, baudrate) database = config[DOMAIN].get(CONF_DATABASE) APPLICATION_CONTROLLER = ControllerApplication(radio, database) listener = ApplicationListener(hass, config) APPLICATION_CONTROLLER.add_listener(listener) await APPLICATION_CONTROLLER.startup(auto_form=True) for device in APPLICATION_CONTROLLER.devices.values(): hass.async_add_job(listener.async_device_initialized(device, False)) async def permit(service): """Allow devices to join this network.""" duration = service.data.get(ATTR_DURATION) _LOGGER.info("Permitting joins for %ss", duration) await APPLICATION_CONTROLLER.permit(duration) hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit, schema=SERVICE_SCHEMAS[SERVICE_PERMIT]) async def remove(service): """Remove a node from the network.""" from bellows.types import EmberEUI64, uint8_t ieee = service.data.get(ATTR_IEEE) ieee = EmberEUI64([uint8_t(p, base=16) for p in ieee.split(':')]) _LOGGER.info("Removing node %s", ieee) await APPLICATION_CONTROLLER.remove(ieee) hass.services.async_register(DOMAIN, SERVICE_REMOVE, remove, schema=SERVICE_SCHEMAS[SERVICE_REMOVE]) return True
def async_setup(hass, config): """Set up ZHA. Will automatically load components to support devices found on the network. """ global APPLICATION_CONTROLLER usb_path = config[DOMAIN].get(CONF_USB_PATH) baudrate = config[DOMAIN].get(CONF_BAUDRATE) radio_type = config[DOMAIN].get(CONF_RADIO_TYPE) if radio_type == RadioType.ezsp: import bellows.ezsp from bellows.zigbee.application import ControllerApplication radio = bellows.ezsp.EZSP() elif radio_type == RadioType.xbee: import zigpy_xbee.api from zigpy_xbee.zigbee.application import ControllerApplication radio = zigpy_xbee.api.XBee() yield from radio.connect(usb_path, baudrate) database = config[DOMAIN].get(CONF_DATABASE) APPLICATION_CONTROLLER = ControllerApplication(radio, database) listener = ApplicationListener(hass, config) APPLICATION_CONTROLLER.add_listener(listener) yield from APPLICATION_CONTROLLER.startup(auto_form=True) for device in APPLICATION_CONTROLLER.devices.values(): hass.async_add_job(listener.async_device_initialized(device, False)) @asyncio.coroutine def permit(service): """Allow devices to join this network.""" duration = service.data.get(ATTR_DURATION) _LOGGER.info("Permitting joins for %ss", duration) yield from APPLICATION_CONTROLLER.permit(duration) hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit, schema=SERVICE_SCHEMAS[SERVICE_PERMIT]) @asyncio.coroutine def remove(service): """Remove a node from the network.""" from bellows.types import EmberEUI64, uint8_t ieee = service.data.get(ATTR_IEEE) ieee = EmberEUI64([uint8_t(p, base=16) for p in ieee.split(':')]) _LOGGER.info("Removing node %s", ieee) yield from APPLICATION_CONTROLLER.remove(ieee) hass.services.async_register(DOMAIN, SERVICE_REMOVE, remove, schema=SERVICE_SCHEMAS[SERVICE_REMOVE]) return True
async def check_zigpy_connection(usb_path, radio_type, database_path): """Test zigpy radio connection.""" if radio_type == RadioType.ezsp.name: import bellows.ezsp from bellows.zigbee.application import ControllerApplication radio = bellows.ezsp.EZSP() elif radio_type == RadioType.xbee.name: import zigpy_xbee.api from zigpy_xbee.zigbee.application import ControllerApplication radio = zigpy_xbee.api.XBee() try: await radio.connect(usb_path, DEFAULT_BAUDRATE) controller = ControllerApplication(radio, database_path) await asyncio.wait_for(controller.startup(auto_form=True), timeout=30) radio.close() except Exception: # pylint: disable=broad-except return False return True
def async_setup(hass, config): """Set up ZHA. Will automatically load components to support devices found on the network. """ global APPLICATION_CONTROLLER usb_path = config[DOMAIN].get(CONF_USB_PATH) baudrate = config[DOMAIN].get(CONF_BAUDRATE) radio_type = config[DOMAIN].get(CONF_RADIO_TYPE) if radio_type == RadioType.ezsp: import bellows.ezsp from bellows.zigbee.application import ControllerApplication radio = bellows.ezsp.EZSP() elif radio_type == RadioType.xbee: import zigpy_xbee.api from zigpy_xbee.zigbee.application import ControllerApplication radio = zigpy_xbee.api.XBee() yield from radio.connect(usb_path, baudrate) database = config[DOMAIN].get(CONF_DATABASE) APPLICATION_CONTROLLER = ControllerApplication(radio, database) listener = ApplicationListener(hass, config) APPLICATION_CONTROLLER.add_listener(listener) yield from APPLICATION_CONTROLLER.startup(auto_form=True) for device in APPLICATION_CONTROLLER.devices.values(): hass.async_add_job(listener.async_device_initialized(device, False)) @asyncio.coroutine def permit(service): """Allow devices to join this network.""" duration = service.data.get(ATTR_DURATION) _LOGGER.info("Permitting joins for %ss", duration) yield from APPLICATION_CONTROLLER.permit(duration) hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit, schema=SERVICE_SCHEMAS[SERVICE_PERMIT]) return True
async def check_zigpy_connection(usb_path, radio_type, database_path): """Test zigpy radio connection.""" if radio_type == RadioType.ezsp.name: import bellows.ezsp from bellows.zigbee.application import ControllerApplication radio = bellows.ezsp.EZSP() elif radio_type == RadioType.xbee.name: import zigpy_xbee.api from zigpy_xbee.zigbee.application import ControllerApplication radio = zigpy_xbee.api.XBee() elif radio_type == RadioType.deconz.name: import zigpy_deconz.api from zigpy_deconz.zigbee.application import ControllerApplication radio = zigpy_deconz.api.Deconz() try: await radio.connect(usb_path, DEFAULT_BAUDRATE) controller = ControllerApplication(radio, database_path) await asyncio.wait_for(controller.startup(auto_form=True), timeout=30) radio.close() except Exception: # pylint: disable=broad-except return False return True
async def async_setup(hass, config): global APPLICATION_CONTROLLER import bellows.ezsp from bellows.zigbee.application import ControllerApplication ezsp_ = bellows.ezsp.EZSP() usb_path = config[DOMAIN].get(CONF_USB_PATH) baudrate = config[DOMAIN].get(CONF_BAUDRATE) await ezsp_.connect(usb_path, baudrate) database = config[DOMAIN].get(CONF_DATABASE) APPLICATION_CONTROLLER = ControllerApplication(ezsp_, database) listener = ApplicationListener(hass, config) APPLICATION_CONTROLLER.add_listener(listener) await APPLICATION_CONTROLLER.startup(auto_form=True) component = EntityComponent(_LOGGER, DOMAIN, hass) zha_controller = zha_state(hass, ezsp_, 'controller', 'Init') listener.controller = zha_controller await component.async_add_entities([zha_controller]) zha_controller.async_schedule_update_ha_state() for device in APPLICATION_CONTROLLER.devices.values(): hass.async_add_job(listener.async_device_initialized(device, False)) await asyncio.sleep(0.1) @asyncio.coroutine def permit(service): """Allow devices to join this network.""" duration = service.data.get(ATTR_DURATION) _LOGGER.info("Permitting joins for %ss", duration) zha_controller._state = 'Permit' zha_controller.async_schedule_update_ha_state() yield from APPLICATION_CONTROLLER.permit(duration) async def _async_clear_state(entity): if entity._state == 'Permit': entity._state = 'Run' entity.async_schedule_update_ha_state() async_track_point_in_time( zha_controller.hass, _async_clear_state(zha_controller), dt_util.utcnow() + datetime.timedelta(seconds=duration)) hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit, schema=SERVICE_SCHEMAS[SERVICE_PERMIT]) async def remove(service): """remove device from the network""" ieee_list = [] ieee = service.data.get(ATTR_IEEE) if ieee == '': _LOGGER.debug("service remove device str empty") return _LOGGER.debug("service remove device str: %s", ieee) for device in APPLICATION_CONTROLLER.devices.values(): if ieee in str(device._ieee): ieee_list.append(device.ieee) for device in ieee_list: await APPLICATION_CONTROLLER.remove(device) hass.services.async_register(DOMAIN, SERVICE_REMOVE, remove, schema=SERVICE_SCHEMAS[SERVICE_REMOVE]) zha_controller._state = "Run" zha_controller.async_schedule_update_ha_state() return True
def app(): ezsp = mock.MagicMock() return ControllerApplication(ezsp)
async def async_setup_entry(hass, config_entry): """Set up ZHA. Will automatically load components to support devices found on the network. """ establish_device_mappings() populate_channel_registry() for component in COMPONENTS: hass.data[DATA_ZHA][component] = (hass.data[DATA_ZHA].get( component, {})) hass.data[DATA_ZHA] = hass.data.get(DATA_ZHA, {}) hass.data[DATA_ZHA][DATA_ZHA_DISPATCHERS] = [] config = hass.data[DATA_ZHA].get(DATA_ZHA_CONFIG, {}) if config.get(ENABLE_QUIRKS, True): # needs to be done here so that the ZHA module is finished loading # before zhaquirks is imported # pylint: disable=W0611, W0612 import zhaquirks # noqa usb_path = config_entry.data.get(CONF_USB_PATH) baudrate = config.get(CONF_BAUDRATE, DEFAULT_BAUDRATE) radio_type = config_entry.data.get(CONF_RADIO_TYPE) if radio_type == RadioType.ezsp.name: import bellows.ezsp from bellows.zigbee.application import ControllerApplication radio = bellows.ezsp.EZSP() radio_description = "EZSP" elif radio_type == RadioType.xbee.name: import zigpy_xbee.api from zigpy_xbee.zigbee.application import ControllerApplication radio = zigpy_xbee.api.XBee() radio_description = "XBee" elif radio_type == RadioType.deconz.name: import zigpy_deconz.api from zigpy_deconz.zigbee.application import ControllerApplication radio = zigpy_deconz.api.Deconz() radio_description = "Deconz" await radio.connect(usb_path, baudrate) hass.data[DATA_ZHA][DATA_ZHA_RADIO] = radio if CONF_DATABASE in config: database = config[CONF_DATABASE] else: database = os.path.join(hass.config.config_dir, DEFAULT_DATABASE_NAME) # patch zigpy listener to prevent flooding logs with warnings due to # how zigpy implemented its listeners from zigpy.appdb import ClusterPersistingListener def zha_send_event(self, cluster, command, args): pass ClusterPersistingListener.zha_send_event = types.MethodType( zha_send_event, ClusterPersistingListener) zha_gateway = ZHAGateway(hass, config) # Patch handle_message until zigpy can provide an event here def handle_message(sender, is_reply, profile, cluster, src_ep, dst_ep, tsn, command_id, args): """Handle message from a device.""" if not sender.initializing and sender.ieee in zha_gateway.devices and \ not zha_gateway.devices[sender.ieee].available: hass.async_create_task( zha_gateway.async_device_became_available( sender, is_reply, profile, cluster, src_ep, dst_ep, tsn, command_id, args)) return sender.handle_message(is_reply, profile, cluster, src_ep, dst_ep, tsn, command_id, args) application_controller = ControllerApplication(radio, database) application_controller.handle_message = handle_message application_controller.add_listener(zha_gateway) await application_controller.startup(auto_form=True) hass.data[DATA_ZHA][DATA_ZHA_BRIDGE_ID] = str(application_controller.ieee) init_tasks = [] for device in application_controller.devices.values(): init_tasks.append(zha_gateway.async_device_initialized(device, False)) await asyncio.gather(*init_tasks) device_registry = await \ hass.helpers.device_registry.async_get_registry() device_registry.async_get_or_create( config_entry_id=config_entry.entry_id, connections={(CONNECTION_ZIGBEE, str(application_controller.ieee))}, identifiers={(DOMAIN, str(application_controller.ieee))}, name="Zigbee Coordinator", manufacturer="ZHA", model=radio_description, ) for component in COMPONENTS: hass.async_create_task( hass.config_entries.async_forward_entry_setup( config_entry, component)) api.async_load_api(hass, application_controller, zha_gateway) def zha_shutdown(event): """Close radio.""" hass.data[DATA_ZHA][DATA_ZHA_RADIO].close() hass.bus.async_listen_once(ha_const.EVENT_HOMEASSISTANT_STOP, zha_shutdown) return True
async def async_setup_entry(hass, config_entry): """Set up ZHA. Will automatically load components to support devices found on the network. """ if config_entry.data.get(ENABLE_QUIRKS): # needs to be done here so that the ZHA module is finished loading # before zhaquirks is imported # pylint: disable=W0611, W0612 import zhaquirks # noqa hass.data[DATA_ZHA] = hass.data.get(DATA_ZHA, {}) hass.data[DATA_ZHA][DATA_ZHA_DISPATCHERS] = [] config = hass.data[DATA_ZHA].get(DATA_ZHA_CONFIG, {}) usb_path = config_entry.data.get(CONF_USB_PATH) baudrate = config.get(CONF_BAUDRATE, DEFAULT_BAUDRATE) radio_type = config_entry.data.get(CONF_RADIO_TYPE) if radio_type == RadioType.ezsp.name: import bellows.ezsp from bellows.zigbee.application import ControllerApplication radio = bellows.ezsp.EZSP() radio_description = "EZSP" elif radio_type == RadioType.xbee.name: import zigpy_xbee.api from zigpy_xbee.zigbee.application import ControllerApplication radio = zigpy_xbee.api.XBee() radio_description = "XBee" await radio.connect(usb_path, baudrate) hass.data[DATA_ZHA][DATA_ZHA_RADIO] = radio if CONF_DATABASE in config: database = config[CONF_DATABASE] else: database = os.path.join(hass.config.config_dir, DEFAULT_DATABASE_NAME) # patch zigpy listener to prevent flooding logs with warnings due to # how zigpy implemented its listeners from zigpy.appdb import ClusterPersistingListener def zha_send_event(self, cluster, command, args): pass ClusterPersistingListener.zha_send_event = types.MethodType( zha_send_event, ClusterPersistingListener) application_controller = ControllerApplication(radio, database) listener = ApplicationListener(hass, config) application_controller.add_listener(listener) await application_controller.startup(auto_form=True) for device in application_controller.devices.values(): hass.async_create_task(listener.async_device_initialized( device, False)) device_registry = await \ hass.helpers.device_registry.async_get_registry() device_registry.async_get_or_create( config_entry_id=config_entry.entry_id, connections={(CONNECTION_ZIGBEE, str(application_controller.ieee))}, identifiers={(DOMAIN, str(application_controller.ieee))}, name="Zigbee Coordinator", manufacturer="ZHA", model=radio_description, ) hass.data[DATA_ZHA][DATA_ZHA_BRIDGE_ID] = str(application_controller.ieee) for component in COMPONENTS: hass.async_create_task( hass.config_entries.async_forward_entry_setup( config_entry, component)) async def permit(service): """Allow devices to join this network.""" duration = service.data.get(ATTR_DURATION) _LOGGER.info("Permitting joins for %ss", duration) await application_controller.permit(duration) hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit, schema=SERVICE_SCHEMAS[SERVICE_PERMIT]) async def remove(service): """Remove a node from the network.""" from bellows.types import EmberEUI64, uint8_t ieee = service.data.get(ATTR_IEEE) ieee = EmberEUI64([uint8_t(p, base=16) for p in ieee.split(':')]) _LOGGER.info("Removing node %s", ieee) await application_controller.remove(ieee) hass.services.async_register(DOMAIN, SERVICE_REMOVE, remove, schema=SERVICE_SCHEMAS[SERVICE_REMOVE]) def zha_shutdown(event): """Close radio.""" hass.data[DATA_ZHA][DATA_ZHA_RADIO].close() hass.bus.async_listen_once(ha_const.EVENT_HOMEASSISTANT_STOP, zha_shutdown) return True
async def async_setup_entry(hass, config_entry): """Set up ZHA. Will automatically load components to support devices found on the network. """ establish_device_mappings() populate_channel_registry() for component in COMPONENTS: hass.data[DATA_ZHA][component] = ( hass.data[DATA_ZHA].get(component, {}) ) hass.data[DATA_ZHA] = hass.data.get(DATA_ZHA, {}) hass.data[DATA_ZHA][DATA_ZHA_DISPATCHERS] = [] config = hass.data[DATA_ZHA].get(DATA_ZHA_CONFIG, {}) if config.get(ENABLE_QUIRKS, True): # needs to be done here so that the ZHA module is finished loading # before zhaquirks is imported # pylint: disable=W0611, W0612 import zhaquirks # noqa usb_path = config_entry.data.get(CONF_USB_PATH) baudrate = config.get(CONF_BAUDRATE, DEFAULT_BAUDRATE) radio_type = config_entry.data.get(CONF_RADIO_TYPE) if radio_type == RadioType.ezsp.name: import bellows.ezsp from bellows.zigbee.application import ControllerApplication radio = bellows.ezsp.EZSP() radio_description = "EZSP" elif radio_type == RadioType.xbee.name: import zigpy_xbee.api from zigpy_xbee.zigbee.application import ControllerApplication radio = zigpy_xbee.api.XBee() radio_description = "XBee" elif radio_type == RadioType.deconz.name: import zigpy_deconz.api from zigpy_deconz.zigbee.application import ControllerApplication radio = zigpy_deconz.api.Deconz() radio_description = "Deconz" await radio.connect(usb_path, baudrate) hass.data[DATA_ZHA][DATA_ZHA_RADIO] = radio if CONF_DATABASE in config: database = config[CONF_DATABASE] else: database = os.path.join(hass.config.config_dir, DEFAULT_DATABASE_NAME) # patch zigpy listener to prevent flooding logs with warnings due to # how zigpy implemented its listeners from zigpy.appdb import ClusterPersistingListener def zha_send_event(self, cluster, command, args): pass ClusterPersistingListener.zha_send_event = types.MethodType( zha_send_event, ClusterPersistingListener ) zha_gateway = ZHAGateway(hass, config) # Patch handle_message until zigpy can provide an event here def handle_message(sender, is_reply, profile, cluster, src_ep, dst_ep, tsn, command_id, args): """Handle message from a device.""" if not sender.initializing and sender.ieee in zha_gateway.devices and \ not zha_gateway.devices[sender.ieee].available: zha_gateway.async_device_became_available( sender, is_reply, profile, cluster, src_ep, dst_ep, tsn, command_id, args ) return sender.handle_message( is_reply, profile, cluster, src_ep, dst_ep, tsn, command_id, args) application_controller = ControllerApplication(radio, database) application_controller.handle_message = handle_message application_controller.add_listener(zha_gateway) await application_controller.startup(auto_form=True) hass.data[DATA_ZHA][DATA_ZHA_BRIDGE_ID] = str(application_controller.ieee) init_tasks = [] for device in application_controller.devices.values(): init_tasks.append(zha_gateway.async_device_initialized(device, False)) await asyncio.gather(*init_tasks) device_registry = await \ hass.helpers.device_registry.async_get_registry() device_registry.async_get_or_create( config_entry_id=config_entry.entry_id, connections={(CONNECTION_ZIGBEE, str(application_controller.ieee))}, identifiers={(DOMAIN, str(application_controller.ieee))}, name="Zigbee Coordinator", manufacturer="ZHA", model=radio_description, ) for component in COMPONENTS: hass.async_create_task( hass.config_entries.async_forward_entry_setup( config_entry, component) ) api.async_load_api(hass, application_controller, zha_gateway) def zha_shutdown(event): """Close radio.""" hass.data[DATA_ZHA][DATA_ZHA_RADIO].close() hass.bus.async_listen_once(ha_const.EVENT_HOMEASSISTANT_STOP, zha_shutdown) return True
def __init__(self): self.ezsp = EZSP() self.app = ControllerApplication( self.ezsp, os.getenv('DATABASE_FILE', "devices.db"))
class ezscApplication(): # __init__ def __init__(self): self.ezsp = EZSP() self.app = ControllerApplication( self.ezsp, os.getenv('DATABASE_FILE', "devices.db")) async def setup_network(self): LOGGER.info("Setting up the Zigbee network ...") await self.ezsp.connect(os.getenv('DEVICE', "/dev/ttyAMA0"), 115200) await self.app.startup(auto_form=True) LOGGER.info("Network setup complete!") async def permit_join(self): await self.app.permit( ) # a function from bellows.zigbee.application that enbale zigbee devices to join the network. await asyncio.sleep(60) def _ieee_to_number( self, ieee ): # a function that will convert a device IEEE to readable numbers ieee_string = str(t.EUI64(map(t.uint8_t, ieee))) return int(ieee_string.replace(':', ''), 16) def _get_device_by_ieee( self, ieee_to_find ): # a function that returns the the device when provided the IEEE number for ieee, dev in self.app.devices.items(): if self._ieee_to_number(ieee) == ieee_to_find: return dev raise Excepting("Device %s is not in the device database" % (ieee_to_find, )) def _get_cluster_by_command(self, device, command): for epid, ep in device.endpoints.items(): if epid == 0 or not hasattr(ep, "in_clusters"): continue for cluster_id, cluster in ep.in_clusters.items(): for server_command_id, server_command in cluster.server_commands.items( ): if command in server_command: return cluster raise Exception("Device does not support command %s!" % (command, )) def get_devices(self): devices = [] for ieee, dev in self.app.devices.items(): device = { "ieee": self._ieee_to_number(ieee), "nwk": dev.nwk, "endpoints": [] } for epid, ep in dev.endpoints.items(): if epid == 0: continue device["endpoints"].append({ "id": epid, "input_clusters": [in_cluster for in_cluster in ep.in_clusters] if hasattr( ep, "in_clusters") else [], "output_clusters": [out_cluster for out_cluster in ep.out_clusters] if hasattr(ep, "out_clusters") else [], "status": "uninitialized" if ep.status == zigpy.endpoint.Status.NEW else "initialized" }) devices.append(device) return devices '''async def send_command(self, device_ieee, command, params=""): device = self._get_device_by_ieee(device_ieee) LOGGER.info("sending command %s to device %s" % (command, device_ieee)) v = await getattr(self._get_cluster_by_command(device, command), command)(*params) LOGGER.info(v)''' async def send_command_to_turn_on_device(self): try: #await self.app.endpoints[i].on_off.on() device = self.app.get_device("10447682632402344369") device.endpoint[1].on_off.on() except Exception as err: LOGGER.exception("Failed to turn on device")
def make_app(database_file): ezsp = mock.MagicMock() return ControllerApplication(ezsp, database_file)
async def async_setup_entry(hass, config_entry): """Set up ZHA. Will automatically load components to support devices found on the network. """ global APPLICATION_CONTROLLER hass.data[DATA_ZHA] = hass.data.get(DATA_ZHA, {}) hass.data[DATA_ZHA][DATA_ZHA_DISPATCHERS] = [] config = hass.data[DATA_ZHA].get(DATA_ZHA_CONFIG, {}) usb_path = config_entry.data.get(CONF_USB_PATH) baudrate = config.get(CONF_BAUDRATE, DEFAULT_BAUDRATE) radio_type = config_entry.data.get(CONF_RADIO_TYPE) if radio_type == RadioType.ezsp.name: import bellows.ezsp from bellows.zigbee.application import ControllerApplication radio = bellows.ezsp.EZSP() radio_description = "EZSP" elif radio_type == RadioType.xbee.name: import zigpy_xbee.api from zigpy_xbee.zigbee.application import ControllerApplication radio = zigpy_xbee.api.XBee() radio_description = "XBee" await radio.connect(usb_path, baudrate) hass.data[DATA_ZHA][DATA_ZHA_RADIO] = radio if CONF_DATABASE in config: database = config[CONF_DATABASE] else: database = os.path.join(hass.config.config_dir, DEFAULT_DATABASE_NAME) APPLICATION_CONTROLLER = ControllerApplication(radio, database) listener = ApplicationListener(hass, config) APPLICATION_CONTROLLER.add_listener(listener) await APPLICATION_CONTROLLER.startup(auto_form=True) for device in APPLICATION_CONTROLLER.devices.values(): hass.async_create_task(listener.async_device_initialized( device, False)) device_registry = await \ hass.helpers.device_registry.async_get_registry() device_registry.async_get_or_create( config_entry_id=config_entry.entry_id, connections={(CONNECTION_ZIGBEE, str(APPLICATION_CONTROLLER.ieee))}, identifiers={(DOMAIN, str(APPLICATION_CONTROLLER.ieee))}, name="Zigbee Coordinator", manufacturer="ZHA", model=radio_description, ) hass.data[DATA_ZHA][DATA_ZHA_BRIDGE_ID] = str(APPLICATION_CONTROLLER.ieee) for component in COMPONENTS: hass.async_create_task( hass.config_entries.async_forward_entry_setup( config_entry, component)) async def permit(service): """Allow devices to join this network.""" duration = service.data.get(ATTR_DURATION) _LOGGER.info("Permitting joins for %ss", duration) await APPLICATION_CONTROLLER.permit(duration) hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit, schema=SERVICE_SCHEMAS[SERVICE_PERMIT]) async def remove(service): """Remove a node from the network.""" from bellows.types import EmberEUI64, uint8_t ieee = service.data.get(ATTR_IEEE) ieee = EmberEUI64([uint8_t(p, base=16) for p in ieee.split(':')]) _LOGGER.info("Removing node %s", ieee) await APPLICATION_CONTROLLER.remove(ieee) hass.services.async_register(DOMAIN, SERVICE_REMOVE, remove, schema=SERVICE_SCHEMAS[SERVICE_REMOVE]) def zha_shutdown(event): """Close radio.""" hass.data[DATA_ZHA][DATA_ZHA_RADIO].close() hass.bus.async_listen_once(ha_const.EVENT_HOMEASSISTANT_STOP, zha_shutdown) return True
async def async_setup(hass, config): global APPLICATION_CONTROLLER import bellows.ezsp from bellows.zigbee.application import ControllerApplication _LOGGER.debug("async_setup zha_new") ezsp_ = bellows.ezsp.EZSP() usb_path = config[DOMAIN].get(CONF_USB_PATH) baudrate = config[DOMAIN].get(CONF_BAUDRATE) await ezsp_.connect(usb_path, baudrate) database = config[DOMAIN].get(CONF_DATABASE) APPLICATION_CONTROLLER = ControllerApplication(ezsp_, database) listener = ApplicationListener(hass, config) APPLICATION_CONTROLLER.add_listener(listener) await APPLICATION_CONTROLLER.startup(auto_form=True) listener.component = component = EntityComponent(_LOGGER, DOMAIN, hass, datetime.timedelta(minutes=1)) zha_controller = zha_state(hass, ezsp_, APPLICATION_CONTROLLER, 'controller', 'Init') listener.controller = zha_controller listener.registry = await hass.helpers.device_registry.async_get_registry() await component.async_add_entities([zha_controller]) zha_controller.async_schedule_update_ha_state() # await asyncio.sleep(5) for device in APPLICATION_CONTROLLER.devices.values(): hass.async_add_job(listener.async_device_initialized(device, False)) await asyncio.sleep(0.1) async def permit(service): """Allow devices to join this network.""" duration = service.data.get(ATTR_DURATION) _LOGGER.info("Permitting joins for %ss", duration) zha_controller._state = 'Permit' zha_controller.async_schedule_update_ha_state() await APPLICATION_CONTROLLER.permit(duration) async def _async_clear_state(entity): if entity._state == 'Permit': entity._state = 'Run' entity.async_schedule_update_ha_state() async_track_point_in_time( zha_controller.hass, _async_clear_state(zha_controller), dt_util.utcnow() + datetime.timedelta(seconds=duration)) hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit, schema=SERVICE_SCHEMAS[SERVICE_PERMIT]) async def remove(service): """remove device from the network""" ieee_list = [] ieee = service.data.get(ATTR_IEEE) nwk = service.data.get(ATTR_NWKID) if ieee == '' and nwk is None: _LOGGER.debug("service remove device str empty") return _LOGGER.debug("service remove device str: %s", ieee if ieee else nwk) for device in APPLICATION_CONTROLLER.devices.values(): if (ieee in str(device._ieee) and ieee != '') or nwk == device.nwk: ieee_list.append(device.ieee) for device in ieee_list: await APPLICATION_CONTROLLER.remove(device) hass.services.async_register(DOMAIN, SERVICE_REMOVE, remove, schema=SERVICE_SCHEMAS[SERVICE_REMOVE]) async def command(service): listener.command(service.data) # hass.services.async_register(DOMAIN, SERVICE_COMMAND, command, # schema=SERVICE_SCHEMAS[SERVICE_COMMAND]) async def mc_command(service): listener.mc_command(service.data) hass.services.async_register(DOMAIN, SERVICE_MC_COMMAND, mc_command, schema=SERVICE_SCHEMAS[SERVICE_MC_COMMAND]) async def async_handle_light_step_up_service(service, *args, **kwargs): _LOGGER.debug("called service light_step_up %s %s", args, kwargs) return hass.services.async_register( DOMAIN, SERVICE_COLORTEMP_STEP_UP, async_handle_light_step_up_service, schema=SERVICE_SCHEMAS[SERVICE_COLORTEMP_STEP]) zha_controller._state = "Run" zha_controller.async_schedule_update_ha_state() return True