Automatisation d'appartement avec HomePod, Raspberry Pi et Node.js



Traduit pour vous un article de Chris Hawkins , dans lequel il parle de transformer son appartement en maison intelligente. Le HomePod d'Apple est utilisé comme base, mais, bien sûr, d'autres systèmes peuvent être utilisés.

J'ai un Apple HomePod qui fonctionne à la maison, ce qui permet de contrôler certains systèmes de la maison (par exemple, les lampes intelligentes) sur simple demande à Siri. Le système fonctionne à la fois à domicile et à l'extérieur (un assistant intelligent est au téléphone).

Skillbox recommande: un cours pratique de deux ans, "Je suis un développeur Web PRO . "

Nous vous rappelons: pour tous les lecteurs de «Habr» - une remise de 10 000 roubles lors de l'inscription à un cours Skillbox en utilisant le code promo «Habr».

Au départ, j'étais sceptique quant à la gestion de la maison à l'aide des commandes vocales, car tout n'est pas correctement reconnu par les assistants (pas seulement Siri). Mais c'est devenu une habitude. Étant donné que les lampes Hue n'ont pas d'interrupteur physique et que dans l'application, vous devez effectuer plusieurs actions pour contrôler l'éclairage, j'ai appelé Siri au travail.

Ensuite, j'ai voulu commencer à utiliser mon assistant vocal pour contrôler d'autres systèmes dans la maison, par exemple un téléviseur ou une console. Dans le cas de la télévision, par exemple, j'ai découvert Simple IP Control - une méthode pour contrôler mon Sony Bravia en envoyant des commandes via TCP.

Personnalisez Siri


Au deuxième semestre 2018, Apple a lancé l'application Shortcuts pour tous les utilisateurs iOS. Il vous permet d'automatiser le travail avec le téléphone (ou la maison intelligente) sans avoir à écrire de code.

L'application possède de nombreuses commandes intégrées. Ce qui lui manque, c'est la possibilité d'utiliser des commandes TCP, bien qu'il existe un mécanisme pour travailler avec les URL.

De plus, vous pouvez écrire vos propres modules en Objective-C ou Swift. J'ai décidé de ne pas le faire, car à l'avenir, je pourrai changer mon HomePod en un autre assistant. Au lieu de cela, je voulais écrire une application Web qui pourrait répondre aux commandes Siri.

Sony Bravia TV Control


Armé d'un manuel avec des commandes pour mon téléviseur, j'ai écrit une application sur Node.js Express (Github) , qui m'a appris à répondre à certaines des commandes courantes. J'ai commencé par allumer et volume.

La commande setPowerStatus fait tout ce dont nous avons besoin.



L'en-tête se compose des caractères * et s, qui sont statiques et sont utilisés pour toutes les commandes. Ensuite, le troisième octet est utilisé pour la commande. Il y a quatre significations qui peuvent tenir cette position. C pour Command (envoi d'une commande sur le téléviseur), E pour Inquiry (vérification de la valeur actuelle d'un certain paramètre, par exemple, le volume), A - Answer (envoyé en réponse aux commandes et requêtes) et N pour Notify (notification d'événement, comme la désactivation du volume )

Pour atteindre mon objectif, j'ai dû étudier la documentation JSON-RPC de Sony . Il s'est avéré que la nature de JSON-RPC sur HTTP a permis de simplifier la tâche et de réduire la quantité de code.

Travailler avec l'API JSON-RPC était simple. Prenez, par exemple, le service (système), la commande (getPowerStatus) plus les paramètres (vrai ou faux) et formez une requête HTTP, que nous envoyons ensuite à la télévision.

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

Par défaut, l'authentification est effectuée à l'aide de la pré-clé envoyée dans l'en-tête de la requête HTTP. Mais il existe un moyen plus sûr et plus pratique de le faire avec accessControl. Dans ce cas, nous pouvons envoyer une commande au téléviseur et échanger en toute sécurité le code avec l'authentification HTTP de base. Une fois l'authentification effectuée, une authentification supplémentaire est effectuée à l'aide d'un cookie.

Mais mon téléviseur est protégé par un pare-feu configuré sur le routeur, j'ai donc utilisé la clé pré-partagée.

Allumez Xbox One


Xbox, bien sûr, nécessitait une configuration différente. Microsoft semble avoir décidé de ne pas utiliser l'API REST, le travail a donc été effectué à l'aide de paquets UDP.

Heureusement, Node.js dispose d'un module dgram qui, prêt à l'emploi, fonctionne avec toutes les fonctionnalités d'USP. C'est ce que j'ai finalement obtenu.

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

Pour la configuration, j'ai utilisé la liste des périphériques d'identification, qui peut être trouvée ici . Si vous souhaitez simplement extraire le code de mon référentiel, vous devez remplacer l'ID dans le fichier config.json.

Configurer des raccourcis pour Siri


Pour que Siri puisse exécuter les commandes que je viens de créer, elle a besoin d'un assistant. Je l'ai créé à partir de Raspberry Pi, car la "framboise" convient à tous égards. Pour cela, j'ai acheté un Pi 3 modèle B + qui prend en charge le Wi-Fi.

Raspbian a une interface graphique à configurer. Je me suis connecté au Wi-Fi, puis j'ai éteint l'écran et j'ai continué à travailler sur SSH. Afin de m'assurer que l'application Web est constamment active, j'ai configuré le socket d'activation de service dans systemd, de sorte que si le processus Node.js plante, le système pourrait le redémarrer automatiquement.

En fait, les raccourcis pour Siri étaient l'étape la plus facile du travail. Il s'agit d'une application intuitive avec prise en charge des commandes vocales natives. Par défaut, il savait déjà comment travailler avec HomePod, il n'était pas nécessaire de configurer quoi que ce soit de plus.



Tout mettre ensemble


Étant donné que mon téléviseur fonctionne sur Android, il prend en charge des applications comme Netflix et YouTube. Dans cet esprit, j'ai créé des commandes pour lancer ces services. De plus, j'ai ajouté des commandes pour contrôler le volume, le mode TV, mettre en pause et lire le contenu.

Voici des exemples de tout ce que j'ai créé. J'ai également essayé de rendre le projet modulaire, donc l'ajout d'autres modèles SmartTV n'est pas un problème.

Voici un exemple de module qui inclut une Xbox, un téléviseur et active le premier port HDMI.

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

Et voici comment tout cela fonctionne dans la pratique.


Malheureusement, la fonctionnalité de Siri n'est pas très bonne. La même Alexa d'Amazon a une gamme de fonctionnalités beaucoup plus étendue et une API très puissante. Je pense que, basé sur Alexa, vous pouvez créer des projets beaucoup plus sérieux.

Skillbox recommande:

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


All Articles