Apple HomeKit mit ESP32 - Teil 1 - AZ-Delivery

¡Hola y bienvenidos a mi primera publicación en AZ-Delivery!

El blog de hoy, la primera parte de una nueva serie de blogs, trata sobre la automatización del hogar con el Homekit de Apple. HomeKit es un framework de SmartHome para dispositivos iOS que permite a los usuarios acceder a todos los dispositivos domésticos inteligentes de su casa en una sola app. El HomeKit abarca todo el proceso de desarrollo. Un principio importante es que los correspondientes dispositivos domésticos inteligentes, como las bombillas, los termostatos o las cámaras, se pueden comunicar directamente a través del Bluetooth o de la red WLAN con el dispositivo de Apple, con el que son controlados.

El HomeKit comprende dos framework para este propósito. El framework de HomeKit para el desarrollo de aplicaciones propias de HomeKit en iOS y el protocolo de accesorios HomeKit para el desarrollo de los correspondientes accesorios de SmartHome (véase la siguiente figura).

Marco HomeKit

El protocolo de accesorios de HomeKit, HAP para abreviar, se publicó como un Proyecto de código abierto. El protocolo de accesorios de HomeKit está implementado en un ESP32, un pequeño y económico microcontrolador de Espressif. La librería utilizada para implementar el estándar HAP es la  librería HomeSpan especialmente desarrollada para el ESP32 y el Arduino IDE. Esto permite implementar varios accesorios de HomeKit con solo unos pocos componentes económicos y con un esfuerzo razonable.

A continuación, primero le presentaré algunos fundamentos del protocolo de accesorios de HomeKit y, posteriormente, la implementación de un LED regulable compatible con HomeKit.

Protocolo de accesorios de HomeKit 

Como ya mencioné, en esta publicación del blog me centraré en el protocolo de accesorios de HomeKit, ya que el framework del HomeKit se utiliza para el desarrollo de aplicaciones para el funcionamiento de los propios dispositivos SmartHome. A continuación, explicaré algunos fundamentos teóricos sobre el HAP, la información más concreta sobre un accesorio de HomeKit y el aspecto de la seguridad en HomeKit seguirán en la segunda parte de esta serie blogs.

El protocolo de accesorios de HomeKit define los requisitos para el desarrollo del dispositivo y la conexión con el framework de HomeKit. En este punto se toma en cuenta el kit de desarrollo de accesorios de HomeKit, que se encarga de tareas como el cifrado para que el desarrollador pueda centrarse en la lógica de la aplicación.

La HAP comienza con la definición del nivel de transporte de red necesario, que incluye Bluetooth Low Energy y los protocolos basados en IP, especialmente en la red WLAN. Para los accesorios basados ​​en IP, que también afectan al LED regulable desarrollado en el contexto de este blog, se aplican varios requisitos. Los más importantes son el soporte simultáneo de conexiones IPv4 e IPv6, la implementación de Bonjour, especialmente en lo que se refiere a los  servicios DNS de multidifusión y la aprobación de ocho conexiones TCP simultáneas a un Servidor de Accesorio HAP. Además, los servidores HAP debe ser capaces de generar y serializar JavaScript Object Notation, JSON para abreviar, dentro del marco de RFC 7159 y codificar y decodificar JSON en formato UTF-8. Así mismo, en el HAP se definen varios requisitos de seguridad, que trataré con más detalle en la próxima publicación del blog. Por otro parte, el HAP se ocupa de las distintas funciones. El cliente HAP, es decir, normalmente un iPhone o iPad, es siempre el controlador, que envía solicitudes al servidor de accesorios HAP, es decir, al dispositivo SmartHome, y recibe la correspondiente información de estado. Además, el cliente debe registrar y procesar los mensajes del servidor HAP, por ejemplo, registrar y procesar una actualización de un valor de color. Adicionalmente, el servidor HAP debe ser compatible con HTTP, según el RFC 7230 y RFC 7231, y ser capaz de responder a las solicitudes HTTP con sus correspondientes respuestas HTTP y los códigos de estado HTTP correspondientes.

