Debugowanie lokalnego domu

1. Zanim zaczniesz

Integracja z inteligentnym domem umożliwia Asystentowi Google sterowanie połączonymi urządzeniami w domach użytkowników. Aby utworzyć działanie dla inteligentnego domu, musisz podać punkt końcowy webhooka w chmurze, który może obsługiwać intencje inteligentnego domu. Gdy na przykład użytkownik powie „OK Google, włącz światła”, Asystent wysyła polecenie do przetwarzania w chmurze, aby zaktualizować stan urządzenia.

Pakiet SDK Local Home zwiększa niezawodność integracji inteligentnego domu, dodając lokalną ścieżkę, po której intencje inteligentnego domu są kierowane bezpośrednio do urządzenia Google Home. Dzięki temu zwiększa się niezawodność i zmniejsza opóźnienie w przetwarzaniu poleceń użytkowników. Umożliwia ona pisanie i wdrażanie aplikacji do lokalnego przetwarzania w języku TypeScript lub JavaScript, która identyfikuje urządzenia i wykonuje polecenia na dowolnym głośniku Google Home lub inteligentnym ekranie Google Nest. Aplikacja komunikuje się wtedy bezpośrednio z dotychczasowymi urządzeniami użytkowników przez sieć lokalną, korzystając z dotychczasowych protokołów standardowych do wykonywania poleceń.

72ffb320986092c.png

Debugowanie działań w inteligentnym domu jest kluczowym krokiem w procesie tworzenia działań o jakości produkcyjnej, ale bez przydatnych i łatwych w użyciu narzędzi do rozwiązywania problemów i testowania może być trudne i czasochłonne. Aby ułatwić debugowanie działań w inteligentnym domu, Google Cloud Platform (GCP) udostępnia danelogowanie oraz pakiet testów dla inteligentnego domu, które pomogą Ci zidentyfikować i rozwiązać problemy z Twoimi działaniami.

Wymagania wstępne

Co utworzysz

W tym ćwiczeniu z programowania utworzysz lokalną realizację działań inteligentnego domu i połączysz ją z Asystentem, a potem przeprowadzisz debugowanie aplikacji Local Home za pomocą zestawu testów dla inteligentnego domu oraz funkcji raportowania i rejestrowania danych w Google Cloud Platform (GCP).

Czego się nauczysz

  • Jak korzystać ze wskaźników i logowania GCP do identyfikowania i rozwiązywania problemów produkcyjnych.
  • Jak za pomocą pakietu testów zidentyfikować problemy z funkcjonalnością i interfejsem API.
  • Jak korzystać z Narzędzi deweloperskich w Chrome podczas tworzenia aplikacji Local Home.

Czego potrzebujesz

2. Uruchamianie aplikacji pralki

Pobieranie kodu źródłowego

Aby pobrać na maszynę programistyczną przykładowy projekt tego ćwiczenia, kliknij ten link:

...lub możesz sklonować repozytorium GitHub z poziomu wiersza poleceń:

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

Informacje o projekcie

Aplikacja startowa zawiera podobne podkatalogi i funkcje w chmurze co kodlab Umożliwienie realizacji lokalnej dla działań w inteligentnym domu. Zamiast app-start mamy tu app-faulty. Zaczniemy od lokalnej aplikacji domowej, która działa, ale niezbyt dobrze.

Połącz się z Firebase

Użyjemy tego samego projektu, który został utworzony w ramach samouczka Włączanie lokalnego przetwarzania w ramach akcji dla urządzeń smart home, ale wdrożymy pliki pobrane w tym samouczku.

Przejdź do katalogu app-faulty, a potem skonfiguruj interfejs wiersza poleceń Firebase z projektem Asystenta utworzonym w ramach ćwiczenia Włączanie lokalnej realizacji działań Asystenta w inteligentnym domu:

$ cd app-faulty
$ firebase use <project-id>

Wdrażanie w Firebase

Otwórz folder app-faulty/functions i zainstaluj wszystkie niezbędne zależności za pomocą npm:

$ cd functions
$ npm install

