Erstes Matter HomeKit Gerät mit ESP32
Heute zeige ich euch wir ihr mit einem günstigen ESP32 euer erstes eigenes Matter Gerät programmieren und in HomeKit einbinden könnt.
Voraussetzung
Damit ihr euer erstes eigene Matter 1.0 WLAN-Licht programmieren könnt benötigt ihr folgendes:
- Arduino IDE (www.arduino.cc/en/software)
- Arduino Library https://github.com/datjan/esp32-arduino-matter (fork from https://github.com/jakubdybczak/esp32-arduino-matter)
- ESP32 DevKit (Amazon Link*)
Folgende Schritte werden wir nun durcharbeiten:
- Arduino IDE installieren
- Bordverwalter ESP32 2.0.5
- Library einbinden
- C++17 Support konfigurieren
- ESP32 mit Rechner verbinden
- Board Konfigurieren
- Sketch hochladen
- Serial Monitor auslesen
- Gerät in HomeKit hinzufügen
Arduino IDE installieren
Als erstes müssen wir die Arduino IDE installieren und den Bordverwalter für die ESP32 Module 2.0.5 (oder höher) hinzufügen.
Eine Anleitung dazu findet ihr hier.
Bordverwalter ESP32 2.0.5
Achtet darauf das ihr den Bordverwalter ESP32 mindestens in der Version 2.0.5 installiert habt. Solltet ihr eine ältere Version 1.0.x installiert haben müsst ihr diese zuerst deinstallieren!
Library einbinden
Damit unser Sketch auch wirklich läuft müssen wir folgende Bibliotheken runterladen (.zip) und in Arduino importieren:
C++17 Support konfigurieren
Wir konfigurieren den C++17 Support in dem wir folgende Datei unserer Arduino Installation bearbeiten:
Mac: /Benutzer/<USER>/Library/Arduino15/packages/esp32/hardware/esp32/2.0.5/platform.txt
Windows: C:\Users\<USER>\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.5\platform.txt
In der “platform.txt” suchen wir nun nach folgenden Stellen “-std=gnu++11” und ersetzen sie durch “-std=gnu++17“
ESP32 mit Rechner verbinden
Nun müsst ihr den ESP32 mit einem USB Kabel an eueren Rechner anschließen.
Board konfigurieren
Jetzt konfigurieren wir Arduino damit die korrekten Parameter für unser ESP32-Board genutzt werden.
- Tools -> Board -> esp32 -> ESP32-WROOM-DA Module
- Tools -> Port -> *Wählt hier den USB Port an dem ihr den ESP32 angeschlossen habt*
- Tools -> Erase All Flash Before Sketch Upload -> Enabled
- Tools -> Partition Scheme -> Minimal SPIFFS
Sketch Hochladen
Jetzt öffnet ihr ein neues Projekt und kopiert folgenden Sketch in die .ino Datei:
#include "Matter.h"
#include <app/server/OnboardingCodesUtil.h>
using namespace chip;
using namespace chip::app::Clusters;
using namespace esp_matter;
using namespace esp_matter::endpoint;
/**
* SERIAL MONITOR 115200 BAUD
*
* This program presents example Matter light device with OnOff cluster by
* controlling LED with Matter and toggle button.
*
* If your ESP does not have buildin LED, please connect it to LED_PIN
*
* You can toggle light by both:
* - Matter (via CHIPTool or other Matter controller)
* - toggle button (by default attached to GPIO0 - reset button, with debouncing)
*/
// Please configure your PINs
const int LED_PIN = 2;
const int TOGGLE_BUTTON_PIN = 0;
// Debounce for toggle button
const int DEBOUNCE_DELAY = 500;
int last_toggle;
// Cluster and attribute ID used by Matter light device
const uint32_t CLUSTER_ID = OnOff::Id;
const uint32_t ATTRIBUTE_ID = OnOff::Attributes::OnOff::Id;
// Endpoint and attribute ref that will be assigned to Matter device
uint16_t light_endpoint_id = 0;
attribute_t *attribute_ref;
// There is possibility to listen for various device events, related for example to setup process
// Leaved as empty for simplicity
static void on_device_event(const ChipDeviceEvent *event, intptr_t arg) {}
static esp_err_t on_identification(identification::callback_type_t type, uint16_t endpoint_id,
uint8_t effect_id, void *priv_data) {
return ESP_OK;
}
// Listener on attribute update requests.
// In this example, when update is requested, path (endpoint, cluster and attribute) is checked
// if it matches light attribute. If yes, LED changes state to new one.
static esp_err_t on_attribute_update(attribute::callback_type_t type, uint16_t endpoint_id, uint32_t cluster_id,
uint32_t attribute_id, esp_matter_attr_val_t *val, void *priv_data) {
if (type == attribute::PRE_UPDATE && endpoint_id == light_endpoint_id &&
cluster_id == CLUSTER_ID && attribute_id == ATTRIBUTE_ID) {
// We got an light on/off attribute update!
boolean new_state = val->val.b;
digitalWrite(LED_PIN, new_state);
}
return ESP_OK;
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
pinMode(TOGGLE_BUTTON_PIN, INPUT);
// Enable debug logging
esp_log_level_set("*", ESP_LOG_DEBUG);
// Setup Matter node
node::config_t node_config;
node_t *node = node::create(&node_config, on_attribute_update, on_identification);
// Setup Light endpoint / cluster / attributes with default values
on_off_light::config_t light_config;
light_config.on_off.on_off = false;
light_config.on_off.lighting.start_up_on_off = false;
endpoint_t *endpoint = on_off_light::create(node, &light_config, ENDPOINT_FLAG_NONE, NULL);
// Save on/off attribute reference. It will be used to read attribute value later.
attribute_ref = attribute::get(cluster::get(endpoint, CLUSTER_ID), ATTRIBUTE_ID);
// Save generated endpoint id
light_endpoint_id = endpoint::get_id(endpoint);
// Start Matter device
esp_matter::start(on_device_event);
// Print codes needed to setup Matter device
PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));
}
// Reads light on/off attribute value
esp_matter_attr_val_t get_onoff_attribute_value() {
esp_matter_attr_val_t onoff_value = esp_matter_invalid(NULL);
attribute::get_val(attribute_ref, &onoff_value);
return onoff_value;
}
// Sets light on/off attribute value
void set_onoff_attribute_value(esp_matter_attr_val_t* onoff_value) {
attribute::update(light_endpoint_id, CLUSTER_ID, ATTRIBUTE_ID, onoff_value);
}
// When toggle light button is pressed (with debouncing),
// light attribute value is changed
void loop() {
if ((millis() - last_toggle) > DEBOUNCE_DELAY) {
if (!digitalRead(TOGGLE_BUTTON_PIN)) {
last_toggle = millis();
// Read actual on/off value, invert it and set
esp_matter_attr_val_t onoff_value = get_onoff_attribute_value();
onoff_value.val.b = !onoff_value.val.b;
set_onoff_attribute_value(&onoff_value);
}
}
}
Den Sketch können wir nun unverändert auf unseren ESP32 hochladen.
Serial Monitor auslesen
Nun wechseln wir in den Arduino Serial Monitor und stellen die Baudrate auf 115200.
Sollten dort nur Hieroglyphen angezeigt werden kannst du den ESP32, nach dem ändern der Baudrate, noch mal kurz vom USB Kabel trennen und wieder anschliessen.
Danach sollte der Output so aussehen:
Den Pairing Code benötigen wir später zum hinzufügen zu HomeKit!
Gerät in HomeKit hinzufügen
Nun können wir endlich mit dem Spaß anfangen.
Da sich der ESP32 über Bluetooth anlernen und steuern lässt müsst ihr euer iPhone jetzt also nahe an den ESP32 heranbringen und dann erst in der Home App ein neue Gerät hinzufügen. Hierbei nutzt ihr die Funktion “Weitere Optionen …”. Dort wird euch das “Matter Accessory” angezeigt.
Nach dem klick auf “Matter Accessory” wird der Konfigurationscode aus dem Serial Monitor abgefragt.
Das Gerät ist kein zertifiziertes Matter Gerät und wird daher als unsicher gekennzeichnet. Ihr müsst hier auf “Trotzdem hinzufügen” klicken damit HomeKit das Gerät hinzufügt.
Der Pairing Prozess kann einige Minuten dauern, da nun eure WLAN Informationen an das Gerät übertragen werden. Danach wartet HomeKit darauf das das Gerät eine WLAN Verbindung aufbaut. Zuletzt wird das neue Matter Gerät noch im Apple Schlüsselbund hinterlegt.
Jetzt könnt ihr das neue Matter Gerät in HomeKit steuern. Solltet ihr das oben verlinkte ESP32 Board* verwendet könnt ihr nun die blaue LED auf dem Board an und ausschalten.
Fazit
Wie unser Beispiel zeigt können auch nicht Matter zertifizierte Geräte von HomeKit genutzt werden. Das ist ein riesiger Vorteil für uns. So bleibt die Möglichkeit weitere DIY Projekte zu realisieren.