mirror of
https://github.com/home-assistant/core
synced 2024-10-04 07:58:43 +02:00
Handle on/off through TemperatrureSetting trait. (#21842)
This commit is contained in:
parent
fe468ace34
commit
81bb928394
@ -21,6 +21,7 @@ from homeassistant.const import (
|
||||
SERVICE_TURN_ON,
|
||||
STATE_LOCKED,
|
||||
STATE_OFF,
|
||||
STATE_ON,
|
||||
TEMP_CELSIUS,
|
||||
TEMP_FAHRENHEIT,
|
||||
ATTR_SUPPORTED_FEATURES,
|
||||
@ -199,8 +200,6 @@ class OnOffTrait(_Trait):
|
||||
@staticmethod
|
||||
def supported(domain, features):
|
||||
"""Test if state is supported."""
|
||||
if domain == climate.DOMAIN:
|
||||
return features & climate.SUPPORT_ON_OFF != 0
|
||||
return domain in (
|
||||
group.DOMAIN,
|
||||
input_boolean.DOMAIN,
|
||||
@ -537,9 +536,17 @@ class TemperatureSettingTrait(_Trait):
|
||||
def sync_attributes(self):
|
||||
"""Return temperature point and modes attributes for a sync request."""
|
||||
modes = []
|
||||
for mode in self.state.attributes.get(climate.ATTR_OPERATION_LIST, []):
|
||||
supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)
|
||||
|
||||
if supported & climate.SUPPORT_ON_OFF != 0:
|
||||
modes.append(STATE_OFF)
|
||||
modes.append(STATE_ON)
|
||||
|
||||
if supported & climate.SUPPORT_OPERATION_MODE != 0:
|
||||
for mode in self.state.attributes.get(climate.ATTR_OPERATION_LIST,
|
||||
[]):
|
||||
google_mode = self.hass_to_google.get(mode)
|
||||
if google_mode is not None:
|
||||
if google_mode and google_mode not in modes:
|
||||
modes.append(google_mode)
|
||||
|
||||
return {
|
||||
@ -554,8 +561,16 @@ class TemperatureSettingTrait(_Trait):
|
||||
response = {}
|
||||
|
||||
operation = attrs.get(climate.ATTR_OPERATION_MODE)
|
||||
if operation is not None and operation in self.hass_to_google:
|
||||
supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)
|
||||
|
||||
if (supported & climate.SUPPORT_ON_OFF
|
||||
and self.state.state == STATE_OFF):
|
||||
response['thermostatMode'] = 'off'
|
||||
elif (supported & climate.SUPPORT_OPERATION_MODE and
|
||||
operation in self.hass_to_google):
|
||||
response['thermostatMode'] = self.hass_to_google[operation]
|
||||
elif supported & climate.SUPPORT_ON_OFF:
|
||||
response['thermostatMode'] = 'on'
|
||||
|
||||
unit = self.hass.config.units.temperature_unit
|
||||
|
||||
@ -644,11 +659,26 @@ class TemperatureSettingTrait(_Trait):
|
||||
}, blocking=True, context=data.context)
|
||||
|
||||
elif command == COMMAND_THERMOSTAT_SET_MODE:
|
||||
target_mode = params['thermostatMode']
|
||||
supported = self.state.attributes.get(ATTR_SUPPORTED_FEATURES)
|
||||
|
||||
if (target_mode in [STATE_ON, STATE_OFF] and
|
||||
supported & climate.SUPPORT_ON_OFF):
|
||||
await self.hass.services.async_call(
|
||||
climate.DOMAIN,
|
||||
(SERVICE_TURN_ON
|
||||
if target_mode == STATE_ON
|
||||
else SERVICE_TURN_OFF),
|
||||
{
|
||||
ATTR_ENTITY_ID: self.state.entity_id,
|
||||
climate.ATTR_OPERATION_MODE: target_mode,
|
||||
}, blocking=True, context=data.context)
|
||||
elif supported & climate.SUPPORT_OPERATION_MODE:
|
||||
await self.hass.services.async_call(
|
||||
climate.DOMAIN, climate.SERVICE_SET_OPERATION_MODE, {
|
||||
ATTR_ENTITY_ID: self.state.entity_id,
|
||||
climate.ATTR_OPERATION_MODE:
|
||||
self.google_to_hass[params['thermostatMode']],
|
||||
self.google_to_hass[target_mode],
|
||||
}, blocking=True, context=data.context)
|
||||
|
||||
|
||||
|
@ -231,10 +231,7 @@ DEMO_DEVICES = [{
|
||||
'name': {
|
||||
'name': 'HeatPump'
|
||||
},
|
||||
'traits': [
|
||||
'action.devices.traits.OnOff',
|
||||
'action.devices.traits.TemperatureSetting'
|
||||
],
|
||||
'traits': ['action.devices.traits.TemperatureSetting'],
|
||||
'type': 'action.devices.types.THERMOSTAT',
|
||||
'willReportState': False
|
||||
}, {
|
||||
|
@ -205,7 +205,6 @@ def test_query_climate_request(hass_fixture, assistant_client, auth_header):
|
||||
devices = body['payload']['devices']
|
||||
assert len(devices) == 3
|
||||
assert devices['climate.heatpump'] == {
|
||||
'on': True,
|
||||
'online': True,
|
||||
'thermostatTemperatureSetpoint': 20.0,
|
||||
'thermostatTemperatureAmbient': 25.0,
|
||||
@ -262,7 +261,6 @@ def test_query_climate_request_f(hass_fixture, assistant_client, auth_header):
|
||||
devices = body['payload']['devices']
|
||||
assert len(devices) == 3
|
||||
assert devices['climate.heatpump'] == {
|
||||
'on': True,
|
||||
'online': True,
|
||||
'thermostatTemperatureSetpoint': -6.7,
|
||||
'thermostatTemperatureAmbient': -3.9,
|
||||
|
@ -408,44 +408,9 @@ async def test_onoff_media_player(hass):
|
||||
|
||||
|
||||
async def test_onoff_climate(hass):
|
||||
"""Test OnOff trait support for climate domain."""
|
||||
assert trait.OnOffTrait.supported(climate.DOMAIN, climate.SUPPORT_ON_OFF)
|
||||
|
||||
trt_on = trait.OnOffTrait(hass, State('climate.bla', STATE_ON),
|
||||
BASIC_CONFIG)
|
||||
|
||||
assert trt_on.sync_attributes() == {}
|
||||
|
||||
assert trt_on.query_attributes() == {
|
||||
'on': True
|
||||
}
|
||||
|
||||
trt_off = trait.OnOffTrait(hass, State('climate.bla', STATE_OFF),
|
||||
BASIC_CONFIG)
|
||||
|
||||
assert trt_off.query_attributes() == {
|
||||
'on': False
|
||||
}
|
||||
|
||||
on_calls = async_mock_service(hass, climate.DOMAIN, SERVICE_TURN_ON)
|
||||
await trt_on.execute(
|
||||
trait.COMMAND_ONOFF, BASIC_DATA,
|
||||
{'on': True})
|
||||
assert len(on_calls) == 1
|
||||
assert on_calls[0].data == {
|
||||
ATTR_ENTITY_ID: 'climate.bla',
|
||||
}
|
||||
|
||||
off_calls = async_mock_service(hass, climate.DOMAIN,
|
||||
SERVICE_TURN_OFF)
|
||||
|
||||
await trt_on.execute(
|
||||
trait.COMMAND_ONOFF, BASIC_DATA,
|
||||
{'on': False})
|
||||
assert len(off_calls) == 1
|
||||
assert off_calls[0].data == {
|
||||
ATTR_ENTITY_ID: 'climate.bla',
|
||||
}
|
||||
"""Test OnOff trait not supported for climate domain."""
|
||||
assert not trait.OnOffTrait.supported(
|
||||
climate.DOMAIN, climate.SUPPORT_ON_OFF)
|
||||
|
||||
|
||||
async def test_dock_vacuum(hass):
|
||||
@ -673,6 +638,48 @@ async def test_scene_script(hass):
|
||||
}
|
||||
|
||||
|
||||
async def test_temperature_setting_climate_onoff(hass):
|
||||
"""Test TemperatureSetting trait support for climate domain - range."""
|
||||
assert not trait.TemperatureSettingTrait.supported(climate.DOMAIN, 0)
|
||||
assert trait.TemperatureSettingTrait.supported(
|
||||
climate.DOMAIN, climate.SUPPORT_OPERATION_MODE)
|
||||
|
||||
hass.config.units.temperature_unit = TEMP_FAHRENHEIT
|
||||
|
||||
trt = trait.TemperatureSettingTrait(hass, State(
|
||||
'climate.bla', climate.STATE_AUTO, {
|
||||
ATTR_SUPPORTED_FEATURES: (
|
||||
climate.SUPPORT_OPERATION_MODE | climate.SUPPORT_ON_OFF),
|
||||
climate.ATTR_OPERATION_MODE: climate.STATE_COOL,
|
||||
climate.ATTR_OPERATION_LIST: [
|
||||
climate.STATE_COOL,
|
||||
climate.STATE_HEAT,
|
||||
climate.STATE_AUTO,
|
||||
],
|
||||
climate.ATTR_MIN_TEMP: None,
|
||||
climate.ATTR_MAX_TEMP: None,
|
||||
}), BASIC_CONFIG)
|
||||
assert trt.sync_attributes() == {
|
||||
'availableThermostatModes': 'off,on,cool,heat,heatcool',
|
||||
'thermostatTemperatureUnit': 'F',
|
||||
}
|
||||
assert trt.can_execute(trait.COMMAND_THERMOSTAT_SET_MODE, {})
|
||||
|
||||
calls = async_mock_service(
|
||||
hass, climate.DOMAIN, SERVICE_TURN_ON)
|
||||
await trt.execute(trait.COMMAND_THERMOSTAT_SET_MODE, BASIC_DATA, {
|
||||
'thermostatMode': 'on',
|
||||
})
|
||||
assert len(calls) == 1
|
||||
|
||||
calls = async_mock_service(
|
||||
hass, climate.DOMAIN, SERVICE_TURN_OFF)
|
||||
await trt.execute(trait.COMMAND_THERMOSTAT_SET_MODE, BASIC_DATA, {
|
||||
'thermostatMode': 'off',
|
||||
})
|
||||
assert len(calls) == 1
|
||||
|
||||
|
||||
async def test_temperature_setting_climate_range(hass):
|
||||
"""Test TemperatureSetting trait support for climate domain - range."""
|
||||
assert not trait.TemperatureSettingTrait.supported(climate.DOMAIN, 0)
|
||||
@ -685,6 +692,7 @@ async def test_temperature_setting_climate_range(hass):
|
||||
'climate.bla', climate.STATE_AUTO, {
|
||||
climate.ATTR_CURRENT_TEMPERATURE: 70,
|
||||
climate.ATTR_CURRENT_HUMIDITY: 25,
|
||||
ATTR_SUPPORTED_FEATURES: climate.SUPPORT_OPERATION_MODE,
|
||||
climate.ATTR_OPERATION_MODE: climate.STATE_AUTO,
|
||||
climate.ATTR_OPERATION_LIST: [
|
||||
STATE_OFF,
|
||||
@ -755,6 +763,8 @@ async def test_temperature_setting_climate_setpoint(hass):
|
||||
|
||||
trt = trait.TemperatureSettingTrait(hass, State(
|
||||
'climate.bla', climate.STATE_AUTO, {
|
||||
ATTR_SUPPORTED_FEATURES: (
|
||||
climate.SUPPORT_OPERATION_MODE | climate.SUPPORT_ON_OFF),
|
||||
climate.ATTR_OPERATION_MODE: climate.STATE_COOL,
|
||||
climate.ATTR_OPERATION_LIST: [
|
||||
STATE_OFF,
|
||||
@ -766,7 +776,7 @@ async def test_temperature_setting_climate_setpoint(hass):
|
||||
climate.ATTR_CURRENT_TEMPERATURE: 20
|
||||
}), BASIC_CONFIG)
|
||||
assert trt.sync_attributes() == {
|
||||
'availableThermostatModes': 'off,cool',
|
||||
'availableThermostatModes': 'off,on,cool',
|
||||
'thermostatTemperatureUnit': 'C',
|
||||
}
|
||||
assert trt.query_attributes() == {
|
||||
|
Loading…
Reference in New Issue
Block a user