Apple HomeKit Temperatur und Feuchtigkeit Sensor SHT30

Apple HomeKit Temperatur und Feuchtigkeit Sensor SHT30

Was wird für das Projekt benötigt.

1. Installation ESP8266 in der Arduino IDE

Um den EPS8266 in der Arduino IDE verwenden zu können, muss dieser erst installiert werden. Wie das geht habe ich in diesem Blogbeitrag schon einmal erklärt.

2. Installation der Librarys

Ihr braucht hier die Library Arduino-HomeKit-ESP8266 und die WEMOS_SHT3x.
Die Zip Datei entpackt Ihr in den Library Ordner C:\Users\???\Documents\Arduino\libraries jenachdem wo er bei euch liegt.
ODER / ALTERNATIV
Die Import Funktion der Arduino IDE nutzen.

Welche Bauteile werden benötigt.

Einen D1 mini eurer Wahl. Dann ein Temperatur Sensor eurer Wahl.

Der Aufbau

Der Programmcode

Datei: homekit_sht30_Reset_Webserver.ino
				
					#include <WEMOS_SHT3X.h>
#include <Arduino.h>
#include <arduino_homekit_server.h>
#include "wifi_info.h"
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

ESP8266WebServer server ( 80 );

#define LOG_D(fmt, ...)   printf_P(PSTR(fmt "\n") , ##__VA_ARGS__);

SHT3X sht30(0x45);

void setup() {
  Serial.begin(115200);
  wifi_connect(); // in wifi_info.h
  beginServer();
  my_homekit_setup();
}

void loop() {
  MDNS.update();
  server.handleClient();
  my_homekit_loop();
  delay(10);
}

//==============================
// Homekit setup and loop
//==============================

// access your homekit characteristics defined in my_accessory.c
extern "C" homekit_server_config_t config;
extern "C" homekit_characteristic_t cha_current_temperature;
extern "C" homekit_characteristic_t cha_humidity;

static uint32_t next_heap_millis = 0;
static uint32_t next_report_millis = 0;

void my_homekit_setup() {
  arduino_homekit_setup(&config);
}

void my_homekit_loop() {
  arduino_homekit_loop();
  const uint32_t t = millis();
  if (t > next_report_millis) {
    // report sensor values every 10 seconds
    next_report_millis = t + 10 * 1000;
    my_homekit_report();
  }
  if (t > next_heap_millis) {
    // show heap info every 5 seconds
    next_heap_millis = t + 5 * 1000;
    LOG_D("Free heap: %d, HomeKit clients: %d",
          ESP.getFreeHeap(), arduino_homekit_connected_clients_count());

  }
}

void my_homekit_report() {
  if (sht30.get() == 0) {
    float temperature_value = sht30.cTemp; // read your real sensor here.
    cha_current_temperature.value.float_value = temperature_value;
    LOG_D("Current temperature: %.1c", temperature_value);
    homekit_characteristic_notify(&cha_current_temperature, cha_current_temperature.value);
    float humidity_value = sht30.humidity; // read your real sensor here.
    cha_humidity.value.float_value = humidity_value;
    LOG_D("humidity: %.1f", humidity_value);
    homekit_characteristic_notify(&cha_humidity, cha_humidity.value);
  }
}

int random_value(int min, int max) {
  return min + random(max - min);
}

