Włącz lokalną realizację w przypadku inteligentnych działań domowych

1. Zanim zaczniesz

Integracja inteligentnego domu pozwala Asystentowi Google sterować połączonymi urządzeniami w domach użytkowników. Aby utworzyć akcję inteligentnego domu, musisz udostępnić punkt końcowy webhooka w chmurze umożliwiający obsługę intencji inteligentnego domu. Jeśli na przykład użytkownik powie „OK Google, włącz światło”, Asystent wyśle polecenie do realizacji w chmurze, aby zaktualizować stan urządzenia.

Pakiet SDK Local Home usprawnia integrację inteligentnego domu przez dodanie lokalnej ścieżki kierującej intencje inteligentnego domu bezpośrednio do urządzenia Google Home. Zwiększa to niezawodność i zmniejsza opóźnienia w przetwarzaniu poleceń użytkownika. Pozwala napisać i wdrożyć w języku TypeScript lub JavaScript aplikację do realizacji lokalnych zamówień, która identyfikuje urządzenia i wykonuje polecenia na dowolnym inteligentnym głośniku Google Home lub inteligentnym ekranie Google Nest. Aplikacja komunikuje się bezpośrednio z dotychczasowymi urządzeniami użytkowników przez sieć lokalną, wykorzystując istniejące standardowe protokoły do wykonywania poleceń.

72ffb320986092c.png

Wymagania wstępne

Co utworzysz

W ramach tego ćwiczenia w programowaniu wdrożysz wcześniej utworzoną integrację z inteligentnym domem z Firebase, a następnie zastosujesz konfigurację skanowania w Konsoli Actions i utworzysz aplikację lokalną za pomocą TypeScriptu, aby wysyłać polecenia napisane w Node.js do wirtualnej pralki.

Czego się nauczysz

  • Jak włączyć i skonfigurować realizację lokalną w Konsoli Actions.
  • Jak użyć pakietu SDK lokalnej strony głównej do napisania lokalnej aplikacji do realizacji zamówień.
  • Jak debugować aplikację do realizacji lokalnej, wczytaną na głośniku Google Home lub inteligentnym ekranie Google Nest.

Czego potrzebujesz

2. Wprowadzenie

Włączanie Zarządzania aktywnością

Aby korzystać z Asystenta Google, musisz udostępnić Google określone dane o aktywności. Asystent Google potrzebuje tych danych do prawidłowego działania, ale wymóg udostępniania danych nie dotyczy tylko pakietu SDK. Aby udostępnić te dane, utwórz konto Google. Możesz użyć dowolnego konta Google – nie musi to być konto dewelopera.

Otwórz stronę Zarządzanie aktywnością na koncie Google, którego chcesz używać z Asystentem.

Sprawdź, czy te przełączniki są włączone:

  • Aktywność w internecie i aplikacjach – zaznacz też pole wyboru Uwzględnij historię Chrome i aktywność na stronach, urządzeniach i w aplikacjach, które używają usług Google.
  • Informacje z urządzenia
  • Aktywność związana z głosem i dźwiękiem

Tworzenie projektu w Actions

  1. Otwórz Konsolę programisty Actions on Google.
  2. Kliknij Nowy projekt, wpisz nazwę projektu i kliknij UTWÓRZ PROJEKT.

AWXw5E1m9zVgvVeyeL3uxwCX6DtWOCK6LRSLmOATFzjMbmE5cSWBdSVhJZDFpEFH2azZTK2eMs6OYYdMJYiGb5bKqFEzxaLyRUYuwVGBlSywXiYXŁYQYPQXQYQYPQY

Wybierz aplikację Inteligentny dom

Na ekranie Przegląd w Konsoli Actions wybierz Inteligentny dom.

L4XXVIII

Wybierz kartę Inteligentny dom. Przekierujemy Cię wtedy do konsoli projektu.

