Apartment Automation mit HomePod, Raspberry Pi und Node.js.



Übersetzt für Sie einen Artikel von Chris Hawkins , in dem er darüber spricht, seine Wohnung in ein intelligentes Zuhause zu verwandeln. Der HomePod von Apple wird als Basis verwendet, aber natürlich können auch andere Systeme verwendet werden.

Zu Hause läuft ein Apple HomePod, mit dessen Hilfe bestimmte Systeme im Haus (z. B. intelligente Lampen) mithilfe einer einfachen Anfrage an Siri gesteuert werden können. Das System funktioniert sowohl von zu Hause als auch von außen (ein intelligenter Assistent ist am Telefon).

Skillbox empfiehlt: einen zweijährigen praktischen Kurs "Ich bin ein PRO Web Developer".

Wir erinnern Sie daran: Für alle Leser von „Habr“ - ein Rabatt von 10.000 Rubel bei der Anmeldung für einen Skillbox-Kurs mit dem Promo-Code „Habr“.

Anfangs war ich skeptisch, das Haus mit Sprachbefehlen zu verwalten, da nicht alles von Assistenten (nicht nur Siri) richtig erkannt wird. Aber dann wurde es zur Gewohnheit. Da Hue-Lampen keinen physischen Schalter haben und Sie in der Anwendung mehrere Aktionen ausführen müssen, um die Beleuchtung zu steuern, habe ich Siri zur Arbeit gezogen.

Dann wollte ich meinen Sprachassistenten verwenden, um andere Systeme im Haus zu steuern, zum Beispiel einen Fernseher oder eine Konsole. Im Fall von TV habe ich beispielsweise Simple IP Control entdeckt - eine Methode zur Steuerung meines Sony Bravia durch Senden von Befehlen über TCP.

Passen Sie Siri an


In der zweiten Hälfte des Jahres 2018 startete Apple die Shortcuts-App für alle iOS-Benutzer. Sie können die Arbeit mit dem Telefon (oder Smart Home) automatisieren, ohne Code schreiben zu müssen.

Die Anwendung verfügt über viele integrierte Befehle. Was ihm fehlt, ist die Fähigkeit, TCP-Befehle zu verwenden, obwohl es einen Mechanismus für die Arbeit mit URLs gibt.

Außerdem können Sie Ihre eigenen Module in Objective-C oder Swift schreiben. Ich habe mich dagegen entschieden, weil ich in Zukunft meinen HomePod auf einen anderen Assistenten umstellen kann. Stattdessen wollte ich eine Webanwendung schreiben, die auf Siri-Befehle reagieren kann.

Sony Bravia TV-Steuerung


Ausgerüstet mit einem Handbuch mit Befehlen für meinen Fernseher schrieb ich eine Anwendung auf Node.js Express (Github) , in der ich lernte, wie man auf einige der gängigen Befehle reagiert. Ich begann mit Einschalten und Lautstärke.

Der Befehl setPowerStatus erledigt alles, was wir brauchen.



Der Header besteht aus den Zeichen * und s, die statisch sind und für alle Befehle verwendet werden. Dann werden die dritten Bytes für den Befehl verwendet. Es gibt vier Bedeutungen, die diese Position halten können. C für Befehl (Senden eines Befehls im Fernsehen), E für Anfrage (Überprüfen des aktuellen Werts eines bestimmten Parameters, z. B. Lautstärke), A - Antwort (als Antwort auf Befehle und Anfragen gesendet) und N für Benachrichtigen (Ereignisbenachrichtigung, z. B. Ausschalten der Lautstärke) )

Um mein Ziel zu erreichen, musste ich die JSON-RPC- Dokumentation von Sony studieren. Wie sich herausstellte, ermöglichte die Art von JSON-RPC über HTTP, die Aufgabe zu vereinfachen und die Codemenge zu reduzieren.

Die Arbeit mit der JSON-RPC-API war einfach. Nehmen Sie zum Beispiel den Dienst (System), den Befehl (getPowerStatus) sowie die Parameter (wahr oder falsch) und bilden Sie eine HTTP-Anfrage, die wir dann an TV senden.

let body = JSON.stringify({ method: command, id: ++this.id, params: params, version: "1.0", }); return new Promise((resolve, reject) => { fetch('http://' + this.ip + ':' + this.port + '/sony/' + service, { method: 'post', headers: { 'X-Auth-PSK': this.psk }, body: body, }).then(response => { return response.json(); }).then(response => { if (response.error && (!response.result || response.result.length === 0)) { reject({ code: response.error[0] }); } else { resolve(response.result[0]); } }).catch(error => { reject(error); }); }); 

