Milight WiFi Gateway Emulator on an ESP8266

Milight bulbs* are cheap smart bulbs that are controllable with an undocumented 2.4 GHz protocol. In order to control them, you either need a remote* (~$13), which allows you to control them directly, or a WiFi gateway* (~$30), which allows you to control them with a mobile app or a UDP protocol.

A few days ago, I posted my Arduino code to emulate a Milight WiFi gateway on an ESP8266 (link). This allows you to use an NRF24L01+ 2.4 GHz tranceiver module* and an ESP8266* to emulate a WiFi gateway, which provides the following benefits:

  1. Virtually unlimited groups. The OTS gateways are limited to four groups.
  2. Exposes a nice REST API as opposed to the clunky UDP protocol.
  3. Secure the gateway with a username/password (note that the 2.4 GHz protocol used by the bulbs is inherently insecure, so this only does so much good).

I wanted to follow up with a blog post that details how to use this. I’m going to cover:

  1. How to setup the hardware.
  2. How to install and configure the firmware.
  3. How to use the web UI and REST API to pair/unpair and control bulbs.

Shopping List

This should run you approximately ~$10, depending on where you shop, and how long you’re willing to wait for shipping. Items from Chinese sellers on ebay usually come at significant discounts, but it often takes 3-4 weeks to receive items you order.

  1. An ESP8266 module that supports SPI. I highly recommend a NodeMCU v2*.
  2. An NRF24L01+ module. You can get a pack of 10* on Amazon for $11. You can also get one that supports an external antenna if range is a concern (link*).
  3. Dupont female-to-female jumper cables (at least 7). You’ll need these to connect the ESP8266 and the NRF24L01+.
  4. Micro USB cable.

If you get a bare ESP8266 module, you’ll need to figure out how to power it (you’ll likely need a voltage regulator), and you’ll probably have to be mildly handy with soldering.

Setting up the Hardware

The only thing to do here is to connect the ESP8266 to the NRF24L01+ using the jumper cables. I found this guide pretty handy, but I’ve included some primitive instructions and photos below.

NodeMCU Pinout

NRF24L01+ Pinout
NodeMCU Pin NRF24L01+ Pin
3V (NOT Vin) VCC
G GND
D2 CE
D5 (HSCLK) SCK
D6 (HMISO) MISO
D7 (HMOSI) MOSI
D8 (HCS) CSN

Update – Jan 4, 2019: The default CE pin has been changed from D0/GPIO16 to D2/GPIO4 as of version 1.8.6.

Installing drivers

There are a couple of different versions of NodeMCUs (I’m not convinced they’re all actually from the same manufacturer). Depending on which one you got, you’ll need to install the corresponding USB driver in order to flash its firmware.

The two versions I’m aware of are the v2 and the v3. The v2 is smaller and has a CP2102 USB to UART module. You can identify it as the small square chip near the micro USB port:

NodeMCU v2 with CP2102 circled

Install drivers for the v2 here.

The v3 is larger and has a CH34* UART module, which thin and rectangular:

NodeMCU v3 with CH34* circled

The CH34* drivers seem more community-supported. This blog post goes over different options.

I’ve been able to use both the v2 and v3 with OS X Yosemite.

Installing Firmware

If you’re comfortable with PlatformIO, you can check out the source from Github. You should be able to build and upload the project from the PlatformIO editor.

Update – Mar 26, 2017: I highly recommend using PlatformIO to install the firmware. The below instructions are finicky and unless you get the arguments exactly right, the filesystem on your ESP will not work correctly. Using PlatformIO is a more robust way to get a fresh ESP set up. Further instructions are in the README.

Update – Feb 26, 2017: if you’ve used your ESP for other things before, it’s probably a good idea to clear the flash with esptool.py --port /dev/ttyUSB0 erase_flash . Thanks to Richard for pointing this out in the comments.

If not, you can download a pre-compiled firmware binary here. If you’re on Windows, the NodeMCU flasher tool is probably the easiest way to get it installed.

On OS X (maybe Linux?), following the NodeMCU guide, you should:

  1. Connect the NodeMCU to your computer using a micro USB cable.
  2. Install esptool
  3. Flash the firmware:

    Note that  /dev/cu.SLAB_USBtoUART should be substituted for  /dev/cu.wchusbserial1410 if you’re using a v3 NodeMCU. Be sure to specify the real path to the firmware file.
  4. Restart the device. To be safe, just unplug it from USB and plug it back in.

