mirror of
https://github.com/home-assistant/core.git
synced 2025-11-14 05:20:17 +00:00
Add Bluetooth WebSocket API to subscribe to scanner details (#136750)
This commit is contained in:
@@ -7,7 +7,12 @@ from functools import lru_cache, partial
|
||||
import time
|
||||
from typing import Any
|
||||
|
||||
from habluetooth import BluetoothScanningMode, HaBluetoothSlotAllocations
|
||||
from habluetooth import (
|
||||
BluetoothScanningMode,
|
||||
HaBluetoothSlotAllocations,
|
||||
HaScannerRegistration,
|
||||
HaScannerRegistrationEvent,
|
||||
)
|
||||
from home_assistant_bluetooth import BluetoothServiceInfoBleak
|
||||
import voluptuous as vol
|
||||
|
||||
@@ -16,6 +21,7 @@ from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.json import json_bytes
|
||||
|
||||
from .api import _get_manager, async_register_callback
|
||||
from .const import DOMAIN
|
||||
from .match import BluetoothCallbackMatcher
|
||||
from .models import BluetoothChange
|
||||
from .util import InvalidConfigEntryID, InvalidSource, config_entry_id_to_source
|
||||
@@ -26,6 +32,7 @@ def async_setup(hass: HomeAssistant) -> None:
|
||||
"""Set up the bluetooth websocket API."""
|
||||
websocket_api.async_register_command(hass, ws_subscribe_advertisements)
|
||||
websocket_api.async_register_command(hass, ws_subscribe_connection_allocations)
|
||||
websocket_api.async_register_command(hass, ws_subscribe_scanner_details)
|
||||
|
||||
|
||||
@lru_cache(maxsize=1024)
|
||||
@@ -191,3 +198,58 @@ async def ws_subscribe_connection_allocations(
|
||||
connection.send_message(
|
||||
json_bytes(websocket_api.event_message(ws_msg_id, current_allocations))
|
||||
)
|
||||
|
||||
|
||||
@websocket_api.require_admin
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "bluetooth/subscribe_scanner_details",
|
||||
vol.Optional("config_entry_id"): str,
|
||||
}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
async def ws_subscribe_scanner_details(
|
||||
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
|
||||
) -> None:
|
||||
"""Handle subscribe scanner details websocket command."""
|
||||
ws_msg_id = msg["id"]
|
||||
source: str | None = None
|
||||
if config_entry_id := msg.get("config_entry_id"):
|
||||
if (
|
||||
not (entry := hass.config_entries.async_get_entry(config_entry_id))
|
||||
or entry.domain != DOMAIN
|
||||
):
|
||||
connection.send_error(
|
||||
ws_msg_id,
|
||||
"invalid_config_entry_id",
|
||||
f"Invalid config entry id: {config_entry_id}",
|
||||
)
|
||||
return
|
||||
source = entry.unique_id
|
||||
assert source is not None
|
||||
|
||||
def _async_event_message(message: dict[str, Any]) -> None:
|
||||
connection.send_message(
|
||||
json_bytes(websocket_api.event_message(ws_msg_id, message))
|
||||
)
|
||||
|
||||
def _async_registration_changed(registration: HaScannerRegistration) -> None:
|
||||
added_event = HaScannerRegistrationEvent.ADDED
|
||||
event_type = "add" if registration.event == added_event else "remove"
|
||||
_async_event_message({event_type: [registration.scanner.details]})
|
||||
|
||||
manager = _get_manager(hass)
|
||||
connection.subscriptions[ws_msg_id] = (
|
||||
manager.async_register_scanner_registration_callback(
|
||||
_async_registration_changed, source
|
||||
)
|
||||
)
|
||||
connection.send_message(json_bytes(websocket_api.result_message(ws_msg_id)))
|
||||
if (scanners := manager.async_current_scanners()) and (
|
||||
matching_scanners := [
|
||||
scanner.details
|
||||
for scanner in scanners
|
||||
if source is None or scanner.source == source
|
||||
]
|
||||
):
|
||||
_async_event_message({"add": matching_scanners})
|
||||
|
||||
Reference in New Issue
Block a user