Apple HomeKit mit ESP32 - Teil 2
Bonjour et bienvenue à la deuxième partie de la série de blogs sur HomeKit !
Comme nous l'avons déjà annoncé dans le premier blog post, aujourd'hui je vais d'abord traiter des bases plus théoriques. Ensuite, j'implémenterai un capteur de température et d'humidité.

ACCESSOIRES

En gros, le HAP fait la distinction entre les ponts et les accessoires, un pont pouvant combiner jusqu'à 150 accessoires et les faire entrer dans HomeKit avec une seule connexion. À titre d'exemple, vous pouvez nommer un pont Zigbee qui transfère tous les produits Zigbee dans le réseau HomeKit en ajoutant uniquement le pont à HomeKit.
Chaque accessoire HomeKit est défini par le modèle de données HomeKit, qui se compose d'accessoires, de services et de caractéristiques. Le HAP définit également comment le code de configuration à 8 chiffres nécessaire à la connexion initiale doit être généré. Cela doit se faire soit sur le dispositif à chaque configuration initiale, indépendamment des données uniques du dispositif, soit de manière aléatoire pour chaque dispositif en production, auquel cas le code doit être stocké conformément au protocole de mot de passe distant sécurisé. Dans les deux cas, le générateur de codes aléatoires doit être sécurisé par des moyens cryptographiques. En outre, un certain nombre de combinaisons de codes très simples sont interdites.

La figure suivante montre, par exemple, le service d'information qui doit être défini pour chaque accessoire et pont HomeKit. Dans le protocole d'accessoire HomeKit, les services représentent l'élément fournissant le contexte d'un accessoire et, selon le type d'accessoire dont il s'agit, contiennent les caractéristiques nécessaires et facultatives correspondantes.

Figure 2: Extraits du protocole d'accessoires Homekit pour le service d'information. (Apple, Spécification du protocole accessoire Homekit. Version non commerciale, version R2, 2019)

Un extrait du protocole de l'accessoire HomeKit pour le service d'information. (Apple, HomeKit Accessory Protocol Specification. Non-Commercial Version, Release R2, 2019)

Le tableau montre que le service d'information, par exemple, doit nécessairement contenir comme caractéristiques la version du micrologiciel, le nom de l'appareil et le numéro de série. Un exemple plus complexe du modèle de données HomeKit serait un ventilateur avec une ampoule et un humidificateur. Ce dispositif représente un accessoire qui se compose de trois services, le service du ventilateur, le service de l'ampoule et le service du purificateur d'air. Ces trois services ont tous leurs propres caractéristiques nécessaires et facultatives. Dans l'app HomeKit standard, cet appareil serait désormais affiché comme un seul appareil et les services correspondants pourraient être définis. Les trois services pourraient également être divisés en trois accessoires individuels qui sont amenés ensemble dans HomeKit via un pont. Dans ce cas, il serait alors possible de visualiser les différents appareils de manière totalement individuelle, c'est-à-dire de les placer dans différentes pièces dans l'application Home.

Comme on peut également le voir sur la figure 2, chaque service HAP possède un UUID, et il en va de même pour chaque caractéristique HAP. Un UUID est un "Universally Unique IDentifier" de 128 bits tel que défini dans le RFC 4122. Un UUID est un identifiant unique au monde qui, en raison de sa taille de 128 bits et du nombre d'identifiants possibles qui en résulte, est unique même sans comité de distribution central, mais grâce à la génération possible dans le RFC 4122 sur la base d'un horodatage. Les UUID offrent donc la possibilité d'identifier de manière unique à la fois les services et les caractéristiques. Ceci est particulièrement important pour la communication via BluetoothLE, car les "Bluetooth Generic Attributes" (GATT en abrégé) sont utilisés à cet effet, qui reposent sur les UUID comme identifiants uniques.

Sécurité

Le thème de la sécurité joue un rôle de plus en plus important dans le secteur du smarthome, car de plus en plus d'appareils ménagers sont intégrés au smarthome et sont donc également vulnérables aux attaques. Cela s'applique aussi bien aux attaques provenant de l'Internet, dans le cas où ils sont en réseau, que directement aux attaques provenant du réseau local. Cela concerne d'une part les sujets relatifs à la sécurité de la maison, comme les serrures de porte ou les systèmes d'alarme, et d'autre part tous les domaines liés à la vie privée, comme les microphones et les caméras notamment.

