Add alexa PowerController on enabled features for climate entities (#109174)

Depend alexa PowerController on enabled features for climate entities
This commit is contained in:
Jan Bouwhuis 2024-01-31 02:38:32 +01:00 committed by GitHub
parent 41fdcce226
commit 712ba2fdca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 195 additions and 2 deletions

View file

@ -478,6 +478,14 @@ class ClimateCapabilities(AlexaEntity):
self.entity.domain == climate.DOMAIN
and climate.HVACMode.OFF
in (self.entity.attributes.get(climate.ATTR_HVAC_MODES) or [])
or self.entity.domain == climate.DOMAIN
and (
supported_features
& (
climate.ClimateEntityFeature.TURN_ON
| climate.ClimateEntityFeature.TURN_OFF
)
)
or self.entity.domain == water_heater.DOMAIN
and (supported_features & water_heater.WaterHeaterEntityFeature.ON_OFF)
):

View file

@ -178,6 +178,8 @@ async def async_api_turn_on(
service = SERVICE_TURN_ON
if domain == cover.DOMAIN:
service = cover.SERVICE_OPEN_COVER
elif domain == climate.DOMAIN:
service = climate.SERVICE_TURN_ON
elif domain == fan.DOMAIN:
service = fan.SERVICE_TURN_ON
elif domain == humidifier.DOMAIN:
@ -227,6 +229,8 @@ async def async_api_turn_off(
service = SERVICE_TURN_OFF
if entity.domain == cover.DOMAIN:
service = cover.SERVICE_CLOSE_COVER
elif domain == climate.DOMAIN:
service = climate.SERVICE_TURN_OFF
elif domain == fan.DOMAIN:
service = fan.SERVICE_TURN_OFF
elif domain == humidifier.DOMAIN:

View file

@ -5,7 +5,11 @@ from unittest.mock import patch
import pytest
from homeassistant.components.alexa import smart_home
from homeassistant.components.climate import ATTR_CURRENT_TEMPERATURE, HVACMode
from homeassistant.components.climate import (
ATTR_CURRENT_TEMPERATURE,
ClimateEntityFeature,
HVACMode,
)
from homeassistant.components.lock import STATE_JAMMED, STATE_LOCKING, STATE_UNLOCKING
from homeassistant.components.media_player import MediaPlayerEntityFeature
from homeassistant.components.valve import ValveEntityFeature
@ -923,6 +927,52 @@ async def test_report_climate_state(hass: HomeAssistant) -> None:
assert msg["event"]["payload"]["type"] == "INTERNAL_ERROR"
async def test_report_on_off_climate_state(hass: HomeAssistant) -> None:
"""Test ThermostatController with on/off features reports state correctly."""
on_off_features = (
ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.TURN_ON
| ClimateEntityFeature.TURN_OFF
)
for auto_modes in (HVACMode.HEAT,):
hass.states.async_set(
"climate.onoff",
auto_modes,
{
"friendly_name": "Climate Downstairs",
"supported_features": on_off_features,
ATTR_CURRENT_TEMPERATURE: 34,
ATTR_UNIT_OF_MEASUREMENT: UnitOfTemperature.CELSIUS,
},
)
properties = await reported_properties(hass, "climate.onoff")
properties.assert_equal("Alexa.ThermostatController", "thermostatMode", "HEAT")
properties.assert_equal(
"Alexa.TemperatureSensor",
"temperature",
{"value": 34.0, "scale": "CELSIUS"},
)
for off_modes in [HVACMode.OFF]:
hass.states.async_set(
"climate.onoff",
off_modes,
{
"friendly_name": "Climate Downstairs",
"supported_features": on_off_features,
ATTR_CURRENT_TEMPERATURE: 34,
ATTR_UNIT_OF_MEASUREMENT: UnitOfTemperature.CELSIUS,
},
)
properties = await reported_properties(hass, "climate.onoff")
properties.assert_equal("Alexa.ThermostatController", "thermostatMode", "OFF")
properties.assert_equal(
"Alexa.TemperatureSensor",
"temperature",
{"value": 34.0, "scale": "CELSIUS"},
)
async def test_report_water_heater_state(hass: HomeAssistant) -> None:
"""Test ThermostatController also reports state correctly for water heaters."""
for operation_mode in (STATE_ECO, STATE_GAS, STATE_HEAT_PUMP):

View file

@ -6,6 +6,7 @@ import pytest
from homeassistant.components.alexa import smart_home, state_report
import homeassistant.components.camera as camera
from homeassistant.components.climate import ClimateEntityFeature
from homeassistant.components.cover import CoverDeviceClass, CoverEntityFeature
from homeassistant.components.media_player import MediaPlayerEntityFeature
from homeassistant.components.vacuum import VacuumEntityFeature
@ -20,7 +21,7 @@ from homeassistant.const import (
from homeassistant.core import Context, Event, HomeAssistant
from homeassistant.helpers import entityfilter
from homeassistant.setup import async_setup_component
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
from homeassistant.util.unit_system import METRIC_SYSTEM, US_CUSTOMARY_SYSTEM
from .test_common import (
MockConfig,
@ -3118,6 +3119,136 @@ async def test_thermostat(hass: HomeAssistant) -> None:
assert call.data["preset_mode"] == "eco"
async def test_onoff_thermostat(hass: HomeAssistant) -> None:
"""Test onoff thermostat discovery."""
on_off_features = (
ClimateEntityFeature.TARGET_TEMPERATURE
| ClimateEntityFeature.TURN_ON
| ClimateEntityFeature.TURN_OFF
)
hass.config.units = METRIC_SYSTEM
device = (
"climate.test_thermostat",
"cool",
{
"temperature": 20.0,
"target_temp_high": None,
"target_temp_low": None,
"current_temperature": 19.0,
"friendly_name": "Test Thermostat",
"supported_features": on_off_features,
"hvac_modes": ["auto"],
"min_temp": 7,
"max_temp": 30,
},
)
appliance = await discovery_test(device, hass)
assert appliance["endpointId"] == "climate#test_thermostat"
assert appliance["displayCategories"][0] == "THERMOSTAT"
assert appliance["friendlyName"] == "Test Thermostat"
capabilities = assert_endpoint_capabilities(
appliance,
"Alexa.PowerController",
"Alexa.ThermostatController",
"Alexa.TemperatureSensor",
"Alexa.EndpointHealth",
"Alexa",
)
properties = await reported_properties(hass, "climate#test_thermostat")
properties.assert_equal("Alexa.ThermostatController", "thermostatMode", "COOL")
properties.assert_equal(
"Alexa.ThermostatController",
"targetSetpoint",
{"value": 20.0, "scale": "CELSIUS"},
)
properties.assert_equal(
"Alexa.TemperatureSensor", "temperature", {"value": 19.0, "scale": "CELSIUS"}
)
thermostat_capability = get_capability(capabilities, "Alexa.ThermostatController")
assert thermostat_capability is not None
configuration = thermostat_capability["configuration"]
assert configuration["supportsScheduling"] is False
supported_modes = ["AUTO"]
for mode in supported_modes:
assert mode in configuration["supportedModes"]
call, msg = await assert_request_calls_service(
"Alexa.ThermostatController",
"SetTargetTemperature",
"climate#test_thermostat",
"climate.set_temperature",
hass,
payload={"targetSetpoint": {"value": 21.0, "scale": "CELSIUS"}},
)
assert call.data["temperature"] == 21.0
properties = ReportedProperties(msg["context"]["properties"])
properties.assert_equal(
"Alexa.ThermostatController",
"targetSetpoint",
{"value": 21.0, "scale": "CELSIUS"},
)
msg = await assert_request_fails(
"Alexa.ThermostatController",
"SetTargetTemperature",
"climate#test_thermostat",
"climate.set_temperature",
hass,
payload={"targetSetpoint": {"value": 0.0, "scale": "CELSIUS"}},
)
assert msg["event"]["payload"]["type"] == "TEMPERATURE_VALUE_OUT_OF_RANGE"
await assert_request_calls_service(
"Alexa.PowerController",
"TurnOn",
"climate#test_thermostat",
"climate.turn_on",
hass,
)
await assert_request_calls_service(
"Alexa.PowerController",
"TurnOff",
"climate#test_thermostat",
"climate.turn_off",
hass,
)
# Test the power controller is not enabled when there is no `off` mode
device = (
"climate.test_thermostat",
"cool",
{
"temperature": 20.0,
"target_temp_high": None,
"target_temp_low": None,
"current_temperature": 19.0,
"friendly_name": "Test Thermostat",
"supported_features": ClimateEntityFeature.TARGET_TEMPERATURE,
"hvac_modes": ["auto"],
"min_temp": 7,
"max_temp": 30,
},
)
appliance = await discovery_test(device, hass)
assert appliance["endpointId"] == "climate#test_thermostat"
assert appliance["displayCategories"][0] == "THERMOSTAT"
assert appliance["friendlyName"] == "Test Thermostat"
capabilities = assert_endpoint_capabilities(
appliance,
"Alexa.ThermostatController",
"Alexa.TemperatureSensor",
"Alexa.EndpointHealth",
"Alexa",
)
async def test_water_heater(hass: HomeAssistant) -> None:
"""Test water_heater discovery."""
hass.config.units = US_CUSTOMARY_SYSTEM