Add Motion manager. All tests ok

This commit is contained in:
Jean-Marc Collin
2024-12-26 15:42:29 +00:00
parent 887d59a08f
commit a11eaef9f7
16 changed files with 743 additions and 338 deletions

View File

@@ -599,12 +599,7 @@ async def create_thermostat(
await hass.config_entries.async_setup(entry.entry_id)
assert entry.state is ConfigEntryState.LOADED
# We should reload the VTherm links
# vtherm_api: VersatileThermostatAPI = VersatileThermostatAPI.get_vtherm_api()
# central_config = vtherm_api.find_central_configuration()
entity = search_entity(hass, entity_id, CLIMATE_DOMAIN)
# if entity and hasattr(entity, "init_presets")::
# await entity.init_presets(central_config)
return entity
@@ -839,7 +834,7 @@ async def send_motion_change_event(
),
},
)
ret = await entity._async_motion_changed(motion_event)
ret = await entity.motion_manager._motion_sensor_changed(motion_event)
if sleep:
await asyncio.sleep(0.1)
return ret
@@ -1009,7 +1004,7 @@ async def set_climate_preset_temp(
await temp_entity.async_set_native_value(temp)
else:
_LOGGER.warning(
"commons tests set_cliamte_preset_temp: cannot find number entity with entity_id '%s'",
"commons tests set_climate_preset_temp: cannot find number entity with entity_id '%s'",
number_entity_id,
)
@@ -1071,9 +1066,14 @@ async def set_all_climate_preset_temp(
NUMBER_DOMAIN,
)
assert temp_entity
if not temp_entity:
raise ConfigurationNotCompleteError(
f"'{number_entity_name}' don't exists as number entity"
)
# Because set_value is not implemented in Number class (really don't understand why...)
assert temp_entity.state == value
await hass.async_block_till_done()
#
# Side effects management

View File

@@ -310,6 +310,8 @@ async def test_motion_binary_sensors(
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
CONF_MOTION_DELAY: 0, # important to not been obliged to wait
CONF_MOTION_PRESET: PRESET_BOOST,
CONF_NO_MOTION_PRESET: PRESET_ECO,
},
)
@@ -329,7 +331,7 @@ async def test_motion_binary_sensors(
await entity.async_set_preset_mode(PRESET_COMFORT)
await entity.async_set_hvac_mode(HVACMode.HEAT)
await send_temperature_change_event(entity, 15, now)
assert entity.motion_state is None
assert entity.motion_state is STATE_UNKNOWN
await motion_binary_sensor.async_my_climate_changed()
assert motion_binary_sensor.state is STATE_OFF

View File

@@ -286,11 +286,14 @@ async def test_full_over_switch_wo_central_config(
assert entity._window_auto_open_threshold == 3
assert entity._window_auto_max_duration == 5
assert entity._motion_sensor_entity_id == "binary_sensor.mock_motion_sensor"
assert entity._motion_delay_sec == 10
assert entity._motion_off_delay_sec == 29
assert entity._motion_preset == "comfort"
assert entity._no_motion_preset == "eco"
assert (
entity.motion_manager.motion_sensor_entity_id
== "binary_sensor.mock_motion_sensor"
)
assert entity.motion_manager.motion_delay_sec == 10
assert entity.motion_manager.motion_off_delay_sec == 29
assert entity.motion_manager.motion_preset == "comfort"
assert entity.motion_manager.no_motion_preset == "eco"
assert entity.power_manager.power_sensor_entity_id == "sensor.mock_power_sensor"
assert (
@@ -406,11 +409,14 @@ async def test_full_over_switch_with_central_config(
assert entity._window_auto_open_threshold == 4
assert entity._window_auto_max_duration == 31
assert entity._motion_sensor_entity_id == "binary_sensor.mock_motion_sensor"
assert entity._motion_delay_sec == 31
assert entity._motion_off_delay_sec == 301
assert entity._motion_preset == "boost"
assert entity._no_motion_preset == "frost"
assert (
entity.motion_manager.motion_sensor_entity_id
== "binary_sensor.mock_motion_sensor"
)
assert entity.motion_manager.motion_delay_sec == 31
assert entity.motion_manager.motion_off_delay_sec == 301
assert entity.motion_manager.motion_preset == "boost"
assert entity.motion_manager.no_motion_preset == "frost"
assert entity.power_manager.power_sensor_entity_id == "sensor.mock_power_sensor"
assert (

View File

@@ -3,20 +3,286 @@
""" Test the Window management """
from datetime import datetime, timedelta
import logging
from unittest.mock import patch
from unittest.mock import patch, call, AsyncMock, MagicMock, PropertyMock
from custom_components.versatile_thermostat.base_thermostat import BaseThermostat
from custom_components.versatile_thermostat.feature_motion_manager import (
FeatureMotionManager,
)
from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import
logging.getLogger().setLevel(logging.DEBUG)
@pytest.mark.parametrize(
"current_state, new_state, temp, nb_call, motion_state, is_motion_detected, preset_refresh, changed",
[
(STATE_OFF, STATE_ON, 21, 1, STATE_ON, True, PRESET_BOOST, True),
# motion is ON. So is_motion_detected is true and preset is BOOST
(STATE_OFF, STATE_ON, 21, 1, STATE_ON, True, PRESET_BOOST, True),
# current_state is ON and motion is OFF. So is_motion_detected is false and preset is ECO
(STATE_ON, STATE_OFF, 17, 1, STATE_OFF, False, PRESET_ECO, True),
],
)
async def test_motion_feature_manager_refresh(
hass: HomeAssistant,
current_state,
new_state, # new state of motion event
temp,
nb_call,
motion_state,
is_motion_detected,
preset_refresh,
changed,
):
"""Test the FeatureMotionManager class direclty"""
fake_vtherm = MagicMock(spec=BaseThermostat)
type(fake_vtherm).name = PropertyMock(return_value="the name")
type(fake_vtherm).preset_mode = PropertyMock(return_value=PRESET_ACTIVITY)
# 1. creation
motion_manager = FeatureMotionManager(fake_vtherm, hass)
assert motion_manager is not None
assert motion_manager.is_configured is False
assert motion_manager.is_motion_detected is False
assert motion_manager.motion_state == STATE_UNAVAILABLE
assert motion_manager.name == "the name"
assert len(motion_manager._active_listener) == 0
custom_attributes = {}
motion_manager.add_custom_attributes(custom_attributes)
assert custom_attributes["motion_sensor_entity_id"] is None
assert custom_attributes["motion_state"] == STATE_UNAVAILABLE
assert custom_attributes["is_motion_configured"] is False
assert custom_attributes["motion_preset"] is None
assert custom_attributes["no_motion_preset"] is None
assert custom_attributes["motion_delay_sec"] == 0
assert custom_attributes["motion_off_delay_sec"] == 0
# 2. post_init
motion_manager.post_init(
{
CONF_MOTION_SENSOR: "sensor.the_motion_sensor",
CONF_USE_MOTION_FEATURE: True,
CONF_MOTION_DELAY: 10,
CONF_MOTION_OFF_DELAY: 30,
CONF_MOTION_PRESET: PRESET_BOOST,
CONF_NO_MOTION_PRESET: PRESET_ECO,
}
)
assert motion_manager.is_configured is True
assert motion_manager.motion_state == STATE_UNKNOWN
assert motion_manager.is_motion_detected is False
custom_attributes = {}
motion_manager.add_custom_attributes(custom_attributes)
assert custom_attributes["motion_sensor_entity_id"] == "sensor.the_motion_sensor"
assert custom_attributes["motion_state"] == STATE_UNKNOWN
assert custom_attributes["is_motion_configured"] is True
assert custom_attributes["motion_preset"] is PRESET_BOOST
assert custom_attributes["no_motion_preset"] is PRESET_ECO
assert custom_attributes["motion_delay_sec"] == 10
assert custom_attributes["motion_off_delay_sec"] == 30
# 3. start listening
motion_manager.start_listening()
assert motion_manager.is_configured is True
assert motion_manager.motion_state == STATE_UNKNOWN
assert motion_manager.is_motion_detected is False
assert len(motion_manager._active_listener) == 1
# 4. test refresh with the parametrized
# fmt:off
with patch("homeassistant.core.StateMachine.get", return_value=State("sensor.the_motion_sensor", new_state)) as mock_get_state:
# fmt:on
# Configurer les méthodes mockées
fake_vtherm.find_preset_temp.return_value = temp
fake_vtherm.change_target_temperature = AsyncMock()
fake_vtherm.async_control_heating = AsyncMock()
fake_vtherm.recalculate = MagicMock()
# force old state for the test
motion_manager._motion_state = current_state
ret = await motion_manager.refresh_state()
assert ret == changed
assert motion_manager.is_configured is True
# in the refresh there is no delay
assert motion_manager.motion_state == new_state
assert motion_manager.is_motion_detected is is_motion_detected
assert mock_get_state.call_count == 1
assert fake_vtherm.find_preset_temp.call_count == nb_call
if nb_call == 1:
fake_vtherm.find_preset_temp.assert_has_calls(
[
call.find_preset_temp(preset_refresh),
]
)
assert fake_vtherm.change_target_temperature.call_count == nb_call
fake_vtherm.change_target_temperature.assert_has_calls(
[
call.find_preset_temp(temp),
]
)
# We do not call control_heating at startup
assert fake_vtherm.recalculate.call_count == 0
assert fake_vtherm.async_control_heating.call_count == 0
fake_vtherm.reset_mock()
# 5. Check custom_attributes
custom_attributes = {}
motion_manager.add_custom_attributes(custom_attributes)
assert custom_attributes["motion_sensor_entity_id"] == "sensor.the_motion_sensor"
assert custom_attributes["motion_state"] == new_state
assert custom_attributes["is_motion_configured"] is True
assert custom_attributes["motion_preset"] is PRESET_BOOST
assert custom_attributes["no_motion_preset"] is PRESET_ECO
assert custom_attributes["motion_delay_sec"] == 10
assert custom_attributes["motion_off_delay_sec"] == 30
motion_manager.stop_listening()
await hass.async_block_till_done()
@pytest.mark.parametrize(
"current_state, long_enough, new_state, temp, nb_call, motion_state, is_motion_detected, preset_event, changed",
[
(STATE_OFF, True, STATE_ON, 21, 1, STATE_ON, True, PRESET_BOOST, True),
# motion is ON but for not enough time but sensor is on at the end. So is_motion_detected is true and preset is BOOST
(STATE_OFF, False, STATE_ON, 21, 1, STATE_ON, True, PRESET_BOOST, True),
# motion is OFF for enough time. So is_motion_detected is false and preset is ECO
(STATE_ON, True, STATE_OFF, 17, 1, STATE_OFF, False, PRESET_ECO, True),
# motion is OFF for not enough time. So is_motion_detected is false and preset is ECO
(STATE_ON, False, STATE_OFF, 21, 1, STATE_ON, True, PRESET_BOOST, True),
],
)
async def test_motion_feature_manager_event(
hass: HomeAssistant,
current_state,
long_enough,
new_state, # new state of motion event
temp,
nb_call,
motion_state,
is_motion_detected,
preset_event,
changed,
):
"""Test the FeatureMotionManager class direclty"""
fake_vtherm = MagicMock(spec=BaseThermostat)
type(fake_vtherm).name = PropertyMock(return_value="the name")
type(fake_vtherm).preset_mode = PropertyMock(return_value=PRESET_ACTIVITY)
# 1. iniitialization creation, post_init, start_listening
motion_manager = FeatureMotionManager(fake_vtherm, hass)
motion_manager.post_init(
{
CONF_MOTION_SENSOR: "sensor.the_motion_sensor",
CONF_USE_MOTION_FEATURE: True,
CONF_MOTION_DELAY: 10,
CONF_MOTION_OFF_DELAY: 30,
CONF_MOTION_PRESET: PRESET_BOOST,
CONF_NO_MOTION_PRESET: PRESET_ECO,
}
)
motion_manager.start_listening()
# 2. test _motion_sensor_changed with the parametrized
# fmt: off
with patch("homeassistant.helpers.condition.state", return_value=long_enough), \
patch("homeassistant.core.StateMachine.get", return_value=State("sensor.the_motion_sensor", new_state)):
# fmt: on
fake_vtherm.find_preset_temp.return_value = temp
fake_vtherm.change_target_temperature = AsyncMock()
fake_vtherm.async_control_heating = AsyncMock()
fake_vtherm.recalculate = MagicMock()
# force old state for the test
motion_manager._motion_state = current_state
delay = await motion_manager._motion_sensor_changed(
event=Event(
event_type=EVENT_STATE_CHANGED,
data={
"entity_id": "sensor.the_motion_sensor",
"new_state": State("sensor.the_motion_sensor", new_state),
"old_state": State("sensor.the_motion_sensor", STATE_UNAVAILABLE),
}))
assert delay is not None
await delay(None)
assert motion_manager.is_configured is True
assert motion_manager.motion_state == motion_state
assert motion_manager.is_motion_detected is is_motion_detected
assert fake_vtherm.find_preset_temp.call_count == nb_call
if nb_call == 1:
fake_vtherm.find_preset_temp.assert_has_calls(
[
call.find_preset_temp(preset_event),
]
)
assert fake_vtherm.change_target_temperature.call_count == nb_call
fake_vtherm.change_target_temperature.assert_has_calls(
[
call.find_preset_temp(temp),
]
)
assert fake_vtherm.recalculate.call_count == 1
assert fake_vtherm.async_control_heating.call_count == 1
fake_vtherm.async_control_heating.assert_has_calls([
call.async_control_heating(force=True)
])
fake_vtherm.reset_mock()
# 3. Check custom_attributes
custom_attributes = {}
motion_manager.add_custom_attributes(custom_attributes)
assert custom_attributes["motion_sensor_entity_id"] == "sensor.the_motion_sensor"
assert custom_attributes["motion_state"] == motion_state
assert custom_attributes["is_motion_configured"] is True
assert custom_attributes["motion_preset"] is PRESET_BOOST
assert custom_attributes["no_motion_preset"] is PRESET_ECO
assert custom_attributes["motion_delay_sec"] == 10
assert custom_attributes["motion_off_delay_sec"] == 30
motion_manager.stop_listening()
await hass.async_block_till_done()
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_movement_management_time_not_enough(
async def test_motion_management_time_not_enough(
hass: HomeAssistant, skip_hass_states_is_state
):
"""Test the Presence management when time is not enough"""
temps = {
"frost": 10,
"eco": 17,
"comfort": 18,
"boost": 19,
"frost_away": 10,
"eco_away": 17,
"comfort_away": 18,
"boost_away": 19,
}
entry = MockConfigEntry(
domain=DOMAIN,
@@ -30,17 +296,11 @@ async def test_movement_management_time_not_enough(
CONF_CYCLE_MIN: 5,
CONF_TEMP_MIN: 15,
CONF_TEMP_MAX: 30,
"eco_temp": 17,
"comfort_temp": 18,
"boost_temp": 19,
"eco_away_temp": 17,
"comfort_away_temp": 18,
"boost_away_temp": 19,
CONF_USE_WINDOW_FEATURE: False,
CONF_USE_MOTION_FEATURE: True,
CONF_USE_POWER_FEATURE: False,
CONF_USE_PRESENCE_FEATURE: True,
CONF_HEATER: "switch.mock_switch",
CONF_UNDERLYING_LIST: ["switch.mock_switch"],
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.01,
@@ -60,11 +320,12 @@ async def test_movement_management_time_not_enough(
hass, entry, "climate.theoverswitchmockname"
)
assert entity
await set_all_climate_preset_temp(hass, entity, temps, "theoverswitchmockname")
tz = get_tz(hass) # pylint: disable=invalid-name
now: datetime = datetime.now(tz=tz)
# start heating, in boost mode, when someone is present. We block the control_heating to avoid running a cycle
# 1. start heating, in boost mode, when someone is present. We block the control_heating to avoid running a cycle
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.async_control_heating"
):
@@ -75,7 +336,7 @@ async def test_movement_management_time_not_enough(
assert entity.preset_mode is PRESET_ACTIVITY
# because no motion is detected yet
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state is STATE_UNKNOWN
event_timestamp = now - timedelta(minutes=5)
@@ -83,9 +344,9 @@ async def test_movement_management_time_not_enough(
await send_ext_temperature_change_event(entity, 10, event_timestamp)
await send_presence_change_event(entity, True, False, event_timestamp)
assert entity.presence_state == "on"
assert entity.presence_state == STATE_ON
# starts detecting motion with time not enough
# 2. starts detecting motion with time not enough
with patch(
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event, patch(
@@ -104,7 +365,9 @@ async def test_movement_management_time_not_enough(
),
):
event_timestamp = now - timedelta(minutes=4)
try_condition = await send_motion_change_event(entity, True, False, event_timestamp)
try_condition = await send_motion_change_event(
entity, True, False, event_timestamp
)
# Will return False -> we will stay on movement False
await try_condition(None)
@@ -137,7 +400,9 @@ async def test_movement_management_time_not_enough(
"homeassistant.helpers.condition.state", return_value=True
) as mock_condition:
event_timestamp = now - timedelta(minutes=3)
try_condition = await send_motion_change_event(entity, True, False, event_timestamp)
try_condition = await send_motion_change_event(
entity, True, False, event_timestamp
)
# Will return True -> we will switch to movement On
await try_condition(None)
@@ -168,7 +433,9 @@ async def test_movement_management_time_not_enough(
),
):
event_timestamp = now - timedelta(minutes=2)
try_condition = await send_motion_change_event(entity, False, True, event_timestamp)
try_condition = await send_motion_change_event(
entity, False, True, event_timestamp
)
# Will return False -> we will stay to movement On
await try_condition(None)
@@ -200,7 +467,9 @@ async def test_movement_management_time_not_enough(
"homeassistant.helpers.condition.state", return_value=True
) as mock_condition:
event_timestamp = now - timedelta(minutes=1)
try_condition = await send_motion_change_event(entity, False, True, event_timestamp)
try_condition = await send_motion_change_event(
entity, False, True, event_timestamp
)
# Will return True -> we will switch to movement Off
await try_condition(None)
@@ -221,7 +490,7 @@ async def test_movement_management_time_not_enough(
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_movement_management_time_enough_and_presence(
async def test_motion_management_time_enough_and_presence(
hass: HomeAssistant, skip_hass_states_is_state
):
"""Test the Motion management when time is not enough"""
@@ -282,7 +551,7 @@ async def test_movement_management_time_enough_and_presence(
assert entity.preset_mode is PRESET_ACTIVITY
# because no motion is detected yet
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state is STATE_UNKNOWN
event_timestamp = now - timedelta(minutes=4)
@@ -312,7 +581,7 @@ async def test_movement_management_time_enough_and_presence(
assert entity.preset_mode is PRESET_ACTIVITY
# because motion is detected yet -> switch to Boost mode
assert entity.target_temperature == 19
assert entity.motion_state == "on"
assert entity.motion_state == STATE_ON
assert entity.presence_state == STATE_ON
assert mock_send_event.call_count == 0
# Change is confirmed. Heater should be started
@@ -340,7 +609,7 @@ async def test_movement_management_time_enough_and_presence(
assert entity.preset_mode is PRESET_ACTIVITY
# because no motion is detected yet
assert entity.target_temperature == 18
assert entity.motion_state == "off"
assert entity.motion_state == STATE_OFF
assert entity.presence_state == STATE_ON
assert mock_send_event.call_count == 0
@@ -352,7 +621,7 @@ async def test_movement_management_time_enough_and_presence(
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_movement_management_time_enoughand_not_presence(
async def test_motion_management_time_enough_and_not_presence(
hass: HomeAssistant, skip_hass_states_is_state
):
"""Test the Presence management when time is not enough"""
@@ -413,7 +682,7 @@ async def test_movement_management_time_enoughand_not_presence(
assert entity.preset_mode is PRESET_ACTIVITY
# because no motion is detected yet and presence is unknown
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state is STATE_UNKNOWN
event_timestamp = now - timedelta(minutes=4)
@@ -421,7 +690,7 @@ async def test_movement_management_time_enoughand_not_presence(
await send_ext_temperature_change_event(entity, 10, event_timestamp)
await send_presence_change_event(entity, False, True, event_timestamp)
assert entity.presence_state == "off"
assert entity.presence_state == STATE_OFF
# starts detecting motion
with patch(
@@ -443,7 +712,7 @@ async def test_movement_management_time_enoughand_not_presence(
assert entity.preset_mode is PRESET_ACTIVITY
# because motion is detected yet -> switch to Boost away mode
assert entity.target_temperature == 19.1
assert entity.motion_state == "on"
assert entity.motion_state == STATE_ON
assert entity.presence_state == STATE_OFF
assert mock_send_event.call_count == 0
@@ -472,7 +741,7 @@ async def test_movement_management_time_enoughand_not_presence(
assert entity.preset_mode is PRESET_ACTIVITY
# because no motion is detected yet
assert entity.target_temperature == 18.1
assert entity.motion_state == "off"
assert entity.motion_state == STATE_OFF
assert entity.presence_state == STATE_OFF
assert mock_send_event.call_count == 0
# 18.1 starts heating with a low on_percent
@@ -484,7 +753,7 @@ async def test_movement_management_time_enoughand_not_presence(
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_movement_management_with_stop_during_condition(
async def test_motion_management_with_stop_during_condition(
hass: HomeAssistant, skip_hass_states_is_state
):
"""Test the Motion management when the movement sensor switch to off and then to on during the test condition"""
@@ -546,7 +815,7 @@ async def test_movement_management_with_stop_during_condition(
assert entity.preset_mode is PRESET_ACTIVITY
# because no motion is detected yet
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state is STATE_UNKNOWN
event_timestamp = now - timedelta(minutes=6)
@@ -554,7 +823,7 @@ async def test_movement_management_with_stop_during_condition(
await send_ext_temperature_change_event(entity, 10, event_timestamp)
await send_presence_change_event(entity, False, True, event_timestamp)
assert entity.presence_state == "off"
assert entity.presence_state == STATE_OFF
# starts detecting motion
with patch(
@@ -580,7 +849,7 @@ async def test_movement_management_with_stop_during_condition(
assert entity.preset_mode is PRESET_ACTIVITY
# because motion is detected yet -> switch to Boost mode
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state == STATE_OFF
# Send a stop detection
event_timestamp = now - timedelta(minutes=4)
@@ -592,7 +861,7 @@ async def test_movement_management_with_stop_during_condition(
assert entity.hvac_mode is HVACMode.HEAT
assert entity.preset_mode is PRESET_ACTIVITY
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state == STATE_OFF
# Resend a start detection
@@ -608,19 +877,19 @@ async def test_movement_management_with_stop_during_condition(
assert entity.preset_mode is PRESET_ACTIVITY
# still no motion detected
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state == STATE_OFF
await try_condition1(None)
# We should have switch this time
assert entity.target_temperature == 19 # Boost
assert entity.motion_state == "on" # switch to movement on
assert entity.motion_state == STATE_ON # switch to movement on
assert entity.presence_state == STATE_OFF # Non change
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize("expected_lingering_timers", [True])
async def test_movement_management_with_stop_during_condition_last_state_on(
async def test_motion_management_with_stop_during_condition_last_state_on(
hass: HomeAssistant, skip_hass_states_is_state
):
"""Test the Motion management when the movement sensor switch to off and then to on during the test condition"""
@@ -681,7 +950,7 @@ async def test_movement_management_with_stop_during_condition_last_state_on(
assert entity.preset_mode is PRESET_ACTIVITY
# because no motion is detected yet
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.motion_state is STATE_UNKNOWN
event_timestamp = now - timedelta(minutes=6)
await send_temperature_change_event(entity, 18, event_timestamp)

View File

@@ -814,7 +814,7 @@ async def test_multiple_switch_power_management(
"type": "start",
"current_power": 50,
"device_power": 100,
"current_power_max": 74,
"current_max_power": 74,
"current_power_consumption": 25.0,
},
),

View File

@@ -113,7 +113,7 @@ async def test_over_climate_valve_mono(hass: HomeAssistant, skip_hass_states_get
assert vtherm.preset_mode is PRESET_NONE
assert vtherm._security_state is False
assert vtherm._window_state is None
assert vtherm._motion_state is None
assert vtherm.motion_state is STATE_UNAVAILABLE
assert vtherm.presence_state is STATE_UNAVAILABLE
assert vtherm.is_device_active is False

View File

@@ -77,7 +77,7 @@ async def test_power_feature_manager(
assert custom_attributes["device_power"] is 0
assert custom_attributes["power_temp"] is None
assert custom_attributes["current_power"] is None
assert custom_attributes["current_power_max"] is None
assert custom_attributes["current_max_power"] is None
# 2. post_init
power_manager.post_init(
@@ -104,7 +104,7 @@ async def test_power_feature_manager(
assert custom_attributes["device_power"] == 1234
assert custom_attributes["power_temp"] == 10
assert custom_attributes["current_power"] is None
assert custom_attributes["current_power_max"] is None
assert custom_attributes["current_max_power"] is None
# 3. start listening
power_manager.start_listening()
@@ -183,7 +183,7 @@ async def test_power_feature_manager(
[
call.fake_vtherm.send_event(
EventType.POWER_EVENT,
{'type': 'end', 'current_power': power, 'device_power': 1234, 'current_power_max': max_power}),
{'type': 'end', 'current_power': power, 'device_power': 1234, 'current_max_power': max_power}),
]
)
@@ -214,7 +214,7 @@ async def test_power_feature_manager(
[
call.fake_vtherm.send_event(
EventType.POWER_EVENT,
{'type': 'start', 'current_power': power, 'device_power': 1234, 'current_power_max': max_power, 'current_power_consumption': 1234.0}),
{'type': 'start', 'current_power': power, 'device_power': 1234, 'current_max_power': max_power, 'current_power_consumption': 1234.0}),
]
)
@@ -232,7 +232,10 @@ async def test_power_feature_manager(
assert custom_attributes["device_power"] == 1234
assert custom_attributes["power_temp"] == 10
assert custom_attributes["current_power"] == power
assert custom_attributes["current_power_max"] == max_power
assert custom_attributes["current_max_power"] == max_power
power_manager.stop_listening()
await hass.async_block_till_done()
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@@ -410,7 +413,7 @@ async def test_power_management_hvac_on(hass: HomeAssistant, skip_hass_states_is
"type": "start",
"current_power": 50,
"device_power": 100,
"current_power_max": 149,
"current_max_power": 149,
"current_power_consumption": 100.0,
},
),
@@ -445,7 +448,7 @@ async def test_power_management_hvac_on(hass: HomeAssistant, skip_hass_states_is
"type": "end",
"current_power": 48,
"device_power": 100,
"current_power_max": 149,
"current_max_power": 149,
},
),
],

View File

@@ -173,3 +173,6 @@ async def test_presence_feature_manager(
assert custom_attributes["presence_sensor_entity_id"] == "sensor.the_presence_sensor"
assert custom_attributes["presence_state"] == presence_state
assert custom_attributes["is_presence_configured"] is True
presence_manager.stop_listening()
await hass.async_block_till_done()

View File

@@ -55,7 +55,7 @@ async def test_over_switch_full_start(hass: HomeAssistant, skip_hass_states_is_s
assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False
assert entity._window_state is None
assert entity._motion_state is None
assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state is STATE_UNKNOWN
assert entity._prop_algorithm is not None
assert entity.have_valve_regulation is False
@@ -114,7 +114,7 @@ async def test_over_climate_full_start(hass: HomeAssistant, skip_hass_states_is_
assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False
assert entity._window_state is None
assert entity._motion_state is None
assert entity.motion_state is STATE_UNAVAILABLE
assert entity.presence_state is STATE_UNAVAILABLE
assert entity.have_valve_regulation is False
@@ -151,18 +151,6 @@ async def test_over_4switch_full_start(hass: HomeAssistant, skip_hass_states_is_
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
) as mock_send_event:
entity = await create_thermostat(hass, entry, "climate.theover4switchmockname")
# entry.add_to_hass(hass)
# await hass.config_entries.async_setup(entry.entry_id)
# assert entry.state is ConfigEntryState.LOADED
#
# def find_my_entity(entity_id) -> ClimateEntity:
# """Find my new entity"""
# component: EntityComponent[ClimateEntity] = hass.data[CLIMATE_DOMAIN]
# for entity in component.entities:
# if entity.entity_id == entity_id:
# return entity
#
# entity: BaseThermostat = find_my_entity("climate.theover4switchmockname")
assert entity
@@ -182,7 +170,7 @@ async def test_over_4switch_full_start(hass: HomeAssistant, skip_hass_states_is_
assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False
assert entity._window_state is None
assert entity._motion_state is None
assert entity.motion_state is STATE_UNKNOWN
assert entity.presence_state is STATE_UNKNOWN
assert entity._prop_algorithm is not None

View File

@@ -91,7 +91,7 @@ async def test_over_switch_ac_full_start(
assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False # pylint: disable=protected-access
assert entity._window_state is None # pylint: disable=protected-access
assert entity._motion_state is None # pylint: disable=protected-access
assert entity.motion_state is STATE_UNKNOWN # pylint: disable=protected-access
assert entity.presence_state is STATE_UNKNOWN
assert entity._prop_algorithm is not None # pylint: disable=protected-access

View File

@@ -100,7 +100,7 @@ async def test_over_valve_full_start(
assert entity.preset_mode is PRESET_NONE
assert entity._security_state is False # pylint: disable=protected-access
assert entity._window_state is None # pylint: disable=protected-access
assert entity._motion_state is None # pylint: disable=protected-access
assert entity.motion_state is STATE_UNKNOWN # pylint: disable=protected-access
assert entity.presence_state is STATE_UNKNOWN
assert entity._prop_algorithm is not None # pylint: disable=protected-access
assert entity.have_valve_regulation is False