pzgHPsmc2LvLoeUvJfkjKQqD_BvO4v8JOPlcrxsmyptFkkjL4PP6LqrM9r5tNvEIfT9HmK-UKw3GWFPXTjqo4nUrhD2o5shUKHBE31OT8iIA69JZCev7_0_nh-lnL2oJHoxGfqqZ4w

Instalowanie interfejsu wiersza poleceń Firebase

Interfejs wiersza poleceń Firebase (CLI) umożliwia udostępnianie aplikacji internetowych lokalnie i wdrażanie ich w hostingu Firebase.

Aby zainstalować interfejs wiersza poleceń, uruchom w terminalu to polecenie npm:

npm install -g firebase-tools

Aby sprawdzić, czy interfejs wiersza poleceń został prawidłowo zainstalowany, uruchom polecenie:

firebase --version

Autoryzuj interfejs wiersza poleceń Firebase na swoim koncie Google, uruchamiając polecenie:

firebase login

Włączanie interfejsu HomeGraph API

HomeGraph API umożliwia przechowywanie i zapytania dotyczące urządzeń oraz ich stanów w Home Graph. Aby używać tego interfejsu API, musisz najpierw otworzyć konsolę Google Cloud i włączyć interfejs HomeGraph API.

W konsoli Google Cloud wybierz projekt zgodny z działaniami <project-id>.. Następnie na ekranie Biblioteka API interfejsu HomeGraph kliknij Włącz.

5SVCzM8IZLi_9DV8M0nEklv16NXkpvM0bIzQK2hSyKyvnFHBxPOz90rbr72ayxzmxd5aNROOqC_Cp4outbdlwJdObDs0DIE_8vYzw6dovoVrP9IZWlWsZxDS7UHOi1jiRbDMG8MqUA

3. Uruchamianie aplikacji startowej

Po skonfigurowaniu środowiska programistycznego możesz wdrożyć projekt początkowy, aby sprawdzić, czy wszystko jest skonfigurowane prawidłowo.

Pobieranie kodu źródłowego

Kliknij poniższy link, aby pobrać na komputerze przykładowy program do przykładowego ćwiczenia:

Możesz też sklonować repozytorium GitHub z wiersza poleceń:

git clone https://github.com/google-home/smarthome-local.git

Informacje o projekcie

Projekt startowy zawiera te podkatalogi:

  • public – interfejs internetowy frontendu pozwalający sterować inteligentną pralką i ją monitorować
  • functions – funkcje Cloud implementujące realizację usług w chmurze na potrzeby działania związanego z inteligentnym domem.
  • local – projekt aplikacji do realizacji lokalnej ze szkieletu z modułami obsługi intencji w pliku index.ts.

Podana realizacja w chmurze obejmuje te funkcje w projekcie index.js:

  • fakeauth – punkt końcowy autoryzacji służący do łączenia kont.
  • faketoken – punkt końcowy tokena do łączenia kont
  • smarthome – punkt końcowy realizacji intencji inteligentnego domu.
  • reportstate – wywołuje interfejs HomeGraph API w przypadku zmiany stanu urządzenia.
  • updateDevice – punkt końcowy używany przez urządzenie wirtualne do aktywowania stanu raportu

Łączenie z Firebase

Przejdź do katalogu app-start, a następnie skonfiguruj interfejs wiersza poleceń Firebase w projekcie Actions:

cd app-start
firebase use <project-id>

Konfigurowanie projektu Firebase

Zainicjuj projekt Firebase.

firebase init

Wybierz funkcje interfejsu wiersza poleceń, Bazę danych czasu rzeczywistego, Funkcje i funkcję Hosting obejmującą Hosting 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

Spowoduje to zainicjowanie wymaganych interfejsów API i funkcji w projekcie.

Po wyświetleniu monitu zainicjuj Bazę danych czasu rzeczywistego. Możesz użyć domyślnej lokalizacji instancji bazy danych.

? 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

