Introduction: Build a Apple HomeKit Temperature Sensor Device Using a ESP8266 and a BME280

In today's instructable, we will be making low cost temperature, humidity and moisture sensor based on either the AOSONG AM2302/DHT22 or BME280 temperature/humidity sensor, YL-69 moisture sensor and the ESP8266/Nodemcu platform. And for displaying the data, we will be using homebridge to integrate to Apple's HomeKit.

This supports multiple devices and device discovery using mDNS, with minimal configuration required in Homebridge.

Parts List

  • NodeMCU / New Wireless module NodeMcu Lua WIFI Internet of Things development board based ESP8266 with pcb Antenna and usb port
    • These are very cheap on Ali Express, only problem is that shipping takes 4-6 weeks
  • Mobile Phone Charger
  • Mini USB Cable
  • AOSONG AM2302/DHT22 temperature/humidity sensor

Or as an alternative sensor

  • Bosch BME280 Temperature, Humidity and Barometric Sensor
  • YL-69 Moisture Sensor
  • 2N3904 Transistor
  • 1K Resistor
    • Transistor and Resistor only needed of YL-69 Moisture Sensor
  • 5 Pin Female to Female cable set ( 1.5' ) ( DHT )
  • 4 Pin Female to Female cable set (1.5') ( BME 280 )
  • Heat shrink tubing small
  • Container to install NodeMCU
    • I used a small plastic food container from dollarama
    • 5 small nuts and bolts for mounting NodeMCU


  • Soldering Iron
  • Solder
  • Wire Cutters

Step 1: Hardware Build - DHT22

Connecting the DHT22

1. Cut the 5 Pin Female to Female cable in half, creating a cable about 9 inches long.

2. On the connecter, pins 2 and 3 are unused and can be removed.

3. Bare about a 1/4" of each wire on the end opposite the connector.

4. With your soldering iron, tin each wire end and the terminals on the DHT22.

5. Cut about 3/4" of heat shrink tubing and push down the wires.

6. Solder the wires to the DHT22 as follows

Connecter Pin --> DHT22 Pin

1 ---> 2 ( Second from left )

4 ---> 1 ( First on the left )

5 ---> 4 ( First on the right )

7. Slide the heat shrink tubing over the DHT22 Pins and shrink the tubing with the soldering iron.

Step 2: Hardware Build - BME280

Connecting the BME280

1. Cut the 4 Pin Female to Female cable in half, creating a cable about 9 inches long.

2. Bare about a 1/4" of each wire on the end opposite the connector.

3. With your soldering iron, tin each wire end.

4. Solder the wires to the BME280 in this order, VCC, GND, SCL, SDA. These need to line up to pins in the connector.

Step 3: Hardware Build - YL-69

Step 4: Build Case

Step 5: Build NodeMCU Firmware

1. Using, create a custom firmware containing at least these modules:


2. Please use esptool to install the float firmware onto your nodemcu. There are alot of guides for this, so I won't repeat it here.

Step 6: Connect Sensors


1. Position cable connector so that pin 1 connects to D2 on nodemcu, pin 4 with 3v3 and pin 5 with gnu.


1. Connect the BME280 to the nodeMCO, lining up the pins as follows:

3V3 -> VCC


D5 -> SCL

D6 -> SDA

Step 7: Install Nodemcu Software

1. Download lua software package zip file from

2. Unzip package

3. Using ESPlorer save each file to ESP, except test.lua and

4. Configure your wifi setup - In config.lua add your wifi SSID and passwords. Please note that the configuration supports multiple wifi networks, one per config line.

module.SSID["network name"] = "password"

5. Model - Either DHT, BME or DHT-YL, used by homebridge-mcuiot to determine which sensor is installed. module.Model = "DHT"


module.Model = "DHT-YL"


module.Model = "BME"

6. Save config.lua to ESP

7. Save test.lua to ESP. Your nodemcu should now boot, output looks like this

> dofile("test.lua")<br>Booting...
Setting Init Timer
Configuring Wifi ...
> Connecting to 67 Bonacres ...
IP unavailable, Waiting...
ESP8266 mode is: 1
MAC address is: 5e:cf:7f:86:08:9d
IP is
Registering service dht22 with mDNS
Web Server Started

Step 8: Testing

1. You can test from the command line with curl or wget, make sure you use the ip address from the Esplorer screen and not mine ;-)

{ "Hostname": "NODE-8689D", "Model": "BME", "Version": "1.2", "Data": {"Temperature": 22.15, "Humidity": 50.453, "Moisture": 8, "Status": 0, "Barometer": 1003.185, "Dew": 11.38 }}

2. In Esplorer you should see the following

GET / HTTP/1.1<br>Host:
User-Agent: curl/7.43.0
Accept: */*
Status: 0
Temp: 22.15
Humi: 50.453
Moisture: 8
Baro: 1003.185
Dew: 11.38

3. Using Esplorer install init.lua. The nodemcu portion of the build is now complete.

4. To test mDNS, I use this command on OS X

dns-sd -B _dht22._tcp

And for the 2 devices on the network, I receive the following output:

Browsing for _dht22._tcp
DATE: ---Mon 19 Sep 2016---
21:11:26.737  ...STARTING...
Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
21:11:26.739  Add        3   4 local.               _dht22._tcp.         NODE-18A6B3
21:11:26.739  Add        2   4 local.               _dht22._tcp.         NODE-871ED8

Step 9: Homebridge-mcuiot Install

1. Install homebridge using:

npm install -g homebridge

I won't go into a lot of details around the initial install of homebridge and how to configure it to autostart etc. Their are a lot of other guides for this.

2. Install homebridge-mcuiot using:

npm install -g homebridge-mcuiot

3. Update your configuration file, see sample-config.json in this directory.


"bridge": {<br>        "name": "Bart",
        "username": "CC:22:3D:E3:CD:39",
        "port": 51826,
        "pin": "031-45-154"
    "description": "HomeBridge",
"platforms": [
    { "platform":   "mcuiot" }
"accessories": [ ]

4. Start homebridge, output should look like this

[10/20/2016, 10:15:20 PM] Loaded plugin: homebridge-mcuiot<br>
[10/20/2016, 10:15:20 PM] Registering platform 'homebridge-mcuiot.mcuiot'
[10/20/2016, 10:15:20 PM] ---
[10/20/2016, 10:15:20 PM] Loaded config.json with 0 accessories and 0 platforms.
[10/20/2016, 10:15:20 PM] ---
[10/20/2016, 10:15:20 PM] Loading 0 platforms...
[10/20/2016, 10:15:20 PM] Loading 0 accessories...
Load homebridge-mcuiot.mcuiot
Scan this code with your HomeKit App on your iOS device to pair with Homebridge:
    │ 031-45-154 │     
[10/20/2016, 10:15:20 PM] [homebridge-mcuiot.mcuiot] Starting mDNS listener
[10/20/2016, 10:15:20 PM] Homebridge is running on port 51826.
[10/20/2016, 10:15:20 PM] [homebridge-mcuiot.mcuiot] Found url <a href="http://NODE-871ED8.local.:80/" rel="nofollow"> http://NODE-871ED8.local.:80/</a>
[10/20/2016, 10:15:20 PM] [homebridge-mcuiot.mcuiot] Found url <a href="http://NODE-869815.local.:80/" rel="nofollow"> http://NODE-869815.local.:80/</a>
[10/20/2016, 10:15:20 PM] [homebridge-mcuiot.mcuiot] Found url <a href="http://NODE-8689D.local.:80/" rel="nofollow"> http://NODE-8689D.local.:80/</a>
[10/20/2016, 10:15:21 PM] [homebridge-mcuiot.mcuiot] addMcuAccessory 195 NODE-8689D BME
[10/20/2016, 10:15:21 PM] [homebridge-mcuiot.mcuiot] addMcuAccessory 195 NODE-871ED8 DHT
[10/20/2016, 10:15:21 PM] [homebridge-mcuiot.mcuiot] addMcuAccessory 195 NODE-869815 DHT

In my environment I have 3 devices running.

Step 10: Homebridge

On your iPhone/iPad start your favourite homekit client and pair you client to homebridge. You should see all the mcuiot devices.

Adding devices

Devices are auto discovered using mDNS, and will add new devices when they appear on mDNS. In the event that devices are not discovered, restarting homebridge will trigger a reconciliation between the plugin and mDNS, and add missing devices. Missing devices are not removed during startup, see below for how to remove non-existent devices.

Removing devices

Devices are removed using the 'Identify Accessory' function. When you use the function from your app, it checks to see if the device is truly not responding then removes the device.


dom_efendi (author)2017-04-09


What am I doing wrong this time? the only accessory I'm getting in HomeApp is MCU-IOT reset switch for some reason :/

NorthernM (author)dom_efendi2017-04-09


The error you showed from homebridge is a timeout when trying to reach your nodemcu device. It looks like it was seen and discovered, but when it was queried by the plugin the request timed out. Is the nodemcu working okay, was there any errors on its console?

dom_efendi (author)NorthernM2017-04-10

this is what I'm getting in ESPlorer:

PORT OPEN 115200

Communication with MCU..Got answer! Communication with MCU established.

AutoDetect firmware...

Can't autodetect firmware, because proper answer not received (may be unknown firmware).

Please, reset module or continue.

�c��o'�lno���bx��l;l{lp�n��dcg�|�ć�;�b��og�l��l`�ogd�d`gs�ۓn;s�``�g��#�gd���'o��lx�o�{�����#g�|��l�#��ng�$�l �o'l`orǛ�'cd`8�g�r�����d�c'�|$섇#��no�d`�no$`'{���g�ls��'�d����g��s��'|�dd$l`��{�d�l�

NodeMCU custom build by

branch: master

commit: b96e31477ca1e207aa1c0cdc334539b1f7d3a7f0

SSL: false

modules: adc,bit,bme280,file,gpio,mdns,net,node,tmr,uart,wifi

build built on: 2017-03-04 19:40

powered by Lua 5.1.4 on SDK 2.0.0(656edbf)


Setting Init Timer

Configuring Wifi ...

> Connecting to TPLink-2.4Ghz ...

IP unavailable, Waiting...

IP unavailable, Waiting...

IP unavailable, Waiting...


ESP8266 mode is: 1

MAC address is: 5e:cf:7f:d5:ea:6f

IP is


Registering service dht22 with mDNS

Web Server Started

NorthernM (author)dom_efendi2017-04-12


It looks like the nodemcu is working correctly, but the true test is when you poll it for data. Can you try this from the command line on your machine.


It should respond with something like this

{ "Hostname": "NODE-18A6B3", "Model": "DHT-YL", "Version": "1.1", "Data": {"Temperature": 20.9, "Humidity": 27, "Moisture": 1024, "Status": 0 }}

Also, what sensor do you have attached? DHT or BME ?

dom_efendi (author)NorthernM2017-04-13


I'm using only BME, I also have a second ESP8266, also no response from it :/

I possibly messed something up in lua files :P


my config.lua:

local module = {}

module.SSID = {}

module.SSID["TPLink-2.4Ghz"] = "XXXXXXXX"

module.SSID["The_Beach"] = "brownieg"

-- Options are DHT or DHT-YL, used by homebridge to determine if moisture data is valid.

module.Model = "BME-GD"

module.Version = "1.3"

module.ID = wifi.sta.gethostname()

module.ledRed = 0 -- gpio16

module.ledBlue = 4 -- gpio2

module.sensor = 7 -- gpio14

module.bme280scl = 5 -- D5

module.bme280sda = 6 -- D6

return module


config = require("config")

led = require("led")

bme = require("bme")

app = require("main")

setup = require("setup")



-- Never gets here


local module = {}

function module.start()

-- Turn off YL-69

gpio.mode(5, gpio.OUTPUT)

gpio.write(5, gpio.LOW)

-- Start a simple http server

print("Web Server Started")






gpio.write(5, gpio.HIGH)


gpio.write(5, gpio.LOW)

temp = -999

humi = -999

baro = -999

dew = -999

gdstring = ""

if string.find(config.Model,"BME") then

status, temp, humi, baro, dew =


status, temp, humi, temp_dec, humi_dec =


-- print("Heap Available:" .. node.heap())

if string.find(config.Model,"GD") then

green, red = gd.getDoorStatus()

gdstring = ", \"Green\": \"""\", \"Red\": \"""\""


-- print("Heap Available:" .. node.heap())

-- print("33")

majorVer, minorVer, devVer, chipid, flashid, flashsize, flashmode, flashspeed =

-- print("35")

print("Status: "..status.."\nTemp: "..temp.."\nHumi: "..humi.."\nMoisture: "..moist_value..

"\nBaro: "..baro.."\nDew: "..dew.."\n")

local response = { "HTTP/1.1 200 OK\n", "Server: ESP (nodeMCU) "..chipid.."\n",

"Content-Type: application/json\n",

"Access-Control-Allow-Origin: *\n\n",

"{ \"Hostname\": \""..config.ID.."\", \"Model\": \""..config.Model.."\", \"Version\": \""..config.Version..

"\", \"Firmware\": \""..majorVer.."."..minorVer.."."..devVer.."\", \"Data\": {\"Temperature\": "..temp..

", \"Humidity\": "..humi..", \"Moisture\": "..moist_value..

", \"Status\": "..status..", \"Barometer\": "..baro..", \"Dew\": "..dew..""..gdstring.." }}\n" }

local function sender (conn)

if #response>0 then conn:send(table.remove(response,1))

else conn:close()



conn:on("sent", sender)




conn:on("sent",function(conn) conn:close() end)



return module

NorthernM (author)dom_efendi2017-04-13


In config.lua you can remove this line, as it isn't needed

module.SSID["The_Beach"] = "brownieg"

And the most important part, change this line from

module.Model = "BME-GD"


module.Model = "BME"

And that should be it

dom_efendi (author)NorthernM2017-04-14


I made those changes in config.lua, ESPlorer prints now this error (see printscreen) when I'm trying to pull curl in Terminal

thanks for your time and help :)

Screen Shot 2017-04-14 at 09.48.00.pngScreen Shot 2017-04-14 at 09.48.22.png
NorthernM (author)dom_efendi2017-04-14

You need to add to config.lua this line


dom_efendi (author)NorthernM2017-04-15

yup all good now, in homekit I can only see Temperature, the rest only in EVE. For some reason I can only add Temperature to the favourites in Eve, the rest (pressure and humidity) can be seen when I click on the temperature tab in EVE. Siri works fine though, giving all of three values when asked :)

NorthernM (author)dom_efendi2017-04-15

This is normal. I set this up as a single temperature sensor accessory that also supports pressure and humidity as well. In home, if you look at the details you should see humidity as well, pressure is not supported by Home.

dom_efendi (author)NorthernM2017-04-15

thank you very much for all your help !

true gent !

NorthernM (author)dom_efendi2017-06-26


Not sure if your interested, but I recently updated all my temperate sensor plugins to log the data to Google sheets so you can create graphs etc.


dom_efendi (author)NorthernM2017-07-16

that's amazing, would love to have that as well. Please do tell me how ? :)

NorthernM (author)dom_efendi2017-07-16

I have updated the instructions in the README here

The steps to install are

1) Install the latest version of homebridge-mcuiot

2) In the README, follow the instructions in 'Optional - Enable access to Google Sheets

3) Create a spreadsheet in Google Sheets, and add the spreadsheet id into config.json

4) Restart homebridge

dom_efendi (author)NorthernM2017-07-05

Amazing ! When you get a chance could you please do a little tutorial ?

NorthernM (author)dom_efendi2017-04-10

That looks perfectly normal, when you restart homebridge and the timeout happens do any errors appear on the nodemcu? I was expecting to see some type of exception on the nodemcu.

About This Instructable




Bio: Creator of multiple Apple HomeKit devices using homebridge in an attempt to increase the WAF score of my home automation attempts.
More by NorthernM:Take Snapshots of Who Visits Your Door With Homebridge and Google DriveReceive Picture Notifications When People Approach Your House With HomeKitBuild a Apple HomeKit Temperature Sensor Device Using a RaspberryPI and a BME280
Add instructable to: