async def async_step_user(self, user_input: dict[str, Any] | None = None ) -> FlowResult: """Handle the user step to pick discovered device.""" if user_input is not None: address = user_input[CONF_ADDRESS] await self.async_set_unique_id(address, raise_on_progress=False) self._abort_if_unique_id_configured() return self.async_create_entry( title=self._discovered_devices[address], data={}) current_addresses = self._async_current_ids() for discovery_info in async_discovered_service_info(self.hass, False): address = discovery_info.address if address in current_addresses or address in self._discovered_devices: continue device = DeviceData() if device.supported(discovery_info): self._discovered_devices[address] = (device.title or device.get_device_name() or discovery_info.name) if not self._discovered_devices: return self.async_abort(reason="no_devices_found") return self.async_show_form( step_id="user", data_schema=vol.Schema( {vol.Required(CONF_ADDRESS): vol.In(self._discovered_devices)}), )
def async_find_existing_service_info( hass: HomeAssistant, local_name: str, address: str) -> BluetoothServiceInfoBleak | None: """Return the service info for the given local_name and address.""" for service_info in async_discovered_service_info(hass): device = service_info.device if device.address == address: return service_info return None
async def async_step_user(self, user_input: dict[str, Any] | None = None ) -> FlowResult: """Handle the user step to pick discovered device.""" if user_input is not None: address = user_input[CONF_ADDRESS] await self.async_set_unique_id(address, raise_on_progress=False) self._abort_if_unique_id_configured() discovery = self._discovered_devices[address] self.context["title_placeholders"] = {"name": discovery.title} # Wait until we have received enough information about this device to detect its encryption type try: self._discovery_info = await self._async_wait_for_full_advertisement( discovery.discovery_info, discovery.device) except asyncio.TimeoutError: # This device might have a really long advertising interval # So create a config entry for it, and if we discover it has encryption later # We can do a reauth return await self.async_step_confirm_slow() self._discovered_device = discovery.device if discovery.device.encryption_scheme == EncryptionScheme.MIBEACON_LEGACY: return await self.async_step_get_encryption_key_legacy() if discovery.device.encryption_scheme == EncryptionScheme.MIBEACON_4_5: return await self.async_step_get_encryption_key_4_5() return self._async_get_or_create_entry() current_addresses = self._async_current_ids() for discovery_info in async_discovered_service_info(self.hass, False): address = discovery_info.address if address in current_addresses or address in self._discovered_devices: continue device = DeviceData() if device.supported(discovery_info): self._discovered_devices[address] = Discovery( title=_title(discovery_info, device), discovery_info=discovery_info, device=device, ) if not self._discovered_devices: return self.async_abort(reason="no_devices_found") titles = { address: discovery.title for (address, discovery) in self._discovered_devices.items() } return self.async_show_form( step_id="user", data_schema=vol.Schema( {vol.Required(CONF_ADDRESS): vol.In(titles)}), )
async def _async_has_devices(hass: HomeAssistant) -> bool: """Return if there are devices that can be discovered.""" service_infos = async_discovered_service_info(hass) for service_info in service_infos: if device_filter(service_info.device, service_info.advertisement): return True return False
def _async_refresh_ble(now: datetime) -> None: """Refresh BLE devices from the discovered service info.""" # Make sure devices are seen again at the scheduled # interval so they do not get set to not_home when # there have been no callbacks because the RSSI or # other properties have not changed. for service_info in bluetooth.async_discovered_service_info( hass, False): _async_update_ble(service_info, bluetooth.BluetoothChange.ADVERTISEMENT)
async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> FlowResult: """Handle the user step to pick discovered device.""" if user_input is not None: address = user_input[CONF_ADDRESS] await self.async_set_unique_id(address, raise_on_progress=False) self._abort_if_unique_id_configured() discovery = self._discovered_devices[address] self.context["title_placeholders"] = {"name": discovery.title} self._discovery_info = discovery.discovery_info self._discovered_device = discovery.device if discovery.device.encryption_scheme == EncryptionScheme.BTHOME_BINDKEY: return await self.async_step_get_encryption_key() return self._async_get_or_create_entry() current_addresses = self._async_current_ids() for discovery_info in async_discovered_service_info(self.hass, False): address = discovery_info.address if address in current_addresses or address in self._discovered_devices: continue device = DeviceData() if device.supported(discovery_info): self._discovered_devices[address] = Discovery( title=_title(discovery_info, device), discovery_info=discovery_info, device=device, ) if not self._discovered_devices: return self.async_abort(reason="no_devices_found") titles = { address: discovery.title for (address, discovery) in self._discovered_devices.items() } return self.async_show_form( step_id="user", data_schema=vol.Schema({vol.Required(CONF_ADDRESS): vol.In(titles)}), )
def _async_discover_devices(self) -> None: current_addresses = self._async_current_ids() for connectable in (True, False): for discovery_info in async_discovered_service_info(self.hass, connectable): address = discovery_info.address if ( format_unique_id(address) in current_addresses or address in self._discovered_advs ): continue parsed = parse_advertisement_data( discovery_info.device, discovery_info.advertisement ) if not parsed: continue model_name = parsed.data.get("modelName") if ( discovery_info.connectable and model_name in CONNECTABLE_SUPPORTED_MODEL_TYPES ) or model_name in NON_CONNECTABLE_SUPPORTED_MODEL_TYPES: self._discovered_advs[address] = parsed if not self._discovered_advs: raise AbortFlow("no_unconfigured_devices")
_LOGGER.exception("Unexpected error") errors["base"] = "unknown" else: await led_ble.stop() return self.async_create_entry( title=local_name, data={ CONF_ADDRESS: discovery_info.address, }, ) if discovery := self._discovery_info: self._discovered_devices[discovery.address] = discovery else: current_addresses = self._async_current_ids() for discovery in async_discovered_service_info(self.hass): if (discovery.address in current_addresses or discovery.address in self._discovered_devices or not any( discovery.name.startswith(local_name) and not discovery.name.startswith( UNSUPPORTED_SUB_MODEL) for local_name in LOCAL_NAMES)): continue self._discovered_devices[discovery.address] = discovery if not self._discovered_devices: return self.async_abort(reason="no_unconfigured_devices") data_schema = vol.Schema({ vol.Required(CONF_ADDRESS):