Aby umożliwić realizację lokalnej realizacji zamówień, musisz utworzyć aplikację do obsługi tych intencji inteligentnego domu:
IDENTIFY
: wspiera wykrywanie urządzeń, które można lokalnie sterować. Moduł obsługi intencji wyodrębnia dane, które urządzenie zwraca podczas wykrywania, i wysyła je w odpowiedzi do Google.EXECUTE
: obsługuje wykonywanie poleceń.QUERY
: obsługuje wysyłanie zapytań o stan urządzenia.REACHABLE_DEVICES
(opcjonalnie) umożliwia wykrywanie urządzeń końcowych, które można lokalnie kontrolować, za urządzeniami centrali (lub mostkami).
Ta aplikacja działa na urządzeniach Google Home lub Google Nest użytkownika i łączy Twoje urządzenie z Asystentem. Aplikację możesz utworzyć za pomocą języka TypeScript (preferowane) lub JavaScriptu.
Zalecamy korzystanie z TypeScript, ponieważ możesz wykorzystać powiązania, aby statycznie mieć pewność, że dane zwracane przez aplikację są zgodne z typami, których oczekuje platforma.
Więcej informacji o tym interfejsie API znajdziesz w dokumentacji interfejsu Local Home SDK API.
Poniższe fragmenty kodu pokazują, jak zainicjować lokalną aplikację realizacji i dołączyć moduły obsługi.
import App = smarthome.App; const localHomeApp: App = new App("1.0.0"); localHomeApp .onIdentify(identifyHandler) .onExecute(executeHandler) .listen() .then(() => { console.log("Ready"); });
import App = smarthome.App; const localHomeApp: App = new App("1.0.0"); localHomeApp .onIdentify(identifyHandler) .onReachableDevices(reachableDevicesHandler) .onExecute(executeHandler) .listen() .then(() => { console.log("Ready"); });
Tworzenie projektu
Aby wdrożyć lokalną aplikację realizacji zamówień, musisz utworzyć pakiet JavaScript dla swojego kodu i wszystkich jego zależności.
Użyj inicjatora projektu w lokalnej aplikacji realizującej projekt, aby wczytać odpowiednią strukturę projektu z preferowaną konfiguracją pakietu SDK.
Szablony projektów
Aby wybrać konfigurację usługi tworzenia pakietów, uruchom polecenie npm init
w sposób pokazany na tych przykładach:
TypeScript bez konfiguracji pakietu SDK:
npm init @google/local-home-app project-directory/ --bundler none
Struktura projektu:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json └── serve.js
Zastąp project-directory nowym katalogiem, który będzie zawierał projekt lokalnej aplikacji do realizacji zamówień.
TypeScript z konfiguracją pakietu webpack:
npm init @google/local-home-app project-directory/ --bundler webpack
Struktura projektu:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json ├── webpack.config.web.js ├── webpack.config.node.js └── serve.js
Zastąp project-directory nowym katalogiem, który będzie zawierał projekt lokalnej aplikacji do realizacji zamówień.
TypeScript z konfiguracją pakietu Rollup:
npm init @google/local-home-app project-directory/ --bundler rollup
Struktura projektu:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json ├── rollup.config.js └── serve.js
Zastąp project-directory nowym katalogiem, który będzie zawierał projekt lokalnej aplikacji do realizacji zamówień.
TypeScript z konfiguracją pakietu Parcel:
npm init @google/local-home-app project-directory/ --bundler parcel
Struktura projektu:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json └── serve.js
Zastąp project-directory nowym katalogiem, który będzie zawierał projekt lokalnej aplikacji do realizacji zamówień.
Wykonywanie typowych zadań na poziomie projektu
Wygenerowany projekt obsługuje te skrypty npm:
cd project-directory/ npm run build
Ten skrypt kompiluje kod źródłowy TypeScript i łączy Twoją aplikację z zależnościami środowiska wykonawczego Chrome w podkatalogu dist/web
i środowisku wykonawczym Node.js w podkatalogu dist/node
.
cd project-directory/ npm run lint npm run compile npm test
Ten skrypt sprawdza składnię kodu TypeScript, kompilowa go bez generowania danych wyjściowych w podkatalogu dist/
i uruchamia automatyczne testy w test.ts
.
cd project-directory/ npm run start
W trakcie programowania skrypt ten udostępnia pakiety aplikacji lokalnie w środowisku wykonawczym Chrome i Node.js.
Implementowanie modułu obsługi IDENTIFY
Moduł obsługi IDENTIFY
uruchomi się po ponownym uruchomieniu urządzenia Google Home lub Google Nest i zobaczy niezweryfikowane urządzenia lokalne (w tym urządzenia końcowe podłączone do hubu). Platforma Local Home będzie skanować w poszukiwaniu urządzeń lokalnych przy użyciu podanych wcześniej informacji o konfiguracji skanowania, a potem z wynikami skanowania wywołać moduł obsługi IDENTIFY
.
IdentifyRequest
z platformy Local Home zawiera dane skanowania instancji LocalIdentifiedDevice
. Zapełniona jest tylko 1 instancja device
na podstawie konfiguracji skanowania, która wykryła urządzenie.
Jeśli wyniki skanowania są zgodne z Twoim urządzeniem, moduł obsługi IDENTIFY
powinien zwrócić obiekt IdentifyResponsePayload
, który zawiera obiekt device
z metadanymi inteligentnego domu (takimi jak typy, cechy i stan raportu).
Google tworzy powiązanie urządzeń, jeśli verificationId
z odpowiedzi IDENTIFY
odpowiada jednej z wartości otherDeviceIds
zwróconych przez odpowiedź SYNC
.
Przykład
Poniższe fragmenty kodu pokazują, jak utworzyć moduły obsługi IDENTIFY
odpowiednio na potrzeby samodzielnych integracji urządzeń i centrów.
const identifyHandler = (request: IntentFlow.IdentifyRequest): IntentFlow.IdentifyResponse => { // Obtain scan data from protocol defined in your scan config const device = request.inputs[0].payload.device; if (device.udpScanData === undefined) { throw Error("Missing discovery response"); } const scanData = device.udpScanData.data; // Decode scan data to obtain metadata about local device const verificationId = "local-device-id"; // Return a response const response: IntentFlow.IdentifyResponse = { intent: Intents.IDENTIFY, requestId: request.requestId, payload: { device: { id: device.id || "", verificationId, // Must match otherDeviceIds in SYNC response }, }, }; return response; };
const identifyHandler = (request: IntentFlow.IdentifyRequest): IntentFlow.IdentifyResponse => { // Obtain scan data from protocol defined in your scan config const device = request.inputs[0].payload.device; if (device.udpScanData === undefined) { throw Error("Missing discovery response"); } const scanData = device.udpScanData.data; // Decode scan data to obtain metadata about local device const proxyDeviceId = "local-hub-id"; // Return a response const response: IntentFlow.IdentifyResponse = { intent: Intents.IDENTIFY, requestId: request.requestId, payload: { device: { id: proxyDeviceId, isProxy: true, // Device can control other local devices isLocalOnly: true, // Device not present in `SYNC` response }, }, }; return response; };
Zidentyfikuj urządzenia za hubem
Jeśli Google zidentyfikuje urządzenie centralne, potraktuje je jako kanał łączący połączone z nim urządzenia końcowe i spróbuje zweryfikować te urządzenia.
Aby umożliwić Google potwierdzenie obecności urządzenia centralnego, postępuj zgodnie z tymi instrukcjami dotyczącymi modułu obsługi IDENTIFY
:
- Jeśli odpowiedź
SYNC
zawiera identyfikatory lokalnych urządzeń końcowych połączonych z hub, ustawisProxy
natrue
wIdentifyResponsePayload
. - Jeśli odpowiedź
SYNC
nie zgłasza urządzenia centrali, ustawisLocalOnly
jakotrue
wIdentifyResponsePayload
. - Pole
device.id
zawiera lokalny identyfikator samego urządzenia centrali.
Wdróż moduł obsługi REACHABLE_DEVICE (tylko integracje centrali)
Google wysyła intencję REACHABLE_DEVICES
w celu sprawdzenia, które urządzenia końcowe mogą być sterowane lokalnie. Ta intencja jest wywoływana za każdym razem, gdy Google uruchamia skanowanie wykrywania (mniej więcej raz na minutę), o ile wykryje, że centrum jest online.
Moduł obsługi REACHABLE_DEVICES
jest wdrażany podobnie jak moduł obsługi IDENTIFY
, z tą różnicą, że musi on zbierać dodatkowe identyfikatory urządzeń dostępne dla lokalnego serwera proxy (czyli urządzenia centrali). Pole device.verificationId
zawiera lokalny identyfikator urządzenia końcowego połączonego z centrum.
ReachableDevicesRequest
z platformy Local Home zawiera wystąpienie LocalIdentifiedDevice
.
Dzięki tej instancji możesz uzyskać identyfikator urządzenia proxy oraz dane z wyników skanowania.
Moduł obsługi REACHABLE_DEVICES
powinien zwracać obiekt ReachableDevicesPayload
zawierający obiekt devices
zawierający tablicę wartości verificationId
reprezentującą urządzenia końcowe sterowane przez centrum. Wartości verificationId
muszą być zgodne z jedną z wartości otherDeviceIds
w odpowiedzi SYNC
.
Poniższy fragment pokazuje, jak możesz utworzyć moduł obsługi REACHABLE_DEVICES
.
const reachableDevicesHandler = (request: IntentFlow.ReachableDevicesRequest): IntentFlow.ReachableDevicesResponse => { // Reference to the local proxy device const proxyDeviceId = request.inputs[0].payload.device.id; // Gather additional device ids reachable by local proxy device // ... const reachableDevices = [ // Each verificationId must match one of the otherDeviceIds // in the SYNC response { verificationId: "local-device-id-1" }, { verificationId: "local-device-id-2" }, ]; // Return a response const response: IntentFlow.ReachableDevicesResponse = { intent: Intents.REACHABLE_DEVICES, requestId: request.requestId, payload: { devices: reachableDevices, }, }; return response; };
Implementowanie modułu obsługi EXECUTE
Moduł obsługi EXECUTE
w aplikacji przetwarza polecenia użytkownika i używa pakietu SDK Local Home do uzyskiwania dostępu do urządzeń za pomocą istniejącego protokołu.
Platforma lokalna strona główna przekazuje ten sam ładunek wejściowy do funkcji obsługi EXECUTE
co w przypadku intencji EXECUTE
w ramach realizacji w chmurze. Podobnie moduł obsługi EXECUTE
zwraca dane wyjściowe w tym samym formacie co podczas przetwarzania intencji EXECUTE
.
Aby uprościć tworzenie odpowiedzi, możesz użyć klasy Execute.Response.Builder
udostępnianej przez pakiet SDK Local Home.
Aplikacja nie ma bezpośredniego dostępu do adresu IP urządzenia. Zamiast tego używaj interfejsu CommandRequest
do tworzenia poleceń na podstawie jednego z tych protokołów: UDP, TCP lub HTTP. Następnie wywołaj funkcję deviceManager.send()
, aby wysłać polecenia.
Podczas kierowania poleceń na urządzenia użyj identyfikatora urządzenia (i parametrów z pola customData
, jeśli jest uwzględnione) z odpowiedzi SYNC
, aby komunikować się z urządzeniem.
Przykład
Poniższy fragment kodu pokazuje, jak możesz utworzyć moduł obsługi EXECUTE
.
const executeHandler = (request: IntentFlow.ExecuteRequest): Promise<IntentFlow.ExecuteResponse> => { // Extract command(s) and device target(s) from request const command = request.inputs[0].payload.commands[0]; const execution = command.execution[0]; const response = new Execute.Response.Builder() .setRequestId(request.requestId); const result = command.devices.map((device) => { // Target id of the device provided in the SYNC response const deviceId = device.id; // Metadata for the device provided in the SYNC response // Use customData to provide additional required execution parameters const customData: any = device.customData; // Convert execution command into payload for local device let devicePayload: string; // ... // Construct a local device command over TCP const deviceCommand = new DataFlow.TcpRequestData(); deviceCommand.requestId = request.requestId; deviceCommand.deviceId = deviceId; deviceCommand.data = devicePayload; deviceCommand.port = customData.port; deviceCommand.operation = Constants.TcpOperation.WRITE; // Send command to the local device return localHomeApp.getDeviceManager() .send(deviceCommand) .then((result) => { response.setSuccessState(result.deviceId, state); }) .catch((err: IntentFlow.HandlerError) => { err.errorCode = err.errorCode || IntentFlow.ErrorCode.INVALID_REQUEST; response.setErrorState(device.id, err.errorCode); }); }); // Respond once all commands complete return Promise.all(result) .then(() => response.build()); };
Implementowanie modułu obsługi QUERY
Moduł obsługi QUERY
w aplikacji przetwarza żądania użytkowników i używa pakietu SDK Local Home do raportowania stanu urządzeń.
Lokalna platforma główna przekazuje ten sam ładunek żądania do funkcji obsługi „QUERY” co dla intencji QUERY
w przypadku realizacji w chmurze. Podobnie moduł obsługi QUERY
zwraca dane w tym samym formacie co podczas przetwarzania intencji QUERY
.
Wysyłanie poleceń do urządzeń za centralą
Aby sterować urządzeniami końcowymi za centrum, konieczne może być podanie dodatkowych informacji w ładunku poleceń protokołu wysyłanym do centrum. Dzięki temu centrum będzie mogło zidentyfikować urządzenie, którego dotyczy polecenie. W niektórych przypadkach można to określić bezpośrednio na podstawie wartości device.id
, ale jeśli nie jest to konieczne, uwzględnij te dodatkowe dane w polu customData
.
Jeśli Twoja aplikacja została utworzona za pomocą TypeScriptu, pamiętaj o skompilowaniu jej do języka JavaScript. Do pisania kodu możesz użyć wybranego systemu modułów. Upewnij się, że środowisko docelowe jest obsługiwane przez przeglądarkę Chrome.