core/tests/components/ecobee/test_climate.py

621 lines
21 KiB
Python
Raw Normal View History

"""The test for the Ecobee thermostat module."""
from http import HTTPStatus
from unittest import mock
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant import const
from homeassistant.components.climate import ClimateEntityFeature
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
from homeassistant.components.ecobee.climate import (
ATTR_PRESET_MODE,
ATTR_SENSOR_LIST,
PRESET_AWAY_INDEFINITELY,
Thermostat,
)
from homeassistant.components.ecobee.const import DOMAIN
from homeassistant.const import ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, STATE_OFF
from homeassistant.core import HomeAssistant
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers import device_registry as dr
from .common import setup_platform
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
from tests.common import MockConfigEntry, async_fire_time_changed
ENTITY_ID = "climate.ecobee"
@pytest.fixture
def ecobee_fixture():
"""Set up ecobee mock."""
vals = {
"name": "Ecobee",
2021-06-17 08:59:13 +00:00
"modelNumber": "athenaSmart",
"identifier": "abc",
"program": {
"climates": [
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
{
"name": "Climate1",
"climateRef": "c1",
"sensors": [{"name": "Ecobee"}],
},
{
"name": "Climate2",
"climateRef": "c2",
"sensors": [{"name": "Ecobee"}],
},
{"name": "Away", "climateRef": "away", "sensors": [{"name": "Ecobee"}]},
{"name": "Home", "climateRef": "home", "sensors": [{"name": "Ecobee"}]},
2019-07-31 19:25:30 +00:00
],
"currentClimateRef": "c1",
},
"runtime": {
"connected": True,
"actualTemperature": 300,
"actualHumidity": 15,
"desiredHeat": 400,
"desiredCool": 200,
"desiredFanMode": "on",
},
"settings": {
"hvacMode": "auto",
"heatStages": 1,
"coolStages": 1,
"fanMinOnTime": 10,
"heatCoolMinDelta": 50,
"holdAction": "nextTransition",
},
"equipmentStatus": "fan",
"events": [
{
"name": "Event1",
"running": True,
"type": "hold",
"holdClimateRef": "c1",
"startDate": "2017-02-02",
"startTime": "11:00:00",
"endDate": "2017-01-01",
"endTime": "10:00:00",
}
],
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
"remoteSensors": [
{
"id": "ei:0",
"name": "Ecobee",
},
{
"id": "rs2:100",
"name": "Remote Sensor 1",
},
],
}
mock_ecobee = mock.Mock()
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
mock_ecobee.get = mock.Mock(side_effect=vals.get)
mock_ecobee.__getitem__ = mock.Mock(side_effect=vals.__getitem__)
mock_ecobee.__setitem__ = mock.Mock(side_effect=vals.__setitem__)
return mock_ecobee
@pytest.fixture(name="data")
def data_fixture(ecobee_fixture):
"""Set up data mock."""
data = mock.Mock()
data.ecobee.get_thermostat.return_value = ecobee_fixture
return data
@pytest.fixture(name="thermostat")
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
def thermostat_fixture(data, hass: HomeAssistant):
"""Set up ecobee thermostat object."""
2021-06-17 08:59:13 +00:00
thermostat = data.ecobee.get_thermostat(1)
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
return Thermostat(data, 1, thermostat, hass)
async def test_name(thermostat) -> None:
"""Test name property."""
assert thermostat.device_info["name"] == "Ecobee"
2023-03-10 11:06:50 +00:00
async def test_aux_heat_not_supported_by_default(hass: HomeAssistant) -> None:
"""Default setup should not support Aux heat."""
await setup_platform(hass, const.Platform.CLIMATE)
state = hass.states.get(ENTITY_ID)
assert (
state.attributes.get(ATTR_SUPPORTED_FEATURES)
== ClimateEntityFeature.PRESET_MODE
| ClimateEntityFeature.FAN_MODE
| ClimateEntityFeature.TARGET_HUMIDITY
| ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
| ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.TURN_OFF
| ClimateEntityFeature.TURN_ON
)
async def test_current_temperature(ecobee_fixture, thermostat) -> None:
"""Test current temperature."""
assert thermostat.current_temperature == 30
ecobee_fixture["runtime"]["actualTemperature"] = HTTPStatus.NOT_FOUND
assert thermostat.current_temperature == 40.4
async def test_target_temperature_low(ecobee_fixture, thermostat) -> None:
"""Test target low temperature."""
assert thermostat.target_temperature_low == 40
ecobee_fixture["runtime"]["desiredHeat"] = 502
assert thermostat.target_temperature_low == 50.2
async def test_target_temperature_high(ecobee_fixture, thermostat) -> None:
"""Test target high temperature."""
assert thermostat.target_temperature_high == 20
ecobee_fixture["runtime"]["desiredCool"] = 679
assert thermostat.target_temperature_high == 67.9
async def test_target_temperature(ecobee_fixture, thermostat) -> None:
"""Test target temperature."""
assert thermostat.target_temperature is None
ecobee_fixture["settings"]["hvacMode"] = "heat"
assert thermostat.target_temperature == 40
ecobee_fixture["settings"]["hvacMode"] = "cool"
assert thermostat.target_temperature == 20
ecobee_fixture["settings"]["hvacMode"] = "auxHeatOnly"
assert thermostat.target_temperature == 40
ecobee_fixture["settings"]["hvacMode"] = "off"
assert thermostat.target_temperature is None
async def test_desired_fan_mode(ecobee_fixture, thermostat) -> None:
"""Test desired fan mode property."""
assert thermostat.fan_mode == "on"
ecobee_fixture["runtime"]["desiredFanMode"] = "auto"
assert thermostat.fan_mode == "auto"
async def test_fan(ecobee_fixture, thermostat) -> None:
"""Test fan property."""
2023-01-30 10:03:23 +00:00
assert thermostat.fan == const.STATE_ON
ecobee_fixture["equipmentStatus"] = ""
assert thermostat.fan == STATE_OFF
ecobee_fixture["equipmentStatus"] = "heatPump, heatPump2"
assert thermostat.fan == STATE_OFF
async def test_hvac_mode(ecobee_fixture, thermostat) -> None:
"""Test current operation property."""
assert thermostat.hvac_mode == "heat_cool"
ecobee_fixture["settings"]["hvacMode"] = "heat"
assert thermostat.hvac_mode == "heat"
ecobee_fixture["settings"]["hvacMode"] = "cool"
assert thermostat.hvac_mode == "cool"
ecobee_fixture["settings"]["hvacMode"] = "auxHeatOnly"
assert thermostat.hvac_mode == "heat"
ecobee_fixture["settings"]["hvacMode"] = "off"
assert thermostat.hvac_mode == "off"
async def test_hvac_modes(thermostat) -> None:
"""Test operation list property."""
2024-06-28 08:46:02 +00:00
assert thermostat.hvac_modes == ["heat_cool", "heat", "cool", "off"]
async def test_hvac_mode2(ecobee_fixture, thermostat) -> None:
"""Test operation mode property."""
assert thermostat.hvac_mode == "heat_cool"
ecobee_fixture["settings"]["hvacMode"] = "heat"
assert thermostat.hvac_mode == "heat"
async def test_extra_state_attributes(ecobee_fixture, thermostat) -> None:
"""Test device state attributes property."""
ecobee_fixture["equipmentStatus"] = "heatPump2"
2024-06-28 08:46:02 +00:00
assert thermostat.extra_state_attributes == {
"fan": "off",
"climate_mode": "Climate1",
"fan_min_on_time": 10,
"equipment_running": "heatPump2",
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
"available_sensors": [],
"active_sensors": [],
2024-06-28 08:46:02 +00:00
}
ecobee_fixture["equipmentStatus"] = "auxHeat2"
2024-06-28 08:46:02 +00:00
assert thermostat.extra_state_attributes == {
"fan": "off",
"climate_mode": "Climate1",
"fan_min_on_time": 10,
"equipment_running": "auxHeat2",
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
"available_sensors": [],
"active_sensors": [],
2024-06-28 08:46:02 +00:00
}
2021-04-12 21:44:13 +00:00
ecobee_fixture["equipmentStatus"] = "compCool1"
2024-06-28 08:46:02 +00:00
assert thermostat.extra_state_attributes == {
"fan": "off",
"climate_mode": "Climate1",
"fan_min_on_time": 10,
"equipment_running": "compCool1",
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
"available_sensors": [],
"active_sensors": [],
2024-06-28 08:46:02 +00:00
}
ecobee_fixture["equipmentStatus"] = ""
2024-06-28 08:46:02 +00:00
assert thermostat.extra_state_attributes == {
"fan": "off",
"climate_mode": "Climate1",
"fan_min_on_time": 10,
"equipment_running": "",
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
"available_sensors": [],
"active_sensors": [],
2024-06-28 08:46:02 +00:00
}
ecobee_fixture["equipmentStatus"] = "Unknown"
2024-06-28 08:46:02 +00:00
assert thermostat.extra_state_attributes == {
"fan": "off",
"climate_mode": "Climate1",
"fan_min_on_time": 10,
"equipment_running": "Unknown",
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
"available_sensors": [],
"active_sensors": [],
2024-06-28 08:46:02 +00:00
}
ecobee_fixture["program"]["currentClimateRef"] = "c2"
2024-06-28 08:46:02 +00:00
assert thermostat.extra_state_attributes == {
"fan": "off",
"climate_mode": "Climate2",
"fan_min_on_time": 10,
"equipment_running": "Unknown",
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
"available_sensors": [],
"active_sensors": [],
2024-06-28 08:46:02 +00:00
}
async def test_set_temperature(ecobee_fixture, thermostat, data) -> None:
"""Test set temperature."""
# Auto -> Auto
data.reset_mock()
thermostat.set_temperature(target_temp_low=20, target_temp_high=30)
data.ecobee.set_hold_temp.assert_has_calls(
[mock.call(1, 30, 20, "nextTransition", None)]
)
# Auto -> Hold
data.reset_mock()
thermostat.set_temperature(temperature=20)
data.ecobee.set_hold_temp.assert_has_calls(
[mock.call(1, 25, 15, "nextTransition", None)]
)
# Cool -> Hold
data.reset_mock()
ecobee_fixture["settings"]["hvacMode"] = "cool"
thermostat.set_temperature(temperature=20.5)
data.ecobee.set_hold_temp.assert_has_calls(
[mock.call(1, 20.5, 20.5, "nextTransition", None)]
)
# Heat -> Hold
data.reset_mock()
ecobee_fixture["settings"]["hvacMode"] = "heat"
thermostat.set_temperature(temperature=20)
data.ecobee.set_hold_temp.assert_has_calls(
[mock.call(1, 20, 20, "nextTransition", None)]
)
# Heat -> Auto
data.reset_mock()
ecobee_fixture["settings"]["hvacMode"] = "heat"
thermostat.set_temperature(target_temp_low=20, target_temp_high=30)
assert not data.ecobee.set_hold_temp.called
async def test_set_hvac_mode(thermostat, data) -> None:
"""Test operation mode setter."""
data.reset_mock()
thermostat.set_hvac_mode("heat_cool")
data.ecobee.set_hvac_mode.assert_has_calls([mock.call(1, "auto")])
data.reset_mock()
thermostat.set_hvac_mode("heat")
data.ecobee.set_hvac_mode.assert_has_calls([mock.call(1, "heat")])
async def test_set_fan_min_on_time(thermostat, data) -> None:
"""Test fan min on time setter."""
data.reset_mock()
thermostat.set_fan_min_on_time(15)
data.ecobee.set_fan_min_on_time.assert_has_calls([mock.call(1, 15)])
data.reset_mock()
thermostat.set_fan_min_on_time(20)
data.ecobee.set_fan_min_on_time.assert_has_calls([mock.call(1, 20)])
async def test_resume_program(thermostat, data) -> None:
"""Test resume program."""
# False
data.reset_mock()
thermostat.resume_program(False)
data.ecobee.resume_program.assert_has_calls([mock.call(1, "false")])
data.reset_mock()
thermostat.resume_program(None)
data.ecobee.resume_program.assert_has_calls([mock.call(1, "false")])
data.reset_mock()
thermostat.resume_program(0)
data.ecobee.resume_program.assert_has_calls([mock.call(1, "false")])
# True
data.reset_mock()
thermostat.resume_program(True)
data.ecobee.resume_program.assert_has_calls([mock.call(1, "true")])
data.reset_mock()
thermostat.resume_program(1)
data.ecobee.resume_program.assert_has_calls([mock.call(1, "true")])
async def test_hold_preference(ecobee_fixture, thermostat) -> None:
"""Test hold preference."""
ecobee_fixture["settings"]["holdAction"] = "indefinite"
assert thermostat.hold_preference() == "indefinite"
for action in ("useEndTime2hour", "useEndTime4hour"):
ecobee_fixture["settings"]["holdAction"] = action
assert thermostat.hold_preference() == "holdHours"
for action in ("nextPeriod", "askMe"):
ecobee_fixture["settings"]["holdAction"] = action
assert thermostat.hold_preference() == "nextTransition"
def test_hold_hours(ecobee_fixture, thermostat) -> None:
"""Test hold hours preference."""
ecobee_fixture["settings"]["holdAction"] = "useEndTime2hour"
assert thermostat.hold_hours() == 2
ecobee_fixture["settings"]["holdAction"] = "useEndTime4hour"
assert thermostat.hold_hours() == 4
for action in ("nextPeriod", "indefinite", "askMe"):
ecobee_fixture["settings"]["holdAction"] = action
assert thermostat.hold_hours() is None
async def test_set_fan_mode_on(thermostat, data) -> None:
"""Test set fan mode to on."""
data.reset_mock()
thermostat.set_fan_mode("on")
data.ecobee.set_fan_mode.assert_has_calls(
[mock.call(1, "on", "nextTransition", holdHours=None)]
)
async def test_set_fan_mode_auto(thermostat, data) -> None:
"""Test set fan mode to auto."""
data.reset_mock()
thermostat.set_fan_mode("auto")
data.ecobee.set_fan_mode.assert_has_calls(
[mock.call(1, "auto", "nextTransition", holdHours=None)]
)
async def test_preset_indefinite_away(ecobee_fixture, thermostat) -> None:
"""Test indefinite away showing correctly, and not as temporary away."""
ecobee_fixture["program"]["currentClimateRef"] = "away"
ecobee_fixture["events"][0]["holdClimateRef"] = "away"
assert thermostat.preset_mode == "away"
ecobee_fixture["events"][0]["endDate"] = "2999-01-01"
assert thermostat.preset_mode == PRESET_AWAY_INDEFINITELY
async def test_set_preset_mode(ecobee_fixture, thermostat, data) -> None:
"""Test set preset mode."""
# Set a preset provided by ecobee.
data.reset_mock()
thermostat.set_preset_mode("Climate2")
data.ecobee.set_climate_hold.assert_has_calls(
[mock.call(1, "c2", thermostat.hold_preference(), thermostat.hold_hours())]
)
# Set the indefinite away preset provided by this integration.
data.reset_mock()
thermostat.set_preset_mode(PRESET_AWAY_INDEFINITELY)
data.ecobee.set_climate_hold.assert_has_calls(
[mock.call(1, "away", "indefinite", thermostat.hold_hours())]
)
Add ecobee set_sensors_used_in_climate service (#102871) * Add set_active_sensors Service * Remove version bump from service addition commit * Reviewer suggested changes * Changed naming to be more clear of functionality * Adjusted additional naming to follow new convention * Updated to pass failing CI tests * Fix typo * Fix to pass CI * Changed argument from climate_name to preset_mode and changed service error * Made loop more clear and changed raised error to log msg * Fix typo Co-authored-by: Erik Montnemery <erik@montnemery.com> * Removed code that was accidentally added back in and fixed mypy errors * Add icon for service * Added sensors as attributes and updated tests * Revert changes made in #126587 * Added tests for remote_sensors and set_sensors_used_in_climate * Changed back to load multiplatforms (#126587) * Check for empty sensor list and negative tests for errors raised * Added tests and fixed errors * Add hass to class init to allow for device_registry lookup at startup and check for name changed by user * Added tests to test the new functions * Simplified code and fixed testing error for simplification * Added freeze in test * Fixed device filtering * Simplified code section * Maintains the ability to call `set_sensors_used_in_climate` function even is the user changes the device name from the ecobee app or thermostat without needing to reload home assistant. * Update tests with new functionality. Changed thermostat identifier to a string, since that is what is provided via the ecobee api * Changed function parameter * Search for specific ecobee identifier * Moved errors to strings.json * Added test for sensor not on thermostat * Improved tests and updated device check * Added attributes to _unrecoreded_attributes * Changed name to be more clear * Improve error message and add test for added property * Renamed variables for clarity * Added device_id to available_sensors to make it easier on user to find it --------- Co-authored-by: Robert Resch <robert@resch.dev> Co-authored-by: Erik Montnemery <erik@montnemery.com>
2024-10-21 14:21:56 +00:00
async def test_remote_sensors(hass: HomeAssistant) -> None:
"""Test remote sensors."""
await setup_platform(hass, [const.Platform.CLIMATE, const.Platform.SENSOR])
platform = hass.data[const.Platform.CLIMATE].entities
for entity in platform:
if entity.entity_id == "climate.ecobee":
thermostat = entity
break
assert thermostat is not None
remote_sensors = thermostat.remote_sensors
assert sorted(remote_sensors) == sorted(["ecobee", "Remote Sensor 1"])
async def test_remote_sensor_devices(
hass: HomeAssistant, freezer: FrozenDateTimeFactory
) -> None:
"""Test remote sensor devices."""
await setup_platform(hass, [const.Platform.CLIMATE, const.Platform.SENSOR])
freezer.tick(100)
async_fire_time_changed(hass)
state = hass.states.get(ENTITY_ID)
device_registry = dr.async_get(hass)
for device in device_registry.devices.values():
if device.name == "Remote Sensor 1":
remote_sensor_1_id = device.id
if device.name == "ecobee":
ecobee_id = device.id
assert sorted(state.attributes.get("available_sensors")) == sorted(
[f"Remote Sensor 1 ({remote_sensor_1_id})", f"ecobee ({ecobee_id})"]
)
async def test_active_sensors_in_preset_mode(hass: HomeAssistant) -> None:
"""Test active sensors in preset mode property."""
await setup_platform(hass, [const.Platform.CLIMATE, const.Platform.SENSOR])
platform = hass.data[const.Platform.CLIMATE].entities
for entity in platform:
if entity.entity_id == "climate.ecobee":
thermostat = entity
break
assert thermostat is not None
remote_sensors = thermostat.active_sensors_in_preset_mode
assert sorted(remote_sensors) == sorted(["ecobee"])
async def test_active_sensor_devices_in_preset_mode(hass: HomeAssistant) -> None:
"""Test active sensor devices in preset mode."""
await setup_platform(hass, [const.Platform.CLIMATE, const.Platform.SENSOR])
state = hass.states.get(ENTITY_ID)
assert state.attributes.get("active_sensors") == ["ecobee"]
async def test_remote_sensor_ids_names(hass: HomeAssistant) -> None:
"""Test getting ids and names_by_user for thermostat."""
await setup_platform(hass, [const.Platform.CLIMATE, const.Platform.SENSOR])
platform = hass.data[const.Platform.CLIMATE].entities
for entity in platform:
if entity.entity_id == "climate.ecobee":
thermostat = entity
break
assert thermostat is not None
remote_sensor_ids_names = thermostat.remote_sensor_ids_names
for id_name in remote_sensor_ids_names:
assert id_name.get("id") is not None
name_by_user_list = [item["name_by_user"] for item in remote_sensor_ids_names]
assert sorted(name_by_user_list) == sorted(["Remote Sensor 1", "ecobee"])
async def test_set_sensors_used_in_climate(hass: HomeAssistant) -> None:
"""Test set sensors used in climate."""
# Get device_id of remote sensor from the device registry.
await setup_platform(hass, [const.Platform.CLIMATE, const.Platform.SENSOR])
device_registry = dr.async_get(hass)
for device in device_registry.devices.values():
if device.name == "Remote Sensor 1":
remote_sensor_1_id = device.id
if device.name == "ecobee":
ecobee_id = device.id
if device.name == "Remote Sensor 2":
remote_sensor_2_id = device.id
entry = MockConfigEntry(domain="test")
entry.add_to_hass(hass)
device_from_other_integration = device_registry.async_get_or_create(
config_entry_id=entry.entry_id, identifiers={("test", "unique")}
)
# Test that the function call works in its entirety.
with mock.patch("pyecobee.Ecobee.update_climate_sensors") as mock_sensors:
await hass.services.async_call(
DOMAIN,
"set_sensors_used_in_climate",
{
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_PRESET_MODE: "Climate1",
ATTR_SENSOR_LIST: [remote_sensor_1_id],
},
blocking=True,
)
await hass.async_block_till_done()
mock_sensors.assert_called_once_with(0, "Climate1", sensor_ids=["rs:100"])
# Update sensors without preset mode.
with mock.patch("pyecobee.Ecobee.update_climate_sensors") as mock_sensors:
await hass.services.async_call(
DOMAIN,
"set_sensors_used_in_climate",
{
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_SENSOR_LIST: [remote_sensor_1_id],
},
blocking=True,
)
await hass.async_block_till_done()
# `temp` is the preset running because of a hold.
mock_sensors.assert_called_once_with(0, "temp", sensor_ids=["rs:100"])
# Check that sensors are not updated when the sent sensors are the currently set sensors.
with mock.patch("pyecobee.Ecobee.update_climate_sensors") as mock_sensors:
await hass.services.async_call(
DOMAIN,
"set_sensors_used_in_climate",
{
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_PRESET_MODE: "Climate1",
ATTR_SENSOR_LIST: [ecobee_id],
},
blocking=True,
)
mock_sensors.assert_not_called()
# Error raised because invalid climate name.
with pytest.raises(ServiceValidationError) as execinfo:
await hass.services.async_call(
DOMAIN,
"set_sensors_used_in_climate",
{
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_PRESET_MODE: "InvalidClimate",
ATTR_SENSOR_LIST: [remote_sensor_1_id],
},
blocking=True,
)
assert execinfo.value.translation_domain == "ecobee"
assert execinfo.value.translation_key == "invalid_preset"
## Error raised because invalid sensor.
with pytest.raises(ServiceValidationError) as execinfo:
await hass.services.async_call(
DOMAIN,
"set_sensors_used_in_climate",
{
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_PRESET_MODE: "Climate1",
ATTR_SENSOR_LIST: ["abcd"],
},
blocking=True,
)
assert execinfo.value.translation_domain == "ecobee"
assert execinfo.value.translation_key == "invalid_sensor"
## Error raised because sensor not available on device.
with pytest.raises(ServiceValidationError):
await hass.services.async_call(
DOMAIN,
"set_sensors_used_in_climate",
{
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_PRESET_MODE: "Climate1",
ATTR_SENSOR_LIST: [remote_sensor_2_id],
},
blocking=True,
)
with pytest.raises(ServiceValidationError) as execinfo:
await hass.services.async_call(
DOMAIN,
"set_sensors_used_in_climate",
{
ATTR_ENTITY_ID: ENTITY_ID,
ATTR_PRESET_MODE: "Climate1",
ATTR_SENSOR_LIST: [
remote_sensor_1_id,
device_from_other_integration.id,
],
},
blocking=True,
)
assert execinfo.value.translation_domain == "ecobee"
assert execinfo.value.translation_key == "sensor_lookup_failed"