C'est pourquoi les appareils HomeKit communiquent exclusivement via un chiffrement de bout en bout, garanti par Apple dans le cadre du kit de développement d'accessoires HomeKit. La connexion initiale, appelée "configuration de la paire", est réalisée par une procédure de cryptage asymétrique. Il s'agit explicitement d'un processus unique de configuration de l'appareil. Le protocole Stanford Secure Remote Password est utilisé pour l'échange sécurisé de clés. Au lieu de la fonction de hachage SHA-1, qui est obsolète, on utilise la fonction de hachage SHA-512, qui est basée sur SHA-2. Le générateur est défini par le groupe de 3072 bits dans le RFC 5054. En plus de la méthode de cryptage asymétrique, l'utilisateur doit également saisir une combinaison de chiffres à 8 chiffres sur son appareil iOS, qui est mappée en conséquence sur l'accessoire HomeKit. Après l'initialisation, une "vérification de la paire" est effectuée pour chaque session ultérieure, c'est-à-dire pour la communication. Un cryptage synchrone est ensuite effectué avec une nouvelle clé générée pour chaque session. La clé correspondante est générée selon la méthode Ephemeral-Diffie-Hellman et ainsi, même si la clé est volée, aucune communication antérieure ne peut être déchiffrée avec elle. C'est ce qu'on appelle le "forward secrecy". Afin d'empêcher autant que possible le vol de la clé, toutes les clés nécessaires au chiffrement, c'est-à-dire même la clé publique nécessaire à la configuration de la paire et à tous les processus connexes, doivent être spécialement sécurisées dans un appareil certifié par Apple pour HomeKit. Apple recommande à cet effet l'utilisation d'une puce de sécurité au niveau matériel, mais permet entre-temps de sécuriser les processus au niveau logiciel. 

Comme nous l'avons mentionné au début, les caméras munies de microphones sont un aspect particulièrement critique pour la protection de la vie privée dans le smarthome. C'est pour cette raison que la fonction " HomeKit Secure Video " a été introduite. Les caméras doivent chiffrer leurs données avec au moins 128 bits AES, mieux 256 bits AES, pour une certification HomeKit Secure Video correspondante, en plus du même chiffrement de bout en bout qui s'applique à tous les appareils HomeKit. Grâce à ce cryptage, toutes les séquences sont cryptées et anonymisées pendant 7 jours dans iCloud. En outre, toutes les analyses du matériel image, par exemple la reconnaissance de personnes, d'animaux ou de paquets, ont lieu localement sur un Hub HomeKit, c'est-à-dire un iPad, une Apple TV ou un HomePod, et non dans le cloud.

Enfin, il faut dire que malgré un certain niveau de sécurité grâce au chiffrement, les appareils Smarthome issus du cadre HomeKit comportent également un certain risque de failles de sécurité, dont les utilisateurs doivent être conscients et contre lesquelles ils doivent prendre les mesures appropriées pour se protéger. Par exemple, les appareils HomeKit sans Hub HomeKit pourraient également être exploités localement dans une certaine mesure. D'autres possibilités consisteraient à faire fonctionner les appareils dans un VLAN distinct du réseau principal, c'est-à-dire un réseau local virtuel, ou, dans le cas des caméras, à éviter les sections d'image extrêmement critiques, par exemple dans la salle de séjour.

Structure du matériel

Composants et brochage

Pour la mise en œuvre, vous avez besoin :

Numéro Composant Note
1 ESP-32 Dev Kit C V4 - AZ-Delivery Il est également possible d'utiliser d'autres versions de l'ESP32.
1 DHT22 Capteur de Température et humidité - AZ-Delivery Il est également possible d'utiliser la carte de circuit imprimé déjà équipée d'une résistance de rappel.
1 Resistor Kit 525 pièces de résistance 0 Ohm -1M Ohm – AZ-Delivery Une sélection de différentes résistances, une résistance de 10k Ohm est nécessaire.
1 Câble Jumper 3 x 40 pcs. chacun 20 cm M2M/ F2M / F2F AZ-Delivery 4 fils de liaison femelle/femelle sont nécessaires. S'il n'est pas disponible, le set spécifié est recommandé.