Uwaga: jeśli zobaczysz komunikat poniżej, możesz go zignorować i kontynuować. Ostrzeżenie jest spowodowane niektórymi starszymi zależnościami. Więcej informacji znajdziesz tutaj.

found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

Aby pobrać kompilator TypeScript i skompilować aplikację, otwórz katalog app-faulty/local/ i uruchom te polecenia:

$ cd ../local
$ npm install
$ npm run build

Skompiluje to źródło index.ts (TypeScript) i umieści w katalogu app-faulty/public/local-home/ te pliki:

  • bundle.js – skompilowany kod JavaScript zawierający lokalną aplikację i zależne komponenty.
  • index.html – strona hostingu lokalnego używana do testowania aplikacji na urządzeniu.

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

$ firebase deploy

Dane wyjściowe konsoli powinny wyglądać tak:

...

✔ Deploy complete!

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

To polecenie wdraża aplikację internetową wraz z kilkoma funkcjami Cloud Functions dla Firebase.

Aktualizowanie HomeGraph

Otwórz adres URL hostingu w przeglądarce (https://<project-id>.web.app), aby wyświetlić aplikację internetową. W interfejsie internetowym kliknij przycisk Odśwież ae8d3b25777a5e30.png, aby zaktualizować HomeGraph za pomocą żądania synchronizacji z najnowszymi metadanymi urządzenia z wadliwej aplikacji do prania:

fa3c47f293cfe0b7.png

Otwórz aplikację Google Home i sprawdź, czy widzisz pralkę z nową nazwą „Awaria pralki”. Pamiętaj, aby przypisać urządzenie do pomieszczenia, w którym znajduje się urządzenie Nest.

2a082ee11d47ad1a.png

3. Włącz inteligentną pralkę

Jeśli masz już za sobą ćwiczenie Włączanie lokalnego działania dla działań inteligentnego domu, prawdopodobnie masz już uruchomioną wirtualną inteligentną pralkę. Jeśli się zatrzyma, uruchom ponownie urządzenie wirtualne.

Uruchomienie urządzenia

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

4. Testowanie lokalnej aplikacji Home

Wysyłanie poleceń do urządzenia za pomocą poleceń głosowych do urządzenia Google Home, takich jak:

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

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

„OK Google, włącz tryb lokalny”

„OK Google, zatrzymaj pralkę”.

Gdy spróbujesz sterować pralką po „wymuszeniu lokalnego”, Asystent Google odpowie: „Wygląda na to, że pralka Faulty nie jest obecnie dostępna”.

Oznacza to, że urządzenie jest niedostępne przez lokalną ścieżkę. Działo się tak przed wydaniem polecenia „Hej Google, użyj lokalnego adresu”, ponieważ w przypadku niedostępności urządzenia przez lokalny adres będziemy używać ścieżki w chmurze. Jednak po wybraniu opcji „Wymuś lokalnie” opcja korzystania z ścieżki w chmurze jest wyłączona.

Aby dowiedzieć się, na czym polega problem, użyjmy dostępnych narzędzi: DaneLogowanie Google Cloud Platform (GCP) oraz Narzędzia deweloperskie w Chrome.

5. Debugowanie aplikacji Home na urządzeniu

W tej sekcji użyjesz narzędzi dostarczonych przez Google, aby dowiedzieć się, dlaczego urządzenie nie jest dostępne za pomocą ścieżki lokalnej. Za pomocą narzędzi dla programistów Google Chrome możesz łączyć się z urządzeniem Google Home, wyświetlać dzienniki konsoli i debugować aplikację Local Home. Do Cloud Logging możesz też wysyłać dzienniki niestandardowe, aby otrzymywać informacje o najczęstszych błędach zgłaszanych przez użytkowników w aplikacji Local Home.

Łączenie z Narzędziami deweloperskimi w Chrome

Aby połączyć debuger z aplikacją do obsługi lokalnej, wykonaj te czynności:

  1. Upewnij się, że urządzenie Google Home jest połączone z użytkownikiem, który ma uprawnienia do korzystania z projektu Konsoli Asystenta.
  2. Zrestartuj urządzenie Google Home, aby umożliwić mu pobranie adresu URL pliku HTML oraz konfiguracji skanowania z konsoli Actions.
  3. Uruchom Chrome na komputerze programisty.
  4. Otwórz nową kartę w Chrome i w polu adresu wpisz chrome://inspect, aby uruchomić inspekcję.

Na stronie powinna wyświetlić się lista urządzeń, a adres URL aplikacji powinien być widoczny pod nazwą urządzenia Google Home.

567f97789a7d8846.png

Uruchamianie inspektora

Aby uruchomić Narzędzia deweloperskie w Chrome, kliknij Zbadaj pod adresem URL aplikacji. Wybierz kartę Konsola i sprawdź, czy widzisz zawartość intencji IDENTIFY wydrukowaną przez aplikację TypeScript.

774c460c59f9f84a.png

Te dane wyjściowe oznaczają, że moduł obsługi IDENTIFY został aktywowany, ale funkcja verificationId zwrócona w tabeli IdentifyResponse nie pasuje do żadnego z urządzeń na wykresie HomeGraph. Aby się tego dowiedzieć, dodajmy kilka niestandardowych dzienników.

Dodawanie niestandardowych logów

Pakiet SDK Local Home zwraca błąd DEVICE_VERIFICATION_FAILED, który nie pomaga w znalezieniu głównej przyczyny problemu. Dodajmy kilka dzienników niestandardowych, aby mieć pewność, że prawidłowo odczytujemy i przetwarzamy dane skanowania. Pamiętaj, że jeśli odrzucimy obietnicę z błędem, komunikat o błędzie zostanie również wysłany do Cloud Logging.

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.
  // Is there something wrong here?
  const localDeviceId = Buffer.from(scanData.data);
  console.log(`IDENTIFY handler: received local device id
      ${localDeviceId}`);

  // Add custom logs
  if (!localDeviceId.toString().match(/^deviceid[0-9]{3}$/gi)) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_device', 'Invalid device id from scan data ' +
        localDeviceId);
    return Promise.reject(err);
  }

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

