Fix Shelly irrigation zone ID retrieval with Sleepy devices (#155514)

This commit is contained in:
Shay Levy
2025-10-31 01:05:14 +02:00
committed by GitHub
parent 4e3664b26f
commit 5b8d373527
2 changed files with 17 additions and 5 deletions
+8 -4
View File
@@ -417,7 +417,7 @@ def get_rpc_sub_device_name(
"""Get name based on device and channel name."""
if key in device.config and key != "em:0":
# workaround for Pro 3EM, we don't want to get name for em:0
if (zone_id := get_irrigation_zone_id(device.config, key)) is not None:
if (zone_id := get_irrigation_zone_id(device, key)) is not None:
# workaround for Irrigation controller, name stored in "service:0"
if zone_name := device.config["service:0"]["zones"][zone_id]["name"]:
return cast(str, zone_name)
@@ -792,9 +792,13 @@ async def get_rpc_scripts_event_types(
return script_events
def get_irrigation_zone_id(config: dict[str, Any], key: str) -> int | None:
def get_irrigation_zone_id(device: RpcDevice, key: str) -> int | None:
"""Return the zone id if the component is an irrigation zone."""
if key in config and (zone := get_rpc_role_by_key(config, key)).startswith("zone"):
if (
device.initialized
and key in device.config
and (zone := get_rpc_role_by_key(device.config, key)).startswith("zone")
):
return int(zone[4:])
return None
@@ -837,7 +841,7 @@ def get_rpc_device_info(
if (
(
component not in (*All_LIGHT_TYPES, "cover", "em1", "switch")
and get_irrigation_zone_id(device.config, key) is None
and get_irrigation_zone_id(device, key) is None
)
or idx is None
or len(get_rpc_key_instances(device.status, component, all_lights=True)) < 2
+9 -1
View File
@@ -1,9 +1,10 @@
"""Tests for Shelly sensor platform."""
from copy import deepcopy
from unittest.mock import Mock
from unittest.mock import Mock, PropertyMock
from aioshelly.const import MODEL_BLU_GATEWAY_G3
from aioshelly.exceptions import NotInitialized
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy.assertion import SnapshotAssertion
@@ -52,6 +53,7 @@ from . import (
register_device,
register_entity,
)
from .conftest import MOCK_CONFIG, MOCK_SHELLY_RPC, MOCK_STATUS_RPC
from tests.common import (
async_fire_time_changed,
@@ -632,6 +634,9 @@ async def test_rpc_restored_sleeping_sensor(
extra_data = {"native_value": "21.0", "native_unit_of_measurement": "°C"}
mock_restore_cache_with_extra_data(hass, ((State(entity_id, ""), extra_data),))
type(mock_rpc_device).shelly = PropertyMock(side_effect=NotInitialized())
type(mock_rpc_device).config = PropertyMock(side_effect=NotInitialized())
type(mock_rpc_device).status = PropertyMock(side_effect=NotInitialized())
monkeypatch.setattr(mock_rpc_device, "initialized", False)
await hass.config_entries.async_setup(entry.entry_id)
@@ -641,6 +646,9 @@ async def test_rpc_restored_sleeping_sensor(
assert state.state == "21.0"
# Make device online
type(mock_rpc_device).shelly = PropertyMock(return_value=MOCK_SHELLY_RPC)
type(mock_rpc_device).config = PropertyMock(return_value=MOCK_CONFIG)
type(mock_rpc_device).status = PropertyMock(return_value=MOCK_STATUS_RPC)
monkeypatch.setattr(mock_rpc_device, "initialized", True)
mock_rpc_device.mock_online()
await hass.async_block_till_done(wait_background_tasks=True)