Skip to content

Commit

Permalink
Add PresenceFeatureManager ok
Browse files Browse the repository at this point in the history
  • Loading branch information
Jean-Marc Collin committed Dec 23, 2024
1 parent b41d0f3 commit c99956f
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 26 deletions.
7 changes: 7 additions & 0 deletions custom_components/versatile_thermostat/presence_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ def is_configured(self) -> bool:
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
Expand All @@ -185,5 +187,10 @@ def is_absence_detected(self) -> bool:
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}"
2 changes: 1 addition & 1 deletion tests/test_binary_sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 8 additions & 2 deletions tests/test_central_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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()

Expand Down
27 changes: 12 additions & 15 deletions tests/test_movement.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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(
Expand All @@ -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)
Expand All @@ -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])
Expand Down
2 changes: 1 addition & 1 deletion tests/test_overclimate_valve.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Check failure on line 117 in tests/test_overclimate_valve.py

View workflow job for this annotation

GitHub Actions / testu

test_over_climate_valve_mono[True-True] AssertionError: assert 'unavailable' is 'unknown' + where 'unavailable' = <entity climate.theoverclimatemockname=off>.presence_state

assert vtherm.is_device_active is False
assert vtherm.valve_open_percent == 0
Expand Down
6 changes: 3 additions & 3 deletions tests/test_start.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions tests/test_switch_ac.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def find_my_entity(entity_id) -> ClimateEntity:
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
Expand All @@ -114,7 +114,7 @@ def find_my_entity(entity_id) -> ClimateEntity:

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
Expand All @@ -131,7 +131,7 @@ def find_my_entity(entity_id) -> ClimateEntity:
# 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
Expand Down
2 changes: 1 addition & 1 deletion tests/test_valve.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit c99956f

Please sign in to comment.