Smart-Home-Aktionen optimieren und sichern

1. Hinweis

Bei Smart-Home-Aktionen werden Gerätetypen verwendet, um Google Assistant mitzuteilen, welche Grammatik auf einem Gerät verwendet werden soll. Mit Geräte-Traits werden die Funktionen eines Gerätetyps definiert. Geräte übernehmen den Status jeder Geräteeigenschaft, die einer Aktion hinzugefügt wird.

dc8dce0dea87cd5c.png

Du kannst alle unterstützten Traits mit dem ausgewählten Gerätetyp verbinden, um die Funktionen der Nutzer anzupassen Geräte. Wenn du in deinen Aktionen benutzerdefinierte Traits implementieren möchtest, die derzeit nicht im Geräteschema verfügbar sind, lassen die Traits Modi und Umschalten bestimmte Einstellungen zu. durch einen von Ihnen definierten Namen.

Neben der grundlegenden Steuerungsfunktion, die durch Typen und Merkmale ermöglicht wird, bietet die Smart Home API zusätzliche Funktionen, die die Nutzerfreundlichkeit verbessern. Fehlerantworten liefern detailliertes Nutzerfeedback, wenn Intents nicht erfolgreich sind. Durch die sekundäre Nutzerbestätigung werden die Antworten erweitert und die Geräteeigenschaft Ihrer Wahl sicherer. Durch das Senden bestimmter Fehlerantworten auf Herausforderungen, die von Assistant ausgegeben werden, benötigt deine Smart-Home-Aktion möglicherweise eine zusätzliche Autorisierung, um einen Befehl auszuführen.

Vorbereitung

Aufgaben

In diesem Codelab stellen Sie eine vordefinierte Smart-Home-Integration mit Firebase bereit und lernen dann, der Smart-Home-Waschmaschine nicht standardmäßige Eigenschaften für die Ladegröße und den Turbomodus hinzuzufügen. Außerdem implementieren Sie Fehler- und Ausnahmeberichte und lernen, wie Sie mithilfe einer sekundären Nutzerbestätigung eine mündliche Bestätigung erzwingen, um die Waschmaschine einzuschalten.

Lerninhalte

  • So fügst du deiner Aktion die Traits für Modi und Ein/Aus-Schaltfläche hinzu
  • Fehler und Ausnahmen melden
  • Sekundäre Nutzerbestätigung anwenden

Voraussetzungen

2. Erste Schritte

Aktivitätseinstellungen aktivieren

Wenn Sie Google Assistant verwenden möchten, müssen Sie bestimmte Aktivitätsdaten mit Google teilen. Google Assistant benötigt diese Daten, um richtig zu funktionieren. Die Anforderung zum Teilen von Daten gilt jedoch nicht speziell 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-Schalter müssen aktiviert sein:

  • Web- und App-Aktivitäten: Klicken Sie außerdem das Kästchen Auch den Chrome-Verlauf sowie Aktivitäten auf Websites, in Apps und auf Geräten berücksichtigen, die Google-Dienste nutzen an.
  • Geräteinformationen
  • Sprach- und Audioaktivitäten

Actions-Projekt erstellen

  1. Rufen Sie die Actions on Google Developer Console auf.
  2. Klicken Sie auf Neues Projekt, geben Sie einen Namen für das Projekt ein und klicken Sie auf PROJEKT ERSTELLEN.

3d6b68ca79afd54c.png

Wähle die Smart Home App aus.

Wählen Sie in der Actions Console auf dem Bildschirm „Übersicht“ die Option Smart Home aus.

2fa4988f44f8914b.png

Wählen Sie die Karte Smart Home aus und klicken Sie auf Mit dem Erstellen beginnen. Sie werden dann zur Projektkonsole weitergeleitet.

Firebase CLI installieren

Mit der Firebase-Befehlszeile (Command Line Interface, CLI) können Sie Ihre Web-Apps lokal bereitstellen und Ihre Web-App für Firebase Hosting bereitstellen.

Führen Sie den folgenden npm-Befehl über das Terminal aus, um die Befehlszeile zu installieren:

npm install -g firebase-tools

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

firebase --version

Autorisieren Sie die Firebase CLI mit Ihrem Google-Konto, indem Sie folgenden Befehl ausführen:

firebase login

HomeGraph API aktivieren

Die HomeGraph API ermöglicht die Speicherung und Abfrage von Geräten und deren Status im Home Graph eines Nutzers. Wenn du diese API verwenden möchtest, musst du zuerst die Google Cloud Console öffnen und die HomeGraph API aktivieren.