El siguiente punto importante de la norma HAP es el modelo de datos. Esto define cómo deben estructurarse los propios accesorios, que también se denominan perfiles y que generalmente describen el dispositivo en general. Para este propósito, los accesorios consisten en objetos y características de servicio, que también trataré con más detalle en la próxima parte de esta serie blogs. Esto también se aplica a los requisitos para el proceso de configuración, que se tratará con más detalle en la siguiente publicación del blog.

Otros requisitos importantes para los dispositivos del protocolo de accesorios de HomeKit son, en el caso de un dispositivo WLAN, la necesidad de estar en la misma red que el cliente de HomeKit, en el caso de una posible comunicación tanto a través de la red WLAN como de BluetoothLE, proporcionar la misma información en ambos canales de comunicación y no permitir las actualizaciones del firmware.

Estructura del hardware

Componentes y pinouts

Para la aplicación se requiere:

número Componente anotación
1 ESP-32 DEV Kit de desarrollo C V4 También se pueden utilizar otras versiones del ESP32.
1 KY-009 RGB LED SMD Módulo de Sensor Dado que no queremos usar los LEDs como RGB LED, por supuesto, cualquier LED simple con resistencia en serie correspondiente también funcionará.
1 Jumper Wire Cable de puente 3 x 40 pcs. 20 cm M2M / F2M / F2F Se requieren 4 cables de puente female / female. Si no está disponible, se recomienda el set especificado especificado.


A continuación, se presenta la disposición de los pines del ESP32 que se presenta arriba:

ESP32 pines

La siguiente es la disposición de los pines del módulo de SMD que se especificó con anterioridad:

RGB SMD

- Tierra
+ Verde
+ Rojo
+ Azul

Cableado

diagrama de circuito Fritzing

Los siguientes pines deben estar conectados entre sí para la construcción del circuito:

  1. El pin GND del módulo RGB LED se debe conectar a cualquier pin GND del microcontrolador.
  2. El pin R del módulo RGB LED se debe conectar a un pin GPIO del microcontrolador.
  3. El pin G del módulo RGB LED se debe conectar a un pin GPIO del microcontrolador.
  4. El pin B del módulo RGB LED se debe conectar a un pin GPIO del microcontrolador.

Alternativa de cableado

Fritzing diagrama de circuito alternativamente

En el caso de un LED, que no esté soldado a una placa de circuito impreso con una resistencia en serie, se debe tener cuidado para asegurarse de que el cableado sea correcto. Para ello, el ánodo, que debe ser el cable más largo, se debe conectar al pin GPIO deseado y el cátodo a tierra. Tenga en cuenta la necesidad en serie adecuada. Como regla general, esto se debe calcular en función del LED utilizado. Como alternativa, las resistencias en serie en el rango de de 150 Ohm a 220 Ohm son generalmente adecuadas para los LED. Sin embargo, se debe tener en cuenta que una resistencia en serie demasiado baja puede conducir a una corriente inadmisiblemente alta y, por lo tanto, a la destrucción del LED.

Estructura de software

La librería que se utiliza en este proyecto es la denominada "HomeSpan" para integrar el protocolo de accesorios HomeKit. Además, se requiere la integración de PWM para atenuar el LED. Esto se puede implementar arbitrariamiente por usted mismo, o alternativamente, la funcionalidad utilizada en HomeSpan se puede utilizar para controlar los LEDs por medio de PWM. En este ejemplo, se va a presentar esto último para que la implementación sea lo más clara y sencilla posible. La librería HomeSpan se puede instalar a través del gestor de librería en el Arduino IDE.