Setup firmware

Note that you’ll have to do all of these things before you can use the UI, even if you used the pre-compiled firmware:

  1. Connect the device to your WiFi. Once it’s booted, you should be able to see a WiFi network named “ESPXXXXXX”, where XXXXXX is a random identifier. Connect to this network and follow the configuration wizard that should come up.  The password will be milightHub.
  2. Find the IP address of the device. There are a bunch of ways to do this. I usually just look in my router’s client list. It should be listening on port 80, so you could use nmap  or something.

You should now be able to navigate to http://<ip_of_isp>.

Using the Web UI

The UI is useful for a couple of things.

If you have Milight bulbs already, you probably have them paired with an existing device. Rather than unpairing them and re-pairing with the ESP8266 gateway, you can just have the ESP8266 gateway spoof the ID of your existing gateway or remote. Just click on the “Start Sniffing” button near the bottom and push buttons in the app or on the remote. You should see packets start to appear:

The “Device ID” field shows the unique identifier assigned to that device. To have the ESP8266 gateway spoof it, scroll up to the top and enter it:

The controls should not work as expected. You can click on the “Save” button below if you want to save the identifier in the dropdown for next time.

The UI is also useful for pairing/unpairing bulbs. Just enter the gateway ID, click on the group corresponding to the bulb you wish to pair/unpair, screw in the bulb, and quickly (within ~3-5s) press the appropriate button. The bulb should flash on and off if it was successful.

Using the REST API

The UI is great for poking around and setting things up, but if you want to tie this into a home automation setup, you’ll probably want a programmatic interface. The API is fully documented in the Github readme, but here’s a quick example:

This will turn bulbs paired with device 0xCD86, group 2 on and set the color to red (hue = 0).

UPDATE – Feb 12, 2017

I realized this project would be a lot more immediately useful to people if it just supported the existing Milight UDP protocol. This would allow people to use the existing integrations others have built for OpenHab, Home Assistant, SmartThings, etc.

The Web UI has a section to manage gateway servers. Each server will need a device ID and a port.

* Amazon affiliate link.

Join the Conversation

565 Comments