Ponieważ używasz kodu projektu początkowego, wybierz domyślny plik reguł zabezpieczeń i upewnij się, że nie zastąpisz istniejącego pliku z regułami bazy danych.

? 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

Jeśli ponownie inicjujesz projekt, w odpowiedzi na pytanie, czy chcesz zainicjować, czy zastąpić bazę kodu, wybierz Zastąp.

? Would you like to initialize a new codebase, or overwrite an existing one?
Overwrite

Podczas konfigurowania funkcji użyj plików domyślnych i nie zastępuj istniejących plików index.js ani package.json w przykładowym projekcie.

? 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

Jeśli ponownie inicjujesz projekt, w odpowiedzi na pytanie, czy chcesz zainicjować czy zastąpić funkcje/.gitignore, wybierz Nie.

? File functions/.gitignore already exists. Overwrite?
No
? Do you want to install dependencies with npm now?
Yes

Na koniec skonfiguruj konfigurację Hostingu tak, aby używała katalogu public w kodzie projektu i używała istniejącego pliku index.html. W odpowiedzi na pytanie o korzystanie z ESLint wybierz Nie.

? 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

Jeśli ESLint został włączony przypadkowo, można go wyłączyć na 2 sposoby:

  1. W interfejsie GUI przejdź do folderu ../functions w projekcie, wybierz ukryty plik .eslintrc.js i usuń go. Nie pomyl go z podobną nazwą .eslintrc.json.
  2. Przy użyciu wiersza poleceń:
    cd functions
    rm .eslintrc.js
    

Aby upewnić się, że konfiguracja Firebase jest prawidłowa, skopiuj plik firebase.json z katalogu washer-done do katalogu washer-start, zastępując plik w pliku washer-start.

W katalogu washer-start:

cp -vp ../washer-done/firebase.json .

Wdrażanie w Firebase

Po zainstalowaniu zależności i skonfigurowaniu projektu możesz po raz pierwszy uruchomić aplikację.

firebase deploy

Powinny pojawić się te dane wyjściowe konsoli:

...

✔ Deploy complete!

Project Console: https://console.firebase.google.com/project/<project-id>/overview
Hosting URL: https://<project-id>.web.app

To polecenie wdraża aplikację internetową i kilka funkcji Cloud Functions dla Firebase.

