
Traduje para usted
un artículo de Chris Hawkins , en el que habla sobre convertir su apartamento en una casa inteligente. El HomePod de Apple se usa como base, pero, por supuesto, se pueden usar otros sistemas.
Tengo un Apple HomePod funcionando en casa, lo que ayuda a controlar ciertos sistemas en el hogar (por ejemplo, lámparas inteligentes) con una simple solicitud a Siri. El sistema funciona tanto desde casa como desde el exterior (hay un asistente inteligente en el teléfono).
Skillbox recomienda: un curso práctico de dos años, "Soy un desarrollador web PRO" .
Le recordamos: para todos los lectores de "Habr": un descuento de 10.000 rublos al registrarse en cualquier curso de Skillbox con el código de promoción "Habr".
Inicialmente, era escéptico sobre la administración de la casa utilizando comandos de voz, porque los asistentes no reconocen todo (no solo Siri) correctamente. Pero luego se convirtió en un hábito. Como las lámparas Hue no tienen un interruptor físico, y en la aplicación debe realizar varias acciones para controlar la iluminación, dibujé a Siri para trabajar.
Luego, quería comenzar a usar mi asistente de voz para controlar otros sistemas en la casa, por ejemplo, un televisor o una consola. En el caso de la televisión, por ejemplo, descubrí el control simple de IP, un método para controlar mi Sony Bravia mediante el envío de comandos a través de TCP.
Personaliza Siri
En la segunda mitad de 2018, Apple lanzó la aplicación Atajos para todos los usuarios de iOS. Le permite automatizar el trabajo con el teléfono (o casa inteligente) sin la necesidad de escribir código.
La aplicación tiene muchos comandos incorporados. Lo que le falta es la capacidad de usar comandos TCP, aunque existe un mecanismo para trabajar con URL.
Además, puede escribir sus propios módulos en Objective-C o Swift. Decidí no hacer esto, porque en el futuro puedo cambiar mi HomePod a otro asistente. En cambio, quería escribir una aplicación web que pudiera responder a los comandos de Siri.
Sony Bravia TV Control
Armado con un manual con comandos para mi TV, escribí una aplicación en
Node.js Express (Github) , que me enseñó cómo responder a algunos de los comandos comunes. Comencé por encender y volumen.
El comando setPowerStatus hace todo lo que necesitamos.

El encabezado consta de los caracteres * ys, que son estáticos y se utilizan para todos los comandos. Luego, el tercer byte (s) se usa para Command. Hay cuatro significados que pueden mantener esta posición. C para Comando (enviando un comando en la TV), E para Consulta (verificando el valor actual de cierto parámetro, por ejemplo, volumen), A - Respuesta (enviado en respuesta a Comandos y Consultas) y N para Notificar (notificación de evento, como apagar el volumen )
Para lograr mi objetivo, tuve que estudiar
la documentación
JSON-RPC de Sony . Al final resultó que, la naturaleza de JSON-RPC sobre HTTP hizo posible simplificar la tarea y reducir la cantidad de código.
Trabajar con la API JSON-RPC fue simple. Tome, por ejemplo, el servicio (sistema), el comando (getPowerStatus) más los parámetros (verdadero o falso) y forme una solicitud HTTP, que luego enviaremos a la TV.
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); }); });
De manera predeterminada, la autenticación se realiza utilizando la clave previa enviada en el encabezado de la solicitud HTTP. Pero hay una manera más segura y conveniente de hacer esto con accessControl. En este caso, podemos enviar un comando al televisor e intercambiar el código de forma segura con la autenticación HTTP básica. Después de que la autenticación se realiza una vez, la autenticación posterior se realiza mediante una cookie.
Pero mi televisor está protegido por un firewall configurado en el enrutador, por lo que utilicé la clave previamente compartida.
Enciende Xbox One
Xbox, por supuesto, requería una configuración diferente. Microsoft parece haber decidido no utilizar la API REST, por lo que el trabajo se realizó utilizando paquetes UDP.
Afortunadamente, Node.js tiene un módulo dgram que funciona con todas las funciones de USP. Eso es lo que obtuve al final.
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(); }); }); }
Para la configuración, utilicé la lista de dispositivos de identificación, que
se puede encontrar aquí . Si solo desea tomar el código de mi repositorio, debe reemplazar la ID en el archivo config.json.
Configurar accesos directos para Siri
Para que Siri pueda ejecutar los comandos que acabo de crear, necesita un asistente. Lo creé a partir de Raspberry Pi, ya que la "frambuesa" es adecuada en todos los aspectos. Para esto, compré un Pi 3 Modelo B + que admite Wi-Fi.
Raspbian tiene una GUI para configurar. Me conecté a Wi-Fi, apagué la pantalla y seguí trabajando en SSH. Para asegurarme de que la aplicación web esté constantemente activa, configuré el socket de activación del servicio en systemd, de modo que si el proceso Node.js fallaba, el sistema podría reiniciarlo automáticamente.
En realidad, los atajos para Siri fueron la etapa más fácil del trabajo. Esta es una aplicación intuitiva con soporte de comando de voz nativo. Por defecto, ya sabía cómo trabajar con HomePod, no era necesario configurar nada adicionalmente.

Poniendo todo junto
Como mi televisor funciona con Android, es compatible con aplicaciones como Netflix y YouTube. Con esto en mente, creé comandos para iniciar estos servicios. Además, agregué comandos para controlar el volumen, el modo de TV, pausar y reproducir contenido.
Aquí hay ejemplos de todo lo que creé. También intenté hacer que el proyecto fuera modular, por lo que agregar otros modelos de SmartTV no es un problema.
Aquí hay un módulo de ejemplo que incluye una Xbox, TV y activa el primer puerto 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); }); });
Y así es como funciona todo en la práctica.
Desafortunadamente, la funcionalidad de Siri no es muy buena. La misma Alexa de Amazon tiene una gama mucho más extensa de características y una API muy poderosa. Creo que, según Alexa, puedes crear proyectos mucho más serios.
Skillbox recomienda: