Um die lokale Auftragsausführung zu unterstützen, müssen Sie eine App für diese Smart-Home-Intents:
IDENTIFY
: Unterstützt die Erkennung lokal steuerbarer Smart-Home-Geräte. Die Intent-Handler extrahiert Daten, die dein Smart-Home-Gerät während der Erkennung zurückgibt und als Antwort an Google gesendet.EXECUTE
: Unterstützt die Ausführung von Befehlen.QUERY
: Unterstützt die Abfrage des Gerätestatus.REACHABLE_DEVICES
(optional): Unterstützt die Erkennung lokal steuerbarer Elemente hinter einem Hub- oder Bridge-Gerät.
Diese App wird auf den Google Home- oder Google Nest-Geräten des Nutzers ausgeführt und verbindet Ihr Smart-Home-Gerät mit Assistent. Sie können die App mit TypeScript (bevorzugt) oder JavaScript erstellen.
TypeScript wird empfohlen, weil Sie Bindungen um statisch sicherzustellen, dass die von Ihrer App zurückgegebenen Daten den Typen entsprechen, die die Plattform erwartet.
Weitere Informationen zur API finden Sie in der Local Home SDK API-Referenz
Die folgenden Snippets zeigen, wie Sie die App für die lokale Auftragsausführung initialisieren und Ihre Handler anhängen.
<ph type="x-smartling-placeholder">import App = smarthome.App; const localHomeApp: App = new App("1.0.0"); localHomeApp .onIdentify(identifyHandler) .onExecute(executeHandler) .listen() .then(() => { console.log("Ready"); });
import App = smarthome.App; const localHomeApp: App = new App("1.0.0"); localHomeApp .onIdentify(identifyHandler) .onReachableDevices(reachableDevicesHandler) .onExecute(executeHandler) .listen() .then(() => { console.log("Ready"); });
Projekt erstellen
Damit Sie Ihre lokale App für die Auftragsausführung bereitstellen können, müssen Sie ein JavaScript-Bundle erstellen. für Ihren Code und alle zugehörigen Abhängigkeiten.
Verwenden Sie das Projekt der lokalen App für die Auftragsausführung Initialisierer Zum Bootstrapping der geeigneten Projektstruktur mit Ihrem bevorzugten Bundler Konfiguration.
Projektvorlagen
Um Ihre Bundler-Konfiguration auszuwählen, führen Sie den Befehl npm init
aus, wie in der
folgende Beispiele:
TypeScript ohne Bundler-Konfiguration:
npm init @google/local-home-app project-directory/ --bundler none
Projektstruktur:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json └── serve.js
Ersetzen Sie project-directory durch ein neues Verzeichnis, das den Projekt für die lokale Auftragsausführung.
TypeScript mit Webpack-Bundler Konfiguration:
npm init @google/local-home-app project-directory/ --bundler webpack
Projektstruktur:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json ├── webpack.config.web.js ├── webpack.config.node.js └── serve.js
Ersetzen Sie project-directory durch ein neues Verzeichnis, das den Projekt für die lokale Auftragsausführung.
TypeScript mit Rollup Bundler-Konfiguration:
npm init @google/local-home-app project-directory/ --bundler rollup
Projektstruktur:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json ├── rollup.config.js └── serve.js
Ersetzen Sie project-directory durch ein neues Verzeichnis, das den Projekt für die lokale Auftragsausführung.
TypeScript mit Parcel Bundler-Konfiguration:
npm init @google/local-home-app project-directory/ --bundler parcel
Projektstruktur:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json └── serve.js
Ersetzen Sie project-directory durch ein neues Verzeichnis, das den Projekt für die lokale Auftragsausführung.
Häufige Aufgaben auf Projektebene ausführen
Das generierte Projekt unterstützt die folgende npm-Funktion Skripts:
<ph type="x-smartling-placeholder">cd project-directory/ npm run build
Dieses Skript kompiliert die TypeScript-Quelle und bündelt Ihre App mit ihren Abhängigkeiten für die Chrome-Laufzeitumgebung im Unterverzeichnis dist/web
und die Node.js-Laufzeitumgebung im Unterverzeichnis dist/node
.
cd project-directory/ npm run lint npm run compile npm test
Dieses Skript überprüft die Syntax Ihres TypeScript-Codes, kompiliert ihn, ohne eine Ausgabe im Unterverzeichnis dist/
zu erzeugen, und führt automatisierte Tests über test.ts
aus.
cd project-directory/ npm run start
Während der Entwicklung stellt dieses Skript Ihre App Bundles für die Chrome- und Node.js-Laufzeitumgebungen lokal bereit.
IDENTIFY-Handler implementieren
Der IDENTIFY
-Handler wird ausgelöst, wenn das Google Home- oder Google Nest-Gerät neu startet und
nicht verifizierte lokale Geräte erkennt, einschließlich Endgeräten, die mit einem Hub verbunden sind. Die
Die Local Home-Plattform sucht anhand der Scankonfigurationsinformationen nach lokalen Geräten
und rufen Sie den IDENTIFY
-Handler mit den Scanergebnissen auf.
Die
IdentifyRequest
von der Local Home-Plattform, enthält die Scandaten eines
LocalIdentifiedDevice
Instanz. Basierend auf der Scankonfiguration wird nur eine device
-Instanz ausgefüllt
der das Gerät gefunden hat.
Wenn die Scanergebnisse mit Ihrem Gerät übereinstimmen, sollte der IDENTIFY
-Handler eine
IdentifyResponsePayload
-Objekt, das ein device
-Objekt mit
Smart-Home-Metadaten (z. B. Typen, Eigenschaften und Berichtsstatus)
Google stellt eine Geräteverknüpfung her, wenn
Der verificationId
aus der IDENTIFY
-Antwort stimmt mit einem der
otherDeviceIds
-Werte, die von der SYNC
-Antwort zurückgegeben werden.
Beispiel
Die folgenden Snippets veranschaulichen, wie Sie IDENTIFY
-Handler für
eigenständige Geräte bzw. Hub-Integrationen.
const identifyHandler = (request: IntentFlow.IdentifyRequest): IntentFlow.IdentifyResponse => { // Obtain scan data from protocol defined in your scan config const device = request.inputs[0].payload.device; if (device.udpScanData === undefined) { throw Error("Missing discovery response"); } const scanData = device.udpScanData.data; // Decode scan data to obtain metadata about local device const verificationId = "local-device-id"; // Return a response const response: IntentFlow.IdentifyResponse = { intent: Intents.IDENTIFY, requestId: request.requestId, payload: { device: { id: device.id || "", verificationId, // Must match otherDeviceIds in SYNC response }, }, }; return response; };
const identifyHandler = (request: IntentFlow.IdentifyRequest): IntentFlow.IdentifyResponse => { // Obtain scan data from protocol defined in your scan config const device = request.inputs[0].payload.device; if (device.udpScanData === undefined) { throw Error("Missing discovery response"); } const scanData = device.udpScanData.data; // Decode scan data to obtain metadata about local device const proxyDeviceId = "local-hub-id"; // Return a response const response: IntentFlow.IdentifyResponse = { intent: Intents.IDENTIFY, requestId: request.requestId, payload: { device: { id: proxyDeviceId, isProxy: true, // Device can control other local devices isLocalOnly: true, // Device not present in `SYNC` response }, }, }; return response; };
Geräte hinter einem Hub erkennen
Wenn Google ein Hub-Gerät erkennt, wird dieser als Conduit betrachtet. mit den verbundenen Endgeräten des Hubs und versuchen Sie, diese zu bestätigen.
So kann Google prüfen, ob ein Hub-Gerät vorhanden ist:
für Ihren IDENTIFY
-Handler:
- Wenn Ihre
SYNC
-Antwort die IDs lokaler Endgeräte meldet, die mit demisProxy
true
imIdentifyResponsePayload
- Wenn deine
SYNC
-Antwort dein Hub-Gerät nicht meldet, richteisLocalOnly
alstrue
in derIdentifyResponsePayload
- Das Feld
device.id
enthält die lokale Geräte-ID für das Hub-Gerät selbst.
REACHABLE_devices-Handler implementieren (nur Hub-Integrationen)
Der Intent REACHABLE_DEVICES
wird von Google gesendet, um zu bestätigen, auf welchen Endgeräten
lokal gesteuert werden können. Dieser Intent wird jedes Mal ausgelöst, wenn Google einen
Discovery-Scan (etwa einmal pro Minute), solange der Hub erkannt wird,
online sein.
Der Handler REACHABLE_DEVICES
wird ähnlich wie der Handler IDENTIFY
implementiert.
Handler bereitgestellt, mit der Ausnahme, dass der Handler zusätzliche Geräte-IDs erfassen muss
die über den lokalen Proxy (d. h. den Hub) erreichbar sind. Die
Das Feld device.verificationId
enthält die lokale Geräte-ID für ein Endgerät
der mit dem Hub verbunden ist.
Die
ReachableDevicesRequest
von der Local Home-Plattform enthält eine Instanz
LocalIdentifiedDevice
Über diese Instanz können Sie die Proxy-Geräte-ID sowie Daten von
die Scanergebnisse.
Der REACHABLE_DEVICES
-Handler sollte eine
ReachableDevicesPayload
, das ein devices
-Objekt enthält, das ein Array von
verificationId
-Werte für die Endgeräte, die der Hub steuert. Die
verificationId
-Werte müssen mit einem der otherDeviceIds
-Werte aus der
SYNC
-Antwort.
Das folgende Snippet zeigt, wie Sie ein REACHABLE_DEVICES
erstellen können.
-Handler.
const reachableDevicesHandler = (request: IntentFlow.ReachableDevicesRequest): IntentFlow.ReachableDevicesResponse => { // Reference to the local proxy device const proxyDeviceId = request.inputs[0].payload.device.id; // Gather additional device ids reachable by local proxy device // ... const reachableDevices = [ // Each verificationId must match one of the otherDeviceIds // in the SYNC response { verificationId: "local-device-id-1" }, { verificationId: "local-device-id-2" }, ]; // Return a response const response: IntentFlow.ReachableDevicesResponse = { intent: Intents.REACHABLE_DEVICES, requestId: request.requestId, payload: { devices: reachableDevices, }, }; return response; };
EXECUTE-Handler implementieren
Der EXECUTE
-Handler in der App verarbeitet Nutzerbefehle und verwendet die
Local Home SDK, um über ein vorhandenes Protokoll auf deine Smart-Home-Geräte zuzugreifen.
Die „Local Home“-Plattform übergibt dieselbe Eingabenutzlast an den EXECUTE
-Handler
wie für EXECUTE
auf die Cloud-Ausführung konzentrieren. Ebenso gibt der EXECUTE
-Handler
Ausgabedaten im selben Format wie bei der Verarbeitung des Intents EXECUTE
.
Um das Erstellen von Antworten zu vereinfachen, können Sie den
Execute.Response.Builder
Klasse, die das Local Home SDK bietet.
Ihre App hat keinen direkten Zugriff auf die IP-Adresse des Geräts. Stattdessen
verwenden Sie die
CommandRequest
Schnittstelle, um Befehle zu erstellen, die auf einem der folgenden Protokolle basieren: UDP, TCP oder HTTP. Rufen Sie dann die Methode
deviceManager.send()
zum Senden der Befehle.
Beim Targeting von Befehlen auf Geräte verwenden Sie die Geräte-ID (und die Parameter aus dem
customData
-Feld, falls enthalten, aus der SYNC
-Antwort, um zu kommunizieren
mit dem Gerät.
Beispiel
Das folgende Code-Snippet zeigt, wie Sie den EXECUTE
-Handler erstellen können.
const executeHandler = (request: IntentFlow.ExecuteRequest): Promise<IntentFlow.ExecuteResponse> => { // Extract command(s) and device target(s) from request const command = request.inputs[0].payload.commands[0]; const execution = command.execution[0]; const response = new Execute.Response.Builder() .setRequestId(request.requestId); const result = command.devices.map((device) => { // Target id of the device provided in the SYNC response const deviceId = device.id; // Metadata for the device provided in the SYNC response // Use customData to provide additional required execution parameters const customData: any = device.customData; // Convert execution command into payload for local device let devicePayload: string; // ... // Construct a local device command over TCP const deviceCommand = new DataFlow.TcpRequestData(); deviceCommand.requestId = request.requestId; deviceCommand.deviceId = deviceId; deviceCommand.data = devicePayload; deviceCommand.port = customData.port; deviceCommand.operation = Constants.TcpOperation.WRITE; // Send command to the local device return localHomeApp.getDeviceManager() .send(deviceCommand) .then((result) => { response.setSuccessState(result.deviceId, state); }) .catch((err: IntentFlow.HandlerError) => { err.errorCode = err.errorCode || IntentFlow.ErrorCode.INVALID_REQUEST; response.setErrorState(device.id, err.errorCode); }); }); // Respond once all commands complete return Promise.all(result) .then(() => response.build()); };
QUERY-Handler implementieren
Der QUERY
-Handler in der App verarbeitet Nutzeranfragen und verwendet die Methode
Local Home SDK, um den Status deiner Smart-Home-Geräte zu melden.
Die „Local Home“-Plattform übergibt die gleiche Anfragenutzlast an die „QUERY“. Handler
wie für QUERY
auf die Cloud-Ausführung konzentrieren. Ebenso gibt der QUERY
-Handler Daten zurück
im selben Format wie bei der Verarbeitung des Intents QUERY
.
Befehle an Geräte hinter einem Hub senden
Zur Steuerung von Endgeräten hinter einem Hub musst du eventuell zusätzliche Informationen angeben
in der protokollspezifischen Befehlsnutzlast, die an den Hub gesendet wird,
um zu ermitteln, für welches Gerät der Befehl bestimmt ist. In einigen Fällen kann dies
device.id
direkt abgeleitet. Sollte dies jedoch nicht der Fall sein,
sollten Sie diese zusätzlichen Daten in das Feld customData
einfügen.
Wenn Sie Ihre App mit TypeScript erstellt haben, denken Sie daran, sie zu kompilieren, JavaScript Sie können das Modulsystem Ihrer Wahl verwenden, um Ihren Code zu schreiben. Prüfen Sie, ob das Ziel vom Chrome-Browser unterstützt wird.