This commit is contained in:
Paulus Schoutsen 2019-07-31 12:25:30 -07:00
parent da05dfe708
commit 4de97abc3a
2676 changed files with 163166 additions and 140084 deletions

View file

@ -8,8 +8,12 @@ from homeassistant.util.decorator import Registry
from homeassistant.const import ATTR_ENTITY_ID
from .const import (
ERR_PROTOCOL_ERROR, ERR_DEVICE_OFFLINE, ERR_UNKNOWN_ERROR,
EVENT_COMMAND_RECEIVED, EVENT_SYNC_RECEIVED, EVENT_QUERY_RECEIVED
ERR_PROTOCOL_ERROR,
ERR_DEVICE_OFFLINE,
ERR_UNKNOWN_ERROR,
EVENT_COMMAND_RECEIVED,
EVENT_SYNC_RECEIVED,
EVENT_QUERY_RECEIVED,
)
from .helpers import RequestData, GoogleEntity, async_get_entities
from .error import SmartHomeError
@ -20,112 +24,107 @@ _LOGGER = logging.getLogger(__name__)
async def async_handle_message(hass, config, user_id, message):
"""Handle incoming API messages."""
request_id = message.get('requestId') # type: str
request_id = message.get("requestId") # type: str
data = RequestData(config, user_id, request_id)
response = await _process(hass, data, message)
if response and 'errorCode' in response['payload']:
_LOGGER.error('Error handling message %s: %s',
message, response['payload'])
if response and "errorCode" in response["payload"]:
_LOGGER.error("Error handling message %s: %s", message, response["payload"])
return response
async def _process(hass, data, message):
"""Process a message."""
inputs = message.get('inputs') # type: list
inputs = message.get("inputs") # type: list
if len(inputs) != 1:
return {
'requestId': data.request_id,
'payload': {'errorCode': ERR_PROTOCOL_ERROR}
"requestId": data.request_id,
"payload": {"errorCode": ERR_PROTOCOL_ERROR},
}
handler = HANDLERS.get(inputs[0].get('intent'))
handler = HANDLERS.get(inputs[0].get("intent"))
if handler is None:
return {
'requestId': data.request_id,
'payload': {'errorCode': ERR_PROTOCOL_ERROR}
"requestId": data.request_id,
"payload": {"errorCode": ERR_PROTOCOL_ERROR},
}
try:
result = await handler(hass, data, inputs[0].get('payload'))
result = await handler(hass, data, inputs[0].get("payload"))
except SmartHomeError as err:
return {
'requestId': data.request_id,
'payload': {'errorCode': err.code}
}
return {"requestId": data.request_id, "payload": {"errorCode": err.code}}
except Exception: # pylint: disable=broad-except
_LOGGER.exception('Unexpected error')
_LOGGER.exception("Unexpected error")
return {
'requestId': data.request_id,
'payload': {'errorCode': ERR_UNKNOWN_ERROR}
"requestId": data.request_id,
"payload": {"errorCode": ERR_UNKNOWN_ERROR},
}
if result is None:
return None
return {'requestId': data.request_id, 'payload': result}
return {"requestId": data.request_id, "payload": result}
@HANDLERS.register('action.devices.SYNC')
@HANDLERS.register("action.devices.SYNC")
async def async_devices_sync(hass, data, payload):
"""Handle action.devices.SYNC request.
https://developers.google.com/actions/smarthome/create-app#actiondevicessync
"""
hass.bus.async_fire(
EVENT_SYNC_RECEIVED,
{'request_id': data.request_id},
context=data.context)
EVENT_SYNC_RECEIVED, {"request_id": data.request_id}, context=data.context
)
devices = await asyncio.gather(*(
entity.sync_serialize() for entity in
async_get_entities(hass, data.config)
if data.config.should_expose(entity.state)
))
devices = await asyncio.gather(
*(
entity.sync_serialize()
for entity in async_get_entities(hass, data.config)
if data.config.should_expose(entity.state)
)
)
response = {
'agentUserId': data.config.agent_user_id or data.context.user_id,
'devices': devices,
"agentUserId": data.config.agent_user_id or data.context.user_id,
"devices": devices,
}
return response
@HANDLERS.register('action.devices.QUERY')
@HANDLERS.register("action.devices.QUERY")
async def async_devices_query(hass, data, payload):
"""Handle action.devices.QUERY request.
https://developers.google.com/actions/smarthome/create-app#actiondevicesquery
"""
devices = {}
for device in payload.get('devices', []):
devid = device['id']
for device in payload.get("devices", []):
devid = device["id"]
state = hass.states.get(devid)
hass.bus.async_fire(
EVENT_QUERY_RECEIVED,
{
'request_id': data.request_id,
ATTR_ENTITY_ID: devid,
},
context=data.context)
{"request_id": data.request_id, ATTR_ENTITY_ID: devid},
context=data.context,
)
if not state:
# If we can't find a state, the device is offline
devices[devid] = {'online': False}
devices[devid] = {"online": False}
continue
entity = GoogleEntity(hass, data.config, state)
devices[devid] = entity.query_serialize()
return {'devices': devices}
return {"devices": devices}
@HANDLERS.register('action.devices.EXECUTE')
@HANDLERS.register("action.devices.EXECUTE")
async def handle_devices_execute(hass, data, payload):
"""Handle action.devices.EXECUTE request.
@ -134,19 +133,19 @@ async def handle_devices_execute(hass, data, payload):
entities = {}
results = {}
for command in payload['commands']:
for device, execution in product(command['devices'],
command['execution']):
entity_id = device['id']
for command in payload["commands"]:
for device, execution in product(command["devices"], command["execution"]):
entity_id = device["id"]
hass.bus.async_fire(
EVENT_COMMAND_RECEIVED,
{
'request_id': data.request_id,
"request_id": data.request_id,
ATTR_ENTITY_ID: entity_id,
'execution': execution
"execution": execution,
},
context=data.context)
context=data.context,
)
# Happens if error occurred. Skip entity for further processing
if entity_id in results:
@ -157,9 +156,9 @@ async def handle_devices_execute(hass, data, payload):
if state is None:
results[entity_id] = {
'ids': [entity_id],
'status': 'ERROR',
'errorCode': ERR_DEVICE_OFFLINE
"ids": [entity_id],
"status": "ERROR",
"errorCode": ERR_DEVICE_OFFLINE,
}
continue
@ -169,9 +168,9 @@ async def handle_devices_execute(hass, data, payload):
await entities[entity_id].execute(data, execution)
except SmartHomeError as err:
results[entity_id] = {
'ids': [entity_id],
'status': 'ERROR',
**err.to_response()
"ids": [entity_id],
"status": "ERROR",
**err.to_response(),
}
final_results = list(results.values())
@ -182,16 +181,18 @@ async def handle_devices_execute(hass, data, payload):
entity.async_update()
final_results.append({
'ids': [entity.entity_id],
'status': 'SUCCESS',
'states': entity.query_serialize(),
})
final_results.append(
{
"ids": [entity.entity_id],
"status": "SUCCESS",
"states": entity.query_serialize(),
}
)
return {'commands': final_results}
return {"commands": final_results}
@HANDLERS.register('action.devices.DISCONNECT')
@HANDLERS.register("action.devices.DISCONNECT")
async def async_devices_disconnect(hass, data, payload):
"""Handle action.devices.DISCONNECT request.
@ -203,6 +204,6 @@ async def async_devices_disconnect(hass, data, payload):
def turned_off_response(message):
"""Return a device turned off response."""
return {
'requestId': message.get('requestId'),
'payload': {'errorCode': 'deviceTurnedOff'}
"requestId": message.get("requestId"),
"payload": {"errorCode": "deviceTurnedOff"},
}