Otwórz w przeglądarce URL hostowania (https://<project-id>.web.app), aby wyświetlić aplikację internetową. Zobaczysz ten interfejs:

L60eA7MOnPmbBMl2XMipT9MdnP-RaVjyjf0Y93Y1b7mEyIsqZrrwczE7D3RQISRs-iusL1g4XbNmGhuA6-5sLcWefnczwNJEPfNLtwBsO4Tb9YvcAZBI6_rX19z8rxbik9Vq8F2fwg

Ten interfejs internetowy reprezentuje platformę firmy zewnętrznej do wyświetlania i modyfikowania stanów urządzeń. Aby rozpocząć wypełnianie bazy danych informacjami o urządzeniu, kliknij AKTUALIZUJ. Na stronie nie pojawią się żadne zmiany, ale bieżący stan pralki będzie przechowywany w bazie danych.

Teraz możesz połączyć wdrożoną z Asystenta Google usługę w chmurze za pomocą Konsoli Actions.

Konfigurowanie projektu w Konsoli Actions

W sekcji Przegląd > Utwórz działanie wybierz Dodaj działania. Wpisz adres URL funkcji w Cloud Functions, która realizuje intencje inteligentnego domu, i kliknij Zapisz.

https://us-central1-<project-id>.cloudfunctions.net/smarthome

Uso-o00XQXBHvOR9vQq9tmpYDYQJKsFEstsgRFnxPAJf7zJ2FxwhISiodo3dB1Tz49Okd6ivi66fjpo7rarS_GZelglGWCT1r9FzDGUl1r67ddIcIbQrxqN8jG9F9GAKOpk0Ckc-eA

Na karcie Programowanie > Wywołanie dodaj wyświetlaną nazwę działania i kliknij Zapisz. Ta nazwa będzie widoczna w aplikacji Google Home.

gvC-TvmKDy-D-xjwkeCjNt__9ErA7DL8hZWa1oH1yPJ9SpYOepDYjxx6WnJ56IG-t37fJ65kmHISQdh72Ot2G-0tu6Flxf4gom5kvx_3hlvFeMqYuFgXr_85pfWWn7VLFHtS55p1zw

s4yc1kOW4XtKUQN1EYegiDLU5oTqmxQ2PNbeaujm26OQmYKKpjug7j5FYmutLSAZ1zBd-ZkcZlL7zyTZqw4bge3_oOeWvJTsqJ-A08vfZwImYQrKiquLskLuTpmMqXEZD1xchhCWGQ

Żeby włączyć łączenie kont, w menu nawigacyjnym po lewej stronie wybierz opcję Programowanie > Łączenie kont. Użyj tych ustawień łączenia kont:

Identyfikator klienta

ABC123

Tajny klucz klienta

DEF456

Adres URL autoryzacji

https://us-central1-<project-id>.cloudfunctions.net/fakeauth

URL tokena

https://us-central1-<project-id>.cloudfunctions.net/faketoken

rRyZTiBSTuPk3YtJtXjDK1pPftUxsaEhs9jzpvFtbHTD6bEwYxM8jV4MWxiljKA1bKVZrIRoO9O3jtBefLKf_OyMpukPjwIj8zGvyU3UwASzMrnRskl-hVAfAmQVi4sC_zAwgYwRXw

Kliknij Zapisz, aby zapisać konfigurację łączenia kont, a potem kliknij Przetestuj, aby włączyć testowanie w projekcie.

OgUvpQfXioygkRwPcaJpzjyNQDZy6enidUC8YMPaCOrZi0YeWCFsCJV9Gqg-_UfsqTnn4KEg--uE3Ymr0QuamDonF4RyYHtRKcULXABDuaEnj2hq8i20LYj1SrGP_1lQ_UsUB90pGw

Przekierujemy Cię do Symulatora. Sprawdź, czy w projekcie włączono testowanie, przesuwając kursor na ikonę Testowanie na urządzeniu ( soCeBB1CkSIEqsBmDc8Cth6EjgcXUnrOHeOpLNlvMiiXM73Rmh8iBK1ZFLFd47kycYqIMq3Fm49ryAGUt79BXVPDyEB1IU3W0fgiL49iqTAVwxrszL10L49iqTAVwxRszVr).

2zbfeYpG-wEd2SFP07Wc4mJzHakLX7YvrNw3IV0_0Kd-TonfsKIvvjKWlwvrmTm5jLj3XPWqCtcDd5J2z6gwn9fnchpYVraw1j_mE4M0LVppAl5WY5cK7g0uZyhZ3VFFS25yPmyksg

Aby przetestować działanie inteligentnego domu, musisz połączyć swój projekt z kontem Google. Umożliwi Ci to testowanie na platformach Asystenta Google i w aplikacji Google Home po zalogowaniu się na to samo konto.

  1. Na telefonie otwórz ustawienia Asystenta Google. Pamiętaj, aby zalogować się na to samo konto co w konsoli.
  2. Wybierz Asystent Google > Ustawienia > Sterowanie domem (w sekcji Asystent).
  3. Kliknij ikonę wyszukiwania w prawym górnym rogu.
  4. Wyszukaj swoją aplikację testową, korzystając z prefiksu [test].
  5. Wybierz ten element. Asystent Google uwierzytelni się w Twojej usłudze i wyśle żądanie SYNC, prosząc usługę o podanie listy urządzeń dla użytkownika.

Otwórz aplikację Google Home i sprawdź, czy widzisz pralkę.

XcWmBVamBZtPfOFqtsr5I38stPWTqDcMfQwbBjetBgxt0FCjEs285pa9K3QXSASptw0KYN2G8yfkT0-xg664V4PjqMreDDs-HPegHjOc4EVtReYPu-WKZyygq9Xmkf8X8z9177nBjQ

Sprawdź, czy możesz sterować pralką za pomocą poleceń głosowych w aplikacji Google Home. Zmiana stanu urządzenia powinna też być widoczna w interfejsie internetowym frontendu w realizacji w chmurze.

Teraz możesz zacząć dodawać do akcji realizację lokalną.

4. Aktualizowanie realizacji w chmurze

Aby obsługiwać realizację lokalną, musisz dodać nowe pole dla poszczególnych urządzeń o nazwie otherDeviceIds do odpowiedzi SYNC w chmurze, która zawiera unikalny identyfikator lokalny urządzenia. To pole wskazuje też możliwość lokalnego sterowania tym urządzeniem.

Dodaj pole otherDeviceIds do odpowiedzi SYNC w sposób podany w tym fragmencie kodu:

functions/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',
        }],
      }],
    },
  };
});

