Cloud-zu-Cloud-Integrationen optimieren und schützen

1. Hinweis

Bei Cloud-to-Cloud-Integrationen werden Gerätetypen verwendet, damit Google Assistant weiß, welche Grammatik für ein Gerät verwendet werden soll. Geräte-Traits definieren die Funktionen eines Gerätetyps. Ein Gerät übernimmt die Status der einzelnen Gerätetraits, die einer Integration hinzugefügt werden.

dc8dce0dea87cd5c.png

Sie können alle unterstützten Traits mit dem ausgewählten Gerätetyp verbinden, um die Funktionen der Geräte Ihrer Nutzer anzupassen. Wenn Sie benutzerdefinierte Traits in Ihren Actions implementieren möchten, die derzeit nicht im Geräteschema verfügbar sind, können Sie mit den Traits Modes und Toggles bestimmte Einstellungen mit einem benutzerdefinierten Namen steuern, den Sie definieren.

Über die grundlegenden Steuerungsmöglichkeiten hinaus, die durch Typen und Eigenschaften bereitgestellt werden, bietet die Smart Home API zusätzliche Funktionen zur Verbesserung der Nutzerfreundlichkeit. Fehlerantworten enthalten detailliertes Nutzerfeedback, wenn Intents nicht erfolgreich sind. Die sekundäre Nutzerbestätigung erweitert diese Antworten und bietet zusätzliche Sicherheit für das von dir ausgewählte Geräteattribut. Wenn Sie bestimmte Fehlerantworten auf Challenge-Blöcke senden, die vom Assistant ausgegeben werden, kann für Ihre Cloud-to-Cloud-Integration eine zusätzliche Autorisierung erforderlich sein, um einen Befehl auszuführen.

Vorbereitung

Aufgaben

In diesem Codelab stellen Sie eine vorgefertigte Smart-Home-Integration mit Firebase bereit und erfahren dann, wie Sie dem Smart-Home-Waschtrockner nicht standardmäßige Merkmale für die Beladungsgröße und den Turbomodus hinzufügen. Außerdem implementieren Sie die Fehler- und Ausnahmeberichterstattung und erfahren, wie Sie eine mündliche Bestätigung erzwingen, um die Waschmaschine mithilfe der sekundären Nutzerbestätigung einzuschalten.

Lerninhalte

  • Modi- und Ein/Aus-Merkmale in Ihre Integration einfügen
  • Fehler und Ausnahmen melden
  • Sekundäre Nutzerbestätigung anwenden

Voraussetzungen

2. Erste Schritte

Aktivitätseinstellungen aktivieren

Damit Sie Google Assistant nutzen können, müssen Sie bestimmte Aktivitätsdaten mit Google teilen. Google Assistant benötigt diese Daten, um richtig zu funktionieren. Die Anforderung, Daten freizugeben, ist jedoch nicht spezifisch für das SDK. Wenn Sie diese Daten teilen möchten, erstellen Sie ein Google-Konto, falls Sie noch keines haben. Sie können ein beliebiges Google-Konto verwenden. Es muss nicht Ihr Entwicklerkonto sein.

Öffnen Sie die Seite „Aktivitätseinstellungen“ für das Google-Konto, das Sie mit Assistant verwenden möchten.

Die folgenden Ein/Aus-Schaltflächen müssen aktiviert sein:

  • Web- & App-Aktivitäten: Setzen Sie außerdem ein Häkchen bei Auch den Chrome-Verlauf sowie Aktivitäten auf Websites, in Apps und auf Geräten berücksichtigen, die Google-Dienste nutzen.
  • Geräteinformationen
  • Sprach- und Audioaktivitäten

Cloud-zu-Cloud-Integrationsprojekt erstellen

  1. Rufen Sie die Entwicklungskonsole auf.
  2. Klicken Sie auf Projekt erstellen, geben Sie einen Namen für das Projekt ein und klicken Sie auf Projekt erstellen.

Projekt benennen

Cloud-zu-Cloud-Integration auswählen

Wählen Sie in der Developer Console auf der Projekthomepage unter Cloud-to-Cloud die Option Cloud-to-Cloud-Integration hinzufügen aus.

Cloud-zu-Cloud-Integration hinzufügen