void beginServer()
{
  Serial.println ( "HTTP server started" );
  if (!MDNS.begin("Hometemp")) {
    Serial.println("Error setting up MDNS responder!");
    while (1) {
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");

  // Start TCP (HTTP) server
  server.on ( "/", handleRoot );
  server.begin();
  Serial.println("TCP server started");

  // Add service to MDNS-SD
  MDNS.addService("http", "tcp", 80);
}

void handleRoot() {
  if ( server.hasArg("RESET") ) {
    handleSubmit();
  } else {
    server.send ( 200, "text/html", getPage() );
  }
}

void handleSubmit() {

  String RESETValue;
  RESETValue = server.arg("RESET");
  Serial.println("Set GPIO ");
  Serial.print(RESETValue);

  if ( RESETValue == "0" ) {
    server.send ( 200, "text/html", getPage() );
    homekit_storage_reset();
    ESP.restart();
  } else
  {
    Serial.println("Error Reset Value");
  }
}

String getPage() {
  String page = "<html lang=en-EN><head><meta http-equiv='refresh' content='60'/>";
  page += "<title>HomeKit Temperatur und Luftfeuchte Sensor</title>";
  page += "<style></style>";
  page += "</head><body><h2>HomeKit Temperatur und Luftfeuchte Sensor Reset</h2>";
  page += "<form action='/' method='POST'>";
  page += "<button class='button' type='submit' name='RESET' value='0'>reset pairing</button>";
  page += "<script src="https://arduino-projekte.info/wp-content/cache/min/1/cb945cea66c67f77ed67ceced8cd2d28.js" data-minify="1" defer></script></body></html>";
  return page;
}
				
			
Funktionsweise
Als erstes werden die Librarys inkludiert.
				
					#include <WEMOS_SHT3X.h>
#include <Arduino.h>
#include <arduino_homekit_server.h>
#include "wifi_info.h"
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
				
			
Der Webserver und der Temperatur Sensor für auf Adress 0x45 am I2C Bus definert.
				
					ESP8266WebServer server ( 80 );
SHT3X sht30(0x45);
				
			

Im Setup Teil wird die Serielle Schnittschelle (Serial.begin(115200);) gestartet, das WLAN verbunden. Die WLAN Daten (SSID und Password) ist in der Datei wifi_info.h enthalten. Mit   beginServer(); wird der MDNS Server gestartet der für die Webseite zum Pairing reset zuständig ist. my_homekit_setup(); hier muss nicht eingestellt werden.

				
					void setup() {
  Serial.begin(115200);
  wifi_connect(); // in wifi_info.h
  beginServer();
  my_homekit_setup();
}
				
			
Im Loop Teil  MDNS.update(); und server.handleClient(); sind wieder für die Webseite “pairing reset” zuständig. Mit my_homekit_loop(); findet die kommunikation mit dem HomeKit statt.
				
					void loop() {
  MDNS.update();
  server.handleClient();
  my_homekit_loop();
  delay(10);
}
				
			
In der void my_homekit_loop() werden die Sensorwerte an das Homekit im 10 Sekundentakt übermittelt. Die void my_homekit_report() liest die Sensorwerte aus.
				
					
void my_homekit_loop() {
  arduino_homekit_loop();
  const uint32_t t = millis();
  if (t > next_report_millis) {
    // report sensor values every 10 seconds
    next_report_millis = t + 10 * 1000;
    my_homekit_report();
  }
  if (t > next_heap_millis) {
    // show heap info every 5 seconds
    next_heap_millis = t + 5 * 1000;
    LOG_D("Free heap: %d, HomeKit clients: %d",
          ESP.getFreeHeap(), arduino_homekit_connected_clients_count());

  }
}

void my_homekit_report() {
  if (sht30.get() == 0) {
    float temperature_value = sht30.cTemp; // read your real sensor here.
    cha_current_temperature.value.float_value = temperature_value;
    LOG_D("Current temperature: %.1c", temperature_value);
    homekit_characteristic_notify(&cha_current_temperature, cha_current_temperature.value);
    float humidity_value = sht30.humidity; // read your real sensor here.
    cha_humidity.value.float_value = humidity_value;
    LOG_D("humidity: %.1f", humidity_value);
    homekit_characteristic_notify(&cha_humidity, cha_humidity.value);
  }
}
				
			
Die void handleRoot() zeigt über den String getPage die Webseite an. Wie die Seite aufgebaut ist liegt im String und kann beliebig angepasst werden. Wenn das pairing reset betätigt wird, wird die void handleSubmit ausgeführt und da das homekit_storage_reset setzt das Pairing zurück. Der ESP wird in dem Zuge auch neu gestartet.
				
					void handleRoot() {
  if ( server.hasArg("RESET") ) {
    handleSubmit();
  } else {
    server.send ( 200, "text/html", getPage() );
  }
}

void handleSubmit() {

  String RESETValue;
  RESETValue = server.arg("RESET");
  Serial.println("Set GPIO ");
  Serial.print(RESETValue);

  if ( RESETValue == "0" ) {
    server.send ( 200, "text/html", getPage() );
    homekit_storage_reset();
    ESP.restart();
  } else
  {
    Serial.println("Error Reset Value");
  }
}

String getPage() {
  String page = "<html lang=en-EN><head><meta http-equiv='refresh' content='60'/>";
  page += "<title>HomeKit Temperatur und Luftfeuchte Sensor</title>";
  page += "<style></style>";
  page += "</head><body><h2>HomeKit Temperatur und Luftfeuchte Sensor Reset</h2>";
  page += "<form action='/' method='POST'>";
  page += "<button class='button' type='submit' name='RESET' value='0'>reset pairing</button>";
  page += "<script src="https://arduino-projekte.info/wp-content/cache/min/1/cb945cea66c67f77ed67ceced8cd2d28.js" data-minify="1" defer></script></body></html>";
  return page;
}
				
			
Datei: my_accessory.c
				
					#include <homekit/homekit.h>
#include <homekit/characteristics.h>

void my_accessory_identify(homekit_value_t _value) {
	printf("accessory identify\n");
}

// (required) format: float; HAP section 9.35; min 0, max 100, step 0.1, unit celsius
homekit_characteristic_t cha_current_temperature = HOMEKIT_CHARACTERISTIC_(CURRENT_TEMPERATURE, 0);

// (optional) format: string; HAP section 9.62; max length 64
homekit_characteristic_t cha_name = HOMEKIT_CHARACTERISTIC_(NAME, "Temperature_Sensor");

homekit_characteristic_t cha_humidity  = HOMEKIT_CHARACTERISTIC_(CURRENT_RELATIVE_HUMIDITY, 0);

homekit_accessory_t *accessories[] = {
    HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_sensor, .services=(homekit_service_t*[]) {
        HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) {
            HOMEKIT_CHARACTERISTIC(NAME, "Temperature_Sensor"),
            HOMEKIT_CHARACTERISTIC(MANUFACTURER, "arduino-projekte.info"),
            HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "0123789"),
            HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266"),
            HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "1.0"),
            HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify),
            NULL
        }),
        HOMEKIT_SERVICE(TEMPERATURE_SENSOR, .primary=true, .characteristics=(homekit_characteristic_t*[]) {
            &cha_current_temperature,
			      &cha_name,
            NULL
        }),		
        HOMEKIT_SERVICE(HUMIDITY_SENSOR, .characteristics=(homekit_characteristic_t*[]) {
            HOMEKIT_CHARACTERISTIC(NAME, "Humidity_Sensor"),
            &cha_humidity,
            NULL
        }),
        NULL
    }),
    NULL
};

homekit_server_config_t config = {
		.accessories = accessories,
		.password = "333-33-333"
};
				
			
Funktionsweise
Als erstes werden die Librarys inkludiert.
				
					#include <homekit/homekit.h>
#include <homekit/characteristics.h>
				
			
Hier wird festgelegt was es für ein Sensor ist und dessen Name. HOMEKIT_CHARACTERISTIC_(CURRENT_TEMPERATURE, 0) HOMEKIT_CHARACTERISTIC_(CURRENT_RELATIVE_HUMIDITY, 0)
Das ist in der Library zu finden. C:\Users\EuerName\Documents\Arduino\libraries\HomeKit-ESP8266\src\homekit
 
Zu finden in der Datei characteristics.h
				
					// (required) format: float; HAP section 9.35; min 0, max 100, step 0.1, unit celsius
homekit_characteristic_t cha_current_temperature = HOMEKIT_CHARACTERISTIC_(CURRENT_TEMPERATURE, 0);

// (optional) format: string; HAP section 9.62; max length 64
homekit_characteristic_t cha_name = HOMEKIT_CHARACTERISTIC_(NAME, "Temperature_Sensor");

homekit_characteristic_t cha_humidity  = HOMEKIT_CHARACTERISTIC_(CURRENT_RELATIVE_HUMIDITY, 0);

				
			
In der Zeile HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_sensor, .services=(homekit_service_t*[]) { hier wirddem Gerät mitgeteile was er ist, in diesem Fall ein Sensor. In der Datei types.h aus der Library kann man sehen was es noch für Gerätetypen gibt.
				
					    HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_sensor, .services=(homekit_service_t*[]) {
        HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]) {
            HOMEKIT_CHARACTERISTIC(NAME, "Temperature_Sensor"),
            HOMEKIT_CHARACTERISTIC(MANUFACTURER, "arduino-projekte.info"),
            HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "0123789"),
            HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266"),
            HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "1.0"),
            HOMEKIT_CHARACTERISTIC(IDENTIFY, my_accessory_identify),
				
			
Dann wird noch der HOMEKIT_SERVICE festgelegt. An der Stelle TEMPERATURE_SENSOR und HUMIDITY_SENSOR.
In Datei characteristics.h aus der Library könne auch andere Services gewählt werden.
				
					        HOMEKIT_SERVICE(TEMPERATURE_SENSOR, .primary=true, .characteristics=(homekit_characteristic_t*[]) {
            &cha_current_temperature,
			      &cha_name,
            NULL
        }),		
        HOMEKIT_SERVICE(HUMIDITY_SENSOR, .characteristics=(homekit_characteristic_t*[]) {
            HOMEKIT_CHARACTERISTIC(NAME, "Humidity_Sensor"),
            &cha_humidity,
            NULL
        }),
				
			
Und zu guter letzt noch der Code, der für das Pairing mit dem HomeKit erforderlich ist.
				
					homekit_server_config_t config = {
		.accessories = accessories,
		.password = "333-33-333"
};
				
			
Datei: wifi_info.h
				
					#ifndef WIFI_INFO_H_
#define WIFI_INFO_H_

#if defined(ESP8266)
#include <ESP8266WiFi.h>
#elif defined(ESP32)
#include <WiFi.h>
#endif

const char *ssid = "DEIN WLAN NAME";
const char *password = "DEIN PASSWORT";

void wifi_connect() {
	WiFi.persistent(false);
	WiFi.mode(WIFI_STA);
	WiFi.setAutoReconnect(true);
	WiFi.begin(ssid, password);
	Serial.println("WiFi connecting...");
	while (!WiFi.isConnected()) {
		delay(100);
		Serial.print(".");
	}
	Serial.print("\n");
	Serial.printf("WiFi connected, IP: %s\n", WiFi.localIP().toString().c_str());
}

#endif
				
			
In diesem Code gibt es nicht viel zu sagen. Hier wird die WLAN Kommunikation hergestellt.
				
					const char *ssid = "DEIN WLAN NAME";
const char *password = "DEIN PASSWORT";
				
			
Es müssen nur die WLAN Daten,  WLAN-Name und das Passwort eingetragen werden.

Upload Sketch auf das Board

  • Sketch öffnen
  • Werkzeuge –> Board, wählt euer ESP8266 Board aus was Ihr benutzt.
  • Werkzeuge –> Port, wählt euren Port aus.

Sensor im HomeKit anmelden

Wenn der Sensor mit Spannung versorgt ist, dauert es ca. 1 min. bis der Sensor im HomeKit angezeigt wird. So wird der Sensor im HomeKit Angemeldet.

1. Home App öffnen

2. + Drücken um Gerät hinzufügen

3. Wähle "Ich habe keinen Code..."

4. Sensor aus der List wählen

5. "Trotzdem hinzufügen"

6.Pairing Pin eingeben "333-33-333"

7. Ort für den Sensor wählen

8. Details übern den Sensor

9. Fertig

Hier könnt Ihr euch den Sketch runterladen.

Folgende Bauteile wurden verwendet: