# pylint: disable=wildcard-import, unused-wildcard-import, protected-access, unused-argument, line-too-long """ Test the Security featrure """ from unittest.mock import patch, call from datetime import timedelta, datetime import logging from custom_components.versatile_thermostat.thermostat_switch import ( ThermostatOverSwitch, ) from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import logging.getLogger().setLevel(logging.DEBUG) @pytest.mark.parametrize("expected_lingering_tasks", [True]) @pytest.mark.parametrize("expected_lingering_timers", [True]) async def test_last_seen_feature(hass: HomeAssistant, skip_hass_states_is_state): """Test the last_ssen feature 1. creates a thermostat and check that security is off 2. activate security feature when date is expired 3. change the last seen sensor 4. check that security is off """ tz = get_tz(hass) # pylint: disable=invalid-name temps = { "frost": 7, "eco": 17, "comfort": 18, "boost": 19, } entry = MockConfigEntry( domain=DOMAIN, title="TheOverSwitchMockName", unique_id="uniqueId", data={ "name": "TheOverSwitchMockName", "thermostat_type": "thermostat_over_switch", "temperature_sensor_entity_id": "sensor.mock_temp_sensor", "last_seen_temperature_sensor_entity_id": "sensor.mock_last_seen_temp_sensor", "external_temperature_sensor_entity_id": "sensor.mock_ext_temp_sensor", "cycle_min": 5, "temp_min": 15, "temp_max": 30, "use_window_feature": False, "use_motion_feature": False, "use_power_feature": False, "use_presence_feature": False, CONF_UNDERLYING_LIST: ["switch.mock_switch"], "proportional_function": "tpi", "tpi_coef_int": 0.3, "tpi_coef_ext": 0.01, "minimal_activation_delay": 30, CONF_SAFETY_DELAY_MIN: 5, # 5 minutes CONF_SAFETY_MIN_ON_PERCENT: 0.2, CONF_SAFETY_DEFAULT_ON_PERCENT: 0.1, }, ) # 1. creates a thermostat and check that security is off now: datetime = datetime.now(tz=tz) entity: ThermostatOverSwitch = await create_thermostat( hass, entry, "climate.theoverswitchmockname" ) assert entity await set_all_climate_preset_temp(hass, entity, temps, "theoverswitchmockname") assert entity.safety_manager.is_safety_detected is False assert entity.preset_mode is not PRESET_SAFETY assert entity._last_ext_temperature_measure is not None assert entity._last_temperature_measure is not None assert (entity._last_temperature_measure.astimezone(tz) - now).total_seconds() < 1 assert ( entity._last_ext_temperature_measure.astimezone(tz) - now ).total_seconds() < 1 # set a preset assert entity.preset_mode is PRESET_NONE await entity.async_set_preset_mode(PRESET_COMFORT) assert entity.preset_mode is PRESET_COMFORT # Turn On the thermostat assert entity.hvac_mode == HVACMode.OFF await entity.async_set_hvac_mode(HVACMode.HEAT) assert entity.hvac_mode == HVACMode.HEAT last_change_time_from_vtherm = entity._last_change_time_from_vtherm # 2. activate security feature when date is expired with patch( "custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event" ) as mock_send_event, patch( "custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on" ) as mock_heater_on: event_timestamp = now - timedelta(minutes=6) # set temperature to 15 so that on_percent will be > safety_min_on_percent (0.2) await send_temperature_change_event(entity, 15, event_timestamp) assert entity.safety_state is STATE_ON assert entity.preset_mode == PRESET_SAFETY assert mock_send_event.call_count == 3 mock_send_event.assert_has_calls( [ call.send_event(EventType.PRESET_EVENT, {"preset": PRESET_SAFETY}), call.send_event( EventType.TEMPERATURE_EVENT, { "last_temperature_measure": event_timestamp.isoformat(), "last_ext_temperature_measure": entity._last_ext_temperature_measure.isoformat(), "current_temp": 15, "current_ext_temp": None, "target_temp": 18, }, ), call.send_event( EventType.SECURITY_EVENT, { "type": "start", "last_temperature_measure": event_timestamp.isoformat(), "last_ext_temperature_measure": entity._last_ext_temperature_measure.isoformat(), "current_temp": 15, "current_ext_temp": None, "target_temp": 18, }, ), ], any_order=True, ) assert mock_heater_on.call_count == 1 assert entity._last_change_time_from_vtherm == last_change_time_from_vtherm # 3. change the last seen sensor event_timestamp = now - timedelta(minutes=4) await send_last_seen_temperature_change_event(entity, event_timestamp) assert entity.safety_state is not STATE_ON assert entity.preset_mode is PRESET_COMFORT assert entity._last_temperature_measure == event_timestamp assert entity._last_change_time_from_vtherm == last_change_time_from_vtherm