Firebase CLI installieren

Mit der Firebase-Befehlszeile (CLI) können Sie Ihre Web-Apps lokal bereitstellen und in Firebase Hosting bereitstellen.

Führen Sie den folgenden npm-Befehl im Terminal aus, um die CLI zu installieren:

npm install -g firebase-tools

Führen Sie folgenden Befehl aus, um zu prüfen, ob die CLI korrekt installiert wurde:

firebase --version

Autorisieren Sie das Firebase CLI mit Ihrem Google-Konto, indem Sie Folgendes ausführen:

firebase login

Firebase zu Ihrem Google Home Developer Console-Projekt hinzufügen

Methode 1: Über die Firebase Console

  1. Rufen Sie Firebase auf.
  2. Klicken Sie auf Firebase-Projekt erstellen.
    Firebase-Projekt erstellen
  3. Klicken Sie auf dem Bildschirm Projekt erstellen auf Firebase dem Google Cloud-Projekt hinzufügen.
    Firebase zu Google Cloud-Projekt hinzufügen
  4. Wählen Sie auf dem Bildschirm Erste Schritte das Google Cloud-Projekt aus, das Sie gerade in der Google Home Developer Console erstellt haben, und klicken Sie dann auf Weiter.
    Google Cloud-Projekt auswählen

Methode 2: Über die Firebase CLI

firebase projects:addfirebase

Wählen Sie das Google Home Developer Console-Projekt aus, das Sie gerade erstellt haben, um Firebase hinzuzufügen.

Wenn Firebase Ihrem Google Home Developer Console-Projekt hinzugefügt wird, wird es in der Firebase Console angezeigt. Die Projekt-ID des Firebase-Projekts entspricht der Projekt-ID Ihres Google Home Developer Console-Projekts.

Cloud-Projekt hinzugefügt

HomeGraph API aktivieren

Mit der HomeGraph API können Geräte und ihre Status im Home Graph eines Nutzers gespeichert und abgefragt werden. Wenn Sie diese API verwenden möchten, müssen Sie zuerst die Google Cloud Console öffnen und die HomeGraph API aktivieren.

Wählen Sie in der Google Cloud Console das Projekt aus, das Ihren Aktionen entspricht <firebase-project-id>. Klicken Sie dann auf dem Bildschirm „API-Bibliothek“ für die HomeGraph API auf Aktivieren.

ee198858a6eac112.png

3. Start-App ausführen

Nachdem Sie Ihre Entwicklungsumgebung eingerichtet haben, können Sie das Starterprojekt bereitstellen, um zu prüfen, ob alles richtig konfiguriert ist.

Quellcode abrufen

Klicken Sie auf den folgenden Link, um das Beispiel für dieses Codelab auf Ihren Entwicklercomputer herunterzuladen:

… oder Sie können das GitHub-Repository über die Befehlszeile klonen:

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

Entpacken Sie die heruntergeladene ZIP-Datei.

Über das Projekt

Das Starter-Projekt enthält die folgenden Unterverzeichnisse:

  • public: Eine Frontend-Benutzeroberfläche, mit der sich der Status der smarten Waschmaschine einfach steuern und überwachen lässt.
  • functions: Ein vollständig implementierter Clouddienst, der die intelligente Waschmaschine mit Cloud Functions for Firebase und Firebase Realtime Database verwaltet.

Die bereitgestellte Cloud-Ausführung umfasst die folgenden Funktionen in index.js:

  • fakeauth: Autorisierungsendpunkt für die Kontoverknüpfung
  • faketoken: Tokenendpunkt für die Kontoverknüpfung
  • smarthome: Smart-Home-Intent-Fulfillment-Endpunkt
  • reportstate: Ruft die Home Graph API bei Änderungen des Gerätestatus auf.
  • requestsync: Ermöglicht die Aktualisierung von Nutzergeräten, ohne dass eine erneute Kontoverknüpfung erforderlich ist.

Mit Firebase verknüpfen

Rufen Sie das Verzeichnis washer-start auf und richten Sie die Firebase CLI mit Ihrem Integrationsprojekt ein:

cd washer-start
firebase use <project-id>

Firebase-Projekt konfigurieren

