Smart-Home-Aktionen optimieren und sichern

1. Hinweis

Smart-Home-Aktionen verwenden Gerätetypen, um Google Assistant mitzuteilen, welche Grammatik auf dem Gerät verwendet werden soll. Geräte-Traits definieren die Funktionen eines Gerätetyps. Ein Gerät übernimmt den Status jeder Geräte-Trait, die einer Aktion hinzugefügt wurde.

dc8dce0dea87cd5c.png

Du kannst alle unterstützten Traits mit dem von dir ausgewählten Gerätetyp verknüpfen, um die Funktionalität der Geräte deiner Nutzer anzupassen. Wenn du in deinen Aktionen benutzerdefinierte Traits implementieren möchtest, die im Geräteschema derzeit nicht verfügbar sind, kannst du mit den Traits Modi und Ein/Aus bestimmte Einstellungen mit einem benutzerdefinierten Namen steuern.

Neben den grundlegenden Steuerungsfunktionen der verschiedenen Typen und Merkmale bietet die Smart Home API weitere Funktionen, die die Nutzerfreundlichkeit verbessern. Fehlerantworten liefern detailliertes Nutzerfeedback, wenn Intents nicht erfolgreich sind. Die sekundäre Nutzerbestätigung erweitert diese Antworten und bietet zusätzlichen Schutz für die Geräteeigenschaft deiner Wahl. Wenn du bestimmte Fehlerantworten an Aufgabenblöcke von Assistant sendest, kann für deine Smart-Home-Aktion eine zusätzliche Autorisierung erforderlich sein, um einen Befehl auszuführen.

Voraussetzungen

Aufgaben

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

Lerninhalte

  • Modi und Ein/Aus-Schaltfläche für Traits zu deiner Aktion hinzufü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 zum Teilen von Daten ist jedoch nicht spezifisch für das SDK. Wenn Sie diese Daten freigeben möchten, erstellen Sie ein Google-Konto, falls Sie noch keines haben. Dabei kann es sich um ein beliebiges Google-Konto handeln. Dabei muss es sich nicht um ein Entwicklerkonto handeln.

Öffnen Sie die Seite Aktivitätseinstellungen des Google-Kontos, das Sie mit Assistant verwenden möchten.

Die folgenden Schieberegler müssen aktiviert sein:

  • Web- & App-Aktivitäten: Sie müssen das Kästchen Auch den Chrome-Verlauf sowie Aktivitäten auf Websites, in Apps und auf Geräten berücksichtigen, die Google-Dienste nutzen anklicken.
  • Geräteinformationen
  • Sprach- & 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

Die Smart-Home App auswählen

Wählen Sie in der Actions Console auf dem Übersichtsbildschirm die Option Smart Home aus.

2fa4988f44f8914b.png

Wähle die Karte Smart Home aus und klicke auf Jetzt erstellen. Du wirst dann zur Projektkonsole weitergeleitet.

Firebase CLI installieren

Mit der Firebase-Befehlszeile können Sie Ihre Webanwendungen 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

Prüfen Sie mit dem folgenden Befehl, 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 das Speichern und Abfragen von Geräten und deren Status in Home Graph eines Nutzers. 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 mit Ihren Aktionen übereinstimmt. <project-id>.. Klicken Sie dann im Bildschirm „API-Bibliothek“ für die HomeGraph API auf Aktivieren.

ee198858a6eac112.png

3. Starte-App ausführen

Nachdem Sie die 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 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 Startprojekt enthält die folgenden Unterverzeichnisse:

  • public: Eine Front-End-Benutzeroberfläche zur einfachen Steuerung und Überwachung 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-Auftragsausführung
  • reportstate::Die Home Graph API wird bei Änderungen des Gerätestatus aufgerufen.
  • requestsync: Ermöglicht Updates von Nutzergeräten, 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 Befehlszeilen-Funktionen Echtzeitdatenbank, Funktionen und Hosting aus, die Firebase Hosting enthalten.

? 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 für Ihr Projekt erforderlichen APIs und Funktionen 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 Code des Startprojekts verwenden, wählen Sie die Standarddatei für die Sicherheitsregeln aus und achten Sie darauf, dass Sie die vorhandene Datei mit den 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