Your email address will not be published. Required fields are marked *

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  1. Hi,

     

    great project.

    Is this only able to send command or also able to receive signals from milight remotes?

    thanks!

  2. Hey, is there a way to reset the wifi setup if I have lost access, (I used the reset wifi utility, and I must have screwed something up when setting up the new wifi, I set a static IP, which is not working, and nothing is showing up on my router DHCP leases)  will one of the buttons on the NodeMCU reset it, or do I need to do a re-install?

    1. If the ESP8266 does not think it successfully connected to your wifi, it should re-enter the config mode. You could check the serial logs to see what it thinks is going on.

      If you’re still getting trouble, it’s probably easiest to just reinstall.

  3. Howdy All.

    I have about 30 LimitedLED lights, 5 older hubs, 2 iBox hubs and 5 remotes. It once all worked so well with my VeraPlus via a plugin and even included support for Google Home, Alexa and Siri thanks to the Automation Bridge hub.

    One day, it all stopped working with Vera as some MiLight update rendered all the older hubs unusable and they would no longer pair with any LimitlessLED/MiLights bulbs. You were forced into buying the newer iBox hubs just to use your lights. The iBox does not work with vera.

    I don’t have any experience with projects like the Milight WiFi Gateway Emulator and I don’t know of a product I can buy that will allow my LimitlessLED/MiLights bulbs to work again with my home automation system.

    Is anyone willing to make it for me? I will pay you of course for parts and your time. Please email me if you’re interested.

    1. Hi Tony,

      Apologize that this sat in the approval queue for so long. just noticed it.

      Someone further back in the comment thread on this post made a board. He was kind enough to ship me one — it works well. Let me know if you’re not able to find him or his contact info and I can try to make an introduction.

      Setting this up yourself isn’t too terrible, though. Just wiring up some components.

  4. Hi Chris,

    MiLight RGB+CCT. It works with FUT92.
    Unfortunately id doesn’t work with MilightHUB.

    Sniffing from other MiLightHUB I found only one difference in packets:

    packet from remote:
    rgb_cct packet received (9 bytes):
    Raw packet: 1B D9 ED 64 52 DD B3 63 1D

    Decoded:
    Key : 1B
    b1 : 20
    ID : 8164
    Command : 02
    Argument : 51
    Sequence : 2C
    Group : 01
    Checksum : E4

    packet from MilightHUB:
    rgb_cct packet received (9 bytes):
    Raw packet: 00 DB 62 3F 63 28 C2 65 2A

    Decoded:
    Key : 00
    b1 : 20
    ID : 8164
    Command : 02
    Argument : B8
    Sequence : 08
    Group : 00
    Checksum : 7F

    The keys in pockets from MilightHUB are always 00.
    Tried with version 1.8.8 and 1.9.0-RC.8

    What I’m doing wrong?

  5. Hi guys! I have a problem adding the milight bridge to diyHue. I added my bridge in diyHue but can’t control it through diyHue. Is there something I need to enable that this is going to work?

  6. Thanks a lot for the instructions, Chris. I built the gateway as instructed, and it works like a charm. However, I ran into a little problem with triggering fades remotely. Like a smooth fade-out before the start of a movie, or fade-in in the morning. The REST API over doesn’t really seem to be ideal for this, if I start sending to many commands at one time, let’s say, from “Tasker” on Android, it just doesn’t seem to handle them. So I guess I need to send UDP commands? But if I don’t use any third party software, the hey format is kind of clunky. Could you suggest the  easiest way (without a lot of external software) to implement on-demand, smooth fading?

  7. Hi, I just built one with a NodeMCU v3 and NRF24L01+. It works for receiving data (I can sniff my FUT089 remote) but sending does not work. I tried by using my remote ID, and by Pairing a new ID, nothing happens. Even sniffing when sending, as suggested in the Troubleshooting, does nothing. Any idea? Thanks!

  8. Hello

    I want to ask if there is someone who want to help me with flashing de nodemcu v3. I bought the Nodemcu v3 with the NRF24L01+ module. Maybe someone would like to help me with flashing it in platformio? My skypename is thieske2478, email tla.jansen@outlook.com and i am dutch but understands english as wel. Thanks in advance.

    Greeting Thijs Jansen the Netherlands.

  9. I can’t get platformIO to flash the files onto the board. I get this annoying error when trying to access the board by USB:

    File “c:\users\rumf\.platformio\penv\lib\site-packages\serial\serialwin32.py”, line 257, in in_waiting
    raise SerialException(“ClearCommError failed ({!r})”.format(ctypes.WinError()))
    SerialException: ClearCommError failed (WindowsError(5, ‘Toegang geweigerd.’))

    “Toegang geweigerd” means access denied in Dutch.

    Does any1 have a good idea about this?

     

  10. First this:

    “Hi Eelco, glad you had fun getting this set up.

    There actually is already a section for this — “Installing Drivers.” 🙂”

    How stupid of me. I was looking at a very different guide. Sorry about that.

    I have a new question now:

    Now I’m trying to add more lights. But I can’t get an additional remote configured. I sniff it and add a new ID under “setup”. It’s in the list, but I can’t select it on the homepage. It doesn’t show up in the dropdown. What am I doing wrong?

    1. To add to this: I tried adding a FUT089 remote. This is the sniffer result:

      Decoded:
      Key : F0
      b1 : 25
      ID : 665D
      Command : 01
      Argument : 0A
      Sequence : E7
      Group : 01
      Checksum : 63

      Problem: when I try to add the device, I get an error message about the device ID not having the right format.

      How can I fix that?

    2. Sorry about this. Please delete these previous posts. Note to self: RTFM!

      The only issue I have now is that my hub keeps forgetting what type of remote I use, resulting in flashing light whenever I switch modes or from a color to white. Also: I don’t see a save button on the home screen.

  11. Hi Chris,

    with a FUT039 controller your Milight WiFi Gateway works great, thank you!

    But with this nice LED CCT lamp (www.aliexpress.com/item//32798059808.html), which is often offered at AliExpress, no paring is possible, although it has a remote control with 2.4G RF logo.  Can I do something to support this lamp? For example reading the remote control codes with a sniff program on ESP8266?

    Peter

  12. Hi Chris,

    amazing work! It worked all right from the start with my CCT LED panel.

    This week I bought a Mi-light LED stripe controller with a FUT/027 remote and tried to connect it to my ESP. Unfortunately, sniffing doesn’t give any result upon pressing any of the remote buttons.

    Any idea what I am doing wrong?

    Thanks in advance,
    Helmut

    1. Hi Helmut,

      If your setup is working with other remotes, I guess that remote isn’t supported. Probably wouldn’t be hard to add support, but would need test hardware in order to do that.

      Chris