Wdróż zaktualizowany projekt w Firebase:

firebase deploy --only functions

Po zakończeniu wdrażania przejdź do interfejsu internetowego i kliknij przycisk Odśwież ae8d3b25777a5e30.png na pasku narzędzi. Spowoduje to uruchomienie operacji synchronizacji żądań, dzięki czemu Asystent otrzyma zaktualizowane dane odpowiedzi z usługi SYNC.

bf4f6a866160a982.png

5. Skonfiguruj realizację lokalną

W tej sekcji dodasz opcje konfiguracji niezbędne do realizacji lokalnej do działania w inteligentnym domu. W trakcie programowania opublikujesz lokalną aplikację do realizacji w Hostingu Firebase, z którego urządzenie Google Home będzie miało dostęp i będzie mogło ją pobrać.

W konsoli Actions wybierz Programowanie > Działania i odszukaj sekcję Skonfiguruj lokalny pakiet SDK dla domu. Wpisz ten adres URL w polu testowego adresu URL, wstaw identyfikator projektu i kliknij Zapisz:

https://<project-id>.web.app/local-home/index.html

7d59b31f8d2a988.png

Następnie trzeba określić, jak urządzenie Google Home ma wykrywać lokalne urządzenia. Platforma Local Home obsługuje kilka protokołów do wykrywania urządzeń, w tym mDNS, UPnP i UDP. Użyjesz transmisji UDP, aby wykryć inteligentną pralkę.

Kliknij Nowa konfiguracja skanowania w sekcji Konfiguracja skanowania urządzeń, aby dodać nową konfigurację skanowania. Wybierz protokół UDP i podaj te atrybuty:

Pole

Opis

Sugerowana wartość

Adres rozgłoszeniowy

Adres rozgłoszeniowy UDP

255.255.255.255

Port nadawania

Port, na który Google Home wysyła transmisję UDP

3311

Port nasłuch

Port, w którym Google Home nasłuchuje odpowiedzi

3312

Pakiet wykrywania

Ładunek danych transmisji UDP

48656c6c6f4c6f63616c486f6d6553444b

4777bf63c53b6858.png

Na koniec kliknij Zapisz u góry okna, by opublikować zmiany.

6. Wdrażanie lokalnej realizacji zamówień

Aplikację do realizacji lokalnej oferty będziesz tworzyć w języku TypeScript, korzystając z pakietu pisania lokalnego pakietu SDK Home. Spójrz na szkielet udostępniony w projekcie startowym:

local/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));

Podstawowym elementem realizacji lokalnej jest klasa smarthome.App. Projekt startowy dołącza moduły obsługi intencji IDENTIFY i EXECUTE, a następnie wywołuje metodę listen(), aby poinformować pakiet SDK Local Home o tym, że aplikacja jest gotowa.

Dodaj moduł IDENTIFY

