Don't use the current temperature from Shelly BLU TRV as a state for External Temperature number entity (#137658)

Introduce RpcBluTrvExtTempNumber for External Temperature entity
pull/137688/head
Maciej Bieniek 2025-02-07 16:32:28 +01:00 committed by Franck Nijhof
parent 7508c14a53
commit 657e3488ba
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
3 changed files with 68 additions and 10 deletions

View File

@ -139,6 +139,24 @@ class RpcBluTrvNumber(RpcNumber):
) )
class RpcBluTrvExtTempNumber(RpcBluTrvNumber):
"""Represent a RPC BluTrv External Temperature number."""
_reported_value: float | None = None
@property
def native_value(self) -> float | None:
"""Return value of number."""
return self._reported_value
async def async_set_native_value(self, value: float) -> None:
"""Change the value."""
await super().async_set_native_value(value)
self._reported_value = value
self.async_write_ha_state()
NUMBERS: dict[tuple[str, str], BlockNumberDescription] = { NUMBERS: dict[tuple[str, str], BlockNumberDescription] = {
("device", "valvePos"): BlockNumberDescription( ("device", "valvePos"): BlockNumberDescription(
key="device|valvepos", key="device|valvepos",
@ -175,7 +193,7 @@ RPC_NUMBERS: Final = {
"method": "Trv.SetExternalTemperature", "method": "Trv.SetExternalTemperature",
"params": {"id": 0, "t_C": value}, "params": {"id": 0, "t_C": value},
}, },
entity_class=RpcBluTrvNumber, entity_class=RpcBluTrvExtTempNumber,
), ),
"number": RpcNumberDescription( "number": RpcNumberDescription(
key="number", key="number",

View File

@ -52,7 +52,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '15.2', 'state': 'unknown',
}) })
# --- # ---
# name: test_blu_trv_number_entity[number.trv_name_valve_position-entry] # name: test_blu_trv_number_entity[number.trv_name_valve_position-entry]

View File

@ -417,24 +417,23 @@ async def test_blu_trv_number_entity(
assert entry == snapshot(name=f"{entity_id}-entry") assert entry == snapshot(name=f"{entity_id}-entry")
async def test_blu_trv_set_value( async def test_blu_trv_ext_temp_set_value(
hass: HomeAssistant, hass: HomeAssistant, mock_blu_trv: Mock
mock_blu_trv: Mock,
monkeypatch: pytest.MonkeyPatch,
) -> None: ) -> None:
"""Test the set value action for BLU TRV number entity.""" """Test the set value action for BLU TRV External Temperature number entity."""
await init_integration(hass, 3, model=MODEL_BLU_GATEWAY_GEN3) await init_integration(hass, 3, model=MODEL_BLU_GATEWAY_GEN3)
entity_id = f"{NUMBER_DOMAIN}.trv_name_external_temperature" entity_id = f"{NUMBER_DOMAIN}.trv_name_external_temperature"
assert hass.states.get(entity_id).state == "15.2" # After HA start the state should be unknown because there was no previous external
# temperature report
assert hass.states.get(entity_id).state is STATE_UNKNOWN
monkeypatch.setitem(mock_blu_trv.status["blutrv:200"], "current_C", 22.2)
await hass.services.async_call( await hass.services.async_call(
NUMBER_DOMAIN, NUMBER_DOMAIN,
SERVICE_SET_VALUE, SERVICE_SET_VALUE,
{ {
ATTR_ENTITY_ID: f"{NUMBER_DOMAIN}.trv_name_external_temperature", ATTR_ENTITY_ID: entity_id,
ATTR_VALUE: 22.2, ATTR_VALUE: 22.2,
}, },
blocking=True, blocking=True,
@ -451,3 +450,44 @@ async def test_blu_trv_set_value(
) )
assert hass.states.get(entity_id).state == "22.2" assert hass.states.get(entity_id).state == "22.2"
async def test_blu_trv_valve_pos_set_value(
hass: HomeAssistant,
mock_blu_trv: Mock,
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Test the set value action for BLU TRV Valve Position number entity."""
# disable automatic temperature control to enable valve position entity
monkeypatch.setitem(mock_blu_trv.config["blutrv:200"], "enable", False)
await init_integration(hass, 3, model=MODEL_BLU_GATEWAY_GEN3)
entity_id = f"{NUMBER_DOMAIN}.trv_name_valve_position"
assert hass.states.get(entity_id).state == "0"
monkeypatch.setitem(mock_blu_trv.status["blutrv:200"], "pos", 20)
await hass.services.async_call(
NUMBER_DOMAIN,
SERVICE_SET_VALUE,
{
ATTR_ENTITY_ID: entity_id,
ATTR_VALUE: 20.0,
},
blocking=True,
)
mock_blu_trv.mock_update()
mock_blu_trv.call_rpc.assert_called_once_with(
"BluTRV.Call",
{
"id": 200,
"method": "Trv.SetPosition",
"params": {"id": 0, "pos": 20},
},
BLU_TRV_TIMEOUT,
)
# device only accepts int for 'pos' value
assert isinstance(mock_blu_trv.call_rpc.call_args[0][1]["params"]["pos"], int)
assert hass.states.get(entity_id).state == "20"