Standardmäßig wird die Authentifizierung mit dem im Header der HTTP-Anforderung gesendeten Vorschlüssel durchgeführt. Es gibt jedoch eine sicherere und bequemere Möglichkeit, dies mit accessControl zu tun. In diesem Fall können wir einen Befehl an das Fernsehgerät senden und den Code sicher mit der grundlegenden HTTP-Authentifizierung austauschen. Nachdem die Authentifizierung einmal durchgeführt wurde, wird die weitere Authentifizierung mithilfe eines Cookies durchgeführt.

Mein Fernseher ist jedoch durch eine auf dem Router konfigurierte Firewall geschützt, sodass ich den vorinstallierten Schlüssel verwendet habe.

Schalten Sie Xbox One ein


Xbox erforderte natürlich ein anderes Setup. Microsoft scheint beschlossen zu haben, die REST-API nicht zu verwenden, daher wurde die Arbeit mit UDP-Paketen durchgeführt.

Glücklicherweise verfügt Node.js über ein dgram-Modul, das sofort mit allen Funktionen von USP funktioniert. Das habe ich am Ende bekommen.

 turnOn() { let socket = dgram.createSocket('udp4'); let powerPayload = new Buffer('\x00' + String.fromCharCode(this.liveId.length) + this.liveId.toUpperCase() + '\x00'); let powerHeader = Buffer.concat([new Buffer('dd0200', 'hex'), new Buffer(String.fromCharCode(powerPayload.length)), new Buffer('\x00\x00')]); let powerPacket = Buffer.concat([powerHeader, powerPayload]); return this._sendPacket(socket, powerPacket); } _sendPacket(socket, buffer) { return new Promise((resolve, reject) => { socket.send(buffer, 0, buffer.length, Constants.xboxPort, this.ip, function(err) { socket.close(); if (err) { return reject(err); } resolve(); }); }); } 

Für die Konfiguration habe ich die Liste der ID-Geräte verwendet, die hier zu finden ist . Wenn Sie nur den Code aus meinem Repository übernehmen möchten, müssen Sie die ID in der Datei config.json ersetzen.

Konfigurieren Sie Verknüpfungen für Siri


Damit Siri die gerade erstellten Befehle ausführen kann, benötigt sie einen Assistenten. Ich habe es aus Raspberry Pi erstellt, da die "Himbeere" in jeder Hinsicht geeignet ist. Dafür habe ich mir ein Pi 3 Model B + gekauft, das Wi-Fi unterstützt.

Raspbian muss eine GUI konfigurieren. Ich stellte eine Verbindung zu Wi-Fi her, schaltete dann das Display aus und arbeitete weiter an SSH. Um sicherzustellen, dass die Webanwendung ständig aktiv ist, habe ich den Dienstaktivierungssocket in systemd so konfiguriert, dass das System ihn automatisch neu starten kann, wenn der Node.js-Prozess abstürzt.

Tatsächlich waren Verknüpfungen für Siri die einfachste Arbeitsstufe. Dies ist eine intuitive Anwendung mit Unterstützung für native Sprachbefehle. Standardmäßig wusste es bereits, wie man mit dem HomePod arbeitet, es war nicht notwendig, etwas zusätzlich zu konfigurieren.



Alles zusammenfügen


Da mein Fernseher auf Android läuft, unterstützt er Apps wie Netflix und YouTube. Vor diesem Hintergrund habe ich Befehle zum Starten dieser Dienste erstellt. Außerdem habe ich Befehle zur Steuerung der Lautstärke, des TV-Modus, der Pause und der Wiedergabe von Inhalten hinzugefügt.

Hier sind Beispiele für alles, was ich erstellt habe. Ich habe auch versucht, das Projekt modular zu gestalten, sodass das Hinzufügen anderer SmartTV-Modelle kein Problem darstellt.

Hier ist ein Beispielmodul, das eine Xbox und einen Fernseher enthält und den ersten HDMI-Anschluss aktiviert.

 router.post('/turnOnXboxAndTV', function(req, res, next) { Promise.all([ xbox.turnOn(), tv.turnOn() .then(() => new Promise(resolve => setTimeout(resolve, 2000))) .then(() => tv.setInput(config.scripts.xboxInput)), ]).then(() => { res.sendStatus(200); }).catch((error) => { res.status(500).send(error); }); }); 

Und so funktioniert das alles in der Praxis.


Leider ist die Funktionalität von Siri nicht sehr gut. Dieselbe Alexa von Amazon verfügt über ein viel umfangreicheres Funktionsspektrum und eine sehr leistungsfähige API. Ich denke, basierend auf Alexa können Sie viel ernstere Projekte erstellen.

Skillbox empfiehlt:

Source: https://habr.com/ru/post/de438292/


All Articles