Migrate shelly Bluetooth scanner to use correct MAC address (#140180)

This commit is contained in:
J. Nick Koston 2025-03-09 01:28:56 -10:00 committed by GitHub
parent 4e7dd92a3d
commit d9d47f7203
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 24 additions and 14 deletions

View File

@ -12,7 +12,7 @@ from aioshelly.exceptions import (
InvalidAuthError, InvalidAuthError,
MacAddressMismatchError, MacAddressMismatchError,
) )
from aioshelly.rpc_device import RpcDevice from aioshelly.rpc_device import RpcDevice, bluetooth_mac_from_primary_mac
import voluptuous as vol import voluptuous as vol
from homeassistant.components.bluetooth import async_remove_scanner from homeassistant.components.bluetooth import async_remove_scanner
@ -339,4 +339,5 @@ async def async_remove_entry(hass: HomeAssistant, entry: ShellyConfigEntry) -> N
if get_device_entry_gen(entry) in RPC_GENERATIONS and ( if get_device_entry_gen(entry) in RPC_GENERATIONS and (
mac_address := entry.unique_id mac_address := entry.unique_id
): ):
async_remove_scanner(hass, mac_address) source = dr.format_mac(bluetooth_mac_from_primary_mac(mac_address)).upper()
async_remove_scanner(hass, source)

View File

@ -9,7 +9,6 @@ from aioshelly.ble.const import BLE_SCAN_RESULT_EVENT, BLE_SCAN_RESULT_VERSION
from homeassistant.components.bluetooth import async_register_scanner from homeassistant.components.bluetooth import async_register_scanner
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback as hass_callback from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback as hass_callback
from homeassistant.helpers.device_registry import format_mac
from ..const import BLEScannerMode from ..const import BLEScannerMode
@ -26,8 +25,7 @@ async def async_connect_scanner(
"""Connect scanner.""" """Connect scanner."""
device = coordinator.device device = coordinator.device
entry = coordinator.config_entry entry = coordinator.config_entry
source = format_mac(coordinator.mac).upper() scanner = create_scanner(coordinator.bluetooth_source, entry.title)
scanner = create_scanner(source, entry.title)
unload_callbacks = [ unload_callbacks = [
async_register_scanner( async_register_scanner(
hass, hass,

View File

@ -18,6 +18,7 @@ from aioshelly.exceptions import (
RpcCallError, RpcCallError,
) )
from aioshelly.rpc_device import RpcDevice, RpcUpdateType from aioshelly.rpc_device import RpcDevice, RpcUpdateType
from aioshelly.rpc_device.utils import bluetooth_mac_from_primary_mac
from propcache.api import cached_property from propcache.api import cached_property
from homeassistant.components.bluetooth import async_remove_scanner from homeassistant.components.bluetooth import async_remove_scanner
@ -496,6 +497,15 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
self._connect_task: asyncio.Task | None = None self._connect_task: asyncio.Task | None = None
entry.async_on_unload(entry.add_update_listener(self._async_update_listener)) entry.async_on_unload(entry.add_update_listener(self._async_update_listener))
@cached_property
def bluetooth_source(self) -> str:
"""Return the Bluetooth source address.
This is the Bluetooth MAC address of the device that is used
for the Bluetooth scanner.
"""
return format_mac(bluetooth_mac_from_primary_mac(self.mac)).upper()
async def async_device_online(self, source: str) -> None: async def async_device_online(self, source: str) -> None:
"""Handle device going online.""" """Handle device going online."""
if not self.sleep_period: if not self.sleep_period:
@ -706,7 +716,7 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
) )
if ble_scanner_mode == BLEScannerMode.DISABLED and self.connected: if ble_scanner_mode == BLEScannerMode.DISABLED and self.connected:
await async_stop_scanner(self.device) await async_stop_scanner(self.device)
async_remove_scanner(self.hass, format_mac(self.mac).upper()) async_remove_scanner(self.hass, self.bluetooth_source)
return return
if await async_ensure_ble_enabled(self.device): if await async_ensure_ble_enabled(self.device):
# BLE enable required a reboot, don't bother connecting # BLE enable required a reboot, don't bother connecting

View File

@ -8,7 +8,6 @@ from homeassistant.components.bluetooth import async_scanner_by_source
from homeassistant.components.diagnostics import async_redact_data from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import format_mac
from .coordinator import ShellyConfigEntry from .coordinator import ShellyConfigEntry
from .utils import get_rpc_ws_url from .utils import get_rpc_ws_url
@ -86,8 +85,7 @@ async def async_get_config_entry_diagnostics(
if k in ["sys", "wifi"] if k in ["sys", "wifi"]
} }
source = format_mac(rpc_coordinator.mac).upper() if scanner := async_scanner_by_source(hass, rpc_coordinator.bluetooth_source):
if scanner := async_scanner_by_source(hass, source):
bluetooth = { bluetooth = {
"scanner": await scanner.async_diagnostics(), "scanner": await scanner.async_diagnostics(),
} }

View File

@ -134,17 +134,17 @@ async def test_rpc_config_entry_diagnostics(
-62, -62,
[], [],
], ],
"details": {"source": "12:34:56:78:9A:BC"}, "details": {"source": "12:34:56:78:9A:BE"},
"name": None, "name": None,
"rssi": -62, "rssi": -62,
} }
], ],
"last_detection": ANY, "last_detection": ANY,
"monotonic_time": ANY, "monotonic_time": ANY,
"name": "Mock Title (12:34:56:78:9A:BC)", "name": "Mock Title (12:34:56:78:9A:BE)",
"scanning": True, "scanning": True,
"start_time": ANY, "start_time": ANY,
"source": "12:34:56:78:9A:BC", "source": "12:34:56:78:9A:BE",
"time_since_last_device_detection": {"AA:BB:CC:DD:EE:FF": ANY}, "time_since_last_device_detection": {"AA:BB:CC:DD:EE:FF": ANY},
"type": "ShellyBLEScanner", "type": "ShellyBLEScanner",
} }

View File

@ -11,6 +11,7 @@ from aioshelly.exceptions import (
InvalidAuthError, InvalidAuthError,
MacAddressMismatchError, MacAddressMismatchError,
) )
from aioshelly.rpc_device.utils import bluetooth_mac_from_primary_mac
import pytest import pytest
from homeassistant.components.shelly.const import ( from homeassistant.components.shelly.const import (
@ -27,7 +28,7 @@ from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
from homeassistant.const import CONF_HOST, CONF_PORT, STATE_ON, STATE_UNAVAILABLE from homeassistant.const import CONF_HOST, CONF_PORT, STATE_ON, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import issue_registry as ir from homeassistant.helpers import issue_registry as ir
from homeassistant.helpers.device_registry import DeviceRegistry from homeassistant.helpers.device_registry import DeviceRegistry, format_mac
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from . import init_integration, mutate_rpc_device_status from . import init_integration, mutate_rpc_device_status
@ -545,4 +546,6 @@ async def test_bluetooth_cleanup_on_remove_entry(
await hass.config_entries.async_remove(entry.entry_id) await hass.config_entries.async_remove(entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
remove_mock.assert_called_once_with(hass, entry.unique_id.upper()) remove_mock.assert_called_once_with(
hass, format_mac(bluetooth_mac_from_primary_mac(entry.unique_id)).upper()
)