La librería HomeSpan asume la implementación del protocolo de accesorios de HomeKit en la variante de código abierto R2. En este caso, interesa especialmente el modelo de datos de HomeKit, es decir, todos los accesorios proporcionados por Apple, incluidos sus servicios y características. Sólo no se pueden crear dispositivos de sonido y vídeo debido a los mayores requisitos de hardware. HomeSpan permite la programación completa de los accesorios de HomeKit en el Arduino IDE y también ofrece una interfaz de línea de comandos con un alto nivel de información de depuración y mensajes de error.

Para su correcta estructuración, el programa se divide en tres partes. La primera parte "dimmable_LED" corresponde a la función principal y se encarga de la definición de los accesorios de HomeKit y crea objetos que representan el servidor HAP de los dispositivos definidos. La segunda parte del programa "DEV_Identify.h" es una función para la creación más clara y rápida de los accesorios de HomeKit. A esta función se le pasan los datos del "Servicio de Información de Accesorios" como una cadena, para que luego la función crea un Accesorio HomeKit a partir de estos datos llamando a las funciones HAP correspondientes. Además, el proceso de inicialización visible requerido en el HAP se implementa mediante un LED intermitente que; sin embargo, no está representado en el lado de hardware en este proyecto. Sin embargo, puede implementar fácilmente esta función conectando un LED en el área de pin de salida definida "DEV_Identify.h" para los flashes. En mi ejemplo, lo he configurado en el GPIO 4. Si se utiliza el módulo LED mencionado anteriormente, por ejemplo, uno de los tres LEDs controlables individualmente podría utilizarse para la implementación del hardware. En la tercera parte del programa "DEV_sensors.h", se definen todos los demás servicios requeridos u opcionales del accesorio y se crea la rutina de lectura de los datos del sensor o, en el caso de los actuadores, la rutina de ejecución del actuador.

En este caso específico, se integró un LED regulable. El LED utilizado se atenúa con la ayuda de la funcionalidad PWM del ESP32.  El LED es el primero en recibir el Servicio de Información de accesorios, que es necesario para todos los accesorios de HomeKit. Este servicio contiene la versión del firmware, una rutina de identificación, un fabricante, una designación del modelo, un nombre y un número de serie como características. A continuación, se implementaron los LED con sus servicios correspondientes en el área "DEV_LED.h".

Con un LED regulable, existe el servicio de energía para describir si el LED está encendido o apagado y un servicio de nivel, que describe el brillo establecido del LED. Se especifica un valor inicial para el Nivel de Servicio, que se asume cuando el LED se enciende sin que el brillo esté definido de forma permanente. Además, se define un área de trabajo para el LED, en la que el usuario puede configurar el brillo en la aplicación HomeKit correspondiente.

El código fuente se comenta como un GitHub Repo para descargar y probarlo.

A continuación, se muestra de nuevo como código fuente:

Dimmable_Led.ino:

 /*********************************************************************************
  * Con Licencia
  *  
  * Copyright (C) 2020 Gregg E. Berman
  *  
  * https://github.com/homespan/homespan
  *  
  * Se concede permiso, de forma gratuita, a cualquier persona que obtenga una copia
  * De este software y archivos de documentación asociados (el "Software"), para hacer frente
  * en el Software sin restricciones, incluyendo, sin limitación, los derechos
  * Para usar, copiar, modificar, fusionar, publicar, distribuir, sublicenciar y / o vender
  * Copias del Software, y para permitir a las personas a las que el Software es
  * Equipado para hacerlo, sujeto a las siguientes condiciones:
  *  
  * El aviso de copyright anterior y este aviso de permiso se incluirán en todos
  * Copias o partes sustanciales del Software.
  *  
  * SOFTWARE se proporciona "como es", sin garantía de ningún tipo, expresa OR
  * Implícita, incluyendo pero no limitado a, las garantías de comerciabilidad,
  * PARA FINES A PARTICULAR Y NO. IN NO CASO LA
  * AUTORES O TITULARES DEL COPYRIGHT responsable de ninguna reclamación, DAÑO U OTRA
  * RESPONSABILIDAD, SEA EN UNA ACCIÓN DE CONTRATO, AGRAVIO O DE OTRO, derivadas de,
  * DE O EN RELACIÓN CON EL SOFTWARE O EL USO O OTRAS OPERACIONES EN EL
  * SOFTWARE.
  *  
  ********************************************************************************/
 
 # include "HomeSpan.h"
 # include "DEV_LED.h"
 # include "DEV_Identify.h"
 
 vacío configuración() {
   
   De serie.empezar(115200);
 
   homeSpan.empezar(Categoría :: Iluminación,"HomeSpan LED");  
                                                         
   // Crear un LED regulable unido a la clavija 16
   nuevo SpanAccessory();                                                          
     nuevo DEV_Identify("Regulable LED","AZ-Entrega","123-ABC","DIRIGIÓ","0.9",0);
     nuevo Servicio :: HAPProtocolInformation();
       nuevo Característica :: Versión("1.1.0");
     nuevo DEV_DimmableLED(16);                                                      
     
 } // final de la instalación ()
 
 //////////////////////////////////////
 
 vacío círculo(){
   
   homeSpan.encuesta();
   
 } // fin de bucle ()

