Issue #902 - Sonoff TRVZB workaround to the 'hvac_action' always Idle issue
This commit is contained in:
@@ -1158,7 +1158,8 @@ class UnderlyingValveRegulation(UnderlyingValve):
|
|||||||
if self.have_closing_degree_entity:
|
if self.have_closing_degree_entity:
|
||||||
await self._send_value_to_number(
|
await self._send_value_to_number(
|
||||||
self._closing_degree_entity_id,
|
self._closing_degree_entity_id,
|
||||||
closing_degree := self._max_opening_degree - self._percent_open,
|
# Patch to fix the hvac_action always Idle issue (issue #902)
|
||||||
|
closing_degree := max(self._max_opening_degree - 1 - self._percent_open, 0),
|
||||||
)
|
)
|
||||||
|
|
||||||
# send offset_calibration to the difference between target temp and local temp
|
# send offset_calibration to the difference between target temp and local temp
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ async def test_over_climate_valve_mono(hass: HomeAssistant, skip_hass_states_get
|
|||||||
mock_service_call.assert_has_calls(
|
mock_service_call.assert_has_calls(
|
||||||
[
|
[
|
||||||
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree'}),
|
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 100}, target={'entity_id': 'number.mock_closing_degree'}),
|
call(domain='number', service='set_value', service_data={'value': 99}, target={'entity_id': 'number.mock_closing_degree'}),
|
||||||
call("climate","set_temperature",{
|
call("climate","set_temperature",{
|
||||||
"entity_id": "climate.mock_climate",
|
"entity_id": "climate.mock_climate",
|
||||||
"temperature": 15, # temp-min
|
"temperature": 15, # temp-min
|
||||||
@@ -188,7 +188,7 @@ async def test_over_climate_valve_mono(hass: HomeAssistant, skip_hass_states_get
|
|||||||
[
|
[
|
||||||
call('climate', 'set_temperature', {'entity_id': 'climate.mock_climate', 'temperature': 19.0}),
|
call('climate', 'set_temperature', {'entity_id': 'climate.mock_climate', 'temperature': 19.0}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 40}, target={'entity_id': 'number.mock_opening_degree'}),
|
call(domain='number', service='set_value', service_data={'value': 40}, target={'entity_id': 'number.mock_opening_degree'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 60}, target={'entity_id': 'number.mock_closing_degree'}),
|
call(domain='number', service='set_value', service_data={'value': 59}, target={'entity_id': 'number.mock_closing_degree'}),
|
||||||
# 3 = 18 (room) - 15 (current of underlying) + 0 (current offset)
|
# 3 = 18 (room) - 15 (current of underlying) + 0 (current offset)
|
||||||
call(domain='number', service='set_value', service_data={'value': 3.0}, target={'entity_id': 'number.mock_offset_calibration'})
|
call(domain='number', service='set_value', service_data={'value': 3.0}, target={'entity_id': 'number.mock_offset_calibration'})
|
||||||
]
|
]
|
||||||
@@ -234,7 +234,7 @@ async def test_over_climate_valve_mono(hass: HomeAssistant, skip_hass_states_get
|
|||||||
mock_service_call.assert_has_calls(
|
mock_service_call.assert_has_calls(
|
||||||
[
|
[
|
||||||
call(domain='number', service='set_value', service_data={'value': 13}, target={'entity_id': 'number.mock_opening_degree'}),
|
call(domain='number', service='set_value', service_data={'value': 13}, target={'entity_id': 'number.mock_opening_degree'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 87}, target={'entity_id': 'number.mock_closing_degree'}),
|
call(domain='number', service='set_value', service_data={'value': 86}, target={'entity_id': 'number.mock_closing_degree'}),
|
||||||
# 6 = 18 (room) - 15 (current of underlying) + 3 (current offset)
|
# 6 = 18 (room) - 15 (current of underlying) + 3 (current offset)
|
||||||
call(domain='number', service='set_value', service_data={'value': 6.899999999999999}, target={'entity_id': 'number.mock_offset_calibration'})
|
call(domain='number', service='set_value', service_data={'value': 6.899999999999999}, target={'entity_id': 'number.mock_offset_calibration'})
|
||||||
]
|
]
|
||||||
@@ -280,7 +280,7 @@ async def test_over_climate_valve_mono(hass: HomeAssistant, skip_hass_states_get
|
|||||||
mock_service_call.assert_has_calls(
|
mock_service_call.assert_has_calls(
|
||||||
[
|
[
|
||||||
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree'}),
|
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 100}, target={'entity_id': 'number.mock_closing_degree'}),
|
call(domain='number', service='set_value', service_data={'value': 99}, target={'entity_id': 'number.mock_closing_degree'}),
|
||||||
# 6 = 18 (room) - 15 (current of underlying) + 3 (current offset)
|
# 6 = 18 (room) - 15 (current of underlying) + 3 (current offset)
|
||||||
call(domain='number', service='set_value', service_data={'value': 9.0}, target={'entity_id': 'number.mock_offset_calibration'})
|
call(domain='number', service='set_value', service_data={'value': 9.0}, target={'entity_id': 'number.mock_offset_calibration'})
|
||||||
]
|
]
|
||||||
@@ -365,25 +365,13 @@ async def test_over_climate_valve_multi_presence(
|
|||||||
mock_get_state_side_effect = SideEffects(
|
mock_get_state_side_effect = SideEffects(
|
||||||
{
|
{
|
||||||
# Valve 1 is open
|
# Valve 1 is open
|
||||||
"number.mock_opening_degree1": State(
|
"number.mock_opening_degree1": State("number.mock_opening_degree1", "10", {"min": 0, "max": 100}),
|
||||||
"number.mock_opening_degree1", "10", {"min": 0, "max": 100}
|
"number.mock_closing_degree1": State("number.mock_closing_degree1", "89", {"min": 0, "max": 100}),
|
||||||
),
|
"number.mock_offset_calibration1": State("number.mock_offset_calibration1", "0", {"min": -12, "max": 12}),
|
||||||
"number.mock_closing_degree1": State(
|
|
||||||
"number.mock_closing_degree1", "90", {"min": 0, "max": 100}
|
|
||||||
),
|
|
||||||
"number.mock_offset_calibration1": State(
|
|
||||||
"number.mock_offset_calibration1", "0", {"min": -12, "max": 12}
|
|
||||||
),
|
|
||||||
# Valve 2 is closed
|
# Valve 2 is closed
|
||||||
"number.mock_opening_degree2": State(
|
"number.mock_opening_degree2": State("number.mock_opening_degree2", "0", {"min": 0, "max": 100}),
|
||||||
"number.mock_opening_degree2", "0", {"min": 0, "max": 100}
|
"number.mock_closing_degree2": State("number.mock_closing_degree2", "99", {"min": 0, "max": 100}),
|
||||||
),
|
"number.mock_offset_calibration2": State("number.mock_offset_calibration2", "10", {"min": -12, "max": 12}),
|
||||||
"number.mock_closing_degree2": State(
|
|
||||||
"number.mock_closing_degree2", "100", {"min": 0, "max": 100}
|
|
||||||
),
|
|
||||||
"number.mock_offset_calibration2": State(
|
|
||||||
"number.mock_offset_calibration2", "10", {"min": -12, "max": 12}
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
State("unknown.entity_id", "unknown"),
|
State("unknown.entity_id", "unknown"),
|
||||||
)
|
)
|
||||||
@@ -443,10 +431,10 @@ async def test_over_climate_valve_multi_presence(
|
|||||||
call('climate', 'set_temperature', {'entity_id': 'climate.mock_climate1', 'temperature': 19.0}),
|
call('climate', 'set_temperature', {'entity_id': 'climate.mock_climate1', 'temperature': 19.0}),
|
||||||
call('climate', 'set_temperature', {'entity_id': 'climate.mock_climate2', 'temperature': 19.0}),
|
call('climate', 'set_temperature', {'entity_id': 'climate.mock_climate2', 'temperature': 19.0}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 40}, target={'entity_id': 'number.mock_opening_degree1'}),
|
call(domain='number', service='set_value', service_data={'value': 40}, target={'entity_id': 'number.mock_opening_degree1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 60}, target={'entity_id': 'number.mock_closing_degree1'}),
|
call(domain='number', service='set_value', service_data={'value': 59}, target={'entity_id': 'number.mock_closing_degree1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 3.0}, target={'entity_id': 'number.mock_offset_calibration1'}),
|
call(domain='number', service='set_value', service_data={'value': 3.0}, target={'entity_id': 'number.mock_offset_calibration1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 40}, target={'entity_id': 'number.mock_opening_degree2'}),
|
call(domain='number', service='set_value', service_data={'value': 40}, target={'entity_id': 'number.mock_opening_degree2'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 60}, target={'entity_id': 'number.mock_closing_degree2'}),
|
call(domain='number', service='set_value', service_data={'value': 59}, target={'entity_id': 'number.mock_closing_degree2'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 12}, target={'entity_id': 'number.mock_offset_calibration2'})
|
call(domain='number', service='set_value', service_data={'value': 12}, target={'entity_id': 'number.mock_offset_calibration2'})
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -474,10 +462,10 @@ async def test_over_climate_valve_multi_presence(
|
|||||||
call('climate', 'set_temperature', {'entity_id': 'climate.mock_climate1', 'temperature': 17.2}),
|
call('climate', 'set_temperature', {'entity_id': 'climate.mock_climate1', 'temperature': 17.2}),
|
||||||
call('climate', 'set_temperature', {'entity_id': 'climate.mock_climate2', 'temperature': 17.2}),
|
call('climate', 'set_temperature', {'entity_id': 'climate.mock_climate2', 'temperature': 17.2}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree1'}),
|
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 100}, target={'entity_id': 'number.mock_closing_degree1'}),
|
call(domain='number', service='set_value', service_data={'value': 99}, target={'entity_id': 'number.mock_closing_degree1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 3.0}, target={'entity_id': 'number.mock_offset_calibration1'}),
|
call(domain='number', service='set_value', service_data={'value': 3.0}, target={'entity_id': 'number.mock_offset_calibration1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree2'}),
|
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree2'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 100}, target={'entity_id': 'number.mock_closing_degree2'}),
|
call(domain='number', service='set_value', service_data={'value': 99}, target={'entity_id': 'number.mock_closing_degree2'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 12}, target={'entity_id': 'number.mock_offset_calibration2'})
|
call(domain='number', service='set_value', service_data={'value': 12}, target={'entity_id': 'number.mock_offset_calibration2'})
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -628,10 +616,10 @@ async def test_over_climate_valve_multi_min_opening_degrees(
|
|||||||
mock_service_call.assert_has_calls([
|
mock_service_call.assert_has_calls([
|
||||||
# min is 60
|
# min is 60
|
||||||
call(domain='number', service='set_value', service_data={'value': 68}, target={'entity_id': 'number.mock_opening_degree1'}),
|
call(domain='number', service='set_value', service_data={'value': 68}, target={'entity_id': 'number.mock_opening_degree1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 32}, target={'entity_id': 'number.mock_closing_degree1'}),
|
call(domain='number', service='set_value', service_data={'value': 31}, target={'entity_id': 'number.mock_closing_degree1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 3.0}, target={'entity_id': 'number.mock_offset_calibration1'}),
|
call(domain='number', service='set_value', service_data={'value': 3.0}, target={'entity_id': 'number.mock_offset_calibration1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 76}, target={'entity_id': 'number.mock_opening_degree2'}),
|
call(domain='number', service='set_value', service_data={'value': 76}, target={'entity_id': 'number.mock_opening_degree2'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 24}, target={'entity_id': 'number.mock_closing_degree2'}),
|
call(domain='number', service='set_value', service_data={'value': 23}, target={'entity_id': 'number.mock_closing_degree2'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 12}, target={'entity_id': 'number.mock_offset_calibration2'})
|
call(domain='number', service='set_value', service_data={'value': 12}, target={'entity_id': 'number.mock_offset_calibration2'})
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -657,10 +645,10 @@ async def test_over_climate_valve_multi_min_opening_degrees(
|
|||||||
assert mock_service_call.call_count == 6
|
assert mock_service_call.call_count == 6
|
||||||
mock_service_call.assert_has_calls([
|
mock_service_call.assert_has_calls([
|
||||||
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree1'}),
|
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 100}, target={'entity_id': 'number.mock_closing_degree1'}),
|
call(domain='number', service='set_value', service_data={'value': 99}, target={'entity_id': 'number.mock_closing_degree1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 7.0}, target={'entity_id': 'number.mock_offset_calibration1'}),
|
call(domain='number', service='set_value', service_data={'value': 7.0}, target={'entity_id': 'number.mock_offset_calibration1'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree2'}),
|
call(domain='number', service='set_value', service_data={'value': 0}, target={'entity_id': 'number.mock_opening_degree2'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 100}, target={'entity_id': 'number.mock_closing_degree2'}),
|
call(domain='number', service='set_value', service_data={'value': 99}, target={'entity_id': 'number.mock_closing_degree2'}),
|
||||||
call(domain='number', service='set_value', service_data={'value': 12}, target={'entity_id': 'number.mock_offset_calibration2'})
|
call(domain='number', service='set_value', service_data={'value': 12}, target={'entity_id': 'number.mock_offset_calibration2'})
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user