Wähle in der Google Cloud Console das Projekt aus, das deinen Aktionen entspricht <project-id>.. Klicke 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 Startprojekt 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 Entwicklungscomputer herunterzuladen:

Oder Sie klonen das GitHub-Repository über die Befehlszeile:

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

Entpacken Sie die heruntergeladene ZIP-Datei.

Über das Projekt

Das Startprojekt enthält die folgenden Unterverzeichnisse:

  • public: Eine Front-End-Benutzeroberfläche zum einfachen Steuern und Überwachen des Status der intelligenten Waschmaschine.
  • functions: Ein vollständig implementierter Cloud-Dienst, der die intelligente Waschmaschine mit Cloud Functions for Firebase und Firebase Realtime Database verwaltet.

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

  • fakeauth: Autorisierungsendpunkt für die Kontoverknüpfung
  • faketoken: Tokenendpunkt für die Kontoverknüpfung
  • smarthome: Endpunkt für die Smart-Home-Intent-Ausführung
  • reportstate: Ruft bei Änderungen des Gerätestatus die Home Graph API auf
  • requestsync::Ermöglicht Updates für Nutzergeräte, ohne dass das Konto neu verknüpft werden muss

Mit Firebase verbinden

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

cd washer-start
firebase use <project-id>

Firebase-Projekt konfigurieren

Initialisieren Sie ein Firebase-Projekt.

firebase init

Wählen Sie die CLI-Funktionen, Realtime Database, Functions und das Hosting-Feature aus, das Firebase Hosting enthält.

? 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

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

Initialisieren Sie Realtime Database, 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 Startcode des Projekts verwenden, wählen Sie die Standarddatei für die Sicherheitsregeln aus und achten Sie darauf, dass Sie die vorhandene Datenbankregeldatei 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

Falls 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 der Funktionen die Standarddateien und achten Sie darauf, dass Sie die vorhandenen Dateien index.js und package.json im Projektbeispiel nicht überschreiben.