Ein Firebase-Projekt initialisieren

firebase init

Wählen Sie die CLI-Funktionen Realtime Database und Functions aus.

? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter
 to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to
 proceed)
>( ) Data Connect: Set up a Firebase Data Connect service
 ( ) Firestore: Configure security rules and indexes files for Firestore
 ( ) Genkit: Setup a new Genkit project with Firebase
 (*) Functions: Configure a Cloud Functions directory and its files
 ( ) App Hosting: Configure an apphosting.yaml file for App Hosting
 ( ) Hosting: Configure files for Firebase Hosting and (optionally) 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
 (*) Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision
default instance
 ( ) Data Connect: Set up a Firebase Data Connect service
 ( ) Firestore: Configure security rules and indexes files for Firestore

Dadurch werden die erforderlichen APIs und Funktionen für Ihr Projekt initialisiert.

Initialisieren Sie die Echtzeitdatenbank, wenn Sie dazu aufgefordert werden. Sie können den Standardspeicherort für die Datenbankinstanz verwenden.

? 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

Da Sie den Code des Starterprojekts verwenden, wählen Sie die Standarddatei für die Sicherheitsregeln aus und achten Sie darauf, dass Sie die vorhandene Datei mit Datenbankregeln nicht überschreiben.

? 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

Wenn Sie Ihr Projekt neu initialisieren, wählen Sie Überschreiben aus, wenn Sie gefragt werden, ob Sie eine Codebasis initialisieren oder überschreiben möchten.

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

Verwenden Sie beim Konfigurieren Ihrer Funktionen die Standarddateien und achten Sie darauf, dass die vorhandenen Dateien index.js und package.json im Projektbeispiel nicht überschrieben werden.

? 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

Wenn Sie Ihr Projekt neu initialisieren, wählen Sie Nein aus, wenn Sie gefragt werden, ob Sie „functions/.gitignore“ initialisieren oder überschreiben möchten.

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

Wenn ESLint versehentlich aktiviert wurde, gibt es zwei Möglichkeiten, es zu deaktivieren:

  1. Rufen Sie in der Benutzeroberfläche den Ordner ../functions im Projekt auf, wählen Sie die verborgene Datei .eslintrc.js aus und löschen Sie sie. Verwechseln Sie es nicht mit dem ähnlich benannten .eslintrc.json.
  2. Befehlszeile verwenden:
    cd functions
    rm .eslintrc.js
    

In Firebase bereitstellen

Nachdem Sie die Abhängigkeiten installiert und Ihr Projekt konfiguriert haben, können Sie die App zum ersten Mal ausführen.

firebase deploy

Die Ausgabe der Konsole sollte so aussehen:

...

✔ Deploy complete!

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

Mit diesem Befehl wird eine Web-App zusammen mit mehreren Cloud Functions für Firebase bereitgestellt.

