async def set_chime_paired_doorbells(hass: HomeAssistant, call: ServiceCall) -> None: """Set paired doorbells on chime.""" ref = async_extract_referenced_entity_ids(hass, call) entity_registry = er.async_get(hass) entity_id = ref.indirectly_referenced.pop() chime_button = entity_registry.async_get(entity_id) assert chime_button is not None assert chime_button.device_id is not None chime_ufp_device_id = _async_unique_id_to_ufp_device_id( chime_button.unique_id) instance = _async_get_ufp_instance(hass, chime_button.device_id) chime = instance.bootstrap.chimes[chime_ufp_device_id] call.data = ReadOnlyDict(call.data.get("doorbells") or {}) doorbell_refs = async_extract_referenced_entity_ids(hass, call) doorbell_ids: set[str] = set() for camera_id in doorbell_refs.referenced | doorbell_refs.indirectly_referenced: doorbell_sensor = entity_registry.async_get(camera_id) assert doorbell_sensor is not None if (doorbell_sensor.platform != DOMAIN or doorbell_sensor.domain != Platform.BINARY_SENSOR or doorbell_sensor.original_device_class != BinarySensorDeviceClass.OCCUPANCY): continue doorbell_ufp_device_id = _async_unique_id_to_ufp_device_id( doorbell_sensor.unique_id) camera = instance.bootstrap.cameras[doorbell_ufp_device_id] doorbell_ids.add(camera.id) chime.camera_ids = sorted(doorbell_ids) await chime.save_device()
def _async_get_protect_from_call(hass: HomeAssistant, call: ServiceCall) -> set[ProtectApiClient]: return { _async_get_ufp_instance(hass, device_id) for device_id in async_extract_referenced_entity_ids( hass, call).referenced_devices }
async def async_handle_turn_service(service: ha.ServiceCall) -> None: """Handle calls to homeassistant.turn_on/off.""" referenced = async_extract_referenced_entity_ids(hass, service) all_referenced = referenced.referenced | referenced.indirectly_referenced # Generic turn on/off method requires entity id if not all_referenced: _LOGGER.error( "The service homeassistant.%s cannot be called without a target", service.service, ) return # Group entity_ids by domain. groupby requires sorted data. by_domain = it.groupby(sorted(all_referenced), lambda item: ha.split_entity_id(item)[0]) tasks = [] unsupported_entities = set() for domain, ent_ids in by_domain: # This leads to endless loop. if domain == DOMAIN: _LOGGER.warning( "Called service homeassistant.%s with invalid entities %s", service.service, ", ".join(ent_ids), ) continue if not hass.services.has_service(domain, service.service): unsupported_entities.update( set(ent_ids) & referenced.referenced) continue # Create a new dict for this call data = dict(service.data) # ent_ids is a generator, convert it to a list. data[ATTR_ENTITY_ID] = list(ent_ids) tasks.append( hass.services.async_call( domain, service.service, data, blocking=True, context=service.context, )) if unsupported_entities: _LOGGER.warning( "The service homeassistant.%s does not support entities %s", service.service, ", ".join(sorted(unsupported_entities)), ) if tasks: await asyncio.gather(*tasks)
async def service_handler(service: ServiceCall) -> None: """Apply a service, i.e. start an effect.""" referenced = async_extract_referenced_entity_ids( self.hass, service) all_referenced = referenced.referenced | referenced.indirectly_referenced if all_referenced: await self.start_effect(all_referenced, service.service, **service.data)
def _async_get_protect_from_call( hass: HomeAssistant, call: ServiceCall) -> list[tuple[dr.DeviceEntry, ProtectApiClient]]: referenced = async_extract_referenced_entity_ids(hass, call) instances: list[tuple[dr.DeviceEntry, ProtectApiClient]] = [] for device_id in referenced.referenced_devices: instances.append(_async_get_ufp_instances(hass, device_id)) return instances