Bei der Konfiguration von Functions sollten Sie die Standarddateien verwenden und 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 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 und die vorhandene Datei index.html verwendet werden. Wählen Sie 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 Benutzeroberfläche zum Ordner ../functions unter dem Projekt, wählen Sie die ausgeblendete Datei .eslintrc.js aus und löschen Sie sie. Verwechseln Sie ihn nicht mit .eslintrc.json, der ähnlich heißt.
  2. Über die Befehlszeile:
    cd functions
    rm .eslintrc.js
    

In Firebase bereitstellen

Nachdem Sie nun die Abhängigkeiten installiert und Ihr 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 werden eine Webanwendung sowie mehrere Cloud Functions for Firebase-Funktionen bereitgestellt.

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

5845443e94705557.png

Diese Web-UI stellt eine Drittanbieterplattform dar, mit der Gerätestatus angezeigt oder geändert werden können. Klicken Sie auf AKTUALISIEREN, um Geräteinformationen in Ihre Datenbank zu übertragen. Sie werden zwar keine Änderungen auf der Seite sehen, der aktuelle Status der Waschmaschine wird jedoch in der Datenbank gespeichert.

Als Nächstes verbinden Sie den von Ihnen bereitgestellten Cloud-Dienst über die Actions Console mit Google Assistant.

Actions Console-Projekt konfigurieren

Wählen Sie unter Übersicht > Aktion erstellen die Option Aktion(en) hinzufügen aus. Geben Sie die URL für die Cloud Functions-Funktion ein, die die Auftragsausführung für die Smart-Home-Intents bereitstellt. Klicken Sie dann auf Speichern.

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

9d7b223427f587ca.png

Fügen Sie auf dem Tab Develop > Invocation einen Anzeigenamen für Ihre Aktion hinzu und klicken Sie auf Save (Speichern). Dieser Name wird in der Google Home App angezeigt.

774d0c40c351c7da.png

a8c4673eb11d76ee.png

Wählen Sie im linken Navigationsbereich die Option Entwickeln > Kontoverknüpfung aus, um die Kontoverknüpfung zu aktivieren. Verwenden Sie diese Einstellungen zur 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

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

Sie werden zum Simulator weitergeleitet. Wenn Test jetzt aktiviert nicht angezeigt wird, klicken Sie auf 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. Dies ermöglicht Tests über Google Assistant-Oberflächen und die Google Home App, 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. Gehen Sie zu Google Assistant > Einstellungen > Smart-Home-Steuerung (unter „Assistant“).
  3. Klicken Sie rechts oben auf das Suchsymbol.
  4. Sie können mithilfe des Präfixes [test] nach Ihrer Test-App suchen.
  5. Wählen Sie das Element aus. Google Assistant authentifiziert sich dann bei deinem Dienst und sendet eine SYNC-Anfrage, in der dein Dienst dem Nutzer eine Liste der Geräte zur Verfügung stellt.

Ö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 mithilfe von Sprachbefehlen in der Google Home App steuern können. Außerdem sollten Sie die Änderung des Gerätestatus in der Frontend-Web-UI Ihrer Cloud-Auftragsausführung sehen können.

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

4. Mobilitätsformen hinzufügen

Mit der Trait 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. Fügen Sie der Waschmaschine einen Modus hinzu, um die Größe der Wäsche zu definieren: klein, mittel oder groß.

SYNC-Antwort aktualisieren

Du musst deiner SYNC-Antwort in functions/index.js Informationen über die neue 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 im Intent EXECUTE den Befehl action.devices.commands.SetModes hinzu, 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, damit Assistant die aktualisierten SYNC-Antwortdaten erhält.

bf4f6a866160a982.png

Jetzt können Sie einen Befehl geben, um den Modus der Waschmaschine festzulegen, z. B.:

„Hey Google, stell die Ladung der Waschmaschine auf groß.“

Zusätzlich können Sie Fragen zu Ihrer Waschmaschine stellen, zum Beispiel:

„Hey Google, wie voll ist die Waschmaschine?“

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

Die Eigenschaft action.devices.traits.Toggles steht für benannte Aspekte eines Geräts, die entweder richtig oder falsch sind, z. B. ob sich die Waschmaschine im Turbomodus befindet.

