-
-
Notifications
You must be signed in to change notification settings - Fork 29.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Google Assistant request sync service #10165
Changes from 2 commits
9651508
30aca62
cc46b81
c8e338d
0912d77
da72f2e
fed15ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,10 +16,14 @@ | |
from typing import Dict, Any # NOQA | ||
|
||
from homeassistant.helpers import config_validation as cv | ||
from homeassistant.helpers.aiohttp_client import async_get_clientsession | ||
from homeassistant.loader import bind_hass | ||
|
||
from .const import ( | ||
DOMAIN, CONF_PROJECT_ID, CONF_CLIENT_ID, CONF_ACCESS_TOKEN, | ||
CONF_EXPOSE_BY_DEFAULT, CONF_EXPOSED_DOMAINS | ||
CONF_EXPOSE_BY_DEFAULT, CONF_EXPOSED_DOMAINS, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trailing whitespace |
||
CONF_AGENT_USER_ID, CONF_HOMEGRAPH_API_KEY, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trailing whitespace |
||
SERVICE_REQUEST_SYNC, REQUEST_SYNC_BASE_URL | ||
) | ||
from .auth import GoogleAssistantAuthView | ||
from .http import GoogleAssistantView | ||
|
@@ -36,10 +40,15 @@ | |
vol.Required(CONF_ACCESS_TOKEN): cv.string, | ||
vol.Optional(CONF_EXPOSE_BY_DEFAULT): cv.boolean, | ||
vol.Optional(CONF_EXPOSED_DOMAINS): cv.ensure_list, | ||
vol.Required(CONF_AGENT_USER_ID): cv.string, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would make this optional and add a default for agent ID. Unless I misunderstood the docs there's no need for a unique agent ID since the integration maps 1:1 with an account. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @philk, I was a bit unsure about this. If HA were to ever become an official Google Assistant app, then the userId will have to be unique across all "cloud" users. Asking users to input their email address here may provide a bit of leeway in that regard. Let me know your thoughts. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, that's kind of why I think it should just be a default for now. If/when that happens it could be made required or the default modified based on some part of the cloud auth system. |
||
vol.Required(CONF_HOMEGRAPH_API_KEY): cv.string | ||
} | ||
}, | ||
extra=vol.ALLOW_EXTRA) | ||
|
||
def request_sync(hass): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
"""Request sync.""" | ||
hass.services.call(DOMAIN, SERVICE_REQUEST_SYNC) | ||
|
||
@asyncio.coroutine | ||
def async_setup(hass: HomeAssistant, yaml_config: Dict[str, Any]): | ||
|
@@ -49,4 +58,24 @@ def async_setup(hass: HomeAssistant, yaml_config: Dict[str, Any]): | |
hass.http.register_view(GoogleAssistantAuthView(hass, config)) | ||
hass.http.register_view(GoogleAssistantView(hass, config)) | ||
|
||
@asyncio.coroutine | ||
def request_sync_service_handler(call): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to move this out of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hey @philk - confused by this comment. I have followed examples from automation, light inits. They all seem to define the service handler inside async_setup There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stylistically it looks weird to me but I looked through a few other components and that just seems to be the way to do it for hass/in python so nevermind, it works and matches so LGTM |
||
"""Handle request sync service calls.""" | ||
#Code to execute request sync goes here | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. block comment should start with '# ' |
||
websession = async_get_clientsession(hass) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. local variable 'websession' is assigned to but never used |
||
try: | ||
agent_user_id = config.get(CONF_AGENT_USER_ID) | ||
with async_timeout.timeout(5, loop=hass.loop): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. undefined name 'async_timeout' There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to import |
||
req = yield from session.post( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. local variable 'req' is assigned to but never used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to do something with the request. I recommend raise_for_status() and separately catching and handling except aiohttp.ClientResponseError:
body = yield from res.read()
_LOGGER.error(
'sync request failed: %d %s', res.status, body)
return |
||
REQUEST_SYNC_BASE_URL+CONF_HOMEGRAPH_API_KEY, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trailing whitespace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The API key being part of params is cleaner: |
||
json={'agent_user_id': agent_user_id}) | ||
_LOGGER.info("Submitted request_sync request to Google") | ||
except (asyncio.TimeoutError, aiohttp.ClientError): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. undefined name 'aiohttp' There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ^ import aiohttp |
||
_LOGGER.error("Could not contact Google for request_sync") | ||
return None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistent return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Think you can just remove all of them? |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
hass.services.async_register( | ||
DOMAIN, SERVICE_REQUEST_SYNC, request_sync_service_handler, | ||
descriptions.get(SERVICE_REQUEST_SYNC)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. undefined name 'descriptions' There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ^ going to need a services.yaml and initialize the description (look for another component that has |
||
|
||
return True |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,8 @@ | |
CONF_ACCESS_TOKEN = 'access_token' | ||
CONF_CLIENT_ID = 'client_id' | ||
CONF_ALIASES = 'aliases' | ||
CONF_AGENT_USER_ID = 'agent_user_id' | ||
CONF_HOMEGRAPH_API_KEY = 'homegraph_api_key' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The API key isn't specific to homegraph, but to the project as a whole. So maybe rename to just |
||
|
||
DEFAULT_EXPOSE_BY_DEFAULT = True | ||
DEFAULT_EXPOSED_DOMAINS = [ | ||
|
@@ -35,3 +37,7 @@ | |
TYPE_LIGHT = PREFIX_TYPES + 'LIGHT' | ||
TYPE_SWITCH = PREFIX_TYPES + 'SWITCH' | ||
TYPE_SCENE = PREFIX_TYPES + 'SCENE' | ||
|
||
SERVICE_REQUEST_SYNC = 'request_sync' | ||
HOMEGRAPH_URL = 'https://homegraph.googleapis.com/' | ||
REQUEST_SYNC_BASE_URL = HOMEGRAPH_URL + 'v1/devices:requestSync?key=' |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,9 @@ | |
DEFAULT_EXPOSED_DOMAINS, | ||
CONF_EXPOSE_BY_DEFAULT, | ||
CONF_EXPOSED_DOMAINS, | ||
ATTR_GOOGLE_ASSISTANT) | ||
ATTR_GOOGLE_ASSISTANT, | ||
CONF_AGENT_USER_ID | ||
) | ||
from .smart_home import entity_to_device, query_device, determine_service | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
@@ -48,6 +50,7 @@ def __init__(self, hass: HomeAssistant, cfg: Dict[str, Any]) -> None: | |
DEFAULT_EXPOSE_BY_DEFAULT) | ||
self.exposed_domains = cfg.get(CONF_EXPOSED_DOMAINS, | ||
DEFAULT_EXPOSED_DOMAINS) | ||
self.agent_user_id = cfg.get(CONF_AGENT_USER_ID) | ||
|
||
def is_entity_exposed(self, entity) -> bool: | ||
"""Determine if an entity should be exposed to Google Assistant.""" | ||
|
@@ -85,7 +88,9 @@ def handle_sync(self, hass: HomeAssistant, request_id: str): | |
devices.append(device) | ||
|
||
return self.json( | ||
make_actions_response(request_id, {'devices': devices})) | ||
make_actions_response(request_id, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trailing whitespace |
||
{'agentUserId': self.agent_user_id, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
'devices': devices})) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
|
||
@asyncio.coroutine | ||
def handle_query(self, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'homeassistant.loader.bind_hass' imported but unused