1. Прежде чем начать
Интеграция с умным домом позволяет Google Assistant управлять подключенными устройствами в домах пользователей. Чтобы построить интеграцию между облаками, вам необходимо предоставить конечную точку облачного веб-перехватчика, способную обрабатывать намерения умного дома . Например, когда пользователь говорит: «Эй, Google, включи свет», Ассистент отправляет команду вашему облаку, чтобы обновить состояние устройства.
Local Home SDK расширяет интеграцию вашего умного дома, добавляя локальный путь для маршрутизации намерений умного дома непосредственно на устройство Google Home, что повышает надежность и уменьшает задержку при обработке команд пользователей. Он позволяет вам написать и развернуть локальное приложение для выполнения заказов на TypeScript или JavaScript, которое идентифицирует устройства и выполняет команды на любом интеллектуальном динамике Google Home или интеллектуальном дисплее Google Nest. Затем ваше приложение напрямую взаимодействует с существующими интеллектуальными устройствами пользователей через локальную сеть, используя существующие стандартные протоколы для выполнения команд.
Предварительные условия
- Создание руководства для разработчиков интеграции облако-облако
- Кодовая лаборатория умной домашней стиральной машины
- Руководство для разработчиков местных реализаций
Что ты построишь
В этой лаборатории кода вы развернете ранее созданную интеграцию умного дома с Firebase, затем примените конфигурацию сканирования в консоли разработчика и создадите локальное приложение с использованием TypeScript для отправки команд, написанных на Node.js, на виртуальное стиральное устройство.
Что вы узнаете
- Как включить и настроить локальное выполнение в консоли разработчика.
- Как использовать Local Home SDK для написания местного приложения для выполнения заказов.
- Как отладить местное приложение для выполнения заказов, загруженное на динамик Google Home или умный дисплей Google Nest.
Что вам понадобится
- Последняя версия Google Chrome
- Устройство iOS или Android с приложением Google Home.
- Умная колонка Google Home или умный дисплей Google Nest.
- Node.js версии 10.16 или новее
- Аккаунт Google
- Платежный аккаунт Google Cloud
2. Начало работы
Включить контроль активности
Чтобы использовать Google Assistant, вы должны предоставить Google определенные данные о деятельности. Google Assistant нужны эти данные для правильной работы; однако требование обмена данными не является специфичным для SDK. Чтобы поделиться этими данными, создайте учетную запись Google , если у вас ее еще нет. Вы можете использовать любую учетную запись Google — это не обязательно должна быть ваша учетная запись разработчика.
Откройте страницу «Контроль активности» для учетной записи Google, которую вы хотите использовать с Ассистентом.
Убедитесь, что следующие тумблеры включены:
- Активность в Интернете и приложениях . Кроме того, обязательно установите флажок Включать историю и активность Chrome на сайтах, приложениях и устройствах, использующих службы 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-local.git
О проекте
Стартовый проект содержит следующие подкаталоги:
-
public
— интерфейсный веб-интерфейс для управления и мониторинга умной стиральной машины. -
functions
— облачные функции, реализующие облачное выполнение для интеграции «облако-облако». -
local
— проект локального приложения-скелета с обработчиками намерений, заглушенными вindex.ts
Предоставленное облачное выполнение включает в себя следующие функции в index.js
:
-
fakeauth
— конечная точка авторизации для привязки учетной записи -
faketoken
— конечная точка токена для привязки учетной записи. -
smarthome
— конечная точка выполнения намерений умного дома -
reportstate
— вызывает API HomeGraph при изменении состояния устройства. -
updateDevice
— Конечная точка, используемая виртуальным устройством для запуска состояния отчета.
Подключиться к Firebase
Перейдите в каталог app-start
, затем настройте Firebase CLI для вашего проекта интеграции облака в облако:
cd app-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.json
из каталога washer-done
в каталог washer-start
, перезаписав файл в washer-start
.
В каталоге washer-start
:
cp -vp ../washer-done/firebase.json .
Развертывание в 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.
В разделе «Фирменный стиль приложения» загрузите png
файл значка приложения размером 144 x 144 пикселей с именем.png
.
Чтобы включить привязку учетной записи, используйте следующие настройки привязки учетной записи:
Идентификатор клиента | |
Секрет клиента | |
URL-адрес авторизации | |
URL-адрес токена | |
В разделе «URL-адрес выполнения облака» введите URL-адрес вашей облачной функции, которая обеспечивает выполнение намерений «умного дома».
https://us-central1- -cloudfunctions.net/smarthome
https://us-central1- -cloudfunctions.net/smarthome
Нажмите «Сохранить» , чтобы сохранить конфигурацию проекта, затем нажмите «Далее: Тест», чтобы включить тестирование вашего проекта.
Теперь вы можете приступить к реализации веб-перехватчиков, необходимых для связи состояния устройства с Ассистентом.
Ссылка на Google Ассистент
Чтобы протестировать интеграцию между облаками, вам необходимо связать свой проект с учетной записью Google. Это позволяет проводить тестирование через поверхности Google Assistant и приложение Google Home, которые вошли в одну и ту же учетную запись.
- На телефоне откройте настройки Google Assistant. Обратите внимание, что вы должны войти в систему под той же учетной записью, что и в консоли.
- Перейдите в «Google Ассистент» > «Настройки» > «Управление домом» (в разделе «Ассистент»).
- Нажмите значок поиска в правом верхнем углу.
- Найдите свое тестовое приложение, используя префикс [test] , чтобы найти конкретное тестовое приложение.
- Выберите этот элемент. Затем Google Assistant пройдет аутентификацию в вашей службе и отправит запрос
SYNC
, попросив вашу службу предоставить пользователю список устройств.
Откройте приложение Google Home и убедитесь, что вы видите стиральную машину.
Убедитесь, что вы можете управлять стиральной машиной с помощью голосовых команд в приложении Google Home. Вы также должны увидеть изменение состояния устройства в веб-интерфейсе вашего облачного сервиса.
Теперь вы можете начать добавлять к своей интеграции локальное выполнение.
4. Обновление облачного исполнения
Для поддержки локального выполнения необходимо добавить в ответ Cloud SYNC
новое поле для каждого устройства под otherDeviceIds
содержащее уникальный локальный идентификатор устройства. Это поле также указывает на возможность локального управления этим устройством.
Добавьте otherDeviceIds
в ответ SYNC
, как показано в следующем фрагменте кода:
функции/index.js
app.onSync((body) => {
return {
requestId: body.requestId,
payload: {
agentUserId: '123',
devices: [{
id: 'washer',
type: 'action.devices.types.WASHER',
traits: [ ... ],
name: { ... },
deviceInfo: { ... },
willReportState: true,
attributes: {
pausable: true,
},
otherDeviceIds: [{
deviceId: 'deviceid123',
}],
}],
},
};
});
Разверните обновленный проект в Firebase:
firebase deploy --only functions
После завершения развертывания перейдите в веб-интерфейс и нажмите кнопку «Обновить». кнопку на панели инструментов. Это запускает операцию запроса синхронизации, в результате чего Помощник получает обновленные данные ответа SYNC
.
5. Настройте локальное выполнение
В этом разделе вы добавите необходимые параметры конфигурации для локального выполнения в вашу облачную интеграцию. В ходе разработки вы опубликуете локальное приложение для выполнения заказов на хостинге Firebase, где устройство Google Home сможет получить к нему доступ и скачать его.
В консоли разработчика выберите «Разработка» > «Действия» и найдите раздел «Настроить локальный домашний SDK» . Введите следующий URL-адрес в поле тестового URL-адреса, вставьте идентификатор своего проекта и нажмите «Сохранить» :
https://<project-id>.web.app/local-home/index.html
Далее нам нужно определить, как устройство Google Home должно обнаруживать локальные интеллектуальные устройства. Платформа Local Home поддерживает несколько протоколов обнаружения устройств, включая mDNS, UPnP и широковещательную передачу UDP. Вы будете использовать широковещательную рассылку UDP, чтобы обнаружить интеллектуальную стиральную машину.
Нажмите «Новая конфигурация сканирования» в разделе «Конфигурация сканирования устройства», чтобы добавить новую конфигурацию сканирования. Выберите UDP в качестве протокола и заполните следующие атрибуты:
Поле | Описание | Рекомендуемое значение |
Широковещательный адрес | Широковещательный адрес UDP | |
Широковещательный порт | Порт, куда Google Home отправляет широковещательную передачу UDP | |
Слушать порт | Порт, на котором Google Home прослушивает ответ | |
Пакет обнаружения | Полезная нагрузка широковещательных данных UDP | |
Наконец, нажмите «Сохранить» в верхней части окна, чтобы опубликовать изменения.
6. Внедрить местное исполнение
Вы разработаете свое локальное приложение для выполнения заказов на TypeScript, используя пакет типизации Local Home SDK. Посмотрите на скелет, представленный в стартовом проекте:
локальный/index.ts
/// <reference types="@google/local-home-sdk" />
import App = smarthome.App;
import Constants = smarthome.Constants;
import DataFlow = smarthome.DataFlow;
import Execute = smarthome.Execute;
import Intents = smarthome.Intents;
import IntentFlow = smarthome.IntentFlow;
...
class LocalExecutionApp {
constructor(private readonly app: App) { }
identifyHandler(request: IntentFlow.IdentifyRequest):
Promise<IntentFlow.IdentifyResponse> {
// TODO: Implement device identification
}
executeHandler(request: IntentFlow.ExecuteRequest):
Promise<IntentFlow.ExecuteResponse> {
// TODO: Implement local fulfillment
}
...
}
const localHomeSdk = new App('1.0.0');
const localApp = new LocalExecutionApp(localHomeSdk);
localHomeSdk
.onIdentify(localApp.identifyHandler.bind(localApp))
.onExecute(localApp.executeHandler.bind(localApp))
.listen()
.then(() => console.log('Ready'))
.catch((e: Error) => console.error(e));
Основным компонентом локального выполнения является класс smarthome.App
. Стартовый проект присоединяет обработчики для намерений IDENTIFY
и EXECUTE
, а затем вызывает метод listen()
чтобы сообщить Local Home SDK о том, что приложение готово.
Добавьте обработчик IDENTIFY
Local Home SDK запускает обработчик IDENTIFY
, когда устройство Google Home обнаруживает непроверенные устройства в локальной сети на основе конфигурации сканирования, представленной в консоли разработчика.
Между тем, платформа вызывает identifyHandler
с полученными данными сканирования, когда Google обнаруживает подходящее устройство. В вашем приложении сканирование происходит с использованием широковещательной передачи UDP, и данные сканирования, передаваемые обработчику IDENTIFY
включают в себя полезную нагрузку ответа, отправленную локальным устройством.
Обработчик возвращает экземпляр IdentifyResponse
, содержащий уникальный идентификатор локального устройства. Добавьте следующий код в свой identifyHandler
, чтобы обработать ответ UDP, поступающий от локального устройства, и определить соответствующий идентификатор локального устройства:
локальный/индекс .ts
identifyHandler(request: IntentFlow.IdentifyRequest):
Promise<IntentFlow.IdentifyResponse> {
console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));
const scanData = request.inputs[0].payload.device.udpScanData;
if (!scanData) {
const err = new IntentFlow.HandlerError(request.requestId,
'invalid_request', 'Invalid scan data');
return Promise.reject(err);
}
// In this codelab, the scan data contains only local device id.
const localDeviceId = Buffer.from(scanData.data, 'hex');
const response: IntentFlow.IdentifyResponse = {
intent: Intents.IDENTIFY,
requestId: request.requestId,
payload: {
device: {
id: 'washer',
verificationId: localDeviceId.toString(),
}
}
};
console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));
return Promise.resolve(response);
}
Обратите внимание, что verificationId
должно соответствовать одному из otherDeviceIds
в вашем ответе SYNC
, который помечает устройство как доступное для локального выполнения в домашнем графике пользователя. После того как Google обнаружит совпадение, это устройство считается проверенным и готовым к реализации на местном уровне.
Добавьте обработчик EXECUTE
Local Home SDK запускает обработчик EXECUTE
, когда устройство, поддерживающее локальное выполнение, получает команду. Содержимое локального намерения эквивалентно намерению EXECUTE
отправленному на выполнение вашего облака, поэтому логика локальной обработки намерения аналогична тому, как вы обрабатываете его в облаке. Действия
Приложение может использовать сокеты TCP/UDP или запросы HTTP(S) для связи с локальными устройствами. В этой кодовой лаборатории HTTP служит протоколом, используемым для управления виртуальным устройством. Номер порта определен в index.ts
как переменная SERVER_PORT
.
Добавьте следующий код в свой метод executeHandler
для обработки входящих команд и отправки их на локальное устройство через HTTP:
локальный/index.ts
executeHandler(request: IntentFlow.ExecuteRequest):
Promise<IntentFlow.ExecuteResponse> {
console.log("EXECUTE intent: " + JSON.stringify(request, null, 2));
const command = request.inputs[0].payload.commands[0];
const execution = command.execution[0];
const response = new Execute.Response.Builder()
.setRequestId(request.requestId);
const promises: Array<Promise<void>> = command.devices.map((device) => {
console.log("Handling EXECUTE intent for device: " + JSON.stringify(device));
// Convert execution params to a string for the local device
const params = execution.params as IWasherParams;
const payload = this.getDataForCommand(execution.command, params);
// Create a command to send over the local network
const radioCommand = new DataFlow.HttpRequestData();
radioCommand.requestId = request.requestId;
radioCommand.deviceId = device.id;
radioCommand.data = JSON.stringify(payload);
radioCommand.dataType = 'application/json';
radioCommand.port = SERVER_PORT;
radioCommand.method = Constants.HttpOperation.POST;
radioCommand.isSecure = false;
console.log("Sending request to the smart home device:", payload);
return this.app.getDeviceManager()
.send(radioCommand)
.then(() => {
const state = {online: true};
response.setSuccessState(device.id, Object.assign(state, params));
console.log(`Command successfully sent to ${device.id}`);
})
.catch((e: IntentFlow.HandlerError) => {
e.errorCode = e.errorCode || 'invalid_request';
response.setErrorState(device.id, e.errorCode);
console.error('An error occurred sending the command', e.errorCode);
});
});
return Promise.all(promises)
.then(() => {
return response.build();
})
.catch((e) => {
const err = new IntentFlow.HandlerError(request.requestId,
'invalid_request', e.message);
return Promise.reject(err);
});
}
Скомпилируйте приложение TypeScript
Перейдите в каталог local/
и выполните следующие команды, чтобы загрузить компилятор TypeScript и скомпилировать приложение:
cd local npm install npm run build
При этом исходный код index.ts
(TypeScript) компилируется и следующее содержимое помещается в каталог public/local-home/
:
-
bundle.js
— скомпилированный вывод JavaScript, содержащий локальное приложение и зависимости. -
index.html
— страница локального хостинга, используемая для обслуживания приложения для тестирования на устройстве.
Развертывание тестового проекта
Разверните обновленные файлы проекта на хостинге Firebase, чтобы вы могли получить к ним доступ с устройства Google Home.
firebase deploy --only hosting
7. Запустите умную стиральную машину.
Теперь пришло время проверить связь между вашим местным приложением для выполнения заказов и умной стиральной машиной! Стартовый проект Codelab включает в себя виртуальную интеллектуальную стиральную машину, написанную на Node.js, которая имитирует интеллектуальную стиральную машину, которой пользователи могут управлять локально.
Настройка устройства
Вам необходимо настроить виртуальное устройство на использование тех же параметров UDP, которые вы применили к конфигурации сканирования для обнаружения устройств в консоли разработчика. Кроме того, вам необходимо сообщить виртуальному устройству, какой идентификатор локального устройства необходимо сообщить, а также идентификатор проекта интеграции «облако-облако», который будет использоваться для событий состояния отчета при изменении состояния устройства.
Параметр | Рекомендуемое значение |
идентификатор устройства | |
открытиеPortOut | |
пакет открытия | |
идентификатор проекта | Идентификатор вашего проекта интеграции облака в облако |
Запустите устройство
Перейдите в каталог virtual-device/
и запустите сценарий устройства, передав параметры конфигурации в качестве аргументов:
cd virtual-device npm install npm start -- \ --deviceId=deviceid123 --projectId=<project-id> \ --discoveryPortOut=3311 --discoveryPacket=HelloLocalHomeSDK
Убедитесь, что сценарий устройства выполняется с ожидаемыми параметрами:
(...): UDP Server listening on 3311 (...): Device listening on port 3388 (...): Report State successful
8. Отладка приложения TypeScript.
В следующем разделе вы убедитесь, что устройство Google Home может правильно сканировать, идентифицировать и отправлять команды на виртуальную интеллектуальную стиральную машину по локальной сети. Вы можете использовать инструменты разработчика Google Chrome для подключения к устройству Google Home, просмотра журналов консоли и отладки приложения TypeScript.
Подключите инструменты разработчика Chrome
Чтобы подключить отладчик к местному приложению выполнения, выполните следующие действия:
- Убедитесь, что вы связали свое устройство Google Home с пользователем, имеющим разрешение на доступ к проекту Developer Console .
- Перезагрузите устройство Google Home, что позволит ему получить URL-адрес вашего HTML-кода, а также конфигурацию сканирования, которую вы разместили в консоли разработчика.
- Запустите Chrome на своей машине разработки.
- Откройте новую вкладку Chrome и введите
chrome://inspect
в поле адреса, чтобы запустить инспектор.
Вы должны увидеть список устройств на странице, а URL-адрес вашего приложения должен появиться под именем вашего устройства Google Home.
Запустить инспектор
Нажмите «Проверить» под URL-адресом вашего приложения, чтобы запустить инструменты разработчика Chrome. Выберите вкладку «Консоль» и убедитесь, что вы видите содержимое намерения IDENTIFY
напечатанное вашим приложением TypeScript.
Этот вывод означает, что ваше местное приложение выполнения успешно обнаружило и идентифицировало виртуальное устройство.
Проверьте местное выполнение
Отправляйте команды на свое устройство с помощью сенсорного управления в приложении Google Home или с помощью голосовых команд на устройство Google Home, например:
«Эй, Google, включи мою стиральную машину».
«Окей, Google, включи мою стиральную машину».
«Эй, Google, останови мою стиральную машину».
Это должно заставить платформу отправить намерение EXECUTE
в ваше приложение TypeScript.
Убедитесь, что вы можете видеть изменение состояния локальной интеллектуальной стиральной машины при каждой команде.
... ***** The washer is RUNNING ***** ... ***** The washer is STOPPED *****
9. Поздравления
Поздравляем! Вы использовали Local Home SDK для интеграции локального выполнения заказов в интеграцию между облаками.
Узнать больше
Вот еще несколько вещей, которые вы можете попробовать:
- Измените конфигурацию сканирования и заставьте ее работать. Например, попробуйте использовать другой порт UDP или пакет обнаружения.
- Измените кодовую базу виртуального интеллектуального устройства для работы на встроенном устройстве, например Raspberry Pi, и используйте светодиоды или дисплей для визуализации текущего состояния.