Zmień też lokalną wersję aplikacji Home, abyśmy mogli sprawdzić, czy używasz prawidłowej wersji.

local/index.ts

const localHomeSdk = new App('1.0.1');

Po dodaniu niestandardowych dzienników musisz ponownie skompilować aplikację i ponownie ją wdrożyć w Firebase.

$ cd ../app-faulty/local
$ npm run build
$ firebase deploy --only hosting

Teraz zrestartuj urządzenie Google Home, by mogło wczytać zaktualizowaną lokalną aplikację ekranu głównego. To, czy urządzenie Google Home korzysta z oczekiwanej wersji, znajdziesz w dziennikach Konsoli w Narzędziach deweloperskich w Chrome.

ecc56508ebcf9ab.png

Otwieranie Cloud Logging

Zobacz, jak używać Cloud Logging do znajdowania błędów. Aby uzyskać dostęp do Cloud Logging w projekcie:

  1. W konsoli Cloud Platform otwórz stronę Projekty.
  2. Wybierz projekt inteligentnego domu.
  3. W sekcji Operacje wybierz Logowanie > Eksplorator logów.

Dostępem do danych logowania użytkowników projektu Actions zarządza się za pomocą Identity and Access Management (IAM). Więcej informacji o rolach i uprawnieniach dotyczących logowania danych znajdziesz w artykule o kontroli dostępu do Cloud Logging.

Korzystanie z filtrów zaawansowanych

Wiemy, że występują błędy w intencji IDENTIFY, ponieważ ścieżka lokalna nie działa, ponieważ nie można zidentyfikować lokalnego urządzenia. Chcemy jednak wiedzieć, na czym dokładnie polega problem, więc najpierw odfiltrujmy błędy występujące w obiekcie IDENTIFY.

Kliknij przełącznik Pokaż zapytanie, aby przełączyć go w pole Konstruktor zapytań. Wpisz jsonPayload.intent="IDENTIFY" w polu Konstruktor zapytań i kliknij przycisk Uruchom zapytanie.

4c0b9d2828ee2447.png

