1. Прежде чем начать
Как разработчик Интернета вещей (IoT), вы можете создавать интеграции «облако-облако» , которые предоставят вашим пользователям возможность управлять своими устройствами с помощью сенсорного управления в приложении Google Home и голосовых команд с помощью Assistant.
Интеграции облако-облако полагаются на Home Graph для предоставления контекстных данных о доме и его устройствах, создавая логическую карту дома. Этот контекст дает помощнику более естественное понимание запросов пользователя относительно его местоположения в доме. Например, Home Graph может хранить концепцию гостиной, которая содержит несколько типов устройств от разных производителей, таких как термостат, лампа, вентилятор и пылесос.
Предпосылки
- Создайте интеграцию облако-облако. Руководство разработчика
Что вы построите
В этой лабораторной работе вы опубликуете облачный сервис, который управляет виртуальной интеллектуальной стиральной машиной, а затем создадите интеграцию «облако-облако» и подключите ее к Ассистенту.
Чему вы научитесь
- Как развернуть облачный сервис «умный дом»
- Как подключить свой сервис к Ассистенту
- Как опубликовать изменения состояния устройства в Google
Что вам понадобится
- Веб-браузер, например Google Chrome
- Устройство iOS или Android с установленным приложением Google Home
- Node.js версии 10.16 или более поздней
- Платежный аккаунт Google Cloud
2. Начало работы
Включить контроль активности
Чтобы использовать Google Assistant, вы должны поделиться определенными данными о действиях с Google. Google Assistant нужны эти данные для правильной работы; однако требование делиться данными не является специфичным для SDK. Чтобы поделиться этими данными, создайте учетную запись Google , если у вас ее еще нет. Вы можете использовать любую учетную запись Google — это не обязательно должна быть ваша учетная запись разработчика.
Откройте страницу «Отслеживание действий» для учетной записи Google, которую вы хотите использовать с Ассистентом.
Убедитесь, что следующие тумблеры включены:
- Активность в Интернете и приложениях . Кроме того, обязательно установите флажок Включить историю Chrome и действия с сайтов, из приложений и с устройств, использующих сервисы Google .
- Информация об устройстве
- Голосовая и аудио активность
Создайте проект интеграции облака в облако
- Перейдите в консоль разработчика .
- Нажмите «Создать проект» , введите имя проекта и нажмите «Создать проект» .
Выберите интеграцию «облако-облако»
На главной странице проекта в консоли разработчика выберите Добавить интеграцию «облако-облако» в разделе «Облако-облако» .
Установите Firebase CLI
Интерфейс командной строки Firebase (CLI) позволит вам обслуживать ваши веб-приложения локально и развертывать их на хостинге Firebase.
Чтобы установить CLI, выполните следующую команду npm из терминала:
npm install -g firebase-tools
Чтобы проверить правильность установки CLI, выполните:
firebase --version
Авторизуйте Firebase CLI с помощью своей учетной записи Google, выполнив следующую команду:
firebase login
3. Запустите стартовое приложение.
Теперь, когда вы настроили среду разработки, вы можете развернуть стартовый проект, чтобы убедиться, что все настроено правильно.
Получить исходный код
Щелкните следующую ссылку, чтобы загрузить пример для этой лабораторной работы на свой компьютер для разработки:
Вы также можете клонировать репозиторий GitHub из командной строки:
git clone https://github.com/google-home/smarthome-washer.git
О проекте
Стартовый проект содержит следующие подкаталоги:
-
public:
внешний пользовательский интерфейс для простого управления и мониторинга состояния интеллектуальной стиральной машины. -
functions:
Полностью реализованный облачный сервис, который управляет интеллектуальной стиральной машиной с помощью облачных функций для Firebase и базы данных Firebase Realtime.
Добавьте Firebase в свой проект консоли разработчика Google Home
Способ 1: Через консоль Firebase
- Перейдите на Firebase .
- Нажмите Создать проект Firebase .
- На экране «Создание проекта» нажмите «Добавить Firebase в проект Google Cloud» .
- На экране «Начало работы» выберите проект Google Cloud, который вы только что создали в консоли разработчика Google Home, а затем нажмите « Продолжить» .
Метод 2: через Firebase CLI
firebase projects:addfirebase
Выберите проект консоли разработчика Google Home, который вы только что создали, чтобы добавить Firebase.
Когда Firebase будет добавлен в ваш проект Google Home Developer Console, он появится в Firebase Console. Идентификатор проекта Firebase будет соответствовать идентификатору вашего проекта Google Home Developer Console.
Подключиться к Firebase
Перейдите в каталог washer-start
, затем настройте Firebase CLI с вашим проектом интеграции:
cd washer-start firebase use <project-id>
Настроить проект Firebase
Инициализируйте проект Firebase.
firebase init
Выберите функции CLI, Realtime Database и функцию Functions .
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed) >( ) Data Connect: Set up a Firebase Data Connect service ( ) Firestore: Configure security rules and indexes files for Firestore ( ) Genkit: Setup a new Genkit project with Firebase (*) Functions: Configure a Cloud Functions directory and its files ( ) App Hosting: Configure an apphosting.yaml file for App Hosting ( ) Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys ( ) Storage: Configure a security rules file for Cloud Storage ( ) Emulators: Set up local emulators for Firebase products ( ) Remote Config: Configure a template file for Remote Config ( ) Extensions: Set up an empty Extensions manifest (*) Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance ( ) Data Connect: Set up a Firebase Data Connect service ( ) Firestore: Configure security rules and indexes files for Firestore
Это позволит инициализировать необходимые API и функции для вашего проекта.
При появлении запроса инициализируйте Realtime Database. Вы можете использовать местоположение по умолчанию для экземпляра базы данных.
? It seems like you haven't initialized Realtime Database in your project yet. Do you want to set it up? Yes ? Please choose the location for your default Realtime Database instance: us-central1
Поскольку вы используете начальный код проекта, выберите файл по умолчанию для правил безопасности и убедитесь, что вы не перезаписываете существующий файл правил базы данных.
? File database.rules.json already exists. Do you want to overwrite it with the Realtime Database Security Rules for <project-ID>-default-rtdb from the Firebase Console? No
Если вы повторно инициализируете свой проект, выберите «Перезаписать» при появлении вопроса, хотите ли вы инициализировать или перезаписать кодовую базу.
? Would you like to initialize a new codebase, or overwrite an existing one? Overwrite
При настройке функций следует использовать файлы по умолчанию и не перезаписывать существующие файлы index.js и package.json в примере проекта.
? What language would you like to use to write Cloud Functions? JavaScript ? Do you want to use ESLint to catch probable bugs and enforce style? No ? File functions/package.json already exists. Overwrite? No ? File functions/index.js already exists. Overwrite? No
Если вы повторно инициализируете свой проект, выберите «Нет» на вопрос, хотите ли вы инициализировать или перезаписать functions/.gitignore.
? File functions/.gitignore already exists. Overwrite? No
? Do you want to install dependencies with npm now? Yes
Если ESLint был случайно включен, есть два способа его отключить:
- Используя GUI, перейдите в папку
../functions
в проекте, выберите скрытый файл.eslintrc.js
и удалите его. Не путайте его с файлом с похожим названием.eslintrc.json
. - Использование командной строки:
cd functions rm .eslintrc.js
В файле washer-start/firebase.json
дополните код следующим образом:
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
},
"headers": [{
"source" : "**/*.@(js|html)",
"headers" : [ {
"key" : "Cache-Control",
"value" : "max-age=0"
} ]
}],
"functions": [
{
"source": "functions",
"codebase": "default",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log",
"*.local"
]
}
]
}
Развертывание в Firebase
Теперь, когда вы установили зависимости и настроили свой проект, вы готовы запустить приложение в первый раз.
firebase deploy
Вот вывод консоли, который вы должны увидеть:
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<project-id>/overview Hosting URL: https://<project-id>.web.app
Эта команда развертывает веб-приложение вместе с несколькими облачными функциями для Firebase .
Откройте URL-адрес хостинга в вашем браузере ( https://<project-id>.web.app
), чтобы просмотреть веб-приложение. Вы увидите следующий интерфейс:
Этот веб-интерфейс представляет собой стороннюю платформу для просмотра или изменения состояний устройств. Чтобы начать заполнение базы данных информацией об устройствах, нажмите ОБНОВИТЬ . Вы не увидите никаких изменений на странице, но текущее состояние вашей стиральной машины будет сохранено в базе данных.
Теперь пришло время подключить развернутый вами облачный сервис к Google Assistant с помощью консоли разработчика Google Home .
Настройте свой проект Developer Console
На вкладке «Разработка» добавьте Отображаемое имя для вашего взаимодействия. Это имя будет отображаться в приложении Google Home.
В разделе «Брендирование приложения» загрузите файл png
для значка приложения размером 144 x 144 пикселей и назовите его
.
Чтобы включить привязку учетных записей , используйте следующие настройки привязки учетных записей:
Идентификатор клиента | |
Секрет клиента | |
URL-адрес авторизации | |
URL-адрес токена | |
В поле URL-адрес выполнения облачного сервиса введите URL-адрес вашей облачной функции, которая обеспечивает выполнение намерений умного дома.
https://us-central1-<project-id>.cloudfunctions.net/smarthome
Нажмите «Сохранить» , чтобы сохранить конфигурацию проекта, затем нажмите «Далее: Тест» , чтобы включить тестирование вашего проекта.
Теперь вы можете приступить к реализации веб-хуков, необходимых для связи состояния устройства с Ассистентом.
4. Создать шайбу
Теперь, когда вы настроили интеграцию, вы можете добавлять устройства и отправлять данные. Ваш облачный сервис должен обрабатывать следующие намерения:
- Намерение
SYNC
возникает, когда помощник хочет узнать, какие устройства подключил пользователь. Это отправляется в вашу службу, когда пользователь привязывает учетную запись. Вы должны ответить полезной нагрузкой JSON всех устройств пользователя и их возможностей. - Намерение
QUERY
возникает, когда помощник хочет узнать текущее состояние или статус устройства. Вы должны ответить полезной нагрузкой JSON с состоянием каждого запрошенного устройства. - Намерение
EXECUTE
возникает, когда помощник хочет управлять устройством от имени пользователя. Вы должны ответить полезной нагрузкой JSON со статусом выполнения каждого запрошенного устройства. - Намерение
DISCONNECT
возникает, когда пользователь отвязывает свою учетную запись от Assistant. Вам следует прекратить отправлять события для устройств этого пользователя в Assistant.
В следующих разделах вы обновите функции, которые вы ранее развернули для обработки этих намерений.
Обновить ответ SYNC
Откройте functions/index.js
, содержащий код для ответа на запросы Помощника.
Вам нужно будет обработать намерение SYNC
, вернув метаданные и возможности устройства. Обновите JSON в массиве onSync
, включив информацию об устройстве и рекомендуемые характеристики для стиральной машины.
индекс.js
app.onSync((body) => {
return {
requestId: body.requestId,
payload: {
agentUserId: USER_ID,
devices: [{
id: 'washer',
type: 'action.devices.types.WASHER',
traits: [
'action.devices.traits.OnOff',
'action.devices.traits.StartStop',
'action.devices.traits.RunCycle',
],
name: {
defaultNames: ['My Washer'],
name: 'Washer',
nicknames: ['Washer'],
},
deviceInfo: {
manufacturer: 'Acme Co',
model: 'acme-washer',
hwVersion: '1.0',
swVersion: '1.0.1',
},
willReportState: true,
attributes: {
pausable: true,
},
}],
},
};
});
Развертывание в Firebase
Разверните обновленную версию облачного решения с помощью Firebase CLI:
firebase deploy --only functions
Ссылка на Google Ассистента
Чтобы протестировать интеграцию Cloud-to-cloud, вам необходимо связать свой проект с аккаунтом Google. Это позволяет проводить тестирование через поверхности Google Assistant и приложение Google Home, которые вошли в тот же аккаунт.
- Откройте настройки Google Assistant на вашем телефоне. Обратите внимание, что вы должны войти в систему под той же учетной записью, что и в консоли.
- Перейдите в Google Assistant > Настройки > Управление домом (в разделе «Помощник»).
- Нажмите на значок поиска в правом верхнем углу.
- Чтобы найти конкретное тестовое приложение, используйте префикс [test] .
- Выберите этот элемент. Затем Google Assistant выполнит аутентификацию в вашем сервисе и отправит запрос
SYNC
, попросив ваш сервис предоставить список устройств для пользователя.
Откройте приложение Google Home и убедитесь, что вы видите свою стиральную машину.
5. Обработка команд и запросов
Теперь, когда ваш облачный сервис правильно передает данные о стиральной машине в Google, вам нужно добавить возможность запрашивать состояние устройства и отправлять команды.
Обработка намерения QUERY
Намерение QUERY
включает набор устройств. Для каждого устройства вы должны ответить его текущим состоянием.
В functions/index.js
отредактируйте обработчик QUERY
для обработки списка целевых устройств, содержащихся в запросе намерения.
индекс.js
app.onQuery(async (body) => {
const {requestId} = body;
const payload = {
devices: {},
};
const queryPromises = [];
const intent = body.inputs[0];
for (const device of intent.payload.devices) {
const deviceId = device.id;
queryPromises.push(queryDevice(deviceId)
.then((data) => {
// Add response to device payload
payload.devices[deviceId] = data;
}
));
}
// Wait for all promises to resolve
await Promise.all(queryPromises);
return {
requestId: requestId,
payload: payload,
};
});
Для каждого устройства, содержащегося в запросе, вернуть текущее состояние, сохраненное в базе данных Realtime. Обновите функции queryFirebase
и queryDevice
, чтобы вернуть данные о состоянии стиральной машины.
индекс.js
const queryFirebase = async (deviceId) => {
const snapshot = await firebaseRef.child(deviceId).once('value');
const snapshotVal = snapshot.val();
return {
on: snapshotVal.OnOff.on,
isPaused: snapshotVal.StartStop.isPaused,
isRunning: snapshotVal.StartStop.isRunning,
};
};
const queryDevice = async (deviceId) => {
const data = await queryFirebase(deviceId);
return {
on: data.on,
isPaused: data.isPaused,
isRunning: data.isRunning,
currentRunCycle: [{
currentCycle: 'rinse',
nextCycle: 'spin',
lang: 'en',
}],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
};
};
Обработка намерения EXECUTE
Намерение EXECUTE
обрабатывает команды для обновления состояния устройства. Ответ возвращает статус каждой команды, например, SUCCESS
, ERROR
или PENDING
, и новое состояние устройства.
В functions/index.js
отредактируйте обработчик EXECUTE
для обработки списка признаков, требующих обновления, и набора целевых устройств для каждой команды:
индекс.js
app.onExecute(async (body) => {
const {requestId} = body;
// Execution results are grouped by status
const result = {
ids: [],
status: 'SUCCESS',
states: {
online: true,
},
};
const executePromises = [];
const intent = body.inputs[0];
for (const command of intent.payload.commands) {
for (const device of command.devices) {
for (const execution of command.execution) {
executePromises.push(
updateDevice(execution, device.id)
.then((data) => {
result.ids.push(device.id);
Object.assign(result.states, data);
})
.catch(() => functions.logger.error('EXECUTE', device.id)));
}
}
}
await Promise.all(executePromises);
return {
requestId: requestId,
payload: {
commands: [result],
},
};
});
Для каждой команды и целевого устройства обновите значения в Realtime Database, которые соответствуют запрошенному признаку. Измените функцию updateDevice
, чтобы обновить соответствующую ссылку Firebase и вернуть обновленное состояние устройства.
индекс.js
const updateDevice = async (execution, deviceId) => {
const {params, command} = execution;
let state; let ref;
switch (command) {
case 'action.devices.commands.OnOff':
state = {on: params.on};
ref = firebaseRef.child(deviceId).child('OnOff');
break;
case 'action.devices.commands.StartStop':
state = params.start
? {isRunning: true, isPaused: false}
: {isRunning: false, isPaused: false};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
case 'action.devices.commands.PauseUnpause':
const data = await queryDevice(deviceId);
state = (data.isPaused === false && data.isRunning === false)
? {isRunning: false, isPaused: false}
: {isRunning: !params.pause, isPaused: params.pause};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
}
return ref.update(state)
.then(() => state);
};
6. Проверьте свою интеграцию
После реализации всех трех намерений вы можете проверить, управляет ли ваша интеграция стиральной машиной.
Развертывание в Firebase
Разверните обновленную версию облачного решения с помощью Firebase CLI:
firebase deploy --only functions
Проверьте стиральную машину
Теперь вы можете увидеть изменение значения, если попробуете ввести любую из следующих голосовых команд на своем телефоне:
«Окей, Google, включи мою стиральную машину».
«Окей, Google, поставь мою стиральную машину на паузу».
«Окей, Google, останови мою стиральную машину».
Вы также можете узнать текущее состояние вашей стиральной машины, задав вопросы.
«Окей, Google, моя стиральная машина включена?»
«Окей, Google, работает ли моя стиральная машина?»
«Окей, Google, какой цикл сейчас у моей стиральной машины?»
Вы можете просмотреть эти запросы и команды в журналах, которые отображаются под вашей функцией в разделе Функции консоли Firebase . Узнайте больше о журналах Firebase в разделе Запись и просмотр журналов .
Вы также можете найти эти запросы и команды в Google Cloud Console , перейдя в Logging > Logs Explorer . Узнайте больше о ведении журналов Google Cloud в разделе Журналы событий Access с Cloud Logging .
7. Сообщайте об обновлениях в Google
Вы полностью интегрировали свой облачный сервис с намерениями умного дома, позволяя пользователям контролировать и запрашивать текущее состояние своих устройств. Однако в реализации все еще отсутствует способ для вашего сервиса проактивно отправлять информацию о событиях, например, об изменениях в присутствии или состоянии устройства, в Assistant.
С помощью Request Sync вы можете инициировать новый запрос синхронизации, когда пользователи добавляют или удаляют устройства или когда изменяются возможности их устройств. С помощью Report State ваш облачный сервис может заранее отправлять состояние устройства в Home Graph, когда пользователи физически изменяют состояние устройства, например, включают выключатель света, или изменяют состояние с помощью другого сервиса.
В этом разделе вы добавите код для вызова этих методов из интерфейсного веб-приложения.
Включить API HomeGraph
API HomeGraph позволяет хранить и запрашивать устройства и их состояния в Home Graph пользователя. Чтобы использовать этот API, сначала нужно открыть консоль Google Cloud и включить API HomeGraph .
В консоли Google Cloud обязательно выберите проект, соответствующий вашей интеграции <project-id>.
Затем на экране API Library для API HomeGraph нажмите Enable .
Включить отчет о состоянии
Записи в базу данных реального времени запускают функцию reportstate
в проекте tarter. Обновите функцию reportstate
в functions/index.js
чтобы захватить данные, записанные в базу данных, и опубликовать их в Home Graph с помощью Report State.
индекс.js
exports.reportstate = functions.database.ref('{deviceId}').onWrite(
async (change, context) => {
functions.logger.info('Firebase write event triggered Report State');
const snapshot = change.after.val();
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of our washer */
[context.params.deviceId]: {
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
},
},
},
},
};
const res = await homegraph.devices.reportStateAndNotification({
requestBody,
});
functions.logger.info('Report state response:', res.status, res.data);
});
Включить запрос синхронизации
Обновление значка в интерфейсе веб-интерфейса запускает функцию requestsync
в стартовом проекте. Реализуйте функцию requestsync
в functions/index.js
для вызова API HomeGraph.
индекс.js
exports.requestsync = functions.https.onRequest(async (request, response) => {
response.set('Access-Control-Allow-Origin', '*');
functions.logger.info(`Request SYNC for user ${USER_ID}`);
try {
const res = await homegraph.devices.requestSync({
requestBody: {
agentUserId: USER_ID,
},
});
functions.logger.info('Request sync response:', res.status, res.data);
response.json(res.data);
} catch (err) {
functions.logger.error(err);
response.status(500).send(`Error requesting sync: ${err}`);
}
});
Развертывание в Firebase
Разверните обновленный код с помощью Firebase CLI:
firebase deploy --only functions
Проверьте свою реализацию
Нажмите « Обновить». в веб-интерфейсе и убедитесь, что вы видите запрос синхронизации в журнале консоли Firebase.
Затем настройте атрибуты устройства мойки в веб-интерфейсе и нажмите Обновить . Убедитесь, что вы видите изменение состояния, сообщенное Google, в журналах консоли Firebase.
8. Поздравления
Поздравляем! Вы успешно интегрировали Assistant с облачным сервисом устройства с помощью интеграции Cloud-to-Cloud.
Узнать больше
Вот несколько идей, которые вы можете реализовать, чтобы пойти глубже:
- Добавьте режимы и переключатели на свое устройство.
- Добавьте больше поддерживаемых характеристик к вашему устройству.
- Изучите локальную реализацию проекта «умный дом».
- Чтобы узнать больше, ознакомьтесь с нашим примером на GitHub .
Вы также можете узнать больше о тестировании и отправке интеграции на рассмотрение, включая процесс сертификации для публикации вашей интеграции для пользователей.