Pakiet SDK Local Home aktywuje moduł obsługi IDENTIFY, gdy urządzenie Google Home wykryje niezweryfikowane urządzenia w sieci lokalnej na podstawie konfiguracji skanowania dostępnej w Konsoli Actions.

W tym czasie, gdy Google znajdzie pasujące urządzenie, wywołuje polecenie identifyHandler z wynikowymi danymi skanowania. W Twojej aplikacji skanowanie odbywa się przy użyciu transmisji UDP, a dane skanowania przekazywane do modułu obsługi IDENTIFY obejmują ładunek odpowiedzi wysłany przez urządzenie lokalne.

Moduł obsługi zwraca instancję IdentifyResponse zawierającą unikalny identyfikator urządzenia lokalnego. Dodaj ten kod do metody identifyHandler, aby przetworzyć odpowiedź UDP z urządzenia lokalnego i ustalić odpowiedni lokalny identyfikator urządzenia:

local/index .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);
}

Pamiętaj, że pole verificationId musi odpowiadać jednej z wartości otherDeviceIds w odpowiedzi SYNC, co oznacza, że urządzenie jest dostępne do realizacji lokalnej na głównym wykresie użytkownika. Gdy Google znajdzie dopasowanie, uznajemy to urządzenie za zweryfikowane i gotowe do realizacji lokalnej.

Dodawanie modułu obsługi EXECUTE

Pakiet SDK aplikacji Local Home aktywuje moduł obsługi EXECUTE, gdy urządzenie, które obsługuje realizację lokalną, otrzyma polecenie. Zawartość intencji lokalnej jest odpowiednikiem intencji EXECUTE wysłanej do realizacji w chmurze, więc logika lokalnego przetwarzania intencji przypomina sposób obsługi intencji w chmurze.

Do komunikacji z urządzeniami lokalnymi aplikacja może używać gniazd TCP/UDP lub żądań HTTP(S). W ramach tego ćwiczenia w programowaniu protokół HTTP służy do sterowania urządzeniem wirtualnym. Numer portu jest zdefiniowany w index.ts jako zmienna SERVER_PORT.

Dodaj ten kod do metody executeHandler, aby przetwarzać przychodzące polecenia i wysyłać je na urządzenie lokalne przez HTTP:

local/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);
    });
}

Skompilowanie aplikacji TypeScript

Przejdź do katalogu local/ i uruchom te polecenia, aby pobrać kompilator TypeScript i skompilować aplikację:

cd local
npm install
npm run build

Spowoduje to skompilowanie źródła index.ts (TypeScript) i umieszczenie tej treści w katalogu public/local-home/:

  • bundle.js – skompilowane dane wyjściowe JavaScriptu zawierające aplikację lokalną i zależności.
  • index.html – lokalna strona hostująca służąca do wyświetlania aplikacji na potrzeby testowania na urządzeniu.

Wdrażanie projektu testowego

Wdróż zaktualizowane pliki projektu w Hostingu Firebase, aby mieć do nich dostęp z urządzenia Google Home.

firebase deploy --only hosting

7. Uruchom inteligentną pralkę

Teraz możesz przetestować komunikację między lokalną aplikacją do realizacji zamówień a inteligentną pralką. Projekt startowy ćwiczeń z programowania zawiera v inteligentną myjkę napisaną w Node.js, która symuluje inteligentną pralkę, którą użytkownicy mogą sterować lokalnie.

Skonfiguruj urządzenie

Musisz skonfigurować urządzenie wirtualne tak, aby używało tych samych parametrów UDP, które zostały zastosowane do konfiguracji skanowania na potrzeby wykrywania urządzeń w Konsoli Actions. Musisz też wskazać urządzeniu wirtualnemu lokalny identyfikator urządzenia, który ma być raportowany, oraz identyfikator projektu Akcje, który ma być używany w przypadku zdarzeń Stanu raportu w przypadku zmiany stanu urządzenia.