DEV_Identify.h:

 
 //////////////////////////////////
 // SERVICIOS ESPECÍFICOS DE DISPOSITIVO //
 //////////////////////////////////
 
 struct DEV_Identify : Servicio :: AccessoryInformation {
 
   En t nBlinks;                    // número de veces que parpadear diodo integrado en identificar la rutina
   SpanCharacteristic *identificar;   // referencia a la Identificar Característica
   
   DEV_Identify(const carbonizarse *nombre, const carbonizarse *manu, const carbonizarse *sn, const carbonizarse *modelo, const carbonizarse *versión, En t nBlinks) : Servicio :: AccessoryInformation(){
     
     nuevo Característica :: Nombre(nombre);                   // crear todas las características requeridas con valores establecidos basan en argumentos anteriores
     nuevo Característica :: Fabricante(manu);
     nuevo Característica :: SerialNumber(sn);    
     nuevo Característica :: Modelo(modelo);
     nuevo Característica :: FirmwareRevision(versión);
     identificar=nuevo Característica :: Identificar();          // almacena una referencia a la identidad característica para temperaturas inferiores
 
     esta->nBlinks=nBlinks;                            // almacenar el número de veces a parpadear el LED
 
     pinMode(homeSpan.getStatusPin(),PRODUCCIÓN);          // hacer que el LED esté conectado a la salida
  }
 
   booleano actualizar(){
       
     por(En t I=0;I<nBlinks;I++){
       digitalWrite(homeSpan.getStatusPin(),BAJO);
       demora(250);
       digitalWrite(homeSpan.getStatusPin(),ELEVADO);
       demora(250);
    }
 
     regreso(cierto);                               // devolver verdadero
     
  } // actualizar
   
 };

DEV_LED.h:

 
 ////////////////////////////////////
 // DISPOSITIVO-ESPECÍFICAS SERVICIOS LED //
 ////////////////////////////////////
 
 // biblioteca de varias funciones PWM
 # include "extras / PwmPin.h"
 
 ////////////////////////////////////
 
 // LEDDimmable
 struct DEV_DimmableLED : Servicio :: bombilla {      
 
   // referencia a Led Pin
   ledPin *ledPin;                                  
   // En referencia a la Característica
   SpanCharacteristic *poder;                        
   // referencia a las características del brillo
   SpanCharacteristic *nivel;                        
 
   // método constructor ()
   DEV_DimmableLED(En t alfiler) : Servicio :: bombilla(){      
 
     poder=nuevo En característica ::();    
 
     // brillo característico con un valor inicial de 50%
     nivel=nuevo Característica :: Brillo(50);      
     // establece el rango de la Brillo a ser desde un mínimo de 5%, hasta un máximo de 100%, en pasos de 1%
     nivel->SetRange(5,100,1);                      
 
     // configura un LED PWM para salida al pin especificado
     esta->ledPin=nuevo ledPin(alfiler);                  
 
     // mensaje de inicialización
     De serie.impresión("Configuración regulable LED: Pin =");
     De serie.impresión(ledPin->GetPin());
     De serie.impresión("\norte");
     
  } // constructor final
   
   // método de actualización ()
   booleano actualizar(){
                                   
     // Muestra información sobre lo que se actualiza
     Log1("Actualización regulable LED en el pin =");      
     Registro1(Ledpin->getpin());
     Registro1(": Actual Power =");
     LOG1(poder->Getval()?"Cierto":"Falso");
     Registro1("Actual Brillo =");
     Log1(nivel->GetVal());
 
     SI(poder->actualizado()){
       Log1("Nuevo Power =");
       Registro1(poder->GETNEWVAL()?"Cierto":"Falso");
    }
 
     SI(nivel->actualizado()){
       Log1("New Brightness =");
       Log1(nivel->GETNEWVAL());
    }
 
     Registro1("\ n");
 
     // actualiza el pin pwm real
     ledPin->colocar(poder->Getnowval()*nivel->GETNEWVAL());    
   
     regreso(cierto);
   
  } // actualizar
 };
 
 ////////////////////////////////////