SYNC-Antwort aktualisieren

In deiner SYNC-Antwort musst du Informationen über die neue Geräteeigenschaft hinzufügen. Er wird 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',
          '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 im Intent EXECUTE den Befehl action.devices.commands.SetToggles hinzu, 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 musst du deine QUERY-Antwort aktualisieren, 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 Ein/Aus-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,
    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 abschließend Ihre reportstate-Funktion, damit Home Graph gemeldet wird, 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, schalte den Turbosensor 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 Nutzern melden, wenn Probleme dazu führen, dass EXECUTE- und QUERY-Antworten fehlschlagen. Die Benachrichtigungen schaffen eine positivere Nutzererfahrung bei der Interaktion mit Ihrem Smart-Home-Gerät und Ihrer Aktion.

Jedes Mal, wenn eine EXECUTE- oder QUERY-Anfrage fehlschlägt, sollte deine Aktion einen Fehlercode zurückgeben. Wenn Sie beispielsweise eine Fehlermeldung ausgeben 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 jetzt ein Nutzer darum bittet, die Waschmaschine zu starten, antwortet Assistant so:

„Der Deckel der Waschmaschine ist offen. Schließen Sie sie und versuchen Sie es noch einmal.“

Ausnahmen ähneln Fehlern, geben jedoch an, wenn eine Benachrichtigung mit einem Befehl verknüpft ist, was die erfolgreiche Ausführung verhindern kann oder nicht. Über eine Ausnahme können zugehörige Informationen mithilfe des Merkmals StatusReport bereitgestellt werden, z. B. der Akkustand oder die letzte Statusänderung. Nicht blockierende Ausnahmecodes werden mit dem Status SUCCESS zurückgegeben, während blockierende Ausnahmecodes mit dem Status EXCEPTIONS zurückgegeben werden.

Das folgende Code-Snippet enthält eine Beispielantwort mit einer Ausnahme:

{
  "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.“

Wenn Sie Fehlerberichte für Ihre Waschmaschine hinzufügen möchten, öffnen Sie functions/index.js und fügen Sie die Fehlerklassendefinition 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 über Modi verfügt, die gesichert werden müssen oder auf eine bestimmte Gruppe autorisierter Nutzer beschränkt sein sollten, z. B. Softwareupdate oder Sperre aufheben.

Du kannst die sekundäre Nutzerbestätigung auf allen Gerätetypen und Eigenschaften implementieren und dabei festlegen, ob die Sicherheitsmaßnahme jedes Mal auftritt oder ob bestimmte Kriterien erfüllt werden müssen.

Es gibt drei unterstützte Arten der Identitätsbestätigung:

  • No challenge: Eine Anfrage und Antwort ohne Identitätsbestätigung (Standardeinstellung).
  • ackNeeded: Eine sekundäre Nutzerbestätigung, die eine explizite 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 eine ackNeeded-Abfrage zum Befehl zum Einschalten der Waschmaschine hinzu und geben Sie die Funktion an, mit der eine Fehlermeldung 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 den Aufgabentyp 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;
  }
}

Sie müssen auch 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 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, Ihre Waschmaschine ein- oder auszuschalten:

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

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

Du: „Ja.“

Eine detaillierte Antwort zu jedem Schritt der sekundären Nutzerbestätigung finden Sie in den Firebase-Logs.

289dbe48f4bb8106.png

8. Glückwunsch

674c4f4392e98c1.png

Glückwunsch! Du hast die Funktionen von Smart-Home-Aktionen über die Traits Modes und Toggles erweitert und ihre Ausführung durch eine sekundäre Nutzerbestätigung gesichert.

Weitere Informationen

Hier sind einige Ideen, die Sie umsetzen können, um tiefer ins Detail zu gehen:

  • Fügen Sie Ihren Geräten Funktionen zur lokalen Ausführung hinzu.
  • Verwende eine andere Art der sekundären Identitätsbestätigung, um den Gerätestatus zu ändern.
  • Aktualisiere die QUERY-Antwort des Trait RunCycle so, dass sie dynamisch aktualisiert wird.
  • Sehen Sie sich dieses GitHub-Beispiel an.