Parametr

Sugerowana wartość

deviceId

deviceid123

discoveryPortOut

3311

discoveryPacket

HelloLocalHomeSDK

projectId

Identyfikator projektu w Actions

Uruchom urządzenie

Przejdź do katalogu virtual-device/ i uruchom skrypt urządzenia, przekazując parametry konfiguracji jako argumenty:

cd virtual-device
npm install
npm start -- \
  --deviceId=deviceid123 --projectId=<project-id> \
  --discoveryPortOut=3311 --discoveryPacket=HelloLocalHomeSDK

Sprawdź, czy skrypt urządzenia działa z oczekiwanymi parametrami:

(...): UDP Server listening on 3311
(...): Device listening on port 3388
(...): Report State successful

8. Debugowanie aplikacji TypeScript

W kolejnej sekcji sprawdzisz, czy urządzenie Google Home może prawidłowo skanować, rozpoznawać i wysyłać polecenia do wirtualnej pralki przez sieć lokalną. Za pomocą Narzędzi dla programistów Google Chrome możesz połączyć się z urządzeniem Google Home, przeglądać dzienniki konsoli i debugować aplikację TypeScript.

Łączenie Narzędzi deweloperskich w Chrome

Aby połączyć debuger z lokalną aplikacją do realizacji zamówień, wykonaj te czynności:

  1. Sprawdź, czy Twoje urządzenie Google Home zostało połączone z użytkownikiem mającym uprawnienia dostępu do projektu w Konsoli Actions.
  2. Zrestartuj urządzenie Google Home, aby uzyskać adres URL Twojego kodu HTML oraz konfigurację skanowania umieszczoną w Konsoli Actions.
  3. Uruchom Chrome na komputerze, na którym pracujesz.
  4. Otwórz nową kartę Chrome i wpisz chrome://inspect w polu adresu, aby uruchomić inspektora.

Na stronie powinna być widoczna lista urządzeń, a adres URL aplikacji powinien pojawić się pod nazwą Twojego urządzenia Google Home.

567f97789a7d8846.png

Uruchom inspektora

Kliknij Zbadaj pod adresem URL aplikacji, aby uruchomić Narzędzia dla programistów w Chrome. Wybierz kartę Console (Konsola) i sprawdź, czy widać treść intencji IDENTIFY drukowaną przez Twoją aplikację TypeScript.

6b67ded470a4c8be.png

Te dane oznaczają, że lokalna aplikacja do realizacji zamówień została pomyślnie wykryta i zidentyfikowana urządzenie wirtualne.

Testowanie realizacji lokalnej

Wysyłaj polecenia głosowe na urządzenie Google Home za pomocą sterowania dotykowego w aplikacji Google Home, na przykład:

„OK Google, włącz pralkę”.

„OK Google, włącz pralkę”.

„OK Google, zatrzymaj pralkę”.

Powinno to aktywować przez platformę wysłanie intencji EXECUTE do Twojej aplikacji TypeScript.

bc030517dacc3ac9.png

Sprawdź, czy przy każdym poleceniu widzisz zmianę stanu lokalnej inteligentnej pralki.

...
***** The washer is RUNNING *****
...
***** The washer is STOPPED *****

9. Gratulacje

764dbc83b95782a.png

Gratulacje! Udało Ci się użyć pakietu SDK Local Home do zintegrowania realizacji zamówień lokalnych z akcją inteligentnego domu.

Więcej informacji

Oto kilka dodatkowych czynności, które możesz wypróbować:

  • Zmień konfigurację skanowania i zadbaj o jej działanie. Na przykład spróbuj użyć innego portu UDP lub pakietu wykrywania.
  • Zmodyfikuj bazę kodu urządzeń wirtualnych, aby uruchamiała się na wbudowanym urządzeniu – takim jak Raspberry Pi – i wizualizowała bieżący stan za pomocą diod LED lub wyświetlacza.