Configuración

Este es el modo de configuración de nuestro LED HomeKit, al que se puede acceder a través de la consola de serie en el Arduino IDE. Tenga en cuenta que se debe ajustar la velocidad de transmisión correcta.

configuración

Escribiendo una "W", la WLAN se puede configurar:

configuraciónAquí, la WLAN ya está configurada y el sensor HomeKit se ha conectado a la red local, en este caso el punto de acceso de mi iPhone. Ahora, esto se puede añadir a su casa en su dispositivo iOS con el código de configuración estándar "466-37-726".

Esto se ve así, por ejemplo, en la aplicación de inicio:

Ejemplo aplicación

En la próxima publicación de esta serie de blogs, profundizaré un poco más sobre los fundamentos teóricos del protocolo de accesorios de HomeKit y le presentaré los temas mencionados sobre accesorios y seguridad. Además, le presentaré el concepto de puente en HomeKit. A continuación, se implementará un sensor de temperatura y humedad.

¡Espero que se haya divertido mucho construyéndolo!

Esp-32Projekte für anfängerSmart home

9 comentarios

Christoph

Christoph

Hallo, ich habe den Code so verwendet und auch bereits die Homespan Beispielversion. Hat ca. 5 mal geklappt, alles 1a verbunden etc. Danach seit mittlerweile 3 Tagen, ist es mir nicht mehr möglich eine Verbindung mit Homekit herzustellen. Wenn ich den Code so ausführe, bleibt er immer bei “Starting HAP Server on port 80 supporting 14 simultaneous HomeKit Controller Connections…” Stehen, das war die ersten male nicht so. Bitte um Hilfe.
MfG

Carsten Witt

Carsten Witt

So, für die Nachwelt … ;-)
Kurz: Es funktioniert problemlos wenn man sich nicht selber ein Bein stellt.
Lang: Ich betreibe zur Home Automatisierung einen RPI4 und nutze dort dies USB3 Schnittstelle für eine SSD und einem “JeeLink” zur Steuerung von Geräten. Da ich nun mehr USB Geräte benötigt hatte (Z-Wave, ..) habe ich einen einfachen USB Hub dort angeschlossen um mehr Ports zur Verfügung zu haben, funktionierte für die Automatisierung soweit auch perfekt. Leider erwies sich der HUB als so “billig” das sein Kabel als Antenne funktioniert hat und somit die daneben stehende FRITZBox auf 2.4GHz komplett gestört hat, ist mir nicht aufgefallen da alle anderen WLAN Geräte auf dem 5GHz Band funktionierten.
Kurzum, HUB entsorgt und gg. etwas besseres mit geschirmter Anschlussleitung getauscht und schon waren meine Probleme verschwunden.
Stichworte: Raspberrypi USB3 2.4GHz Probleme FRITZBox ESP32 HomeSpan

