Add PresenceFeatureManager ok

This commit is contained in:
Jean-Marc Collin
2024-12-23 13:53:55 +00:00
parent b41d0f34dc
commit c99956f50c
8 changed files with 36 additions and 26 deletions

View File

@@ -175,6 +175,8 @@ class FeaturePresenceManager(BaseFeatureManager):
def presence_state(self) -> str | None:
"""Return the current presence state STATE_ON or STATE_OFF
or STATE_UNAVAILABLE if not configured"""
if not self._is_configured:
return STATE_UNAVAILABLE
return self._presence_state
@property
@@ -185,5 +187,10 @@ class FeaturePresenceManager(BaseFeatureManager):
STATE_OFF,
]
@property
def presence_sensor_entity_id(self) -> bool:
"""Return true if the presence is configured and presence sensor is OFF"""
return self._presence_sensor_entity_id
def __str__(self):
return f"PresenceManager-{self.name}"

View File

@@ -419,7 +419,7 @@ async def test_presence_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.presence_state is None
assert entity.presence_state is STATE_UNKNOWN
await presence_binary_sensor.async_my_climate_changed()
assert presence_binary_sensor.state is STATE_OFF

View File

@@ -295,7 +295,10 @@ async def test_full_over_switch_wo_central_config(
assert entity._power_sensor_entity_id == "sensor.mock_power_sensor"
assert entity._max_power_sensor_entity_id == "sensor.mock_max_power_sensor"
assert entity._presence_sensor_entity_id == "binary_sensor.mock_presence_sensor"
assert (
entity._presence_manager.presence_sensor_entity_id
== "binary_sensor.mock_presence_sensor"
)
entity.remove_thermostat()
@@ -409,7 +412,10 @@ async def test_full_over_switch_with_central_config(
assert entity._power_sensor_entity_id == "sensor.mock_power_sensor"
assert entity._max_power_sensor_entity_id == "sensor.mock_max_power_sensor"
assert entity._presence_sensor_entity_id == "binary_sensor.mock_presence_sensor"
assert (
entity._presence_manager.presence_sensor_entity_id
== "binary_sensor.mock_presence_sensor"
)
entity.remove_thermostat()

View File

@@ -76,7 +76,7 @@ async def test_movement_management_time_not_enough(
# because no motion is detected yet
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.presence_state is None
assert entity.presence_state is STATE_UNKNOWN
event_timestamp = now - timedelta(minutes=5)
await send_temperature_change_event(entity, 18, event_timestamp)
@@ -283,7 +283,7 @@ async def test_movement_management_time_enough_and_presence(
# because no motion is detected yet
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.presence_state is None
assert entity.presence_state is STATE_UNKNOWN
event_timestamp = now - timedelta(minutes=4)
await send_temperature_change_event(entity, 18, event_timestamp)
@@ -313,8 +313,7 @@ async def test_movement_management_time_enough_and_presence(
# because motion is detected yet -> switch to Boost mode
assert entity.target_temperature == 19
assert entity.motion_state == "on"
assert entity.presence_state == "on"
assert entity.presence_state == STATE_ON
assert mock_send_event.call_count == 0
# Change is confirmed. Heater should be started
assert mock_heater_on.call_count == 1
@@ -342,7 +341,7 @@ async def test_movement_management_time_enough_and_presence(
# because no motion is detected yet
assert entity.target_temperature == 18
assert entity.motion_state == "off"
assert entity.presence_state == "on"
assert entity.presence_state == STATE_ON
assert mock_send_event.call_count == 0
assert mock_heater_on.call_count == 0
@@ -415,7 +414,7 @@ async def test_movement_management_time_enoughand_not_presence(
# because no motion is detected yet and presence is unknown
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.presence_state is None
assert entity.presence_state is STATE_UNKNOWN
event_timestamp = now - timedelta(minutes=4)
await send_temperature_change_event(entity, 18, event_timestamp)
@@ -445,7 +444,7 @@ async def test_movement_management_time_enoughand_not_presence(
# because motion is detected yet -> switch to Boost away mode
assert entity.target_temperature == 19.1
assert entity.motion_state == "on"
assert entity.presence_state == "off"
assert entity.presence_state == STATE_OFF
assert mock_send_event.call_count == 0
# Change is confirmed. Heater should be started
@@ -474,8 +473,7 @@ async def test_movement_management_time_enoughand_not_presence(
# because no motion is detected yet
assert entity.target_temperature == 18.1
assert entity.motion_state == "off"
assert entity.presence_state == "off"
assert entity.presence_state == STATE_OFF
assert mock_send_event.call_count == 0
# 18.1 starts heating with a low on_percent
assert mock_heater_on.call_count == 1
@@ -549,7 +547,7 @@ async def test_movement_management_with_stop_during_condition(
# because no motion is detected yet
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.presence_state is None
assert entity.presence_state is STATE_UNKNOWN
event_timestamp = now - timedelta(minutes=6)
await send_temperature_change_event(entity, 18, event_timestamp)
@@ -583,8 +581,7 @@ async def test_movement_management_with_stop_during_condition(
# because motion is detected yet -> switch to Boost mode
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.presence_state == "off"
assert entity.presence_state == STATE_OFF
# Send a stop detection
event_timestamp = now - timedelta(minutes=4)
try_condition = await send_motion_change_event(
@@ -596,7 +593,7 @@ async def test_movement_management_with_stop_during_condition(
assert entity.preset_mode is PRESET_ACTIVITY
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.presence_state == "off"
assert entity.presence_state == STATE_OFF
# Resend a start detection
event_timestamp = now - timedelta(minutes=3)
@@ -612,13 +609,13 @@ async def test_movement_management_with_stop_during_condition(
# still no motion detected
assert entity.target_temperature == 18
assert entity.motion_state is None
assert entity.presence_state == "off"
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.presence_state == "off" # Non change
assert entity.presence_state == STATE_OFF # Non change
@pytest.mark.parametrize("expected_lingering_tasks", [True])

View File

@@ -114,7 +114,7 @@ async def test_over_climate_valve_mono(hass: HomeAssistant, skip_hass_states_get
assert vtherm._security_state is False
assert vtherm._window_state is None
assert vtherm._motion_state is None
assert vtherm._presence_state is None
assert vtherm.presence_state is STATE_UNKNOWN
assert vtherm.is_device_active is False
assert vtherm.valve_open_percent == 0

View File

@@ -56,7 +56,7 @@ async def test_over_switch_full_start(hass: HomeAssistant, skip_hass_states_is_s
assert entity._security_state is False
assert entity._window_state is None
assert entity._motion_state is None
assert entity._presence_state is None
assert entity.presence_state is STATE_UNKNOWN
assert entity._prop_algorithm is not None
assert entity.have_valve_regulation is False
@@ -115,7 +115,7 @@ async def test_over_climate_full_start(hass: HomeAssistant, skip_hass_states_is_
assert entity._security_state is False
assert entity._window_state is None
assert entity._motion_state is None
assert entity._presence_state is None
assert entity.presence_state is STATE_UNAVAILABLE
assert entity.have_valve_regulation is False
# should have been called with EventType.PRESET_EVENT and EventType.HVAC_MODE_EVENT
@@ -183,7 +183,7 @@ async def test_over_4switch_full_start(hass: HomeAssistant, skip_hass_states_is_
assert entity._security_state is False
assert entity._window_state is None
assert entity._motion_state is None
assert entity._presence_state is None
assert entity.presence_state is STATE_UNKNOWN
assert entity._prop_algorithm is not None
assert entity.nb_underlying_entities == 4

View File

@@ -92,7 +92,7 @@ async def test_over_switch_ac_full_start(
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._presence_state is None # pylint: disable=protected-access
assert entity.presence_state is STATE_UNKNOWN
assert entity._prop_algorithm is not None # pylint: disable=protected-access
# should have been called with EventType.PRESET_EVENT and EventType.HVAC_MODE_EVENT
@@ -114,7 +114,7 @@ async def test_over_switch_ac_full_start(
event_timestamp = now - timedelta(minutes=4)
await send_presence_change_event(entity, True, False, event_timestamp)
assert entity._presence_state == STATE_ON # pylint: disable=protected-access
assert entity.presence_state == STATE_ON # pylint: disable=protected-access
await entity.async_set_hvac_mode(HVACMode.COOL)
assert entity.hvac_mode is HVACMode.COOL
@@ -131,7 +131,7 @@ async def test_over_switch_ac_full_start(
# Unset the presence
event_timestamp = now - timedelta(minutes=3)
await send_presence_change_event(entity, False, True, event_timestamp)
assert entity._presence_state == STATE_OFF # pylint: disable=protected-access
assert entity.presence_state == STATE_OFF # pylint: disable=protected-access
assert entity.target_temperature == 27 # eco_ac_away
# Open a window

View File

@@ -101,7 +101,7 @@ async def test_over_valve_full_start(
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._presence_state is None # 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