? 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 No (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

Konfigurieren Sie abschließend Ihre Hosting-Einrichtung so, dass im Projektcode das Verzeichnis public verwendet wird, und verwenden Sie die vorhandene Datei index.html. Wählen Sie No (Nein) aus, wenn Sie gefragt werden, ob Sie ESLint verwenden möchten.

? 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

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

  1. Gehen Sie über die grafische Benutzeroberfläche zum Ordner ../functions unter dem Projekt, wählen Sie die versteckte Datei .eslintrc.js aus und löschen Sie sie. Verwechseln Sie ihn nicht mit dem ähnlich benannten .eslintrc.json.
  2. Über die Befehlszeile:
    cd functions
    rm .eslintrc.js
    

In Firebase bereitstellen

Nachdem Sie nun die Abhängigkeiten installiert und das Projekt konfiguriert haben, können Sie die Anwendung 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 Webanwendung zusammen mit mehreren Cloud Functions for Firebase bereitgestellt.

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

5845443e94705557.png

Diese Web-UI stellt eine Drittanbieterplattform zum Ansehen oder Ändern des Gerätestatus dar. Klicken Sie auf AKTUALISIEREN, um die Datenbank mit Geräteinformationen zu füllen. Auf der Seite sind keine Änderungen zu sehen, aber der aktuelle Status der Waschmaschine wird in der Datenbank gespeichert.

Verbinden Sie nun den von Ihnen bereitgestellten Cloud-Dienst über die Actions Console mit Google Assistant.

Actions Console-Projekt konfigurieren

Gehen Sie unter Übersicht > Erstellen Sie eine Aktion und wählen Sie Aktion(en) hinzufügen aus. Geben Sie die URL der Cloud Functions-Funktion ein, die die Ausführung für die Smart-Home-Intents ermöglicht, und klicken Sie auf Save (Speichern).

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

9d7b223427f587ca.png

Klicken Sie auf der Seite Entwickeln > Aufruf, fügen Sie einen Anzeigenamen für Ihre Aktion hinzu und klicken Sie auf Speichern. Dieser Name wird in der Google Home App angezeigt.

774d0c40c351c7da.png

a8c4673eb11d76ee.png

Um die Kontoverknüpfung zu aktivieren, wählen Sie die Option Entwickeln > Kontoverknüpfung. Folgende Einstellungen für die Kontoverknüpfung verwenden:

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

9730d20b90bcc038.png

Klicken Sie auf Speichern, um die Konfiguration der Kontoverknüpfung zu speichern. Klicken Sie dann auf Testen, um Tests für Ihr Projekt zu aktivieren.

ee0547f05b5efd98.png

Du wirst zum Simulator weitergeleitet. Wenn die Option Test now enabled (Jetzt testen) nicht angezeigt wird, klicken Sie auf Reset Test (Test zurücksetzen), um zu prüfen, ob das Testen aktiviert ist.

d0495810dbadf059.png

Damit du deine Smart-Home-Aktion testen kannst, musst du dein Projekt mit einem Google-Konto verknüpfen. So können Tests über Google Assistant-Oberflächen und die Google Home App durchgeführt werden, 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 Konsole.
  2. Rufen Sie Google Assistant > Einstellungen > Smart-Home-Steuerung (unter „Assistant“).
  3. Klicken Sie oben rechts auf das Suchsymbol.
  4. Verwenden Sie das Präfix [test], um nach Ihrer Test-App zu suchen.
  5. Wählen Sie das Element aus. Google Assistant authentifiziert sich dann bei deinem Dienst und sendet eine SYNC-Anfrage, in der der Dienst aufgefordert wird, eine Liste der Geräte für den Nutzer bereitzustellen.

Öffnen Sie die Google Home App und prüfen Sie, ob Sie die Waschmaschine sehen können.

ae252220753726f6.png

Prüfen Sie, ob Sie die Waschmaschine per Sprachbefehl in der Google Home App steuern können. Die Änderung des Gerätestatus sollte auch in der Front-End-Web-UI Ihrer Cloud-Auftragsausführung angezeigt werden.

Nachdem du nun eine einfache Waschmaschine bereitgestellt hast, kannst du die auf deinem Gerät verfügbaren Modi anpassen.

4. Mobilitätsformen hinzufügen

Mit dem Trait action.devices.traits.Modes kann auf einem Gerät eine beliebige Anzahl von Einstellungen für einen Modus festgelegt werden, von denen jeweils nur eine festgelegt werden kann. Sie fügen der Waschmaschine einen Modus hinzu, um die Wäschekapazität festzulegen: klein, mittel oder groß.

SYNC-Antwort aktualisieren

Du musst deiner SYNC-Antwort in functions/index.js Informationen zum neuen Trait hinzufügen. Diese Daten werden im traits-Array und im attributes-Objekt angezeigt, wie im folgenden Code-Snippet gezeigt.

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 den 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 Ihre 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 Lasteinstellung 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 Aktion bereitzustellen:

firebase deploy --only functions

Rufen Sie nach Abschluss der Bereitstellung die Web-UI auf und klicken Sie in der Symbolleiste auf die Schaltfläche Aktualisieren ae8d3b25777a5e30.png. Dadurch wird eine Anfragesynchronisierung ausgelöst und Assistant erhält die aktualisierten SYNC-Antwortdaten.

bf4f6a866160a982.png

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

„Hey Google, stell die Ladung der Waschmaschine auf die höchste Stufe.“

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

„Hey Google, wie viel Ladung hat die Waschmaschine?“

5. Ein-/Aus-Schaltflächen hinzufügen

Das Trait action.devices.traits.Toggles steht für benannte Aspekte eines Geräts, die einen wahren oder falschen Zustand haben, z. B. ob sich die Waschmaschine im Turbomodus befindet.

SYNC-Antwort aktualisieren

In deiner SYNC-Antwort musst du Informationen zur neuen Geräteeigenschaft angeben. Er erscheint im traits-Array und attributes-Objekt, wie im folgenden Code-Snippet gezeigt.

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 den 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

Schließlich müssen Sie Ihre QUERY-Antwort aktualisieren, um den Turbomodus der Waschmaschine zu melden. Fügen Sie die aktualisierten Änderungen an den Funktionen queryFirebase und queryDevice hinzu, um die Ein/Aus-Schaltfläche aus der Realtime Database zu erhalten.

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 an 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 Anfragesynchronisierung auszulösen.

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

„Hey Google, schalte den Turbo für die Waschmaschine ein.“

Sie können auch prüfen, ob sich Ihre Waschmaschine bereits im Turbomodus befindet, indem Sie Folgendes fragen:

„Hey Google, ist meine Waschmaschine im Turbomodus?“

6. Fehler und Ausnahmen melden

Mit der Fehlerbehandlung in deiner Smart-Home-Aktion kannst du Nutzer melden, wenn Probleme dazu führen, dass Antworten von EXECUTE und QUERY fehlschlagen. Die Benachrichtigungen schaffen eine positivere User Experience für deine Nutzer, wenn sie mit deinem Smart-Home-Gerät und deiner Aktion interagieren.

Jedes Mal, wenn eine EXECUTE- oder QUERY-Anfrage fehlschlägt, sollte die Aktion einen Fehlercode zurückgeben. Wenn Sie beispielsweise einen Fehler ausgeben möchten, wenn ein Nutzer versucht, die Waschmaschine bei geöffnetem Deckel zu starten, würde die 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 mit Folgendem:

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

Ausnahmen ähneln Fehlern, geben jedoch an, wenn einem Befehl eine Benachrichtigung zugeordnet ist. Dies kann eine erfolgreiche Ausführung blockieren oder auch nicht. Eine Ausnahme kann zugehörige Informationen mit dem Trait „StatusReport“ liefern, z. B. der Akkustand oder die letzte Statusänderung. Nicht blockierende Ausnahmecodes werden mit dem Status SUCCESS zurückgegeben, während Ausnahmen für die Blockierung mit dem Status EXCEPTIONS zurückgegeben werden.

Eine Beispielantwort mit einer Ausnahme befindet sich 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"
      }
    }]
  }
}

