Clean up Google Assistant (#11375)
* Clean up Google Assistant * Fix tests
This commit is contained in:
parent
fcbf7abdaa
commit
fc8b25a71f
6 changed files with 165 additions and 183 deletions
|
@ -1,4 +1,6 @@
|
|||
"""Support for Google Assistant Smart Home API."""
|
||||
import asyncio
|
||||
from collections import namedtuple
|
||||
import logging
|
||||
|
||||
# Typing imports
|
||||
|
@ -10,6 +12,7 @@ from homeassistant.helpers.entity import Entity # NOQA
|
|||
from homeassistant.core import HomeAssistant # NOQA
|
||||
from homeassistant.util import color
|
||||
from homeassistant.util.unit_system import UnitSystem # NOQA
|
||||
from homeassistant.util.decorator import Registry
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_SUPPORTED_FEATURES, ATTR_ENTITY_ID,
|
||||
|
@ -34,6 +37,7 @@ from .const import (
|
|||
CONF_ALIASES, CLIMATE_SUPPORTED_MODES
|
||||
)
|
||||
|
||||
HANDLERS = Registry()
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# Mapping is [actions schema, primary trait, optional features]
|
||||
|
@ -65,9 +69,7 @@ MAPPING_COMPONENT = {
|
|||
} # type: Dict[str, list]
|
||||
|
||||
|
||||
def make_actions_response(request_id: str, payload: dict) -> dict:
|
||||
"""Make response message."""
|
||||
return {'requestId': request_id, 'payload': payload}
|
||||
Config = namedtuple('GoogleAssistantConfig', 'should_expose,agent_user_id')
|
||||
|
||||
|
||||
def entity_to_device(entity: Entity, units: UnitSystem):
|
||||
|
@ -286,3 +288,98 @@ def determine_service(
|
|||
return (SERVICE_TURN_OFF, service_data)
|
||||
|
||||
return (None, service_data)
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_handle_message(hass, config, message):
|
||||
"""Handle incoming API messages."""
|
||||
request_id = message.get('requestId') # type: str
|
||||
inputs = message.get('inputs') # type: list
|
||||
|
||||
if len(inputs) > 1:
|
||||
_LOGGER.warning('Got unexpected more than 1 input. %s', message)
|
||||
|
||||
# Only use first input
|
||||
intent = inputs[0].get('intent')
|
||||
payload = inputs[0].get('payload')
|
||||
|
||||
handler = HANDLERS.get(intent)
|
||||
|
||||
if handler:
|
||||
result = yield from handler(hass, config, payload)
|
||||
else:
|
||||
result = {'errorCode': 'protocolError'}
|
||||
|
||||
return {'requestId': request_id, 'payload': result}
|
||||
|
||||
|
||||
@HANDLERS.register('action.devices.SYNC')
|
||||
@asyncio.coroutine
|
||||
def async_devices_sync(hass, config, payload):
|
||||
"""Handle action.devices.SYNC request."""
|
||||
devices = []
|
||||
for entity in hass.states.async_all():
|
||||
if not config.should_expose(entity):
|
||||
continue
|
||||
|
||||
device = entity_to_device(entity, hass.config.units)
|
||||
if device is None:
|
||||
_LOGGER.warning("No mapping for %s domain", entity.domain)
|
||||
continue
|
||||
|
||||
devices.append(device)
|
||||
|
||||
return {
|
||||
'agentUserId': config.agent_user_id,
|
||||
'devices': devices,
|
||||
}
|
||||
|
||||
|
||||
@HANDLERS.register('action.devices.QUERY')
|
||||
@asyncio.coroutine
|
||||
def async_devices_query(hass, config, payload):
|
||||
"""Handle action.devices.QUERY request."""
|
||||
devices = {}
|
||||
for device in payload.get('devices', []):
|
||||
devid = device.get('id')
|
||||
# In theory this should never happpen
|
||||
if not devid:
|
||||
_LOGGER.error('Device missing ID: %s', device)
|
||||
continue
|
||||
|
||||
state = hass.states.get(devid)
|
||||
if not state:
|
||||
# If we can't find a state, the device is offline
|
||||
devices[devid] = {'online': False}
|
||||
|
||||
devices[devid] = query_device(state, hass.config.units)
|
||||
|
||||
return {'devices': devices}
|
||||
|
||||
|
||||
@HANDLERS.register('action.devices.EXECUTE')
|
||||
@asyncio.coroutine
|
||||
def handle_devices_execute(hass, config, payload):
|
||||
"""Handle action.devices.EXECUTE request."""
|
||||
commands = []
|
||||
for command in payload.get('commands', []):
|
||||
ent_ids = [ent.get('id') for ent in command.get('devices', [])]
|
||||
for execution in command.get('execution'):
|
||||
for eid in ent_ids:
|
||||
success = False
|
||||
domain = eid.split('.')[0]
|
||||
(service, service_data) = determine_service(
|
||||
eid, execution.get('command'), execution.get('params'),
|
||||
hass.config.units)
|
||||
if domain == "group":
|
||||
domain = "homeassistant"
|
||||
success = yield from hass.services.async_call(
|
||||
domain, service, service_data, blocking=True)
|
||||
result = {"ids": [eid], "states": {}}
|
||||
if success:
|
||||
result['status'] = 'SUCCESS'
|
||||
else:
|
||||
result['status'] = 'ERROR'
|
||||
commands.append(result)
|
||||
|
||||
return {'commands': commands}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue