1
0
mirror of https://github.com/home-assistant/core.git synced 2026-07-15 02:23:47 +01:00
Files
2026-07-07 14:10:08 +02:00

127 lines
3.4 KiB
Python

"""Bluetooth proxy for SLZB devices using bleak-smlight."""
from functools import partial
import logging
from bleak_smlight import SLZB_BLE_SERVER_PORT, connect_scanner
from pysmlight import Api2, BleProxyClient, Info
from homeassistant.components.bluetooth import (
BluetoothScanningMode,
async_register_scanner,
)
from homeassistant.const import CONF_HOST
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.helpers import device_registry as dr
from .const import CONF_BLE_SCANNER_MODE, DOMAIN, BLEScannerMode
from .coordinator import SmConfigEntry, base_device_info
_LOGGER = logging.getLogger(__name__)
@callback
def _async_unload(
unload_callbacks: list[CALLBACK_TYPE],
client: BleProxyClient,
) -> None:
"""Unload callbacks and stop client."""
for callback_func in unload_callbacks:
callback_func()
client.stop()
@callback
def async_connect_scanner(
hass: HomeAssistant,
entry: SmConfigEntry,
model: str | None,
device_id: str,
scanner_mode: BluetoothScanningMode = BluetoothScanningMode.AUTO,
) -> CALLBACK_TYPE:
"""Connect scanner using the external bleak-smlight backend."""
assert entry.unique_id is not None
client_data = connect_scanner(
source=entry.unique_id,
name=entry.title,
host=entry.data[CONF_HOST],
port=SLZB_BLE_SERVER_PORT,
)
client_data.scanner.async_set_scanning_mode(scanner_mode)
entry.async_create_background_task(
hass,
client_data.client.start(),
f"smlight-ble-proxy-client-{entry.unique_id}",
)
unload_callbacks = [
async_register_scanner(
hass,
client_data.scanner,
source_domain=DOMAIN,
source_model=model,
source_config_entry_id=entry.entry_id,
source_device_id=device_id,
),
client_data.scanner.async_setup(),
]
return partial(_async_unload, unload_callbacks, client_data.client)
async def async_setup_ble_scanner(
hass: HomeAssistant,
entry: SmConfigEntry,
client: Api2,
info: Info,
) -> CALLBACK_TYPE | None:
"""Set up the BLE scanner/proxy configuration."""
assert info.ble is not None
scanner_mode = get_ble_scanner_mode(entry, info)
remote_adapter_enabled = scanner_mode != BLEScannerMode.DISABLED
if remote_adapter_enabled:
if not info.ble.proxy_enabled:
_LOGGER.warning(
"SMLIGHT BLE proxy is enabled in Home Assistant options but disabled on the device. "
"Please reconfigure the integration options to align settings"
)
return None
device_registry = dr.async_get(hass)
device = device_registry.async_get_or_create(
config_entry_id=entry.entry_id,
**base_device_info(info, client.host),
)
return async_connect_scanner(
hass,
entry,
info.model,
device.id,
BluetoothScanningMode(scanner_mode),
)
return None
@callback
def get_ble_scanner_mode(
entry: SmConfigEntry,
info: Info,
) -> BLEScannerMode:
"""Get the BLE scanner mode config or default."""
if info.ble is None:
return BLEScannerMode.DISABLED
return BLEScannerMode(
entry.options.get(
CONF_BLE_SCANNER_MODE,
BLEScannerMode.AUTO if info.ble.proxy_enabled else BLEScannerMode.DISABLED,
)
)