Google Assistant: Create and pass context to service calls (#21551)

* Google Assistant: Create and pass context to service calls

* Refactor request data into separate object and pass to execute.
This commit is contained in:
Penny Wood authored and Paulus Schoutsen committed 2019-03-05 20:00:53 -08:00
1 parent fc1ee9be43
commit d1038ea79f
8 files changed
+345 -265

No files matched your search

@@ -1,7 +1,7 @@
"""Test Google Smart Home."""
import pytest
from homeassistant.core import State
from homeassistant.core import State, EVENT_CALL_SERVICE
from homeassistant.const import (
ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT, TEMP_CELSIUS)
from homeassistant.setup import async_setup_component
@@ -19,8 +19,7 @@ from tests.common import (mock_device_registry, mock_registry,
BASIC_CONFIG = helpers.Config(
should_expose=lambda state: True,
allow_unlock=False,
agent_user_id='test-agent',
allow_unlock=False
)
REQ_ID = 'ff36a3cc-ec34-11e6-b1a0-64510650abcf'
@@ -56,7 +55,6 @@ async def test_sync_message(hass):
config = helpers.Config(
should_expose=lambda state: state.entity_id != 'light.not_expose',
allow_unlock=False,
agent_user_id='test-agent',
entity_config={
'light.demo_light': {
const.CONF_ROOM_HINT: 'Living Room',
@@ -68,12 +66,14 @@ async def test_sync_message(hass):
events = []
hass.bus.async_listen(EVENT_SYNC_RECEIVED, events.append)
result = await sh.async_handle_message(hass, config, {
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.SYNC"
}]
})
result = await sh.async_handle_message(
hass, config, 'test-agent',
{
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.SYNC"
}]
})
assert result == {
'requestId': REQ_ID,
@@ -114,6 +114,7 @@ async def test_sync_message(hass):
}
# pylint: disable=redefined-outer-name
async def test_sync_in_area(hass, registries):
"""Test a sync message where room hint comes from area."""
area = registries.area.async_create("Living Room")
@@ -142,19 +143,20 @@ async def test_sync_in_area(hass, registries):
config = helpers.Config(
should_expose=lambda _: True,
allow_unlock=False,
agent_user_id='test-agent',
entity_config={}
)
events = []
hass.bus.async_listen(EVENT_SYNC_RECEIVED, events.append)
result = await sh.async_handle_message(hass, config, {
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.SYNC"
}]
})
result = await sh.async_handle_message(
hass, config, 'test-agent',
{
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.SYNC"
}]
})
assert result == {
'requestId': REQ_ID,
@@ -216,21 +218,23 @@ async def test_query_message(hass):
events = []
hass.bus.async_listen(EVENT_QUERY_RECEIVED, events.append)
result = await sh.async_handle_message(hass, BASIC_CONFIG, {
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.QUERY",
"payload": {
"devices": [{
"id": "light.demo_light",
}, {
"id": "light.another_light",
}, {
"id": "light.non_existing",
}]
}
}]
})
result = await sh.async_handle_message(
hass, BASIC_CONFIG, 'test-agent',
{
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.QUERY",
"payload": {
"devices": [{
"id": "light.demo_light",
}, {
"id": "light.another_light",
}, {
"id": "light.non_existing",
}]
}
}]
})
assert result == {
'requestId': REQ_ID,
@@ -280,39 +284,44 @@ async def test_execute(hass):
'light': {'platform': 'demo'}
})
events = []
hass.bus.async_listen(EVENT_COMMAND_RECEIVED, events.append)
await hass.services.async_call(
'light', 'turn_off', {'entity_id': 'light.ceiling_lights'},
blocking=True)
result = await sh.async_handle_message(hass, BASIC_CONFIG, {
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.EXECUTE",
"payload": {
"commands": [{
"devices": [
{"id": "light.non_existing"},
{"id": "light.ceiling_lights"},
],
"execution": [{
"command": "action.devices.commands.OnOff",
"params": {
"on": True
}
}, {
"command":
"action.devices.commands.BrightnessAbsolute",
"params": {
"brightness": 20
}
events = []
hass.bus.async_listen(EVENT_COMMAND_RECEIVED, events.append)
service_events = []
hass.bus.async_listen(EVENT_CALL_SERVICE, service_events.append)
result = await sh.async_handle_message(
hass, BASIC_CONFIG, None,
{
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.EXECUTE",
"payload": {
"commands": [{
"devices": [
{"id": "light.non_existing"},
{"id": "light.ceiling_lights"},
],
"execution": [{
"command": "action.devices.commands.OnOff",
"params": {
"on": True
}
}, {
"command":
"action.devices.commands.BrightnessAbsolute",
"params": {
"brightness": 20
}
}]
}]
}]
}
}]
})
}
}]
})
assert result == {
"requestId": REQ_ID,
@@ -383,6 +392,24 @@ async def test_execute(hass):
}
}
assert len(service_events) == 2
assert service_events[0].data == {
'domain': 'light',
'service': 'turn_on',
'service_data': {'entity_id': 'light.ceiling_lights'}
}
assert service_events[0].context == events[2].context
assert service_events[1].data == {
'domain': 'light',
'service': 'turn_on',
'service_data': {
'brightness_pct': 20,
'entity_id': 'light.ceiling_lights'
}
}
assert service_events[1].context == events[2].context
assert service_events[1].context == events[3].context
async def test_raising_error_trait(hass):
"""Test raising an error while executing a trait command."""
@@ -397,26 +424,28 @@ async def test_raising_error_trait(hass):
hass.bus.async_listen(EVENT_COMMAND_RECEIVED, events.append)
await hass.async_block_till_done()
result = await sh.async_handle_message(hass, BASIC_CONFIG, {
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.EXECUTE",
"payload": {
"commands": [{
"devices": [
{"id": "climate.bla"},
],
"execution": [{
"command": "action.devices.commands."
"ThermostatTemperatureSetpoint",
"params": {
"thermostatTemperatureSetpoint": 10
}
result = await sh.async_handle_message(
hass, BASIC_CONFIG, 'test-agent',
{
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.EXECUTE",
"payload": {
"commands": [{
"devices": [
{"id": "climate.bla"},
],
"execution": [{
"command": "action.devices.commands."
"ThermostatTemperatureSetpoint",
"params": {
"thermostatTemperatureSetpoint": 10
}
}]
}]
}]
}
}]
})
}
}]
})
assert result == {
"requestId": REQ_ID,
@@ -446,6 +475,7 @@ async def test_raising_error_trait(hass):
async def test_serialize_input_boolean(hass):
"""Test serializing an input boolean entity."""
state = State('input_boolean.bla', 'on')
# pylint: disable=protected-access
entity = sh._GoogleEntity(hass, BASIC_CONFIG, state)
result = await entity.sync_serialize()
assert result == {
@@ -466,15 +496,17 @@ async def test_unavailable_state_doesnt_sync(hass):
)
light.hass = hass
light.entity_id = 'light.demo_light'
light._available = False
light._available = False # pylint: disable=protected-access
await light.async_update_ha_state()
result = await sh.async_handle_message(hass, BASIC_CONFIG, {
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.SYNC"
}]
})
result = await sh.async_handle_message(
hass, BASIC_CONFIG, 'test-agent',
{
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.SYNC"
}]
})
assert result == {
'requestId': REQ_ID,
@@ -495,12 +527,14 @@ async def test_empty_name_doesnt_sync(hass):
light.entity_id = 'light.demo_light'
await light.async_update_ha_state()
result = await sh.async_handle_message(hass, BASIC_CONFIG, {
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.SYNC"
}]
})
result = await sh.async_handle_message(
hass, BASIC_CONFIG, 'test-agent',
{
"requestId": REQ_ID,
"inputs": [{
"intent": "action.devices.SYNC"
}]
})
assert result == {
'requestId': REQ_ID,
@@ -513,11 +547,13 @@ async def test_empty_name_doesnt_sync(hass):
async def test_query_disconnect(hass):
"""Test a disconnect message."""
result = await sh.async_handle_message(hass, BASIC_CONFIG, {
'inputs': [
{'intent': 'action.devices.DISCONNECT'}
],
'requestId': REQ_ID
})
result = await sh.async_handle_message(
hass, BASIC_CONFIG, 'test-agent',
{
'inputs': [
{'intent': 'action.devices.DISCONNECT'}
],
'requestId': REQ_ID
})
assert result is None
+110 -89
View File
@@ -19,19 +19,25 @@ from homeassistant.components.google_assistant import trait, helpers, const
from homeassistant.const import (
STATE_ON, STATE_OFF, ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF,
TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_SUPPORTED_FEATURES, ATTR_TEMPERATURE)
from homeassistant.core import State, DOMAIN as HA_DOMAIN
from homeassistant.core import State, DOMAIN as HA_DOMAIN, EVENT_CALL_SERVICE
from homeassistant.util import color
from tests.common import async_mock_service
BASIC_CONFIG = helpers.Config(
should_expose=lambda state: True,
allow_unlock=False,
agent_user_id='test-agent',
allow_unlock=False
)
REQ_ID = 'ff36a3cc-ec34-11e6-b1a0-64510650abcf'
BASIC_DATA = helpers.RequestData(
BASIC_CONFIG,
'test-agent',
REQ_ID,
)
UNSAFE_CONFIG = helpers.Config(
should_expose=lambda state: True,
agent_user_id='test-agent',
allow_unlock=True,
)
@@ -51,16 +57,28 @@ async def test_brightness_light(hass):
'brightness': 95
}
events = []
hass.bus.async_listen(EVENT_CALL_SERVICE, events.append)
calls = async_mock_service(hass, light.DOMAIN, light.SERVICE_TURN_ON)
await trt.execute(trait.COMMAND_BRIGHTNESS_ABSOLUTE, {
'brightness': 50
})
await trt.execute(
trait.COMMAND_BRIGHTNESS_ABSOLUTE, BASIC_DATA,
{'brightness': 50})
await hass.async_block_till_done()
assert len(calls) == 1
assert calls[0].data == {
ATTR_ENTITY_ID: 'light.bla',
light.ATTR_BRIGHTNESS_PCT: 50
}
assert len(events) == 1
assert events[0].data == {
'domain': 'light',
'service': 'turn_on',
'service_data': {'brightness_pct': 50, 'entity_id': 'light.bla'}
}
async def test_brightness_cover(hass):
"""Test brightness trait support for cover domain."""
@@ -79,9 +97,9 @@ async def test_brightness_cover(hass):
calls = async_mock_service(
hass, cover.DOMAIN, cover.SERVICE_SET_COVER_POSITION)
await trt.execute(trait.COMMAND_BRIGHTNESS_ABSOLUTE, {
'brightness': 50
})
await trt.execute(
trait.COMMAND_BRIGHTNESS_ABSOLUTE, BASIC_DATA,
{'brightness': 50})
assert len(calls) == 1
assert calls[0].data == {
ATTR_ENTITY_ID: 'cover.bla',
@@ -107,9 +125,9 @@ async def test_brightness_media_player(hass):
calls = async_mock_service(
hass, media_player.DOMAIN, media_player.SERVICE_VOLUME_SET)
await trt.execute(trait.COMMAND_BRIGHTNESS_ABSOLUTE, {
'brightness': 60
})
await trt.execute(
trait.COMMAND_BRIGHTNESS_ABSOLUTE, BASIC_DATA,
{'brightness': 60})
assert len(calls) == 1
assert calls[0].data == {
ATTR_ENTITY_ID: 'media_player.bla',
@@ -137,18 +155,18 @@ async def test_onoff_group(hass):
}
on_calls = async_mock_service(hass, HA_DOMAIN, SERVICE_TURN_ON)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': True
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': True})
assert len(on_calls) == 1
assert on_calls[0].data == {
ATTR_ENTITY_ID: 'group.bla',
}
off_calls = async_mock_service(hass, HA_DOMAIN, SERVICE_TURN_OFF)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': False
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': False})
assert len(off_calls) == 1
assert off_calls[0].data == {
ATTR_ENTITY_ID: 'group.bla',
@@ -176,9 +194,9 @@ async def test_onoff_input_boolean(hass):
}
on_calls = async_mock_service(hass, input_boolean.DOMAIN, SERVICE_TURN_ON)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': True
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': True})
assert len(on_calls) == 1
assert on_calls[0].data == {
ATTR_ENTITY_ID: 'input_boolean.bla',
@@ -186,9 +204,9 @@ async def test_onoff_input_boolean(hass):
off_calls = async_mock_service(hass, input_boolean.DOMAIN,
SERVICE_TURN_OFF)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': False
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': False})
assert len(off_calls) == 1
assert off_calls[0].data == {
ATTR_ENTITY_ID: 'input_boolean.bla',
@@ -216,18 +234,18 @@ async def test_onoff_switch(hass):
}
on_calls = async_mock_service(hass, switch.DOMAIN, SERVICE_TURN_ON)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': True
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': True})
assert len(on_calls) == 1
assert on_calls[0].data == {
ATTR_ENTITY_ID: 'switch.bla',
}
off_calls = async_mock_service(hass, switch.DOMAIN, SERVICE_TURN_OFF)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': False
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': False})
assert len(off_calls) == 1
assert off_calls[0].data == {
ATTR_ENTITY_ID: 'switch.bla',
@@ -252,18 +270,18 @@ async def test_onoff_fan(hass):
}
on_calls = async_mock_service(hass, fan.DOMAIN, SERVICE_TURN_ON)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': True
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': True})
assert len(on_calls) == 1
assert on_calls[0].data == {
ATTR_ENTITY_ID: 'fan.bla',
}
off_calls = async_mock_service(hass, fan.DOMAIN, SERVICE_TURN_OFF)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': False
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': False})
assert len(off_calls) == 1
assert off_calls[0].data == {
ATTR_ENTITY_ID: 'fan.bla',
@@ -290,18 +308,18 @@ async def test_onoff_light(hass):
}
on_calls = async_mock_service(hass, light.DOMAIN, SERVICE_TURN_ON)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': True
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': True})
assert len(on_calls) == 1
assert on_calls[0].data == {
ATTR_ENTITY_ID: 'light.bla',
}
off_calls = async_mock_service(hass, light.DOMAIN, SERVICE_TURN_OFF)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': False
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': False})
assert len(off_calls) == 1
assert off_calls[0].data == {
ATTR_ENTITY_ID: 'light.bla',
@@ -329,9 +347,9 @@ async def test_onoff_cover(hass):
}
on_calls = async_mock_service(hass, cover.DOMAIN, cover.SERVICE_OPEN_COVER)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': True
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': True})
assert len(on_calls) == 1
assert on_calls[0].data == {
ATTR_ENTITY_ID: 'cover.bla',
@@ -339,9 +357,9 @@ async def test_onoff_cover(hass):
off_calls = async_mock_service(hass, cover.DOMAIN,
cover.SERVICE_CLOSE_COVER)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': False
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': False})
assert len(off_calls) == 1
assert off_calls[0].data == {
ATTR_ENTITY_ID: 'cover.bla',
@@ -369,9 +387,9 @@ async def test_onoff_media_player(hass):
}
on_calls = async_mock_service(hass, media_player.DOMAIN, SERVICE_TURN_ON)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': True
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': True})
assert len(on_calls) == 1
assert on_calls[0].data == {
ATTR_ENTITY_ID: 'media_player.bla',
@@ -380,9 +398,9 @@ async def test_onoff_media_player(hass):
off_calls = async_mock_service(hass, media_player.DOMAIN,
SERVICE_TURN_OFF)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': False
})
await trt_on.execute(
trait.COMMAND_ONOFF, BASIC_DATA,
{'on': False})
assert len(off_calls) == 1
assert off_calls[0].data == {
ATTR_ENTITY_ID: 'media_player.bla',
@@ -410,9 +428,9 @@ async def test_onoff_climate(hass):
}
on_calls = async_mock_service(hass, climate.DOMAIN, SERVICE_TURN_ON)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': True
})
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',
@@ -421,9 +439,9 @@ async def test_onoff_climate(hass):
off_calls = async_mock_service(hass, climate.DOMAIN,
SERVICE_TURN_OFF)
await trt_on.execute(trait.COMMAND_ONOFF, {
'on': False
})
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',
@@ -445,7 +463,8 @@ async def test_dock_vacuum(hass):
calls = async_mock_service(hass, vacuum.DOMAIN,
vacuum.SERVICE_RETURN_TO_BASE)
await trt.execute(trait.COMMAND_DOCK, {})
await trt.execute(
trait.COMMAND_DOCK, BASIC_DATA, {})
assert len(calls) == 1
assert calls[0].data == {
ATTR_ENTITY_ID: 'vacuum.bla',
@@ -469,7 +488,7 @@ async def test_startstop_vacuum(hass):
start_calls = async_mock_service(hass, vacuum.DOMAIN,
vacuum.SERVICE_START)
await trt.execute(trait.COMMAND_STARTSTOP, {'start': True})
await trt.execute(trait.COMMAND_STARTSTOP, BASIC_DATA, {'start': True})
assert len(start_calls) == 1
assert start_calls[0].data == {
ATTR_ENTITY_ID: 'vacuum.bla',
@@ -477,7 +496,7 @@ async def test_startstop_vacuum(hass):
stop_calls = async_mock_service(hass, vacuum.DOMAIN,
vacuum.SERVICE_STOP)
await trt.execute(trait.COMMAND_STARTSTOP, {'start': False})
await trt.execute(trait.COMMAND_STARTSTOP, BASIC_DATA, {'start': False})
assert len(stop_calls) == 1
assert stop_calls[0].data == {
ATTR_ENTITY_ID: 'vacuum.bla',
@@ -485,7 +504,7 @@ async def test_startstop_vacuum(hass):
pause_calls = async_mock_service(hass, vacuum.DOMAIN,
vacuum.SERVICE_PAUSE)
await trt.execute(trait.COMMAND_PAUSEUNPAUSE, {'pause': True})
await trt.execute(trait.COMMAND_PAUSEUNPAUSE, BASIC_DATA, {'pause': True})
assert len(pause_calls) == 1
assert pause_calls[0].data == {
ATTR_ENTITY_ID: 'vacuum.bla',
@@ -493,7 +512,7 @@ async def test_startstop_vacuum(hass):
unpause_calls = async_mock_service(hass, vacuum.DOMAIN,
vacuum.SERVICE_START)
await trt.execute(trait.COMMAND_PAUSEUNPAUSE, {'pause': False})
await trt.execute(trait.COMMAND_PAUSEUNPAUSE, BASIC_DATA, {'pause': False})
assert len(unpause_calls) == 1
assert unpause_calls[0].data == {
ATTR_ENTITY_ID: 'vacuum.bla',
@@ -532,7 +551,7 @@ async def test_color_spectrum_light(hass):
})
calls = async_mock_service(hass, light.DOMAIN, SERVICE_TURN_ON)
await trt.execute(trait.COMMAND_COLOR_ABSOLUTE, {
await trt.execute(trait.COMMAND_COLOR_ABSOLUTE, BASIC_DATA, {
'color': {
'spectrumRGB': 1052927
}
@@ -581,14 +600,14 @@ async def test_color_temperature_light(hass):
calls = async_mock_service(hass, light.DOMAIN, SERVICE_TURN_ON)
with pytest.raises(helpers.SmartHomeError) as err:
await trt.execute(trait.COMMAND_COLOR_ABSOLUTE, {
await trt.execute(trait.COMMAND_COLOR_ABSOLUTE, BASIC_DATA, {
'color': {
'temperature': 5555
}
})
assert err.value.code == const.ERR_VALUE_OUT_OF_RANGE
await trt.execute(trait.COMMAND_COLOR_ABSOLUTE, {
await trt.execute(trait.COMMAND_COLOR_ABSOLUTE, BASIC_DATA, {
'color': {
'temperature': 2857
}
@@ -626,7 +645,7 @@ async def test_scene_scene(hass):
assert trt.can_execute(trait.COMMAND_ACTIVATE_SCENE, {})
calls = async_mock_service(hass, scene.DOMAIN, SERVICE_TURN_ON)
await trt.execute(trait.COMMAND_ACTIVATE_SCENE, {})
await trt.execute(trait.COMMAND_ACTIVATE_SCENE, BASIC_DATA, {})
assert len(calls) == 1
assert calls[0].data == {
ATTR_ENTITY_ID: 'scene.bla',
@@ -643,7 +662,7 @@ async def test_scene_script(hass):
assert trt.can_execute(trait.COMMAND_ACTIVATE_SCENE, {})
calls = async_mock_service(hass, script.DOMAIN, SERVICE_TURN_ON)
await trt.execute(trait.COMMAND_ACTIVATE_SCENE, {})
await trt.execute(trait.COMMAND_ACTIVATE_SCENE, BASIC_DATA, {})
# We don't wait till script execution is done.
await hass.async_block_till_done()
@@ -695,10 +714,11 @@ async def test_temperature_setting_climate_range(hass):
calls = async_mock_service(
hass, climate.DOMAIN, climate.SERVICE_SET_TEMPERATURE)
await trt.execute(trait.COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE, {
'thermostatTemperatureSetpointHigh': 25,
'thermostatTemperatureSetpointLow': 20,
})
await trt.execute(
trait.COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE, BASIC_DATA, {
'thermostatTemperatureSetpointHigh': 25,
'thermostatTemperatureSetpointLow': 20,
})
assert len(calls) == 1
assert calls[0].data == {
ATTR_ENTITY_ID: 'climate.bla',
@@ -708,7 +728,7 @@ async def test_temperature_setting_climate_range(hass):
calls = async_mock_service(
hass, climate.DOMAIN, climate.SERVICE_SET_OPERATION_MODE)
await trt.execute(trait.COMMAND_THERMOSTAT_SET_MODE, {
await trt.execute(trait.COMMAND_THERMOSTAT_SET_MODE, BASIC_DATA, {
'thermostatMode': 'heatcool',
})
assert len(calls) == 1
@@ -718,9 +738,9 @@ async def test_temperature_setting_climate_range(hass):
}
with pytest.raises(helpers.SmartHomeError) as err:
await trt.execute(trait.COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT, {
'thermostatTemperatureSetpoint': -100,
})
await trt.execute(
trait.COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT, BASIC_DATA,
{'thermostatTemperatureSetpoint': -100})
assert err.value.code == const.ERR_VALUE_OUT_OF_RANGE
hass.config.units.temperature_unit = TEMP_CELSIUS
@@ -762,13 +782,13 @@ async def test_temperature_setting_climate_setpoint(hass):
hass, climate.DOMAIN, climate.SERVICE_SET_TEMPERATURE)
with pytest.raises(helpers.SmartHomeError):
await trt.execute(trait.COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT, {
'thermostatTemperatureSetpoint': -100,
})
await trt.execute(
trait.COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT, BASIC_DATA,
{'thermostatTemperatureSetpoint': -100})
await trt.execute(trait.COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT, {
'thermostatTemperatureSetpoint': 19,
})
await trt.execute(
trait.COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT, BASIC_DATA,
{'thermostatTemperatureSetpoint': 19})
assert len(calls) == 1
assert calls[0].data == {
ATTR_ENTITY_ID: 'climate.bla',
@@ -793,7 +813,7 @@ async def test_lock_unlock_lock(hass):
assert trt.can_execute(trait.COMMAND_LOCKUNLOCK, {'lock': True})
calls = async_mock_service(hass, lock.DOMAIN, lock.SERVICE_LOCK)
await trt.execute(trait.COMMAND_LOCKUNLOCK, {'lock': True})
await trt.execute(trait.COMMAND_LOCKUNLOCK, BASIC_DATA, {'lock': True})
assert len(calls) == 1
assert calls[0].data == {
@@ -830,7 +850,7 @@ async def test_lock_unlock_unlock(hass):
assert trt.can_execute(trait.COMMAND_LOCKUNLOCK, {'lock': False})
calls = async_mock_service(hass, lock.DOMAIN, lock.SERVICE_UNLOCK)
await trt.execute(trait.COMMAND_LOCKUNLOCK, {'lock': False})
await trt.execute(trait.COMMAND_LOCKUNLOCK, BASIC_DATA, {'lock': False})
assert len(calls) == 1
assert calls[0].data == {
@@ -910,7 +930,8 @@ async def test_fan_speed(hass):
trait.COMMAND_FANSPEED, params={'fanSpeed': 'medium'})
calls = async_mock_service(hass, fan.DOMAIN, fan.SERVICE_SET_SPEED)
await trt.execute(trait.COMMAND_FANSPEED, params={'fanSpeed': 'medium'})
await trt.execute(
trait.COMMAND_FANSPEED, BASIC_DATA, {'fanSpeed': 'medium'})
assert len(calls) == 1
assert calls[0].data == {
@@ -995,7 +1016,7 @@ async def test_modes(hass):
calls = async_mock_service(
hass, media_player.DOMAIN, media_player.SERVICE_SELECT_SOURCE)
await trt.execute(
trait.COMMAND_MODES, params={
trait.COMMAND_MODES, BASIC_DATA, {
'updateModeSettings': {
trt.HA_TO_GOOGLE.get(media_player.ATTR_INPUT_SOURCE): 'media'
}})