Assistant antwortet, indem er Folgendes sagt:

„Die Waschmaschine ist fertig.“

Um Fehlerberichte für Ihre Waschmaschine hinzuzufügen, öffnen Sie functions/index.js und fügen Sie die Definition der Fehlerklasse hinzu, wie im folgenden Code-Snippet gezeigt:

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 „execute“-Antwort, 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( ... )
          //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;
            }
          })
      );
    }
  }
}

Assistant kann Ihre Nutzer jetzt über jeden Fehlercode informieren, den Sie melden. Ein konkretes Beispiel sehen Sie im nächsten Abschnitt.

7. Sekundäre Nutzerbestätigung hinzufügen

Du solltest die sekundäre Nutzerbestätigung in deiner Aktion implementieren, wenn dein Gerät Modi hat, die geschützt werden müssen oder auf eine bestimmte Gruppe autorisierter Nutzer beschränkt sein sollten, z. B. ein Softwareupdate oder die Deaktivierung des Schlosses.

Sie können die sekundäre Nutzerbestätigung für alle Gerätetypen und ‐merkmale implementieren und anpassen, ob die Sicherheitsmaßnahme jedes Mal auftritt oder bestimmte Kriterien erfüllt werden müssen.

Es gibt drei unterstützte Arten von Herausforderungen:

  • No challenge: Eine Anfrage und Antwort, für die keine Authentifizierung erforderlich ist (dies ist das Standardverhalten)
  • ackNeeded: Eine sekundäre Nutzerbestätigung, die eine ausdrückliche Bestätigung erfordert (Ja oder Nein)
  • 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-Abfrage hinzu und geben Sie an, dass ein Fehler zurückgegeben wird, wenn die sekundäre Bestätigung fehlschlägt.

Öffnen Sie functions/index.js und fügen Sie eine Fehlerklassendefinition hinzu, die den Fehlercode und die Art der Herausforderung zurückgibt, wie im folgenden Code-Snippet gezeigt:

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 Fehler challengeNeeded 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( ... )
          .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 ausdrückliche 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, Ihre Waschmaschine ein- oder auszuschalten. Beispiel:

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

Der Google Assistant: „Bist du sicher, dass du die Waschmaschine einschalten möchtest?“

Ich: „Ja.“

Eine detaillierte Antwort für jeden Schritt des sekundären Nutzerbestätigungsvorgangs finden Sie in Ihren Firebase-Protokollen.

289dbe48f4bb8106.png

8. Glückwunsch

674c4f4392e98c1.png

Glückwunsch! Du hast die Funktionen von Smart-Home-Aktionen durch die Traits Modes und Toggles erweitert und deren Ausführung mit einer sekundären Nutzerbestätigung gesichert.

Weitere Informationen

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

  • Fügen Sie Ihren Geräten Funktionen zur lokalen Ausführung hinzu.
  • Verwenden Sie eine andere Art der Identitätsbestätigung, um den Gerätestatus zu ändern.
  • Aktualisieren Sie die QUERY-Antwort für das Trait „RunCycle“ so, dass sie dynamisch aktualisiert wird.
  • Sehen Sie sich dieses GitHub-Beispiel an.