def handle_service_remove_device(call): dev_id = call.data.get("dev_id") dev_id = [int(x,0) for x in dev_id[1:-1].split(",")] # remove device from registry dreg = asyncio.run_coroutine_threadsafe( hass.helpers.device_registry.async_get_registry() , hass.loop).result() dreg_dev = dreg.async_get_device({(DOMAIN, combine_hex(dev_id))}, set()) dreg.async_remove_device(device_id=dreg_dev.id) # remove device from domain specific data hass.data[DOMAIN][DATA_DEVICES].pop(combine_hex(dev_id)) # remove device from database file database_remove_device(db_file, dev_id)
def device_info(self): _LOGGER.debug(self.hass.data[DOMAIN].keys()) return { "identifiers": { # Serial numbers are unique identifiers within a specific domain (DOMAIN, combine_hex(self.dev_id)) }, "name": self.dev_name, "manufacturer": self.dev_manufacturer, "model": self.dev_model, "sw_version": self.dev_sw_version, "via_device": self.dev_via_device, }
async def async_add_switches(): dreg = await hass.helpers.device_registry.async_get_registry() devices = hass.data[DOMAIN][DATA_DEVICES] _LOGGER.debug(f"[async_add_switches()] devices: {devices}") for dev in devices.values(): if CONF_SWITCHES in dev[ATTR_DEVICE_CLASS].keys(): if not dev[CONF_LOADED]: dev_id = dev[CONF_ID] dev_manufacturer = dev[CONF_MANUFACTURER] dev_model = dev[CONF_MODEL] dev_no_of_channels = dev[ATTR_DEVICE_CLASS][CONF_SWITCHES][ CONF_NO_OF_CHANNELS] _LOGGER.debug( f"Class '{CONF_SWITCHES}' found for device id {dev_id}!" ) # delay device initialization randomly within [0,DELAY_INIT) seconds to avoid conflicts/timeouts with many devices rand_nb = random.random() * DELAY_INIT await asyncio.sleep(rand_nb) async_add_entities([ EnOceanSwitch( dev_id=dev_id, dev_name= f"{ENOCEAN_SWITCH}, ID [{', '.join([hex(x) for x in dev_id])}]", dev_manufacturer=dev_manufacturer, dev_model=dev_model, dev_via_device=( DOMAIN, combine_hex( hass.data[DOMAIN][DATA_BASE][CONF_ID])), dev_channel=dev_ch, ) for dev_ch in range(0, dev_no_of_channels) ]) hass.data[DOMAIN][DATA_DEVICES][combine_hex( dev_id)][CONF_LOADED] = True
def handle_service_add_switch(call): dev_data = { CONF_ID: [int(x,0) for x in call.data.get("dev_id")[1:-1].split(",")], CONF_NAME: None, CONF_MANUFACTURER: call.data.get("dev_manufacturer"), CONF_MODEL: call.data.get("dev_model"), CONF_VIA_DEVICE: hass.data[DOMAIN][DATA_BASE][CONF_ID], CONF_LOADED: False, ATTR_DEVICE_CLASS: { CONF_SWITCHES: { CONF_NO_OF_CHANNELS: call.data.get("dev_no_of_channels"), }, } } _LOGGER.debug(f"[handle_service_add_switch()] dev_data: {dev_data}") hass.data[DOMAIN][DATA_DEVICES][combine_hex(dev[CONF_ID])] = dev_data hass.helpers.dispatcher.async_dispatcher_send(SIGNAL_ADD_ENTITIES) database_add_device(db_file, dev_data)
def _wait_for_base_id(self): """wait until the base id is ready""" time_step = 0.05 time_counter = 0 while not self._shutdown: # wait for getting the adapter id time.sleep(time_step) time_counter += time_step if time_counter > 30: raise RuntimeError("Couldn't get my own Enocean ID!?") base_id = self._enocean_connector.base_id if base_id: # got a base id EnoceanPacketFactory.set_sender_id(base_id) if type(base_id) == list: base_id = enocean_utils.combine_hex(base_id) _logger.info("base_id=%s", hex(base_id)) break
def _message_received_callback(self, packet): """Handle incoming packets.""" from enocean.utils import combine_hex if packet.sender_int == combine_hex(self.dev_id): self.value_changed(packet)
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry): """Set up EnOcean from a config entry.""" _LOGGER.debug(f"[async_setup_entry()] config_entry.data: {config_entry.data}") _LOGGER.debug(f"[async_setup_entry()] config_entry.options: {config_entry.options}") if DOMAIN not in hass.data.keys(): hass.data[DOMAIN] = {} hass.data[DOMAIN][DATA_DISPATCHERS] = [] """Set up EnOcean Hub from Config Entry.""" _LOGGER.debug(f"Class '{CONF_BASE}' found in config_entry attributes!") """Set up the EnOcean hub.""" dongle = EnOceanDongle( hass, config_entry.data[ATTR_DEVICE_CLASS][CONF_BASE][CONF_SERIAL_PORT] ) hass.data[DOMAIN][DATA_DONGLE] = dongle _LOGGER.debug(f"[async_setup_entry()] dongle.dev_id: {dongle.dev_id}") dreg = await hass.helpers.device_registry.async_get_registry() dreg.async_get_or_create( config_entry_id=config_entry.entry_id, name=f"{ENOCEAN_TRANSCEIVER}, ID [{', '.join([hex(x) for x in dongle.dev_id])}]", connections=None, identifiers={(DOMAIN, combine_hex(dongle.dev_id))}, manufacturer=config_entry.data[CONF_MANUFACTURER], model=config_entry.data[CONF_MODEL], sw_version=None, via_device=None, ) # get device object for hub device = dreg.async_get_device({(DOMAIN, combine_hex(dongle.dev_id))}, set()) hass.data[DOMAIN][DATA_BASE] = { CONF_ENTRY_ID: config_entry.entry_id, CONF_ID: dongle.dev_id, } database_name = DEFAULT_DATABASE_NAME db_file = os.path.join(hass.config.config_dir, database_name) db_state = database_init(hass, db_file) dev_data = { CONF_ID: dongle.dev_id, CONF_MANUFACTURER: config_entry.data[CONF_MANUFACTURER], CONF_MODEL: config_entry.data[CONF_MODEL], CONF_LOADED: True, ATTR_DEVICE_CLASS: config_entry.data[ATTR_DEVICE_CLASS], } if db_state==RETURN_DB_NEW: database_add_device(db_file, dev_data) elif db_state==RETURN_DB_EXISTING: database_update_hub(db_file, dev_data) hass.data[DOMAIN][DATA_DEVICES] = {} dev_all = database_get_device(db_file, [0xFF,0xFF,0xFF,0xFF]) for dev in dev_all: dev[CONF_LOADED] = False hass.data[DOMAIN][DATA_DEVICES][combine_hex(dev[CONF_ID])] = dev _LOGGER.debug(f"[async_setup_entry()] dev_all: {hass.data[DOMAIN][DATA_DEVICES]}") to_setup = [] for component in PLATFORMS: task = hass.async_create_task( hass.config_entries.async_forward_entry_setup(config_entry, component) ) to_setup.append(task) hass.data[DOMAIN][DATA_PLATFORM] = to_setup _LOGGER.debug(f"[async_setup_entry()] to_setup: {to_setup}") asyncio.create_task(async_load_entities(hass)) #config_entry.add_update_listener(update_listener) def handle_service_teach_in(call): dev_id = call.data.get("dev_id") dev_id = [int(x,0) for x in dev_id[1:-1].split(",")] _LOGGER.debug(f"[handle_service_teach_in]: {dev_id}") hass.helpers.dispatcher.dispatcher_send(SIGNAL_TEACH_IN, dev_id) hass.services.async_register( domain=DOMAIN, service=SERVICE_TEACH_IN, service_func=handle_service_teach_in, schema=vol.Schema( { vol.Required("dev_id"): str, } ), ) def handle_service_add_switch(call): dev_data = { CONF_ID: [int(x,0) for x in call.data.get("dev_id")[1:-1].split(",")], CONF_NAME: None, CONF_MANUFACTURER: call.data.get("dev_manufacturer"), CONF_MODEL: call.data.get("dev_model"), CONF_VIA_DEVICE: hass.data[DOMAIN][DATA_BASE][CONF_ID], CONF_LOADED: False, ATTR_DEVICE_CLASS: { CONF_SWITCHES: { CONF_NO_OF_CHANNELS: call.data.get("dev_no_of_channels"), }, } } _LOGGER.debug(f"[handle_service_add_switch()] dev_data: {dev_data}") hass.data[DOMAIN][DATA_DEVICES][combine_hex(dev[CONF_ID])] = dev_data hass.helpers.dispatcher.async_dispatcher_send(SIGNAL_ADD_ENTITIES) database_add_device(db_file, dev_data) hass.services.async_register( domain=DOMAIN, service=SERVICE_ADD_SWITCH, service_func=handle_service_add_switch, schema=vol.Schema( { vol.Required("dev_id"): str, vol.Required("dev_manufacturer"): str, vol.Required("dev_model"): str, vol.Required("dev_no_of_channels"): int, } ), ) def handle_service_remove_device(call): dev_id = call.data.get("dev_id") dev_id = [int(x,0) for x in dev_id[1:-1].split(",")] # remove device from registry dreg = asyncio.run_coroutine_threadsafe( hass.helpers.device_registry.async_get_registry() , hass.loop).result() dreg_dev = dreg.async_get_device({(DOMAIN, combine_hex(dev_id))}, set()) dreg.async_remove_device(device_id=dreg_dev.id) # remove device from domain specific data hass.data[DOMAIN][DATA_DEVICES].pop(combine_hex(dev_id)) # remove device from database file database_remove_device(db_file, dev_id) hass.services.async_register( domain=DOMAIN, service=SERVICE_REMOVE_DEVICE, service_func=handle_service_remove_device, schema=vol.Schema( { vol.Required("dev_id"): str, } ), ) return True
def _packet_received_callback(self, packet): """Handle incoming packets.""" if packet.sender_int == combine_hex(self.dev_id): self.packet_receiver(packet)
def _teach_in_callback(self, dev_id): """Handle teach in.""" if combine_hex(dev_id) == combine_hex(self.dev_id): self.teach_in()