W efekcie otrzymujesz wszystkie dzienniki błędów wygenerowane w obiekcie IDENTIFY. Następnie rozwiń ostatni błąd. W modułu obsługi IDENTIFY znajdziesz parametry errorCodedebugString, które zostały ustawione podczas odrzucania obietnicy.

71f2f156c6887496.png

debugString wynika, że identyfikator lokalnego urządzenia ma nieprawidłowy format. Aplikacja Lokalna Home oczekuje identyfikatora urządzenia lokalnego w postaci ciągu znaków zaczynającego się od deviceid, po którym następują 3 cyfry, ale lokalny identyfikator urządzenia jest w tym przypadku ciągiem szesnastkowym.

Naprawianie błędu

Wracając do kodu źródłowego, w którym analizujemy identyfikator lokalnego urządzenia na podstawie danych ze skanowania, zauważamy, że podczas konwertowania ciągu na bajty nie podano kodowania. Dane skanowania są odbierane jako ciąg szesnastkowy, więc podczas wywoływania funkcji Buffer.from() należy podać kodowanie znaków hex.

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');
  console.log(`IDENTIFY handler: received local device id
      ${localDeviceId}`);

  if (!localDeviceId.toString().match(/^deviceid[0-9]{3}$/gi)) {
    const err = new IntentFlow.HandlerError(request.requestId,
      'invalid_device', 'Invalid device id from scan data ' +
      localDeviceId);
    return Promise.reject(err);
  }

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

Zmień też lokalną wersję aplikacji Home, abyśmy mogli sprawdzić, czy używasz prawidłowej wersji.

local/index.ts

const localHomeSdk = new App('1.0.2');

Po naprawieniu błędu skompiluj aplikację i ponownie wdroń ją na Firebase. W app-faulty/local uruchom:

$ npm run build
$ firebase deploy --only hosting

Przetestuj rozwiązanie

Po wdrożeniu zrestartuj urządzenie Google Home, aby załadować zaktualizowaną lokalną aplikację domową. Upewnij się, że wersja lokalnej aplikacji domowej to 1.0.2. Tym razem w konsoli Chrome DevTools nie powinno być żadnych błędów.

c8456f7b5f77f894.png

Teraz możesz spróbować ponownie wysłać polecenia do urządzenia.

„OK Google, włącz tryb lokalny”.

„OK Google, zatrzymaj pralkę”.

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

„OK Google, ustaw domyślnie”.

6. Uruchamianie zestawu testów urządzeń inteligentnego domu

Po zweryfikowaniu urządzenia za pomocą elementów sterujących dotykowych w aplikacji Google Home lub poleceń głosowych możesz użyć automatycznego pakietu testów dla domu inteligentnego, aby sprawdzić przypadki użycia na podstawie typów urządzeń i właściwości powiązanych z Twoim działaniem. Pakiet testów przeprowadza serię testów w celu wykrycia problemów w Twoim działaniu i wyświetla komunikaty informacyjne o nieudanych przypadkach testowych, aby przyspieszyć debugowanie przed zapoznaniem się z dziennikami zdarzeń.

Uruchamianie pakietu testów inteligentnego domu

Aby przetestować swoje działanie dotyczące inteligentnego domu za pomocą Test Suite:

  1. W przeglądarce otwórz Test Suite for smart home.
  2. Zaloguj się w Google, klikając przycisk w prawym górnym rogu. Dzięki temu pakiet testów może wysyłać polecenia bezpośrednio do Asystenta Google.
  3. W polu Identyfikator projektu wpisz identyfikator projektu swojego działania dotyczącego inteligentnego domu. Aby kontynuować, kliknij DALEJ.
  4. Na etapie Test Settings (Ustawienia testu) w sekcji Devices and Trais (Urządzenia i ślady) powinna wyświetlić się pralka Faulty Washer.
  5. Wyłącz opcję Testuj synchronizację żądań, ponieważ przykładowa aplikacja do prania nie ma interfejsu użytkownika umożliwiającego dodawanie, usuwanie ani zmianę nazwy pralki. W systemie produkcyjnym musisz aktywować żądanie synchronizacji za każdym razem, gdy użytkownik doda, usunie lub zmieni nazwę urządzenia.
  6. Pozostaw włączoną opcję Local Home SDK, ponieważ będziemy testować ścieżki lokalne i w chmurze.
  7. Aby rozpocząć testowanie, kliknij Dalej: środowisko testowe.