Voici la disposition des broches de l'ESP32 donnée ci-dessus :

Pincement

Voici la disposition des broches du DHT22 donnée ci-dessus :

DHT22


  • Vin - c'est la broche d'alimentation. Pour une utilisation avec un ESP32, 3,3 V doivent être appliqués ici.
  • DATA - ligne de données. Cette broche nécessite une résistance pull-up de 10K vers Vin.
  • NULL - sans fonction
  • GND - Ground 

Câblage


schéma

Les broches suivantes doivent être connectées ensemble pour construire le circuit :

  1. La broche Vin du DHT22 doit être connectée à la broche 3.3V du microcontrôleur.
  2. La broche GND du DHT22 doit être connectée à n'importe quelle broche GND du microcontrôleur.
  3. La broche de données du DHT22 doit être connectée à une broche GPIO du microcontrôleur. De plus, une résistance pull-up vers Vin doit être insérée.

Structure logicielle

Les bibliothèques utilisées dans ce projet sont la bibliothèque "HomeSpan" mentionnée précédemment pour intégrer le protocole d'accessoires HomeKit et la bibliothèque "Adafruit_DHTxx" pour lire le capteur de température utilisé. Les deux bibliothèques peuvent être installées via le gestionnaire de bibliothèque dans l'IDE Arduino.

La bibliothèque HomeSpan reprend l'implémentation du protocole d'accessoires HomeKit dans la variante open source R2. Le modèle de données HomeKit, c'est-à-dire l'ensemble des accessoires fournis par Apple, incluant leurs services et leurs caractéristiques, présente ici un intérêt particulier. Seuls les dispositifs de son et de vidéo ne peuvent être créés en raison de leurs exigences matérielles accrues. HomeSpan permet une programmation complète des accessoires HomeKit dans l'IDE Arduino et offre également une interface en ligne de commande avec un niveau élevé d'informations de débogage et de messages d'erreur.

Pour une bonne structuration, le programme est réparti en trois parties. La première partie "HomeSpan-DHT22-Temperature-Sensor" correspond à la fonction principale. Il se charge de définir les accessoires HomeKit et crée des objets qui représentent le serveur HAP des appareils définis. En outre, contrairement au premier blog post, l'accessoire HomeKit est défini comme un pont, de sorte que plusieurs appareils peuvent être appariés via une seule connexion dans le cadre de ce dernier. La deuxième partie du programme "DEV_Identify.h" est une fonction permettant une création plus claire et plus rapide des accessoires HomeKit. On transmet à cette fonction les données du "Service d'information sur les accessoires" sous forme de chaîne de caractères, puis on crée un accessoire HomeKit à partir de ces données en appelant les fonctions HAP correspondantes. En outre, le processus d'initialisation visible requis dans le HAP est mis en œuvre par une LED clignotante, mais cela n'est pas représenté dans le matériel de ce projet. Dans la troisième partie du programme, "DEV_Sensors.h", tous les autres services nécessaires ou facultatifs de l'accessoire sont définis et la routine de lecture des données du capteur, ou dans le cas des actionneurs, la routine d'exécution de l'actionneur, est créée.

Dans ce cas précis, le DHT22 a été intégré comme capteur. Ce capteur contient un capteur de température et un capteur pour déterminer l'humidité. Tout d'abord, tous deux reçoivent le service d'information sur les accessoires, qui est nécessaire pour chaque accessoire HomeKit. Ce service contient la version du micrologiciel, une routine d'identification, un fabricant, la désignation du modèle, un nom et le numéro de série comme caractéristiques. Ensuite, dans la zone "DEV_Sensors.h", les capteurs ont été implémentés avec leurs services correspondants. Pour le capteur de température, par exemple, la gamme de fonctionnement de la température a été modifiée de 0 à 100 degrés Celsius, qui sont stockés en standard dans HomeKit, à -50 à 100 degrés Celsius, c'est-à-dire la gamme du capteur de température qui peut être prise dans la fiche technique. En outre, la caractéristique de la température actuelle a été déclarée. Toutes les 10 secondes, la valeur de la température est définie et donc transmise à HomeKit. Ici, nous nous limitons à un intervalle de temps quelconque afin de ne pas surcharger inutilement le réseau domestique.
La même chose est mise en œuvre pour le capteur d'humidité.

Le code source est commenté et disponible sous forme de dépôt GitHub pour le téléchargement et les tests.

HomeSpan-DHT22-Temperatur-Sensor.ino

/*********************************************************************************
  * MIT License
  *  
  * Copyright (c) 2020 Gregg E. Berman
  *  
  * https://github.com/HomeSpan/HomeSpan
  *  
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  * copies of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
  *  
  * The above copyright notice and this permission notice shall be included in all
  * copies or substantial portions of the Software.
  *  
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *  
  ********************************************************************************/
 
 ////////////////////////////////////////////////////////////
 //                                                       //
 //   HomeSpan: A HomeKit implementation for the ESP32   //
 //   ------------------------------------------------   //
 //                                                       //
 ////////////////////////////////////////////////////////////
 
 #include "HomeSpan.h"
 #include "DEV_Identify.h"      
 #include "DEV_Sensors.h"
 
 void setup() {
   
   Serial.begin(115200);
   homeSpan.begin(Category::Bridges,"AZDelivery Temp Sensor Bridge");
 
   new SpanAccessory();  
     new DEV_Identify("AZDelivery HomeKit","SmartHomeFactory","123-ABC","HS Bridge","0.9",3);
     new Service::HAPProtocolInformation();
       new Characteristic::Version("1.1.0");
       
   new SpanAccessory();                                                          
     new DEV_Identify("DHT22 Temp Sensor","SmartHomeFactory","123-ABC","Sensor","0.9",0);
     // Create a Temperature Sensor (see DEV_Sensors.h for definition)
     new DEV_TempSensor();
         
 
   new SpanAccessory();
     new DEV_Identify("DHT22 Humidity Sensor","SmartHomeFactory","123-ABC","Sensor","0.9",0);
     // Create a Humidity Sensor (see DEV_Sensors.h for definition)
     new DEV_HumSensor();
     
 // end of setup()
 
 //////////////////////////////////////
 
 void loop(){
   
   homeSpan.poll();
   
 // end of loop()

DEV_Identify.h

  //////////////////////////////////
 //   DEVICE-SPECIFIC SERVICES   //
 //////////////////////////////////
 
 struct DEV_Identify : Service::AccessoryInformation {
 
   int nBlinks;                    // number of times to blink built-in LED in identify routine
   SpanCharacteristic *identify;   // reference to the Identify Characteristic
   
   DEV_Identify(const char *nameconst char *manuconst char *snconst char *modelconst char *versionint nBlinks) : Service::AccessoryInformation(){
     
     new Characteristic::Name(name);                   // create all the required Characteristics with values set based on above arguments
     new Characteristic::Manufacturer(manu);
     new Characteristic::SerialNumber(sn);    
     new Characteristic::Model(model);
     new Characteristic::FirmwareRevision(version);
     identify=new Characteristic::Identify();          // store a reference to the Identify Characteristic for use below
 
     this->nBlinks=nBlinks;                            // store the number of times to blink the LED
 
     pinMode(homeSpan.getStatusPin(),OUTPUT);          // make sure LED is set for output
  }
 
   boolean update(){
       
     for(int i=0;i<nBlinks;i++){
       digitalWrite(homeSpan.getStatusPin(),LOW);
       delay(250);
       digitalWrite(homeSpan.getStatusPin(),HIGH);
       delay(250);
    }
 
     return(true);                               // return true
     
  } // update
   
 };

DEV_Sensors.h

 /////////////////////////////////
 //   DEVICE-SPECIFIC SERVICES //
 ////////////////////////////////
 #include "DHT.h"
 
 #define DHTPIN 17
 #define DHTTYPE DHT22
 
 // reference to the Sensor Objects
 DHT dht(DHTPINDHTTYPE);
 
 // A standalone Temperature sensor
 struct DEV_TempSensor : Service::TemperatureSensor {    
 
   // reference to the Current Temperature Characteristic
   SpanCharacteristic *temp;                                      
 
   // constructor() method
   DEV_TempSensor() : Service::TemperatureSensor() {      
 
     // start dhttemp Object
     dht.begin();                                    
 
     // instantiate the Current Temperature Characteristic
     temp = new Characteristic::CurrentTemperature(-10.0);    
     // expand the range from the HAP default of 0-100 to -50 to 100 to allow for negative temperatures
     temp->setRange(-50100);                                
 
     // initialization message
     Serial.print("Configuring Temperature Sensor");          
     Serial.print("\n");
 
  } // end constructor
 
   void loop() {
 
     // the temperature refreshes every 10 seconds by the elapsed time
     if (temp->timeVal() > 10000) {
       // read temperature from sensor dht22
       float temperature = dht.readTemperature();        
       // set the new temperature; this generates an Event Notification and also resets the elapsed time
       temp->setVal(temperature);                            
 
       LOG1("Temperature Update: ");
       LOG1(temperature);
       LOG1(" ; ");
    }
  } // loop
 };
 
 ////////////////////////////////////
 
 // A standalone Humidity sensor
 struct DEV_HumSensor : Service::HumiditySensor {    
 
   // reference to the Current Humidity Characteristic
   SpanCharacteristic *hum;                                  
 
   // constructor() method
   DEV_HumSensor() : Service::HumiditySensor() {      
 
     // start dhthum Object
     dht.begin();                                  
 
     // instantiate the Current Temperature Characteristic
     hum = new Characteristic::CurrentRelativeHumidity(50);
     // expand the range to 30%-100%
     hum->setRange(30100);                                
 
     // initialization message
     Serial.print("Configuring Humidity Sensor");          
     Serial.print("\n");
 
  } // end constructor
 
   void loop() {
 
     // the humidity refreshes every 10 seconds by the elapsed time
     if (hum->timeVal() > 10000) {
       // read humidity from sensor dht22
       float humidity = dht.readHumidity();  
       // set the new humidity; this generates an Event Notification and also resets the elapsed time        
       hum->setVal(humidity);                            
 
       LOG1("Humidity Update: ");
       LOG1(humidity);
       LOG1(" ; ");
    }
  } // loop
 };
 
 //////////////////////////////////

Configuration

Console de démarrage

Il s'agit du mode de configuration de notre capteur de température HomeKit, auquel on peut accéder via la console série de l'IDE Arduino. Notez que le débit en bauds correct doit être défini. Le WLAN peut être configuré en tapant un "W".

Console WiFi

Ici, le Wi-Fi est maintenant configuré et le capteur HomeKit s'est connecté au réseau local. Désormais, il peut être ajouté à votre maison HomeKit sur votre appareil IOS avec le code de configuration standard "466-37-726".

Cela ressemble à ceci dans l'application HomeKit standard, par exemple :

Homekit

J'espère que vous vous amuserez à les réaliser !

Esp-32Projekte für anfänger

13 commentaires

Björn

Björn

Hi!

Ich habe meinen Fehler gefunden. Die Meldung „Geräteerkennung fehlgeschlagen“ scheint zu kommen, wenn der Sensor keine korrekten Werte/Daten liefert.

Dies hatte ich mit folgendem Programm getestet:
https://randomnerdtutorials.com/esp32-dht11-dht22-temperature-humidity-sensor-arduino-ide/

Dort kam immer der Lesefehler. Nachdem ich dann auch den korrekten Pin im Board erwischt hatte, lieferte der Sensor korrekte Werte und lies sich auch in Apple HomeKit einbinden.

Jonas

Jonas

Moin, sieht bei mir genauso aus. Geräterkennung fehlgeschlagen… wäre für jeden tipp dankbar

Björn

Björn

Moin!

Bei mir funktioniert fast alles … aber eben nur fast. Beim Einfügen der Bridge ins HomeKit bekomme ich die Fehlermeldung “Geräteerkennung fehlgeschlagen”. Gibt es eine Idee woran dies liegt bzw. was man dagegen tun muss?

Andreas Wolter

Andreas Wolter

@Gonzalo: please check the external repo and documentation of the HomeSpan Library:

https://bytemeta.vip/index.php/repo/HomeSpan/HomeSpan
https://github.com/HomeSpan/HomeSpan/blob/master/docs/Overview.md

Gonzalo

Gonzalo

hello. Thank you very much for posting this project. I’m from chile. I have a little problem. the esp32 disconnects many times from the wifi and therefore I cannot access the information of the sensors through the iPhone. Is there a way to automatically reconnect? For it to work properly again, I press the “EN” button and it works again, but ideally it would connect automatically… greetings and excellent work!

Leon

Leon

Hallo Oliver,
meinst du die Meldung, dass das Gerät nicht zertifiziert und deswegen möglicherweise nicht kompatibel ist oder eine andere Fehlermeldung?
Die Home App warnt bei der Registrierung immer vor allen nicht ganz offiziell von Apple zertifizierten Geräten.

Mit freundlichen Grüßen
Leon

Oliver

Oliver

Hi… Ich konnte den ESP32 erfolgreich konfigurieren.
Nur sagt mit meine HOME APP, daß das zu verbindende Gerät nicht kompatibel ist.
Was kann ich tun?
Danke

Leon

Leon

Hallo Thomas,
hat sich dein Problem mit der Stromversorgung inzwischen aufgelöst?
Meine Erfahrung heirbei ist, dass man teilweise beim Testen in Situationen gelangt in denen sich der ESP32 entweder nicht mehr mit dem Wlan oder dem entsprechenden Homekit Gerät verbinden will. In dem Fall hilft es häufig über das CLI mit ‘E’ einmal alle Daten zu löschen und den ESP neu mit WLAN und Homekit zu verbinden.
Mit der Anzeige der Luftfeuchtigkeit hatte ich tatsächlich auch öfters Probleme und eine andere Lösung als die Range entsprechend anzupassen ist mir hier leider auch nicht bekannt. Wenn sich hier etwas neues ergibt würde ich mich nochmal melden.

Viele Grüße
Leon

Renhold

Renhold

Wenn die Range 0..100% konfiguriert ist, stimmt die Anzeige.
hum→setRange(0, 100);

Hendrik

Hendrik

Moin, ich habe auch das Problem, dass in der Übersicht ein knapp 20% geringerer Wert für die Luftfeuchtigkeit angezeigt wird. Wenn ich den Wert direkt anzeigen lasse, wird der korrekte Wert angezeigt.

Thomas Hecker

Thomas Hecker

Hallo Leon,
ich habe da noch eine Nachfrage.
Mein Versuch den Sensor nun unabhängig von einem USB Anschluß zu betreiben scheitert. Weder die Versorgung über 3,3V noch 5V führt zum Erfolg. Die LED des ESP32 leuchtet zwar aber vermutlich kann er sich nicht ins WLAN einloggen. Auf den Serial Monitor kann ich nicht zugreifen es sei denn ich schließe wieder das USB Kabel an. Hast Du da, gerne auch jemand der das Problem bereits gelöst hat, einen Rat?
Viele Grüße
Thomas

Thomas Hecker

Thomas Hecker

Vielen Dank für das schöne Projekt!
Ich bin noch sehr am Anfang mit der Arduino-ESP Bastelei, hatte aber bei der praktischen Umsetzung keine Probleme. Die Theorie dahinter ist noch in mehr oder weniger dichtem Nebel.
Die Anzeige der Bridge in Home weist bei der Feuchtigkeit einen niedrigeren Wert (18%) aus als ich ihn gezeigt bekomme wenn ich mir die einzelnen Komponenten der Bridge anzeigen lasse. Feuchtigkeit 40%.
Lässt sich das im Programmcode anpassen? Umrechnung anders?
Viele Grüße
Thomas

Michael

Michael

Hallo, sehr schön Dein Prjekt. Schöner wäre es wenn due einen “GY-BME280” Sensor genommen hättest. Sind genauer.

Laisser un commentaire

Tous les commentaires sont modérés avant d'être publiés