Danke fürs TUT!, bin gespannt ob es weitere Blogs dazu geben wird (von Teil zwei abgesehen) ;-)

Andreas Wolter

Andreas Wolter

@Nils: Die ESP32 Dev Kits müssen mit der Boot-Taste in den Downloadmodus gebracht werden. Wenn die Arduino IDE das Kompilieren beendet hat, versucht das esptool die Verbindung herzustellen. Dann muss man die Taste drücken, bis die Verbindung hergestellt ist.

Es gibt einen Hardware Hack, damit man das nicht ständig machen muss. Benötigt wird ein ein 10µF Kondensator. Der wird GND an GND und + an EN des ESP angeschlossen. Dann fällt das Tastedrücken weg.

Grüße,
Andreas Wolter

Nils

Nils

Super Blog, die LED läßt sich ohne Probleme mit dem IPhone steuern. Die einzige Hürde war den ESP dazu zu bringen den Sketch zu laden. Ich verwende das ESP32 Dev KitC V2 hier aus dem Shop, und bekomme den Download nur hin wenn ich die BOOT Taste drücke und wieder loslasse, sobald die Arduino IDE bestätigt, dass die Verbindung aufgebaut ist. Sollte doch eigentlich automatisch passieren bei diem Modul. Scheint ein Fehler zu sein. Weiß Jemand, wie man das fixen kann?

Leon

Leon

Hallo,
ich konnte das Problem leider bisher weder bei mir noch bei Kollegen beobachten.
Tritt das nur bei der Verbindung mit dem Wlan Router oder auch im persönlichen Hotspot auf?

Ansonsten kann dir in der GitHub Community (https://github.com/HomeSpan/HomeSpan) eventuell jemand weiterhelfen, da auch der Ersteller der Bibliothek sehr aktiv ist.

Mit freundlichen Grüßen

Mike

Mike

Hallo,
ich habe dasselbe Problem wie @Carsten mit dem WLAN:
E (1758) wifi:AP has neither DSSS parameter nor HT Information, drop it
E (1798) wifi:AP has neither DSSS parameter nor HT Information, drop it

Könnt ihr dabei helfen ?

Leon Ehring

Leon Ehring

Hallo Elias,
nein im Normalfall kannst du das ganz normal zu deinem Heimnetzwerk hinzufügen. Dann kannst du das als normales HomeKit Zubehör nutzen.
Die Verbindung mit dem Hotspot des IPhone ist eher ein minimal Beispiel, womit man externe Fehlerquellen ausschließen kann.

Mit freundlichen Grüßen

Carsten

Carsten

Hallo,
Danke erstmal für den Blog Eintrag, musste ich gleich mal ausprobieren :-)
Leider bekomme ich keine Verbindung zu meiner FritzBox (MAC Adressen Filter ist ausgeschaltet) und ich sehe auch keinen Verbindungsaufbauversuch im Log des Routers.
Im Seriellen Monitor habe ich die Credentials eingegeben und der ESP versucht “etwas”, allerdings kommt nur:
E (187432) wifi:AP has neither DSSS parameter nor HT Information, drop it
E (187495) wifi:AP has neither DSSS parameter nor HT Information, drop it
Trying to connect to XXXX. Waiting 2 second(s) for response…
….. wiederholt sich immer wieder
Hat dazu jemand vielleicht eine Idee?
Besten Dank und Grüße!

Elias

Elias

Hallo Leon,
Danke für den Beitrag! Das Thema kannte ich noch nicht und es ist super über diesen Blog darauf zu stoßen direkt mit einer kleinen Implementierung!

Funktioniert das HomeKit Netz nur in den persönlichen Hotspots der Geräte oder kann man die smarten Geräte auch im WLAN der Wohnung anmelden und dann mit einem Apple Geräte welches im gleichen WLAN ist Steuern?

Grüße
Weiter so!

Deja un comentario

Todos los comentarios son moderados antes de ser publicados