67433d9190fa770e.png

Po zakończeniu testów zauważysz, że testy wstrzymywania i wznawiania w ścieżce lokalnej kończą się niepowodzeniem, a testy w ścieżce w chmurze przechodzą.

d1ebd5cfae2a2a47.png

Analizowanie komunikatu o błędzie

Sprawdź komunikaty o błędach w nieudanych przypadkach testowych. i informują, jaki jest stan oczekiwany i rzeczywisty. W tym przypadku stan oczekiwany dla „Wstrzymaj pranie” to isPaused: true, ale rzeczywisty stan to isPaused: false. Podobnie w przypadku „Wstrzymaj pranie” oczekiwany stan to isPaused: true, ale uzyskaliśmy stan isPaused: false.

6bfd3acef9c16b84.png

Z komunikatów o błędach wynika, że na ścieżce lokalnej odwrotnie ustawiamy stan isPaused.

Zidentyfikowanie i naprawienie błędu

Znajdź kod źródłowy, w którym aplikacja Local Home wysyła polecenie wykonania do urządzenia. getDataCommand() to funkcja wywoływana przez executeHandler() w celu ustawienia wartości payload w poleceniu wykonania wysyłanym do urządzenia.

local/index.ts

getDataForCommand(command: string, params: IWasherParams): unknown {
    switch (command) {
        case 'action.devices.commands.OnOff':
            return {
                on: params.on ? true : false
            };
        case 'action.devices.commands.StartStop':
            return {
                isRunning: params.start ? true : false
            };
        case 'action.devices.commands.PauseUnpause':
            return {
                // Is there something wrong here?
                isPaused: params.pause ? false : true
            };
        default:
            console.error('Unknown command', command);
            return {};
    }
}

Ustawienie isPause jest odwrotne, powinno być true, gdy params.pause ma wartość true, a w przeciwnym razie – false. Naprawmy to.

local/index.ts

getDataForCommand(command: string, params: IWasherParams): unknown {
    switch (command) {
        case 'action.devices.commands.OnOff':
            return {
                on: params.on ? true : false
            };
        case 'action.devices.commands.StartStop':
            return {
                isRunning: params.start ? true : false
            };
        case 'action.devices.commands.PauseUnpause':
            return {
                isPaused: params.pause ? true : false
            };
        default:
            console.error('Unknown command', command);
            return {};
    }
}

Zmień lokalną wersję aplikacji domowej, abyśmy mogli sprawdzić, czy używamy prawidłowej wersji.

local/index.ts

const localHomeSdk = new App('1.0.3');

Pamiętaj, aby ponownie skompilować aplikację i ponownie wdrożyć ją w Firebase. W app-faulty/local wykonaj te czynności:

$ npm run build
$ firebase deploy --only hosting

Teraz uruchom ponownie urządzenie Google Home, aby załadować zaktualizowaną lokalną aplikację domową. Upewnij się, że wersja lokalnej aplikacji domowej to 1.0.3.

Testowanie poprawki

Teraz ponownie uruchom zestaw testów dla inteligentnego domu z tymi samymi konfiguracjami. Zobaczysz, że wszystkie przypadki testowe zostały zaliczone.

b7fc8c5d3c727d8d.png

7. Gratulacje

764dbc83b95782a.png

Gratulacje! Wiesz już, jak rozwiązywać problemy z aplikacją Google Home na urządzeniu lokalnym za pomocą pakietu testów dla inteligentnych urządzeń domowych i zapisów w chmurze.

Więcej informacji

Oto kilka dodatkowych rozwiązań, które możesz wypróbować:

Możesz też dowiedzieć się więcej o testowaniu i przesyłaniu działania do sprawdzenia, w tym o procesie certyfikacji, który umożliwia opublikowanie działania dla użytkowników.