1. Прежде чем начать
Интеграции облако-облако используют типы устройств , чтобы Google Assistant знал, какую грамматику следует использовать с устройством. Черты устройства определяют возможности типа устройства. Устройство наследует состояния каждой черты устройства, добавленной к интеграции.
Вы можете подключить любые поддерживаемые черты к выбранному типу устройства, чтобы настроить функциональность устройств ваших пользователей. Если вы хотите реализовать пользовательские черты в своих действиях, которые в настоящее время недоступны в схеме устройства, то черты Modes и Toggles позволяют управлять определенными настройками с помощью пользовательского имени, которое вы определяете.
Помимо основных возможностей управления, предоставляемых типами и признаками, API Smart Home имеет дополнительные функции для улучшения пользовательского опыта. Ответы об ошибках предоставляют подробную обратную связь для пользователя, когда намерения не удаются. Вторичная проверка пользователя расширяет эти ответы и добавляет дополнительную безопасность признаку устройства по вашему выбору. Отправляя определенные ответы об ошибках в блоки вызовов, выпущенные Assistant, ваша интеграция Cloud-to-cloud может потребовать дополнительной авторизации для выполнения команды.
Предпосылки
- Создайте интеграцию облако-облако. Руководство разработчика
- Умная домашняя стиральная машина codelab
- Типы и характеристики устройств Руководство разработчика
Что вы построите
В этой кодовой лаборатории вы развернете готовую интеграцию умного дома с Firebase, а затем узнаете, как добавить нестандартные черты в умную домашнюю стиральную машину для размера загрузки и турборежима. Вы также реализуете отчеты об ошибках и исключениях и научитесь применять устное подтверждение для включения стиральной машины с использованием вторичной проверки пользователя.
Чему вы научитесь
- Как добавить черты «Режимы» и «Переключатели» в вашу интеграцию
- Как сообщать об ошибках и исключениях
- Как применить вторичную проверку пользователя
Что вам понадобится
- Веб-браузер, например Google Chrome
- Устройство iOS или Android с установленным приложением Google Home
- Node.js версии 10.16 или более поздней
- Аккаунт Google
- Платежный аккаунт 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
Добавьте 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.
Включить API HomeGraph
API HomeGraph позволяет хранить и запрашивать устройства и их состояния в Home Graph пользователя. Чтобы использовать этот API, сначала нужно открыть консоль Google Cloud и включить API HomeGraph .
В консоли Google Cloud обязательно выберите проект, соответствующий вашим Actions <firebase-project-id>.
Затем на экране API Library для API HomeGraph нажмите Enable .
3. Запустите стартовое приложение.
Теперь, когда вы настроили среду разработки, вы можете развернуть стартовый проект, чтобы убедиться, что все настроено правильно.
Получить исходный код
Щелкните следующую ссылку, чтобы загрузить пример для этой лабораторной работы на свой компьютер для разработки:
...или вы можете клонировать репозиторий GitHub из командной строки:
git clone https://github.com/google-home/smarthome-traits.git
Распакуйте загруженный zip-файл.
О проекте
Стартовый проект содержит следующие подкаталоги:
-
public:
внешний пользовательский интерфейс для простого управления и мониторинга состояния интеллектуальной стиральной машины. -
functions:
Полностью реализованный облачный сервис, который управляет интеллектуальной стиральной машиной с помощью облачных функций для Firebase и базы данных Firebase Realtime.
Предоставленное облачное исполнение включает в себя следующие функции в index.js
:
-
fakeauth
: конечная точка авторизации для привязки аккаунта -
faketoken
: конечная точка токена для привязки аккаунта -
smarthome
: Конечная точка выполнения намерений умного дома -
reportstate
: вызывает API Home Graph при изменении состояния устройства. -
requestsync
: позволяет обновлять данные на устройствах пользователей без необходимости повторной привязки учетной записи.
Подключиться к 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
Развертывание в 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://<firebase-project-id>.web.app
), чтобы просмотреть веб-приложение. Вы увидите следующий интерфейс:
Этот веб-интерфейс представляет собой стороннюю платформу для просмотра или изменения состояний устройств. Чтобы начать заполнение базы данных информацией об устройствах, нажмите ОБНОВИТЬ . Вы не увидите никаких изменений на странице, но текущее состояние вашей стиральной машины будет сохранено в базе данных.
Теперь пришло время подключить развернутый вами облачный сервис к Google Assistant с помощью консоли разработчика .
Настройте свой проект Developer Console
На вкладке «Разработка» добавьте Отображаемое имя для вашего взаимодействия. Это имя будет отображаться в приложении Google Home.
В разделе «Брендирование приложения» загрузите файл png
для значка приложения размером 144 x 144 пикселей и назовите его
.
Чтобы включить привязку учетных записей , используйте следующие настройки привязки учетных записей:
Идентификатор клиента | |
Секрет клиента | |
URL-адрес авторизации | |
URL-адрес токена | |
В поле URL-адрес выполнения облачного сервиса введите URL-адрес вашей облачной функции, которая обеспечивает выполнение намерений умного дома.
https://us-central1-<project-id>.cloudfunctions.net/smarthome
Нажмите «Сохранить» , чтобы сохранить конфигурацию проекта, затем нажмите «Далее: Тест» , чтобы включить тестирование вашего проекта.
Теперь вы можете приступить к реализации веб-хуков, необходимых для связи состояния устройства с Ассистентом.
Ссылка на Google Ассистента
Чтобы протестировать интеграцию Cloud-to-cloud, вам необходимо связать свой проект с аккаунтом Google. Это позволяет проводить тестирование через поверхности Google Assistant и приложение Google Home, которые вошли в тот же аккаунт.
- Откройте настройки Google Assistant на вашем телефоне. Обратите внимание, что вы должны войти в систему под той же учетной записью, что и в консоли.
- Перейдите в Google Assistant > Настройки > Управление домом (в разделе «Помощник»).
- Нажмите на значок поиска в правом верхнем углу.
- Чтобы найти конкретное тестовое приложение, используйте префикс [test] .
- Выберите этот элемент. Затем Google Assistant выполнит аутентификацию в вашем сервисе и отправит запрос
SYNC
, попросив ваш сервис предоставить список устройств для пользователя.
Откройте приложение Google Home и убедитесь, что вы видите свою стиральную машину.
Убедитесь, что вы можете управлять стиральной машиной с помощью голосовых команд в приложении Google Home. Вы также должны увидеть изменение состояния устройства в веб-интерфейсе вашего облачного сервиса.
Теперь, когда у вас есть базовая стиральная машина, вы можете настроить режимы, доступные на вашем устройстве.
4. Добавить режимы
Черта action.devices.traits.Modes
позволяет устройству иметь произвольное количество настроек для режима, из которых только один может быть установлен за раз. Вы добавите режим в стиральную машину, чтобы определить размер загрузки белья: маленький, средний или большой.
Обновить ответ SYNC
Вам необходимо добавить информацию о новом признаке в ваш ответ SYNC
в functions/index.js
. Эти данные появляются в массиве traits
и объекте attributes
, как показано в следующем фрагменте кода.
индекс.js
app.onSync(body => {
return {
requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
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',
// Add Modes trait
'action.devices.traits.Modes',
],
name: { ... },
deviceInfo: { ... },
attributes: {
pausable: true,
//Add availableModes
availableModes: [{
name: 'load',
name_values: [{
name_synonym: ['load'],
lang: 'en',
}],
settings: [{
setting_name: 'small',
setting_values: [{
setting_synonym: ['small'],
lang: 'en',
}]
}, {
setting_name: 'medium',
setting_values: [{
setting_synonym: ['medium'],
lang: 'en',
}]
}, {
setting_name: 'large',
setting_values: [{
setting_synonym: ['large'],
lang: 'en',
}]
}],
ordered: true,
}],
},
}],
},
};
});
Добавить новые команды намерения EXECUTE
В намерении EXECUTE
добавьте команду action.devices.commands.SetModes
, как показано в следующем фрагменте кода.
индекс.js
const updateDevice = async (execution,deviceId) => {
const {params,command} = execution;
let state, 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 = {isRunning: params.start};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
case 'action.devices.commands.PauseUnpause':
state = {isPaused: params.pause};
ref = firebaseRef.child(deviceId).child('StartStop');
Break;
// Add SetModes command
case 'action.devices.commands.SetModes':
state = {load: params.updateModeSettings.load};
ref = firebaseRef.child(deviceId).child('Modes');
break;
}
};
Обновить ответ на ЗАПРОС
Затем обновите ответ QUERY
, чтобы сообщить текущее состояние стиральной машины.
Добавьте обновленные изменения в функции 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,
// Add Modes snapshot
load: snapshotVal.Modes.load,
};
};
const queryDevice = async (deviceId) => {
const data = await queryFirebase(deviceId);
return {
on: data.on,
isPaused: data.isPaused,
isRunning: data.isRunning,
currentRunCycle: [{ ... }],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
// Add currentModeSettings
currentModeSettings: {
load: data.load,
},
};
};
Обновление отчета о состоянии
Наконец, обновите функцию reportstate
, чтобы она передавала текущие настройки загрузки стиральной машины в Home Graph.
индекс.js
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of your washer */
[context.params.deviceId]: {
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
// Add currentModeSettings
currentModeSettings: {
load: snapshot.Modes.load,
},
},
},
},
},
};
Развертывание в Firebase
Выполните следующую команду для развертывания обновленной интеграции:
firebase deploy --only functions
После завершения развертывания перейдите в веб-интерфейс и нажмите кнопку «Обновить». кнопка на панели инструментов. Это запускает запрос синхронизации, чтобы помощник получил обновленные данные ответа
SYNC
.
Теперь вы можете дать команду на установку режима работы стиральной машины, например:
«Окей, Google, установи большую загрузку стиральной машины».
Кроме того, вы можете задать вопросы о вашей стиральной машине, например:
«Окей, Google, сколько белья загружено в стиральную машину?»
5. Добавьте переключатели
Черта action.devices.traits.Toggles
представляет именованные аспекты устройства, которые имеют истинное или ложное состояние, например, находится ли стиральная машина в турборежиме.
Обновить ответ SYNC
В вашем ответе SYNC
вам необходимо добавить информацию о новом признаке устройства. Он появится в массиве traits
и объекте attributes
, как показано в следующем фрагменте кода.
индекс.js
app.onSync(body => {
return {
requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
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',
'action.devices.traits.Modes',
// Add Toggles trait
'action.devices.traits.Toggles',
],
name: { ... },
deviceInfo: { ... },
attributes: {
pausable: true,
availableModes: [{
name: 'load',
name_values: [{
name_synonym: ['load'],
lang: 'en'
}],
settings: [{ ... }],
ordered: true,
}],
//Add availableToggles
availableToggles: [{
name: 'Turbo',
name_values: [{
name_synonym: ['turbo'],
lang: 'en',
}],
}],
},
}],
},
};
});
Добавить новые команды намерения EXECUTE
В намерении EXECUTE
добавьте команду action.devices.commands.SetToggles
, как показано в следующем фрагменте кода.
индекс.js
const updateDevice = async (execution,deviceId) => {
const {params,command} = execution;
let state, 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 = {isRunning: params.start};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
case 'action.devices.commands.PauseUnpause':
state = {isPaused: params.pause};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
case 'action.devices.commands.SetModes':
state = {load: params.updateModeSettings.load};
ref = firebaseRef.child(deviceId).child('Modes');
break;
// Add SetToggles command
case 'action.devices.commands.SetToggles':
state = {Turbo: params.updateToggleSettings.Turbo};
ref = firebaseRef.child(deviceId).child('Toggles');
break;
}
Обновить ответ на ЗАПРОС
Наконец, вам нужно обновить ваш ответ QUERY
, чтобы сообщить о турборежиме стиральной машины. Добавьте обновленные изменения в функции queryFirebase
и queryDevice
, чтобы получить состояние переключения, сохраненное в базе данных Realtime.
индекс.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,
load: snapshotVal.Modes.load,
// Add Toggles snapshot
Turbo: snapshotVal.Toggles.Turbo,
};
}
const queryDevice = async (deviceId) => {
const data = queryFirebase(deviceId);
return {
on: data.on,
isPaused: data.isPaused,
isRunning: data.isRunning,
currentRunCycle: [{ ... }],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
currentModeSettings: {
load: data.load,
},
// Add currentToggleSettings
currentToggleSettings: {
Turbo: data.Turbo,
},
};
};
Обновление отчета о состоянии
Наконец, обновите функцию reportstate
, чтобы она сообщала Home Graph, установлена ли стиральная машина в режим турбо.
индекс.js
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of your washer */
[context.params.deviceId]: {
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
currentModeSettings: {
load: snapshot.Modes.load,
},
// Add currentToggleSettings
currentToggleSettings: {
Turbo: snapshot.Toggles.Turbo,
},
},
},
},
},
};
Развертывание в Firebase
Выполните следующую команду для развертывания обновленных функций:
firebase deploy --only functions
Нажмите « Обновить». кнопку в веб-интерфейсе пользователя, чтобы запустить запрос синхронизации после завершения развертывания.
Теперь вы можете дать команду перевести стиральную машину в турборежим, сказав:
«Окей, Google, включи турборежим стиральной машины».
Вы также можете проверить, находится ли ваша стиральная машина в турборежиме, спросив:
«Окей, Google, моя стиральная машина находится в турборежиме?»
6. Сообщение об ошибках и исключениях
Обработка ошибок в вашей интеграции Cloud-to-cloud позволяет вам сообщать пользователям, когда проблемы приводят к сбою ответов EXECUTE
и QUERY
. Уведомления создают более позитивный пользовательский опыт для ваших пользователей, когда они взаимодействуют с вашим смарт-устройством и интеграцией.
Всякий раз, когда запрос EXECUTE
или QUERY
терпит неудачу, ваша интеграция должна возвращать код ошибки. Если, например, вы хотите выдать ошибку, когда пользователь пытается запустить стиральную машину с открытой крышкой, то ваш ответ EXECUTE
будет выглядеть как следующий фрагмент кода:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"commands": [
{
"ids": [
"456"
],
"status": "ERROR",
"errorCode": "deviceLidOpen"
}
]
}
}
Теперь, когда пользователь просит запустить стиральную машину, Помощник отвечает следующим образом:
«Крышка стиральной машины открыта. Пожалуйста, закройте ее и попробуйте еще раз».
Исключения похожи на ошибки, но указывают, когда оповещение связано с командой, которая может или не может блокировать успешное выполнение. Исключение может предоставить связанную информацию с помощью признака StatusReport
, например уровень заряда батареи или недавнее изменение состояния. Коды неблокирующих исключений возвращаются вместе со статусом SUCCESS
, тогда как коды блокирующих исключений возвращаются со статусом EXCEPTIONS
.
Пример ответа с исключением приведен в следующем фрагменте кода:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"commands": [{
"ids": ["123"],
"status": "SUCCESS",
"states": {
"online": true,
"isPaused": false,
"isRunning": false,
"exceptionCode": "runCycleFinished"
}
}]
}
}
Помощник отвечает:
«Стиральная машина закончила работу».
Чтобы добавить отчеты об ошибках для вашей стиральной машины, откройте functions/index.js
и добавьте определение класса ошибок, как показано в следующем фрагменте кода:
индекс.js
app.onQuery(async (body) => {...});
// Add SmartHome error handling
class SmartHomeError extends Error {
constructor(errorCode, message) {
super(message);
this.name = this.constructor.name;
this.errorCode = errorCode;
}
}
Обновите ответ на выполнение, чтобы вернуть код ошибки и статус ошибки:
индекс.js
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) => {
...
})
//Add error response handling
.catch((error) => {
functions.logger.error('EXECUTE', device.id, error);
result.ids.push(device.id);
if (error instanceof SmartHomeError) {
result.status = 'ERROR';
result.errorCode = error.errorCode;
}
})
);
}
}
}
Теперь помощник может сообщать вашим пользователям о любом коде ошибки , о котором вы сообщаете. Вы увидите конкретный пример в следующем разделе.
7. Добавить вторичную проверку пользователя
Вам следует реализовать вторичную проверку пользователя в вашей интеграции, если на вашем устройстве есть какие-либо режимы, которые необходимо защитить или ограничить определенной группой авторизованных пользователей, например, обновление программного обеспечения или снятие блокировки.
Вы можете реализовать вторичную проверку пользователя для всех типов устройств и характеристик, настроив, будет ли проверка безопасности происходить каждый раз или необходимо будет соблюдать определенные критерии.
Поддерживаются три типа испытаний :
-
No
challenge
— запрос и ответ, не использующие проверку подлинности (это поведение по умолчанию). -
ackNeeded
— вторичная проверка пользователя, требующая явного подтверждения (да или нет) -
pinNeeded
— вторичная проверка пользователя, требующая персонального идентификационного номера (ПИН-кода)
Для этой лабораторной работы добавьте вызов ackNeeded
к команде включения стиральной машины и функциональность для возврата ошибки в случае сбоя вторичной проверки.
Откройте functions/index.js
и добавьте определение класса ошибки, которое возвращает код ошибки и тип вызова, как показано в следующем фрагменте кода:
индекс.js
class SmartHomeError extends Error { ... }
// Add secondary user verification error handling
class ChallengeNeededError extends SmartHomeError {
/**
* Create a new ChallengeNeededError
* @param {string} suvType secondary user verification challenge type
*/
constructor(suvType) {
super('challengeNeeded', suvType);
this.suvType = suvType;
}
}
Вам также необходимо обновить ответ на выполнение, чтобы вернуть ошибку challengeNeeded
следующим образом:
индекс.js
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) => {
...
})
.catch((error) => {
functions.logger.error('EXECUTE', device.id, error);
result.ids.push(device.id);
if (error instanceof SmartHomeError) {
result.status = 'ERROR';
result.errorCode = error.errorCode;
//Add error response handling
if (error instanceof ChallengeNeededError) {
result.challengeNeeded = {
type: error.suvType
};
}
}
})
);
}
}
}
Наконец, измените updateDevice
так, чтобы для включения или выключения стиральной машины требовалось явное подтверждение.
индекс.js
const updateDevice = async (execution,deviceId) => {
const {challenge,params,command} = execution; //Add secondary user challenge
let state, ref;
switch (command) {
case 'action.devices.commands.OnOff':
//Add secondary user verification challenge
if (!challenge || !challenge.ack) {
throw new ChallengeNeededError('ackNeeded');
}
state = {on: params.on};
ref = firebaseRef.child(deviceId).child('OnOff');
break;
...
}
return ref.update(state)
.then(() => state);
};
Развертывание в Firebase
Выполните следующую команду для развертывания обновленной функции:
firebase deploy --only functions
После развертывания обновленного кода вам необходимо устно подтвердить действие, когда вы просите Помощника включить или выключить стиральную машину, например:
Вы: «Окей, Google, включи стиральную машину».
Помощник: «Вы уверены, что хотите включить стиральную машину?»
Вы: «Да».
Вы также можете увидеть подробный ответ для каждого шага процесса вторичной проверки пользователя, открыв журналы Firebase .
8. Поздравления
Поздравляем! Вы расширили возможности интеграции облако-облако с помощью свойств Modes
и Toggles
и обеспечили их выполнение посредством вторичной проверки пользователем.
Узнать больше
Вот несколько идей, которые вы можете реализовать, чтобы пойти глубже:
- Добавьте возможности локального выполнения на свои устройства.
- Используйте другой тип вторичной проверки пользователя, чтобы изменить состояние вашего устройства.
- Обновите ответ QUERY признака
RunCycle
для динамического обновления. - Изучите этот пример GitHub .