Лаба “Smart Home Washer” по созданию устройств для Google Home объясняет, как сделать “облачную” часть собственного устройства и связать ее с “облаком” Google Home. Но это только начало: далее необходимо “олбако” связать с самим устройством.

Архитектура полученного решения такова: услышав пользователя, Google Assistant передает распознанную команду в Google Home. Тот, в свою очередь, определяет, какому устройству команда предназначается, и вызывает соответствующий webhook. Лаба объясняет, как создать webhook с помощью Firebase Cloud Functions и сохранить состояние устройства в Firebase Realtime Database.

База данных - это еще не само устройство. Следующая задача - связать исполнителя команд с базой данных и получать сообщения об изменении сохраненного в базе состояния устройства. Изменение состояния в базе означаен необходимость привести реальное устройство в это же состояние (передать устройству команду).

Далее примеры на Python. Документация универсальная.

Шаг первый: получить авторизационный токен. Поскольку это прототип, и к тому же не выходящий за пределы дома проект, то авторизация с помощью service account key не выглядит большой уязвимостью.

Получение токена описано здесь. Там же есть инструкция, как сгенерировать ключ и получить файл с ключом. Подсказка: чтобы найти нужную секцию, нужно у проекта в Firebase открыть Project Settings (иконка-шестеренка рядом с пунктом “Project Overview”).

from google.oauth2 import service_account
import google.auth.transport.requests as google

# Define the required scopes
scopes = [
  "https://www.googleapis.com/auth/userinfo.email",
  "https://www.googleapis.com/auth/firebase.database"
]

# Authenticate a credential with the service account
credentials = service_account.Credentials.from_service_account_file(
    "path/to/serviceAccountKey.json", scopes=scopes)
auth_request = google.Request()
credentials.refresh(auth_request)
access_token = credentials.token

Шаг второй. подготовить запрос для получения необходимых данных.

import requests

url = "https://your-codelab-url.firebaseio.com/washer.json?access_token={}".format(access_token)

washer = requests.get(url)
print(washer.text)

Использование REST API для получения данных описано здесь.

Шаг третий: оформить подписку на события.

Если к готовому запросу добавить заголовок Assept: text/event-stream, то вместо JSON от сервера придет поток в формате EventSource / Server-Sent Events protocol.

Работа с потоком обновлений описана в том же документе

Для работы с Server-Set Events на Python есть библиотека Python SSE Client

from sseclient import SSEClient
import datetime

messages = SSEClient(url)
for msg in messages:
    print(datetime.datetime.now())
    print(msg.event)
    print(msg.data)

Пример того, что приходит:

2019-05-15 05:29:41.799600
put
{"path":"/","data":{"OnOff":{"on":true},"RunCycle":{"dummy":true},"StartStop":{"isPaused":false,"isRunning":false}}}
2019-05-15 05:29:48.867432
put
{"path":"/OnOff/on","data":false}
2019-05-15 05:30:18.877440
keep-alive
null
2019-05-15 05:30:48.927935
keep-alive
null
2019-05-15 05:31:18.886840
keep-alive
null

Как дальше обрабатывать события - уже за рамками этой истории.