1. Прежде чем начать
Действия «умного дома» используют типы устройств , чтобы сообщить Google Assistant, какую грамматику следует использовать с устройством. Характеристики устройства определяют возможности типа устройства. Устройство наследует состояния каждой характеристики устройства, добавленной в действие.
Вы можете подключить любые поддерживаемые функции к выбранному вами типу устройства, чтобы настроить функциональность устройств ваших пользователей. Если вы хотите реализовать в своих действиях пользовательские свойства, которые в настоящее время недоступны в схеме устройства, то свойства « Режимы » и «Переключатели » позволяют управлять конкретными настройками с помощью пользовательского имени, которое вы определяете.
Помимо базовых возможностей управления, предоставляемых типами и характеристиками, API Smart Home имеет дополнительные функции, улучшающие взаимодействие с пользователем. Реакции на ошибки предоставляют подробную обратную связь с пользователем, когда намерения не увенчались успехом. Вторичная проверка пользователя расширяет эти ответы и добавляет дополнительную безопасность выбранной вами характеристике устройства. Отправляя конкретные ответы об ошибках на блоки запросов, отправленные из Ассистента, вашему действию умного дома может потребоваться дополнительная авторизация для выполнения команды.
Предварительные условия
- Создайте умный дом. Руководство для разработчиков действий.
- Кодовая лаборатория умной домашней стиральной машины
- Руководство для разработчиков типов и характеристик устройств
Что ты построишь
В этой лабораторной работе вы развернете готовую интеграцию умного дома с 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 .
- Информация об устройстве
- Голосовая и аудио активность
Создать проект действий
- Перейдите в Действия в консоли разработчика Google .
- Нажмите «Новый проект» , введите имя проекта и нажмите «СОЗДАТЬ ПРОЕКТ» .
Выберите приложение «Умный дом».
На экране «Обзор» в консоли «Действия» выберите «Умный дом» .
Выберите карточку «Умный дом» , нажмите «Начать сборку» , и вы будете перенаправлены на консоль вашего проекта.
Установите интерфейс командной строки Firebase
Интерфейс командной строки Firebase (CLI) позволит вам обслуживать ваши веб-приложения локально и развертывать их на хостинге Firebase.
Чтобы установить CLI, выполните следующую команду npm из терминала:
npm install -g firebase-tools
Чтобы убедиться, что CLI установлен правильно, запустите:
firebase --version
Авторизуйте Firebase CLI с помощью своей учетной записи Google, выполнив:
firebase login
Включите API HomeGraph
API HomeGraph позволяет хранить и запрашивать устройства и их состояния в Home Graph пользователя. Чтобы использовать этот API, необходимо сначала открыть консоль Google Cloud и включить HomeGraph API .
В консоли Google Cloud обязательно выберите проект, соответствующий вашим действиям <project-id>.
Затем на экране библиотеки API для HomeGraph API нажмите «Включить» .
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 для вашего проекта Actions:
cd washer-start firebase use <project-id>
Настроить проект Firebase
Инициализируйте проект Firebase.
firebase init
Выберите функции CLI, базу данных реального времени , функции и функцию хостинга , включающую хостинг Firebase.
? Which Firebase CLI features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. ❯◉ Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance ◯ Firestore: Configure security rules and indexes files for Firestore ◉ Functions: Configure a Cloud Functions directory and its files ◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys ◯ Hosting: 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
Это инициализирует необходимые API и функции для вашего проекта.
При появлении запроса инициализируйте базу данных реального времени. Вы можете использовать расположение по умолчанию для экземпляра базы данных.
? 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
Если вы повторно инициализируете свой проект, выберите «Нет» , когда вас спросят, хотите ли вы инициализировать или перезаписать function/.gitignore.
? File functions/.gitignore already exists. Overwrite? No
? Do you want to install dependencies with npm now? Yes
Наконец, настройте хостинг для использования public
каталога в коде проекта и используйте существующий файл index.html . Выберите Нет , когда вас попросят использовать ESLint.
? What do you want to use as your public directory? public ? Configure as a single-page app (rewrite all urls to /index.html)? Yes ? Set up automatic builds and deploys with GitHub? No ? File public/index.html already exists. Overwrite? No
Если ESLint был случайно включен, его можно отключить двумя способами:
- Используя графический интерфейс, перейдите в папку
../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://<project-id>.web.app
), чтобы просмотреть веб-приложение. Вы увидите следующий интерфейс:
Этот веб-интерфейс представляет собой стороннюю платформу для просмотра или изменения состояний устройства. Чтобы начать заполнять базу данных информацией об устройстве, нажмите «ОБНОВИТЬ» . На странице вы не увидите никаких изменений, но текущее состояние вашей стиральной машины будет сохранено в базе данных.
Теперь пришло время подключить развернутый вами облачный сервис к Google Assistant с помощью консоли Actions .
Настройте проект консоли Actions
В разделе «Обзор» > «Создайте свое действие» выберите «Добавить действия» . Введите URL-адрес своей облачной функции, обеспечивающей реализацию намерений умного дома, и нажмите «Сохранить» .
https://us-central1-<project-id>.cloudfunctions.net/smarthome
На вкладке «Разработка» > «Вызов» добавьте отображаемое имя для своего действия и нажмите «Сохранить» . Это имя появится в приложении Google Home.
Чтобы включить привязку учетной записи, выберите параметр «Разработка» > «Привязка учетной записи» на левой панели навигации. Используйте следующие настройки привязки учетной записи:
ID клиента | |
Секрет клиента | |
URL-адрес авторизации | |
URL-адрес токена | |
Нажмите «Сохранить» , чтобы сохранить конфигурацию привязки вашей учетной записи, затем нажмите «Тестировать» , чтобы включить тестирование в вашем проекте.
Вы будете перенаправлены в Симулятор . Если вы не видите сообщение « Тест теперь включен », нажмите «Сбросить тест» , чтобы убедиться, что тестирование включено.
Ссылка на Google Ассистент
Чтобы протестировать действие вашего умного дома, вам необходимо связать свой проект с учетной записью Google. Это позволяет проводить тестирование через поверхности Google Assistant и приложение Google Home, которые вошли в одну и ту же учетную запись.
- На телефоне откройте настройки Google Assistant. Обратите внимание, что вы должны войти в систему под той же учетной записью, что и в консоли.
- Перейдите в «Google Ассистент» > «Настройки» > «Управление домом» (в разделе «Ассистент»).
- Нажмите значок поиска в правом верхнем углу.
- Найдите свое тестовое приложение, используя префикс [test] , чтобы найти конкретное тестовое приложение.
- Выберите этот элемент. Затем Google Assistant пройдет аутентификацию в вашей службе и отправит запрос
SYNC
, попросив вашу службу предоставить пользователю список устройств.
Откройте приложение Google Home и убедитесь, что вы видите стиральную машину.
Убедитесь, что вы можете управлять стиральной машиной с помощью голосовых команд в приложении Google Home. Вы также должны увидеть изменение состояния устройства в веб-интерфейсе вашего облачного сервиса.
Теперь, когда у вас есть базовая стиральная машина, вы можете настроить режимы, доступные на вашем устройстве.
4. Добавьте режимы
Признак action.devices.traits.Modes
позволяет устройству иметь произвольное количество настроек для режима, из которых одновременно можно установить только одну. Вы добавите в стиральную машину режим, определяющий размер загрузки белья: маленький, средний или большой.
Обновить ответ SYNC
Вам необходимо добавить информацию о новом признаке в ваш ответ SYNC
в functions/index.js
. Эти данные отображаются в массиве traits
и объекте attributes
, как показано в следующем фрагменте кода.
index.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
, как показано в следующем фрагменте кода.
index.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
Затем обновите ответ QUERY
, чтобы сообщить о текущем состоянии стиральной машины.
Добавьте обновленные изменения в функции queryFirebase
и queryDevice
, чтобы получить состояние, хранящееся в базе данных реального времени.
index.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.
index.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
, как показано в следующем фрагменте кода.
index.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
, как показано в следующем фрагменте кода.
index.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
Наконец, вам необходимо обновить ответ QUERY
, чтобы сообщить о турбо-режиме стиральной машины. Добавьте обновленные изменения в функции queryFirebase
и queryDevice
, чтобы получить состояние переключения, хранящееся в базе данных реального времени.
index.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, включена ли стиральная машина в режиме турбо.
index.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. Отчеты об ошибках и исключениях
Обработка ошибок в вашем умном доме. Действие позволяет вам сообщать пользователям, когда проблемы приводят к сбою ответов 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
и добавьте определение класса ошибок, как показано в следующем фрагменте кода:
index.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;
}
}
Обновите ответ на выполнение, чтобы вернуть код ошибки и статус ошибки:
index.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( ... )
//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
и добавьте определение класса ошибки, которое возвращает код ошибки и тип проблемы, как показано в следующем фрагменте кода:
index.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
следующим образом:
index.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( ... )
.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
, чтобы требовать явного подтверждения для включения или выключения стиральной машины.
index.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 .