Add alexa PowerController on enabled features for climate entities (#109174)
Depend alexa PowerController on enabled features for climate entities
This commit is contained in:
parent
41fdcce226
commit
712ba2fdca
4 changed files with 195 additions and 2 deletions
|
@ -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)
|
||||
):
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue