ESPHap is an Arduino library which natively implements Apple's HomeKit protocol for your ESP32/ESP8266 based projects without the need for additional bridges. ESPHap currently supports both ESP32 and ESP8266.
Please note: There are some minor known bugs within the ESP8266 implementation, especially during device pairing. Not all pairing attempts succeed, it can take up to 3 attempts to pair devices. Once paired, devices work well and stable though. ! Since version v1.0.7and usage IOS >14 the pairing process is stable for ESP8266, therefore known bugs are fixed and library can be easilly used for ESP8266
ESPHap allows to implement up to 16 different accessories on the same ESP32/ESP8266 board.
Many thanks to maximkulkin for providing some fine libraries for native integration and which are part of this project.
Many thanks to Mixiaoxiao for hinting on how to stop the watchdog on ESP8266 and also on how to implement low memory usage functions.
This project makes use of wolfSSL, an embedded, lightweight SSL library written in ANSI C and targeted for embedded systems like RTOS. wolfSSL needs to be slightly patched and this section describes some technical details for users who had already installed wolfSSL.
ESPHap for ESP32 works well with wolfSSL versions 4.2.0 and 3.13.0. Full instruction on how to configure wolfSSL can be found here.
To simplify installation, ESPHap comes with pre-configured versions of wolfSSL which can be used out of the box. Extract either wolfSSL_3_13_0.rar or wolfssl.rar into an Arduino library folder named "wolfssl".
If you want to configure wolfSSL yourself, please use settings.h and user_settings.h from the provided preconfigured libraries as reference, you will need to edit these files according to your needs.
ESPHap for ESP8266 only works with wolfSSL 3.13.0.
To simplify installation, ESPHap comes with a pre-configured and slightly patched versions of wolfSSL 3.13.0 which can be used out of the box. Extract wolfSSL_3_13_0.rar into an Arduino library folder named "wolfssl". ESPHap ONLY works with the provided patched wolfSSL version.
! Note for ESP8266 boards select lwIP Variant :v2 High bandwidth. Device behaviours is more stable especially in pairing process
Some of the more advanced code examples below come with an integrated webserver which features a SPIFFS (Serial Peripheral Interface Flash File System) backend. The webserver is often used to display sensor data, control devices, configure device WiFi settings or to store data like Homekit binding credentials or historical sensor data. Once you've connected your device to your WLAN, it will be available under http://IPADDRESS/
. Your IP address is displayed within Arduino's serial monitor window during the boot sequence, so the IP is 172.16.0.169 in this case:
Also, the list of available website pages for your device is displayed, so http://IPADDRESS/
, http://IPADDRESS/browse
and http://IPADDRESS/update
in the above case.
http://IPADDRESS/
Your device's root page located under http://IPADDRESS/
is usually configured to display sensor data, like temperature and humidity in the Thermostat DHT example:
http://IPADDRESS/browse
The file browser enables you to access the files stored on your device. More importantly, you are able to upload or delete files to or from your device.
For instance, if you want to delete the Homekit pairing data stored in pair.dat
, you may simply do so by clicking the correspondin delete button.
After any file operation you need to restart your device by clicking on "Press to restart" button.
The sketches EspHapLed (for ESP32) and EspHapLed8266 (for ESP8266) are very basic examples for how to handle (switching on/off) a simple LED connected to your board.
Before you compile your sketch you first need to:
const char* ssid = "WLAN SSID";
const char* password = "WLAN password";
const int led_gpio = 4;
This example does not implement any of the more sophisticated pairing options (like QR code), instead please choose manual pairing within your Apple Home app using the password 111 11 111. More detailed instructions on how to pair HomeKit devices with you Home app can be found here.
These examples can be used to handle other device like relays which implement two statuses on/off.
The example folder contains 3 sketches for Sonoff devices:
Sonoff is based on ESP8265 and the examples already work quite well. But still there some known problems especially during pairing phase. For more informations, please have a look at the extended instructions.
The example folder also contains a more advanced sketch for EspHapSonoff_RFBridge.
This is an alternative firmware for the Sonoff RF switch, which provides two accessories: switch and motion detection. The main idea of this sketch is to re-use the Sonoff RF module to accept signals from Sonoff PIR2 motion detection module and notify Apple Home app. This gives you the opportunity to define new scenarios within the Apple Home app (i.e. to define what should happen once a motion is detected). The Sonof RF has a RF module assigned to button in the original firmware, with this sketch you will loose this functionality. The sketch now interprets and treats a button press (directly or from RF signal) as a motion detection.
Example folders contains sketch for Advanced LED and Advanced dimmable LED This is sketch compatible with both ESP32 & ESP8266, handles LED Switching on/off, LED brightness and contains advanced features:
This is a basic demonstration of an advanced IOT device, which features such functionalities.
The example folder contains the two sketches Thermostat DHT and
Universal Thermostat which will implement temperature and humidity sensing within the Apple Home app. The sketches work both for ESP32 and ESP8266 and use Adafruit's DHT and BME280 sensor libraries which will work for many common DHT sensors. The sketches can easily be adjusted to work with other sensors.
The thermostat sketches also implement some more advanced features:
The Universal Thermostat sketch also able to send historical data to thingSpeak.
The example folder contains the sketch Switch, which implements a simple switch within the Apple Home app. The sketch works both for ESP32 and ESP8266 and could for example be used to control a relay.
This sketch also implements some advanced features:
Build instructions are the same as for sketches above.
The example folder contains the sketch RGB & Motion device, which implements a RGB bulb and a motion sensor within the Apple Home app. The sketch works for ESP32 and ESP8266 and is used to control a WS2812 LED strip via an attached motion sensor (HC-SR501 in this example).
This sketch also implements some advanced features:
The web site allows to demonstrate the bidirectional capabilities of Apple HomeKit: whenever color, brightness or state of the RGB strip is changed from the built-in web site, Apple HomeKit refreshes the corresponding values or state within the Apple Home app.
Any motion sensor can be used, the sketch simply checks for changes of the HIGH value of the predefined GPIO pin.
The sketch drives a WS2812 RGB strip but other types should work in a similier way, but you would have to figure out how to process color and brightness values received from the Home app or the built-in web site with your specific RGB strip.
The combination of a motion sensor along with a RGB strip (or a switch) is suited to demonstrate Apple Home Automation capabilities; based on the motion state, the RGB strip can be configured to be switched on or off.
Build instructions are the same as for the sketches above.
The example folder contains the sketch Button, which implements a button within the Apple Home app. This is a universal sketch applicable for ESP32 and ESP8266 (still in beta) and can be used to create Apple Home Automation scenarios within your Apple Home app.
This sketch also implements some advanced features:
Build instructions are the same as for the sketches above.
The example folder contains the sketch Air Quality sensor, which implements an Air Quality Sensor within Apple Home app. This sketch uses a MQ135 sensor and works both for ESP32 and ESP8266. The built-in web site displays historic data of the CO2 concentration. You need to enter the appropriate calibrattion data for your sensor, for this purpose the following line should be changed
const float factor=14.0; //to be calibrated with your MQ135
This sketch also implements some advanced features:
Build instructiona are the same as for the sketches above.
The example folder contains the sketch FAN, which implements a fan within Apple Home app. You are able to control fan characteristics such as
This sketch also implements some advanced features:
Build instructions are the same as for the sketches above.
This is one of the experimental scenario for ESP32 camera module. Sketch based on well known [example] (https://robotzero.one/esp32-face-door-entry/) with additional feathures. First of all it can works as simple motion detector and notify Apple that motion occurs.
Additionally :
it keeps functionality for face recognition and internal web site for camera setting and live video streaming.
Allow to handle servo (if that attached) for camera position
If face recognized it's able to send RF signal. So any receiver can validate signal and apply any action for instance open a door lock
Possibility to send e-mail with capture, when motion detected
All of that is experimental. But main achievemnts is to find a way how to detect motion, due to the lot of bug's and limitation in camera API's. I found a fastest way (in my opinion). Main algorith is traditional: comparing two camera snapshots and based on the sensitivity level and pixels changed detect motion. This looks abnormally but fastest way is:
To achieve this, PSRAM memory is used and it's enought for two snapshots less than 1280x1024.
*Additionally, due to specific SPIFFS usage this is a good example how to keep pairing data in the EEPROM
extern "C"{
}
2. If you are using ESP8266, add the following to the setup section
```c
#ifdef ESP8266
disable_extra4k_at_link_time();
#endif
Initialize the file storage to store pairing information (any filename will do)
init_hap_storage("/pair.dat");
It is up to you how to store device pairing information, the sketches EspHapLed (for ESP32) and EspHapLed8266 (for ESP8266) contain code examples to demonstrate custom implementations.
Set at least one base accessory type:
hap_setbase_accessorytype(homekit_accessory_category_lightbulb);
The full list of availbale device types can be found in the header file types.h (section enum homekit_accessory_category_t).
Set the base information for your device like hostname, manufacturer, serial number, model, firmware version:
hap_initbase_accessory_service(HOSTNAME,"Yurik72","0","EspHapLed","1.0");
Then you need to define all accessories, the services they provide and the characteristics of these services. Do not forgot that you already have one base accessory, therefore you need to define a setup for this one, too. For example for a lightbulb you would need
hapservice= hap_add_lightbulb_service("LED",led_callback,(void*)&led_gpio);
led_callback
is the name of the callback function which is called from Apple Home app whenever a change occurs(void*)&led_gpio
is the callback parameterOptinally you can set a default (initial) value to be informed Apple about initial state
homekit_characteristic_t * ch= homekit_service_characteristic_by_type(hapservice, HOMEKIT_CHARACTERISTIC_ON);
INIT_CHARACHTERISTIC_VAL(bool,ch,false); // will inform apple that lights is OFF
After that you can add more accessories like this
hapservice_motion= hap_add_motion_service_as_accessory(homekit_accessory_category_security_system,"Motion",motion_callback,NULL);
The full list of all services and their characteristic can be found in the header file characteristic.h. This header file is well documented and descibes all service types and their characteristics.
The API to add services and accessories is documented in the header file homeintegration.h, its funtions are self-explanatory.
Once all accessories, services and characteristics are defined, we need to call
hap_init_homekit_server();
Every callback has the following parameters
The callback function is invoked whenever the accessory's state is changed from within the Apple Home app. Based on the returned values, you may manage your device accordingly. Please check carefully which type (bool, int, float) must be used for the different characteristics.
void led_callback(homekit_characteristic_t *ch, homekit_value_t value, void *context) {
Serial.println("led_callback");
digitalWrite(led_gpio, value.bool_value?HIGH:LOW);
}
Optionally, you may also implement notify functions which are used to inform the Apple Home app about device state changes. This is a must for accessories like thermostat and for a lightbulb we could notify the app about power state (on/off, represented in the bool value true/false).
To retrieve characteristics, the API function homekit_service_characteristic_by_type
should be used.
The first parameter is a pointer to the hapservice (from the setup), the second parameter is the characteristic type.
void notify_hap(){
homekit_characteristic_t * ch= homekit_service_characteristic_by_type(hapservice, HOMEKIT_CHARACTERISTIC_ON);
HAP_NOTIFY_CHANGES(bool, ch, <new bool value>, 0)
}
In the main loop function and only for ESP8266 we have to add
#ifdef ESP8266
hap_homekit_loop();
#endif
Since version 1.0.2, the ESPHap library contains a submodule for a built-in web server. To use it, you need include the corresponding header file
#include <hapweb/hap_webserver.hpp>
Within the setup section, include
set_indexhml(FPSTR(INDEX_HTML)); // optional if you want to have your own root page
hap_webserver_begin();
set_indexhml(FPSTR(INDEX_HTML))
allows to define your own root page content, see example Advanced Led.
If you use the built-in web server, by default it provides access to a setup/pairing page/image by QR code which can be accessed by visiting http://\<Your Device IP Address>/setup.html, see example Advanced LED.
Fixed issue with for stable pairing process on ESP8266
You can support the development of this project by donating to it
TODO -