Öffnen Sie die Hosting-URL in Ihrem Browser (https://<firebase-project-id>.web.app), um die Web-App aufzurufen. Die folgende Benutzeroberfläche wird angezeigt:

5845443e94705557.png

Diese Web-UI ist eine Drittanbieterplattform, auf der Gerätestatus angezeigt oder geändert werden kann. Klicken Sie auf AKTUALISIEREN, um die Datenbank mit Geräteinformationen zu füllen. Auf der Seite werden keine Änderungen angezeigt, der aktuelle Status Ihrer Waschmaschine wird jedoch in der Datenbank gespeichert.

Jetzt müssen Sie den Cloud-Dienst, den Sie bereitgestellt haben, über die Entwicklerkonsole mit Google Assistant verbinden.

Developer Console-Projekt konfigurieren

Fügen Sie auf dem Tab Entwickeln einen Anzeigenamen für Ihre Interaktion hinzu. Dieser Name wird in der Google Home App angezeigt.

Anzeigenamen hinzufügen

Laden Sie unter App-Branding eine png-Datei für das App-Symbol mit den Abmessungen 144 × 144 Pixel und dem Namen .png hoch.

App-Symbol hinzufügen

So aktivieren Sie die Kontoverknüpfung:

Client-ID

ABC123

Clientschlüssel

DEF456

Autorisierungs-URL

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

Token-URL

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

URLs für die Kontoverknüpfung aktualisieren

Geben Sie unter Cloud-Ausführungs‑URL die URL für Ihre Cloud-Funktion ein, die die Ausführung für die Smart-Home-Intents bereitstellt.

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

Cloud Functions-URL hinzufügen

Klicken Sie auf Speichern, um die Projektkonfiguration zu speichern, und dann auf Weiter: Test, um Tests für Ihr Projekt zu aktivieren.

Cloud-zu-Cloud-Integration testen

Jetzt können Sie mit der Implementierung der Webhooks beginnen, die erforderlich sind, um den Gerätestatus mit Assistant zu verbinden.

Um deine Cloud-to-Cloud-Integration zu testen, musst du dein Projekt mit einem Google-Konto verknüpfen. So können Sie über Google Assistant-Oberflächen und die Google Home App testen, die im selben Konto angemeldet sind.

  1. Öffnen Sie auf Ihrem Smartphone die Google Assistant-Einstellungen. Sie sollten mit demselben Konto angemeldet sein wie in der Console.
  2. Gehe zu Google Assistant > Einstellungen > Smart-Home-Steuerung (unter „Assistant“).
  3. Klicken Sie oben rechts auf das Suchsymbol.
  4. Suchen Sie mit dem Präfix [test] nach Ihrer Test-App.
  5. Wählen Sie das Element aus. Google Assistant authentifiziert sich dann bei Ihrem Dienst und sendet eine SYNC-Anfrage, in der Ihr Dienst aufgefordert wird, eine Liste der Geräte für den Nutzer bereitzustellen.

Öffnen Sie die Google Home App und prüfen Sie, ob Ihre Waschmaschine angezeigt wird.

ae252220753726f6.png

Prüfe, ob du die Waschmaschine mit Sprachbefehlen in der Google Home App steuern kannst. Außerdem sollte sich der Gerätestatus in der Frontend-Web-UI deines Cloud-Fulfillment ändern.

Nachdem Sie eine einfache Waschmaschine bereitgestellt haben, können Sie die auf Ihrem Gerät verfügbaren Modi anpassen.

4. Modi hinzufügen

Mit dem Merkmal action.devices.traits.Modes kann ein Gerät eine beliebige Anzahl von Einstellungen für einen Modus haben, von denen jeweils nur eine festgelegt werden kann. Du fügst der Waschmaschine einen Modus hinzu, um die Größe der Wäscheladung festzulegen: klein, mittel oder groß.

SYNC-Antwort aktualisieren

Sie müssen Ihrer SYNC-Antwort in functions/index.js Informationen zum neuen Merkmal hinzufügen. Diese Daten werden im Array traits und im Objekt attributes angezeigt, wie im folgenden Code-Snippet zu sehen ist.

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

Neue EXECUTE-Intent-Befehle hinzufügen

Fügen Sie in Ihrem Intent EXECUTE den Befehl action.devices.commands.SetModes ein, wie im folgenden Code-Snippet gezeigt.

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-Antwort aktualisieren

Aktualisieren Sie als Nächstes die QUERY-Antwort, um den aktuellen Status der Waschmaschine zu melden.

Fügen Sie die aktualisierten Änderungen den Funktionen queryFirebase und queryDevice hinzu, um den in der Realtime Database gespeicherten Status abzurufen.

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

Berichtsstatus aktualisieren

Aktualisieren Sie schließlich die Funktion reportstate, um die aktuelle Beladungseinstellung der Waschmaschine an Home Graph zu melden.

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

In Firebase bereitstellen

Führen Sie den folgenden Befehl aus, um die aktualisierte Integration bereitzustellen:

firebase deploy --only functions

Rufen Sie nach Abschluss der Bereitstellung die Weboberfläche auf und klicken Sie in der Symbolleiste auf die Schaltfläche Aktualisieren ae8d3b25777a5e30.png. Dadurch wird eine Synchronisierung angefordert, damit Assistant die aktualisierten SYNC-Antwortdaten erhält.

bf4f6a866160a982.png

Jetzt können Sie einen Befehl zum Festlegen des Modus der Waschmaschine geben, z. B.:

„Hey Google, stelle die Waschmaschinenladung auf ‚groß‘ ein.“

Außerdem können Sie Fragen zu Ihrer Waschmaschine stellen, z. B.:

„Hey Google, wie viel Wäsche ist in der Waschmaschine?“

5. Ein/Aus-Schalter hinzufügen

Das Merkmal action.devices.traits.Toggles stellt benannte Aspekte eines Geräts dar, die einen „Wahr“- oder „Falsch“-Status haben, z. B. ob sich die Waschmaschine im Turbomodus befindet.

SYNC-Antwort aktualisieren

Fügen Sie in Ihrer SYNC-Antwort Informationen zum neuen Gerätetyp hinzu. Sie wird im Array traits und im Objekt attributes angezeigt, wie im folgenden Code-Snippet dargestellt.

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

Neue EXECUTE-Intent-Befehle hinzufügen

Fügen Sie in Ihrem Intent EXECUTE den Befehl action.devices.commands.SetToggles ein, wie im folgenden Code-Snippet gezeigt.

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-Antwort aktualisieren

Aktualisieren Sie schließlich Ihre QUERY-Antwort, um den Turbomodus der Waschmaschine zu melden. Fügen Sie die aktualisierten Änderungen den Funktionen queryFirebase und queryDevice hinzu, um den in der Realtime Database gespeicherten Umschaltstatus abzurufen.

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

Berichtsstatus aktualisieren

Aktualisieren Sie schließlich die Funktion reportstate, um Home Graph zu melden, ob die Waschmaschine auf „Turbo“ eingestellt ist.

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

In Firebase bereitstellen

Führen Sie den folgenden Befehl aus, um die aktualisierten Funktionen bereitzustellen:

firebase deploy --only functions

Klicken Sie in der Web-UI auf die Schaltfläche Aktualisieren ae8d3b25777a5e30.png, um nach Abschluss der Bereitstellung eine Synchronisierung anzufordern.

Sie können jetzt einen Befehl geben, um die Waschmaschine in den Turbomodus zu versetzen, indem Sie Folgendes sagen:

„Hey Google, stelle die Waschmaschine auf den Turbomodus.“

Sie können auch fragen, ob sich Ihre Waschmaschine bereits im Turbomodus befindet:

„Hey Google, läuft meine Waschmaschine im Turbomodus?“

6. Fehler und Ausnahmen melden

Durch die Fehlerbehandlung in Ihrer Cloud-zu-Cloud-Integration können Sie Nutzer informieren, wenn Probleme dazu führen, dass EXECUTE- und QUERY-Antworten fehlschlagen. Die Benachrichtigungen sorgen für eine bessere Nutzererfahrung, wenn Nutzer mit Ihrem Smart-Home-Gerät und Ihrer Integration interagieren.

Jedes Mal, wenn eine EXECUTE- oder QUERY-Anfrage fehlschlägt, sollte Ihre Integration einen Fehlercode zurückgeben. Wenn Sie beispielsweise einen Fehler auslösen möchten, wenn ein Nutzer versucht, die Waschmaschine bei geöffnetem Deckel zu starten, würde Ihre EXECUTE-Antwort so aussehen:

{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "456"
        ],
        "status": "ERROR",
        "errorCode": "deviceLidOpen"
      }
    ]
  }
}

Wenn ein Nutzer nun darum bittet, die Waschmaschine zu starten, antwortet Assistant:

„Der Deckel der Waschmaschine ist offen. Bitte schließe ihn und versuche es dann noch einmal.“

Ausnahmen ähneln Fehlern, geben aber an, wann ein Hinweis mit einem Befehl verknüpft ist, der die erfolgreiche Ausführung blockieren kann. Eine Ausnahme kann mithilfe des StatusReport-Traits zugehörige Informationen wie den Akkustand oder die letzte Zustandsänderung liefern. Nicht blockierende Ausnahmefehlercodes werden zusammen mit dem Status SUCCESS zurückgegeben, blockierende Ausnahmefehlercodes mit dem Status EXCEPTIONS.

Ein Beispiel für eine Antwort mit einer Ausnahme finden Sie im folgenden Code-Snippet:

{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [{
      "ids": ["123"],
      "status": "SUCCESS",
      "states": {
        "online": true,
        "isPaused": false,
        "isRunning": false,
        "exceptionCode": "runCycleFinished"
      }
    }]
  }
}

Der Assistent antwortet:

„Die Waschmaschine ist fertig.“

Wenn Sie die Fehlerberichterstattung für Ihre Waschmaschine hinzufügen möchten, öffnen Sie functions/index.js und fügen Sie die Definition der Fehlerklasse wie im folgenden Code-Snippet hinzu:

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

Aktualisieren Sie die Ausführungsantwort, um den Fehlercode und den Fehlerstatus zurückzugeben:

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(
        updateDevice(execution, device.id)
        .then((data) => {
          ...
        })
        //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;
          }
        })
      );
    }
  }
}

Der Assistant kann Ihren Nutzern jetzt alle Fehlercodes mitteilen, die Sie melden. Im nächsten Abschnitt finden Sie ein konkretes Beispiel.

7. Sekundäre Nutzerbestätigung hinzufügen

Sie sollten die Bestätigung des sekundären Nutzers in Ihre Integration einbauen, wenn Ihr Gerät Modi hat, die gesichert werden müssen oder auf eine bestimmte Gruppe autorisierter Nutzer beschränkt sein sollten, z. B. ein Softwareupdate oder das Entriegeln eines Schlosses.

Sie können die sekundäre Nutzerbestätigung für alle Gerätetypen und Merkmale implementieren und anpassen, ob die Sicherheitsabfrage jedes Mal oder nur bei bestimmten Kriterien erfolgen soll.

Es gibt drei unterstützte Arten von Sicherheitsmaßnahmen:

  • No challenge: Eine Anfrage und Antwort, bei der keine Authentifizierungs-Challenge verwendet wird (dies ist das Standardverhalten).
  • ackNeeded: Eine sekundäre Nutzerbestätigung, die eine ausdrückliche Bestätigung (Ja oder Nein) erfordert
  • pinNeeded: Eine sekundäre Nutzerbestätigung, für die eine persönliche Identifikationsnummer (PIN) erforderlich ist

Fügen Sie für dieses Codelab dem Befehl zum Einschalten der Waschmaschine eine ackNeeded-Herausforderung hinzu und implementieren Sie die Funktion, die einen Fehler zurückgibt, wenn die sekundäre Bestätigung fehlschlägt.

Öffnen Sie functions/index.js und fügen Sie eine Fehlerklassendefinition hinzu, die den Fehlercode und den Challenge-Typ zurückgibt, wie im folgenden Code-Snippet zu sehen ist:

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

Außerdem müssen Sie die Ausführungsantwort so aktualisieren, dass der challengeNeeded-Fehler wie folgt zurückgegeben wird:

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(

        updateDevice(execution, device.id)
        .then((data) => {
          ...
        })
        .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
              };
            }
          }
        })
      );
    }
  }
}

Ändern Sie schließlich updateDevice so, dass zum Ein- oder Ausschalten der Waschmaschine eine explizite Bestätigung erforderlich ist.

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

In Firebase bereitstellen

Führen Sie den folgenden Befehl aus, um die aktualisierte Funktion bereitzustellen:

firebase deploy --only functions

Nachdem Sie den aktualisierten Code bereitgestellt haben, müssen Sie die Aktion mündlich bestätigen, wenn Sie Assistant bitten, die Waschmaschine ein- oder auszuschalten. Beispiel:

Du : „Hey Google, schalte die Waschmaschine ein.“

Assistant : „Möchtest du die Waschmaschine wirklich einschalten?“

Ich : „Ja.“

Sie können auch eine detaillierte Antwort für jeden Schritt des sekundären Nutzerbestätigungsprozesses aufrufen, indem Sie Ihre Firebase-Logs öffnen.

289dbe48f4bb8106.png

8. Glückwunsch

674c4f4392e98c1.png

Glückwunsch! Sie haben die Funktionen von Cloud-to-Cloud-Integrationen über die Traits Modes und Toggles erweitert und die Ausführung durch die sekundäre Nutzerbestätigung gesichert.

Weitere Informationen

Hier sind einige Ideen, die Sie umsetzen können, um tiefer in die Materie einzutauchen: