From 075e9eeccd2a3afb2eb7a15d9abbdc54f99b3362 Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Fri, 24 Jan 2025 23:48:26 +0100 Subject: [PATCH 1/7] Bump aioshelly --- homeassistant/components/shelly/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/shelly/manifest.json b/homeassistant/components/shelly/manifest.json index cf5c59da5e3a75..e0d8c03ffc49b6 100644 --- a/homeassistant/components/shelly/manifest.json +++ b/homeassistant/components/shelly/manifest.json @@ -8,7 +8,7 @@ "integration_type": "device", "iot_class": "local_push", "loggers": ["aioshelly"], - "requirements": ["aioshelly==12.3.1"], + "requirements": ["aioshelly==12.3.2"], "zeroconf": [ { "type": "_http._tcp.local.", diff --git a/requirements_all.txt b/requirements_all.txt index 8f8c70082357b9..f3e0a26bd527d7 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -368,7 +368,7 @@ aioruuvigateway==0.1.0 aiosenz==1.0.0 # homeassistant.components.shelly -aioshelly==12.3.1 +aioshelly==12.3.2 # homeassistant.components.skybell aioskybell==22.7.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 3751dd24184c94..76b38b44cc211a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -350,7 +350,7 @@ aioruuvigateway==0.1.0 aiosenz==1.0.0 # homeassistant.components.shelly -aioshelly==12.3.1 +aioshelly==12.3.2 # homeassistant.components.skybell aioskybell==22.7.0 From 607f41bfd9d8e0e6ad16598c7f0765b6a6ec7a00 Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Sun, 26 Jan 2025 21:59:07 +0100 Subject: [PATCH 2/7] Add timeout parameter for call_rpc --- homeassistant/components/shelly/entity.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/shelly/entity.py b/homeassistant/components/shelly/entity.py index 8c9044aeaff379..e1c314634834bb 100644 --- a/homeassistant/components/shelly/entity.py +++ b/homeassistant/components/shelly/entity.py @@ -390,7 +390,9 @@ def _update_callback(self) -> None: """Handle device update.""" self.async_write_ha_state() - async def call_rpc(self, method: str, params: Any) -> Any: + async def call_rpc( + self, method: str, params: Any, timeout: float | None = None + ) -> Any: """Call RPC method.""" LOGGER.debug( "Call RPC for entity %s, method: %s, params: %s", @@ -399,6 +401,8 @@ async def call_rpc(self, method: str, params: Any) -> Any: params, ) try: + if timeout: + return await self.coordinator.device.call_rpc(method, params, timeout) return await self.coordinator.device.call_rpc(method, params) except DeviceConnectionError as err: self.coordinator.last_update_success = False From 34bc59f4a0100d6a11013c355bd7d90d815101e7 Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Sun, 26 Jan 2025 22:12:48 +0100 Subject: [PATCH 3/7] Increase timeout for BLU TRV --- homeassistant/components/shelly/climate.py | 2 ++ homeassistant/components/shelly/const.py | 3 +++ homeassistant/components/shelly/number.py | 13 ++++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/shelly/climate.py b/homeassistant/components/shelly/climate.py index f8e157a6a5d589..f1491acdd81a3f 100644 --- a/homeassistant/components/shelly/climate.py +++ b/homeassistant/components/shelly/climate.py @@ -36,6 +36,7 @@ from .const import ( BLU_TRV_TEMPERATURE_SETTINGS, + BLU_TRV_TIMEOUT, DOMAIN, LOGGER, NOT_CALIBRATED_ISSUE_ID, @@ -604,4 +605,5 @@ async def async_set_temperature(self, **kwargs: Any) -> None: "method": "Trv.SetTarget", "params": {"id": 0, "target_C": target_temp}, }, + timeout=BLU_TRV_TIMEOUT, ) diff --git a/homeassistant/components/shelly/const.py b/homeassistant/components/shelly/const.py index f81ba5ca7f70ac..e78a6f1a59df6f 100644 --- a/homeassistant/components/shelly/const.py +++ b/homeassistant/components/shelly/const.py @@ -265,3 +265,6 @@ class BLEScannerMode(StrEnum): API_WS_URL = "/api/shelly/ws" COMPONENT_ID_PATTERN = re.compile(r"[a-z\d]+:\d+") + +# value confirmed by Shelly team +BLU_TRV_TIMEOUT = 60 diff --git a/homeassistant/components/shelly/number.py b/homeassistant/components/shelly/number.py index fb61c885423ca3..7140c79fbb64e4 100644 --- a/homeassistant/components/shelly/number.py +++ b/homeassistant/components/shelly/number.py @@ -25,7 +25,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_registry import RegistryEntry -from .const import CONF_SLEEP_PERIOD, LOGGER, VIRTUAL_NUMBER_MODE_MAP +from .const import BLU_TRV_TIMEOUT, CONF_SLEEP_PERIOD, LOGGER, VIRTUAL_NUMBER_MODE_MAP from .coordinator import ShellyBlockCoordinator, ShellyConfigEntry, ShellyRpcCoordinator from .entity import ( BlockEntityDescription, @@ -127,6 +127,17 @@ def __init__( connections={(CONNECTION_BLUETOOTH, ble_addr)} ) + async def async_set_native_value(self, value: float) -> None: + """Change the value.""" + if TYPE_CHECKING: + assert isinstance(self._id, int) + + await self.call_rpc( + self.entity_description.method, + self.entity_description.method_params_fn(self._id, value), + timeout=BLU_TRV_TIMEOUT, + ) + NUMBERS: dict[tuple[str, str], BlockNumberDescription] = { ("device", "valvePos"): BlockNumberDescription( From e798d598123c198dd309f99667920cbb64102ba8 Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Sun, 26 Jan 2025 22:20:04 +0100 Subject: [PATCH 4/7] Log timeout --- homeassistant/components/shelly/entity.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/shelly/entity.py b/homeassistant/components/shelly/entity.py index e1c314634834bb..001727c74b3fd5 100644 --- a/homeassistant/components/shelly/entity.py +++ b/homeassistant/components/shelly/entity.py @@ -395,10 +395,11 @@ async def call_rpc( ) -> Any: """Call RPC method.""" LOGGER.debug( - "Call RPC for entity %s, method: %s, params: %s", + "Call RPC for entity %s, method: %s, params: %s, timeout: %s", self.name, method, params, + timeout, ) try: if timeout: From 21436a22e652cd7ef85d871ae5c573c6b4bcebaa Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Sun, 26 Jan 2025 22:20:59 +0100 Subject: [PATCH 5/7] Update test --- tests/components/shelly/test_climate.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/components/shelly/test_climate.py b/tests/components/shelly/test_climate.py index 352bdcb0a7d69d..bdc37b58993e65 100644 --- a/tests/components/shelly/test_climate.py +++ b/tests/components/shelly/test_climate.py @@ -804,6 +804,7 @@ async def test_blu_trv_climate_set_temperature( "method": "Trv.SetTarget", "params": {"id": 0, "target_C": 28.0}, }, + 60, ) assert get_entity_attribute(hass, entity_id, ATTR_TEMPERATURE) == 28 From 1d013c71e29518089e487863bc3e46c922eddd51 Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Sun, 26 Jan 2025 22:25:35 +0100 Subject: [PATCH 6/7] Use const in test --- tests/components/shelly/test_climate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/components/shelly/test_climate.py b/tests/components/shelly/test_climate.py index bdc37b58993e65..5ad298c15a1ec1 100644 --- a/tests/components/shelly/test_climate.py +++ b/tests/components/shelly/test_climate.py @@ -26,7 +26,7 @@ HVACAction, HVACMode, ) -from homeassistant.components.shelly.const import DOMAIN +from homeassistant.components.shelly.const import BLU_TRV_TIMEOUT, DOMAIN from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState from homeassistant.const import ( @@ -804,7 +804,7 @@ async def test_blu_trv_climate_set_temperature( "method": "Trv.SetTarget", "params": {"id": 0, "target_C": 28.0}, }, - 60, + BLU_TRV_TIMEOUT, ) assert get_entity_attribute(hass, entity_id, ATTR_TEMPERATURE) == 28 From 015dc8b7e3ed931354f2425023c79ca5520a899f Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Mon, 27 Jan 2025 09:03:03 +0100 Subject: [PATCH 7/7] Coverage --- tests/components/shelly/test_number.py | 38 +++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/tests/components/shelly/test_number.py b/tests/components/shelly/test_number.py index 2a64ab839ea3a1..15ed098093b27d 100644 --- a/tests/components/shelly/test_number.py +++ b/tests/components/shelly/test_number.py @@ -18,7 +18,7 @@ SERVICE_SET_VALUE, NumberMode, ) -from homeassistant.components.shelly.const import DOMAIN +from homeassistant.components.shelly.const import BLU_TRV_TIMEOUT, DOMAIN from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState from homeassistant.const import ATTR_ENTITY_ID, ATTR_UNIT_OF_MEASUREMENT, STATE_UNKNOWN from homeassistant.core import HomeAssistant, State @@ -415,3 +415,39 @@ async def test_blu_trv_number_entity( entry = entity_registry.async_get(entity_id) assert entry == snapshot(name=f"{entity_id}-entry") + + +async def test_blu_trv_set_value( + hass: HomeAssistant, + mock_blu_trv: Mock, + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Test the set value action for BLU TRV number entity.""" + await init_integration(hass, 3, model=MODEL_BLU_GATEWAY_GEN3) + + entity_id = f"{NUMBER_DOMAIN}.trv_name_external_temperature" + + assert hass.states.get(entity_id).state == "15.2" + + monkeypatch.setitem(mock_blu_trv.status["blutrv:200"], "current_C", 22.2) + await hass.services.async_call( + NUMBER_DOMAIN, + SERVICE_SET_VALUE, + { + ATTR_ENTITY_ID: f"{NUMBER_DOMAIN}.trv_name_external_temperature", + ATTR_VALUE: 22.2, + }, + blocking=True, + ) + mock_blu_trv.mock_update() + mock_blu_trv.call_rpc.assert_called_once_with( + "BluTRV.Call", + { + "id": 200, + "method": "Trv.SetExternalTemperature", + "params": {"id": 0, "t_C": 22.2}, + }, + BLU_TRV_TIMEOUT, + ) + + assert hass.states.get(entity_id).state == "22.2"