Allow Bluetooth proxy for Shelly devices only if Zigbee firmware is not active (#149193)

Co-authored-by: Shay Levy <levyshay1@gmail.com>
Co-authored-by: Norbert Rittel <norbert@rittel.de>
This commit is contained in:
Maciej Bieniek 2025-07-24 20:14:44 +02:00 committed by GitHub
parent 5c4862ffe1
commit 56c53fdb9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 14 additions and 13 deletions

View File

@ -298,7 +298,7 @@ async def _async_setup_rpc_entry(hass: HomeAssistant, entry: ShellyConfigEntry)
translation_key="firmware_unsupported", translation_key="firmware_unsupported",
translation_placeholders={"device": entry.title}, translation_placeholders={"device": entry.title},
) )
runtime_data.rpc_zigbee_enabled = device.zigbee_enabled runtime_data.rpc_zigbee_firmware = device.zigbee_firmware
runtime_data.rpc_supports_scripts = await device.supports_scripts() runtime_data.rpc_supports_scripts = await device.supports_scripts()
if runtime_data.rpc_supports_scripts: if runtime_data.rpc_supports_scripts:
runtime_data.rpc_script_events = await get_rpc_scripts_event_types( runtime_data.rpc_script_events = await get_rpc_scripts_event_types(

View File

@ -475,8 +475,8 @@ class OptionsFlowHandler(OptionsFlow):
return self.async_abort(reason="cannot_connect") return self.async_abort(reason="cannot_connect")
if not supports_scripts: if not supports_scripts:
return self.async_abort(reason="no_scripts_support") return self.async_abort(reason="no_scripts_support")
if self.config_entry.runtime_data.rpc_zigbee_enabled: if self.config_entry.runtime_data.rpc_zigbee_firmware:
return self.async_abort(reason="zigbee_enabled") return self.async_abort(reason="zigbee_firmware")
if user_input is not None: if user_input is not None:
return self.async_create_entry(title="", data=user_input) return self.async_create_entry(title="", data=user_input)

View File

@ -94,7 +94,7 @@ class ShellyEntryData:
rpc_poll: ShellyRpcPollingCoordinator | None = None rpc_poll: ShellyRpcPollingCoordinator | None = None
rpc_script_events: dict[int, list[str]] | None = None rpc_script_events: dict[int, list[str]] | None = None
rpc_supports_scripts: bool | None = None rpc_supports_scripts: bool | None = None
rpc_zigbee_enabled: bool | None = None rpc_zigbee_firmware: bool | None = None
type ShellyConfigEntry = ConfigEntry[ShellyEntryData] type ShellyConfigEntry = ConfigEntry[ShellyEntryData]
@ -730,7 +730,7 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
if not self.sleep_period: if not self.sleep_period:
if ( if (
self.config_entry.runtime_data.rpc_supports_scripts self.config_entry.runtime_data.rpc_supports_scripts
and not self.config_entry.runtime_data.rpc_zigbee_enabled and not self.config_entry.runtime_data.rpc_zigbee_firmware
): ):
await self._async_connect_ble_scanner() await self._async_connect_ble_scanner()
else: else:

View File

@ -105,7 +105,7 @@
"abort": { "abort": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"no_scripts_support": "Device does not support scripts and cannot be used as a Bluetooth scanner.", "no_scripts_support": "Device does not support scripts and cannot be used as a Bluetooth scanner.",
"zigbee_enabled": "Device with Zigbee enabled cannot be used as a Bluetooth scanner. Please disable it to use the device as a Bluetooth scanner." "zigbee_firmware": "A device with Zigbee firmware cannot be used as a Bluetooth scanner. Please switch to Matter firmware to use the device as a Bluetooth scanner."
} }
}, },
"selector": { "selector": {

View File

@ -548,6 +548,7 @@ def _mock_rpc_device(version: str | None = None):
), ),
xmod_info={}, xmod_info={},
zigbee_enabled=False, zigbee_enabled=False,
zigbee_firmware=False,
ip_address="10.10.10.10", ip_address="10.10.10.10",
) )
type(device).name = PropertyMock(return_value="Test name") type(device).name = PropertyMock(return_value="Test name")

View File

@ -870,17 +870,17 @@ async def test_options_flow_abort_no_scripts_support(
assert result["reason"] == "no_scripts_support" assert result["reason"] == "no_scripts_support"
async def test_options_flow_abort_zigbee_enabled( async def test_options_flow_abort_zigbee_firmware(
hass: HomeAssistant, mock_rpc_device: Mock, monkeypatch: pytest.MonkeyPatch hass: HomeAssistant, mock_rpc_device: Mock, monkeypatch: pytest.MonkeyPatch
) -> None: ) -> None:
"""Test ble options abort if Zigbee is enabled for the device.""" """Test ble options abort if Zigbee firmware is active."""
monkeypatch.setattr(mock_rpc_device, "zigbee_enabled", True) monkeypatch.setattr(mock_rpc_device, "zigbee_firmware", True)
entry = await init_integration(hass, 4) entry = await init_integration(hass, 4)
result = await hass.config_entries.options.async_init(entry.entry_id) result = await hass.config_entries.options.async_init(entry.entry_id)
assert result["type"] is FlowResultType.ABORT assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "zigbee_enabled" assert result["reason"] == "zigbee_firmware"
async def test_zeroconf_already_configured(hass: HomeAssistant) -> None: async def test_zeroconf_already_configured(hass: HomeAssistant) -> None:

View File

@ -864,7 +864,7 @@ async def test_rpc_update_entry_fw_ver(
@pytest.mark.parametrize( @pytest.mark.parametrize(
("supports_scripts", "zigbee_enabled", "result"), ("supports_scripts", "zigbee_firmware", "result"),
[ [
(True, False, True), (True, False, True),
(True, True, False), (True, True, False),
@ -877,14 +877,14 @@ async def test_rpc_runs_connected_events_when_initialized(
mock_rpc_device: Mock, mock_rpc_device: Mock,
monkeypatch: pytest.MonkeyPatch, monkeypatch: pytest.MonkeyPatch,
supports_scripts: bool, supports_scripts: bool,
zigbee_enabled: bool, zigbee_firmware: bool,
result: bool, result: bool,
) -> None: ) -> None:
"""Test RPC runs connected events when initialized.""" """Test RPC runs connected events when initialized."""
monkeypatch.setattr( monkeypatch.setattr(
mock_rpc_device, "supports_scripts", AsyncMock(return_value=supports_scripts) mock_rpc_device, "supports_scripts", AsyncMock(return_value=supports_scripts)
) )
monkeypatch.setattr(mock_rpc_device, "zigbee_enabled", zigbee_enabled) monkeypatch.setattr(mock_rpc_device, "zigbee_firmware", zigbee_firmware)
monkeypatch.setattr(mock_rpc_device, "initialized", False) monkeypatch.setattr(mock_rpc_device, "initialized", False)
await init_integration(hass, 2) await init_integration(hass, 2)