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

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 --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.

UPDATE – Nov 8, 2019: Ready-Made Hub

You can find more information about a ready-made version of this hub here:

Ready-Made MiLight Hub

* Amazon affiliate link.

Join the Conversation


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 Chris,


    Do you know about B4 milight remote controller and its protocol?

    I recently discovered it can drive FUT017 also having a set of bulbs paired with it

    Traffic is normally geared with the Hub but curiously I can managed only 4 against the total of  6, alltogether branched to the same switch

    For documention only I think you can add this remote controller to the readme.MD file

    1. Hi Brignoud,

      Yes, B4 uses the same protocol as FUT092 (called in the firmware “rgb_cct”). Adding it to the documentation sounds like a good idea.

  2. Thanks for the guide – i’ve been meaning to make one of these for a while and finally took the plunge over christmas – everything went to plan except i don’t think its sending any signals. It can sniff, but when i send a command the sniff detects nothing, and no bulbs are changed.

    I figured it was a dead / fake NRF24 – so i bought a pack of 4 – these also don’t send, but sniff ok. So i guess i have a wiring issue – but i cant find one…

    Im using an NodeMCU Amica – which cable connection is responsible for sending on the NRF24, so i can try replacing where it is connected to on the NodeMCU?

    So close, yet so far!

    1. Hi Oli, please check out the Troubleshooting Guide if you haven’t already.

      Couple of tips based on the background you shared:

      1. There’s not really a “send” cable. The nRF uses SPI, so MOSI, MISO, SCK, and CE are all used for both sends and receives. I think CSN might be used exclusively for sends.
      2. If packets aren’t showing up when you send commands locally, something is definitely wrong. My guess is that if you looked at Serial logs, you’d see a WDT crash. This happens in general when some code is in a busy wait and doesn’t yield back to the system. In this particular case, there’s some stuff in the nRF library that triggers this when things aren’t wired correctly.

  3. Thanks for this! I was lazy and choose to use the UDP / milight protocol ;-). If I may make one suggestion: only after intensive googling I found out you need to install a driver for the Nodemcu. After that it was all downhill. Again: thanks. Loved the tinkering with electronic I never heard of before.

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

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

  4. Hi,


    as i wrote above i unpair my bulb with android app.


    now i have 2 milighthub 1 sniff 1 send


    i power in and instant click pair


    the sniffer got this:

    what can i do now?

  5. Hi Guys

    Newbie here and just need help compiling and running from PlatformIO

    I have a Nodemcuv2 board

    When I run the following commands

    The Term: Export is not a …..

    Unexpected error extra argument error

    If I run  platformio run -e nodemcuv2 I successfully compile ONLY the Nodemcuv2 and others are skipped

    platformio run -t upload successfully uploads but uploads all and the last one uploaded is Huzzah – which is not correct.

    Can anyone give the correct syntax?


    1. It’s bash. It sounds like it’s working? If so, don’t worry about it. 🙂

      Maybe true pio run -t upload -e nodemcuv2?

  6. Hi Chris,
    In your github page its says that ‘LT8900 is more performant.’ If I buy a the long range 400m LT8900 ( will it be the best option for this project?
    The github page also says ‘NRF24s … require software emulation’ so how can i disable this if the LT8900 is being used instead of a long range (with antenna) NRF24L01 ?

    Thanks in advance! Great work!!

  7. Hi Chris,

    Happy newyear to you to!
    I added some remotes in my house this week and now i noticed that when pressing controls for group0 i dont receive a mqtt message (not from any group). When controlling a individual group (1-4) on the remote i do get a mqtt message. I don’t know where i am going wrong. even going through the web UI no mqtt package on group0 control, but i do get them on group1-4. Am i right when i think no mqtt package is sent on controlling group0? I’m running the latest firmware(1.8.7) on nodemcuv2. Is it possible for me to add this myself in the source?

    Greets Jimmy

    1. Hi Jimmy,

      It’s expected that Group 0 doesn’t issue state updates. See this issue on Github for context:

      You will see non-state updates (e.g., updates corresponding to single packets), but state is not accumulated for group 0 because it’s not a real group.

      I’ve not thought of a super clean way to resolve this confusing behavior. Having Group 0 behave like other groups causes different kinds of confusing behavior.

    2. Is it possible to have hub send mqtt messages for group1-4 when group0 is controlled? My openhab now loses sinc if the wife uses group0 on the control pannel to switch off all lights. Any sort of message to openhab would do. So i can keep the waf (wife acceptance factor) up to par 😁. Thanks

    3. If i understand the post on github correctly i should get an mqtt message for group 1-4 if i control group0 on touchpannel. But i don’t seem to get any message at all. I only use groups1-4 in my openhab. All lights are contolled by an openhab group containing milight groups 1-4. So if i would get mqtt message for group 1-4 when controlling group0 all my problems would be solved. Am i understanfing the github post correctly?

      Sorry if i’m asking stupid questions, but i just dont see the solution. Thanks jimmy

    4. Hi Chris,
      I just found out i didnt define a update topic pattern in the hub. This was the reason i didnt get any mqtt message on controlling group0 on the remote. Now i can look for this update message in openhab and push the state to groups 1-4 via a rule. This is the solution to all my problems. Thanks

  8. I have a dumb question, as im not an electrician or programmer 🙂

    Problem is when using wall switch to turn lights on, there is no update on light state on homeautomation… Does this project improve that situation ?

    I do believe it doesnt ?

    1. Correct — supplying power to bulbs does not result in a state update. Since bulbs don’t send any communication when they start up, there’s no real way to do this.

  9. Hi Chris,

    just got hardware and try to build up all.


    I can sniff it with nodemcu v2 like this:

    But i cant unpair them with my milight wifi bridge or pair them with my setup.


    can you give me some hints i can try?

    its a bulb i want to use on Zone2 in my android app (not the new app – old one )



  10. Hi Chris,
    I’m still waiting for my new tranceivers to be delivered but i noticed something else. Don’t know if i should post it here or on the openhab esp milight hub binding page. Seems like the lights i don’t have linked to an official remote don’t have a link between state and level. I mean if i turn off the switch (state) in openhab the level stays at the level it was before switching state. Same for switching state on. When i reduce the level to 0%, the state doesn’t turn off in openhab either and vice versa. When i do this for lights that are linked to an official remote this does work as expected, ie switch goes off when level is set to 0%, switch goes on above 0%, level goes to 100% when switch is turned on and goes to 0% when switched off.

    I allso noticed the lights i mostly get a bad response off are the small gu10 rgbw spots. Other lights that are much further away and have more walls inbetween them allmost allways respond correct. I must say i’m allso using a mysensors network in my home that uses the nrf24l01+ to wirelessly send sensordata to my openhab server. But each sensor only sends every 5min for a very short duration. Do you think this could cause interference? Is it possible to switch the channel of the nrf24l01+ on the hub to try and mitigate this? Otherwise i can try to disable my sensornetwork and do some testing.


    Happy holidays

    1. Hi Jimmy, did you solve youurs problems with small gu10 rgbw spots?
      Because I have the same problem with the same condition, some other bulbs works correctly but the GU10 not
      Eventually which tranceiver did you apply?

  11. Hello,

    I’m looking to do something similiar, only I would like to have a wired  ethernet connection instead of wifi, any suggestions as to what I could use instead of the ESP8266?


    Thanks much!

    1. Don’t have much experience with other chips. This project is pretty specifically built for the ESP8266, but all of the reverse engineering learnings should be usable if you want to port 🙂

  12. Hi Chris,

    Great project, thank you so much. However, I am really puzzled here. I thought that one of the main reasons to start this project at all is the possibility to have unlimited groups (whereas the ibox is limited to 4). I might have read this wrong. You say ”virtually unlimited groups” and “OTS”. What is OTS?

    I have a lot of trouble with the hardware and software. The sniffing feature suddenly stopped working and I lack the save button so i cannot save anything. Any ideas as to what could be causing this?

    I decided to bypass the above and just unpair/pair my lamps. I now have them in the ESP8266 hub but I cannot name the groups. So you will never be able to remember which group is which. Is this correct?

    Then I tried to add the virtual hub to the Milight app. Is this possible? I don’t know what the procedure is for doing so. If it is indeed possible, could you maybe explain how this works?

    Your answers would be greatly appreciated.



    1. OTS is off-the-shelf. The line you’re referencing is meant to contrast the ESP8266 hub with the official hub.

      You might find this troubleshooting guide helpful. It’s possible your wiring is loose.

      I think most folks use espMH in combination with a home automation platform like HomeAssistant or OpenHAB. I personally use HomeAssistant. I’d be happy to look at any suggestions for how to improve espMH as a standalone, but it’s not now I’ve envisioned it working.

      espMH has worked with the Milight app in the past, but the “official” Milight UDP protocol is an undocumented mess, so entirely possible that it broke with updates.

  13. Where is the Save Button?

    Hi Chris, thanks for the nice program.

    Everything works fine and the bulb changes the colors,
    but I can not save the Device ID anywhere.

    How can I save the Device ID to keep it in list after website reload?

    Best regards

    1. Hi Thomas,

      This is super janky — you open the settings dialog and hit save.

      It should auto-save. There’s a ticket on the Github project for this, but haven’t gotten around to it yet.


    2. Hi Chris,

      many Thanks for help.
      Do you mean Settings -> “Submit” instead of “Save”?
      Now it works. But it doesn’t keep the remote type of the Device ID?

      Best regards

  14. Hello, first of all thanks for all your great work developing this hub. Everything works great for me. Only problem i have is that sometimes not all my bulbs react to commands. I have 8 gu10 spots in 1 zone, when i send a command to this zone some random spots don’t react or react randomly. I tried moving the hub directly under the lights. This helps but i still get random lights that react wrong or not at all. I suspect the problem is the 8 lights in one zone. Is there a parameter on the hub i can try adjusting to improve the problem? I allready tried changing some parameters but no result. I’m kinda a noob to this. Thanks

    1. Hi Jimmy,

      You might find this troubleshooting guide helpful:

      Given that it works inconsistently, some suggestions:

      1. When leaving the hardware still and in one place, do the same bulbs tend to not respond? If so, I’d try a capacitor across Gnd and Vin on the nRF, a new nRF module, and a better power supply.
      2. Are bulbs less responsive when the hardware is moving around or isn’t fully supported (i.e., on a solid surface)? If so, connections are probably loose. Try different jumper wires, or ideally soldered joints.


    2. Hi Chris,

      Only one non-responsive bulb (one furthest away) remaines unresponsive (allmost everytime), the rest will respond incorrect randomly. I’m using nodeMCU and nRF24L01+ pa/lna allready soldered to a pcb. Both antenna’s are facing in opposite direction with just a little less than the length of a nodeMCU in between them. I have one tantalum cap 100uF (107E stamped on package) infront of the 3.3v regulator and one behind, close to the powersupply of the nRF24L01+. As soon as one of my new nRF24’s (PA version) comes in i will try swapping it out to test. Allready swapt it for a nRF24L01+ with onboard antenna but same result. I verified all bulbs work propperly when i use the official wall mounted touchpannel to control them. I will allso try to reduce the number of lights per zone to 2, so 4 zones x 2 lights = 8 lights. And see if this improves on the problem (i will let you know). I’m using fut103 lights with rgb+cct remote settings. I started out with self-compiled firmware on the hub, but have since updated thru the browser interface to the latest version (1.8.5nodeMCUv2). Thanks again for all your work and efford.

    3. Hi Chris, i ordered a couple E01-ML01DP5 from different suppliers. I think i might have some bad quality nRF24L01+ pa/lna’s. Once these arrive i will do some testing and let you know how it goes. Greets

    4. Hey Jimmy,

      Sounds like you’re way ahead of me. 🙂

      The number of bulbs per zone shouldn’t affect anything — the hub is sending the same data, and bulbs don’t respond to commands.


    5. Hi Chris,

      Yesterday i got the new radios (E01-Ml01DP5). After checking the pinout i exchanged my nRF24L01+ pa/lna with the new radio. Suddenly my hub didnt work anymore, tried the other one i ordered, didnt work either. So i replaced the radio again with the original nRF24L01+, but still the hub was dead. Looks like it keeps restarting (from looking at the leds). The radio has its own 3.3v regulator with 100uF tantalum capacitor. Hub now even restarts without a radio plugged in. I will investigate further and keep you posted.

      Greets Jimmy

    6. Hi Chris,

      My apollogies, nothing was wrong with the hub, turen out my f*** ISP’s mandatory router was flipping again. It kept turning off the wifi for a split second (I think this was the problem). after resetting the router it still didn’t work via openhab but it did work via the webapp. Turned out my openhab server got a different IP, so allso the mqtt broker was on a different ip. changed the ip in the thing file and via the webinterface. Now everything works great again. The new radio’s are a massive improvement, no more inresponsive bulbs. Thanks

    7. Hi Chris,

      Happy newyear to you to!
      I added some remotes in my house this week and now i noticed that when pressing controls for group0 i dont receive a mqtt message. When controlling a individual group (1-4) on the remote i do get a mqtt message. I don’t know where i am going wrong. even going through the web UI no mqtt package on group0 control, but i do get them on group1-4. Am i right when i think no mqtt package is sent on controlling group0? I’m running the latest firmware(1.8.7) on nodemcuv2

      Greets Jimmy

  15. Is there a convenient way to disable the web interface once you have things set up?

    It seems like even if you set an admin password anyone with the ip address of the device can just load up the interface and change or disable the password. Maybe I’m misunderstanding how the password functionality works.

    Other than that, your project has been very helpful – great addition to my “homebrew” smart home system I’m working on.

    1. If a username/password are supplied, authentication is enforced for anything hitting the HTTP server. This includes the REST API and the web server.

      After setting a username/password, try refreshing. You should be asked to login.

    2. I could have sworn I tried that exact procedure without any login prompt the other day –

      Tried again and now I get the login screen.

      I doubt I’ll have anyone around who would try to hack the system just to mess with the lights but this is a nice plus. Thanks.

    3. Follow up question: How do you supply the user/password when making an API request? I tried putting the key/value pairs in the header and the body, but all combinations I try get 401. Not sure what the exact structure is that the server expects.

      I tried checking your code but I can’t see where you actually pull the values out of the request.


    4. Let me know if you can find a way to reproduce. Definitely should be enforced on every request.

      Keep in mind that the Milight RF protocol has absolutely no security mechanism. So the username/password on the API doesn’t accomplish a whole lot 🙂

      It’s just Basic HTTP Authentication. Whatever HTTP library you’re using probably has baked-in support for it. With curl, it’s just curl -u 'user:pass' ...

  16. It would be great to be able to broadcast and receive over multiple IP addresses and be able to assign specific device IDs to different IPs.   This would allow you to integrate with not only the cell phone app but also with third parties that require it (i.e. Polyglot with an ISY).  Thoughts?

  17. Hi folks.

    Last few weeks my hub appears to be rebooting few times a day.  It causes one bulb to flash on full white then all lamps turn off.

    I use the hub with home assistant and mqtt.  Ive not changed any settings but i did update firmware to latest in attempt to cure the issue.

    Im unsure what the cause is. Or if there is logging ?  I did notice if i reboot my wifi it seems to cause the same behaviour…  I even bought new router. Perhaps my node mcu is faulty ?

    Hopefully someone has an idea.


    If I build a new one Whats the best parts these days (im uk based)



  18. Hello Chris,

    Thank you for much for your great work.

    I built one based on a D1 mini.

    It works great mostly.

    There is one thing I can’t get to work though.

    I have two groups of Milight devices, one group is paired to an older Wifi bridge and one group to a newer iBox v3.

    The new group I can control via the GUI and also by sending UDP commands. This is a RGBW+CCT device.

    The other group though, I can only control via the GUI. These are RGBW devices.

    If I send UPD commands, nothing happens.

    Any ideas what goes wrong?

    Best regards, Bart

    1. Hi Chris,

      I am still unable to get it to work using UDP protocol.
      I have uploaded some images to show you the hardware I’m using and settings here:

      As said, I am able to control the LEDs via the web browser GUI, but not via a script using UDP commands.
      Then I am using the following script code:
      import socket, sys, urllib2;

      ## Configuration ##
      ## BadkamerLEDs, tuinverlichting en lamp Ivo
      IBOX_IP = "" # iBox IP address
      UDP_PORT_SEND = 5988 # Port for sending
      UDP_PORT_RECEIVE = 55054 # Port for receiving
      UDP_MAX_TRY = 5 # Max sending max value is 256
      UDP_TIMEOUT = 5 # Wait for data in sec
      DOMOTICZ_IP = "" # Domoticz IP only needed for logging
      DOMOTICZ_PORT = "8080" # Domoticz port only needed for logging
      DOMOTICZ_LOG = 1 # Turn logging to Domoticz on/off 0=off and 1=on

      ## Log to Domoticz ##
      def doLog(MSG):
      if DOMOTICZ_LOG == 1:
      urllib2.urlopen("http://"+DOMOTICZ_IP+":"+DOMOTICZ_PORT+"/json.htm?type=command&param=addlogmessage&message="+MSG.replace(" ", "%20")).read()

      except Exception as ex:
      print "[DEBUG] log error :", ex

      ## iBox v6 commands ##
      def iBoxV6Commands(x):
      return {
      "COLOR001" : "31 00 00 08 01 BA BA BA BA",
      "COLOR002" : "31 00 00 08 01 FF FF FF FF",
      "COLOR003" : "31 00 00 08 01 7A 7A 7A 7A",
      "COLOR004" : "31 00 00 08 01 1E 1E 1E 1E",
      "SATUR00" : "31 00 00 08 02 64 00 00 00",
      "SATUR25" : "31 00 00 08 02 4B 00 00 00",
      "SATUR50" : "31 00 00 08 02 32 00 00 00",
      "SATUR75" : "31 00 00 08 02 19 00 00 00",
      "SATUR100" : "31 00 00 08 02 00 00 00 00",
      "DIM00" : "31 00 00 08 03 64 00 00 00",
      "DIM25" : "31 00 00 08 03 4B 00 00 00",
      "DIM50" : "31 00 00 08 03 32 00 00 00",
      "DIM75" : "31 00 00 08 03 19 00 00 00",
      "DIM100" : "31 00 00 08 03 00 00 00 00",
      "ON" : "31 00 00 08 04 01 00 00 00",
      "OFF" : "31 00 00 08 04 02 00 00 00",
      "SPEEDUP" : "31 00 00 08 04 03 00 00 00",
      "SPEEDDOWN" : "31 00 00 08 04 04 00 00 00",
      "NIGHTON" : "31 00 00 08 04 05 00 00 00",
      "WHITEON" : "31 00 00 08 05 64 00 00 00",
      "WW00" : "31 00 00 08 05 64 00 00 00",
      "WW25" : "31 00 00 08 05 4B 00 00 00",
      "WW50" : "31 00 00 08 05 32 00 00 00",
      "WW75" : "31 00 00 08 05 19 00 00 00",
      "WW100" : "31 00 00 08 05 00 00 00 00",
      "MODE01" : "31 00 00 08 06 01 00 00 00",
      "MODE02" : "31 00 00 08 06 02 00 00 00",
      "MODE03" : "31 00 00 08 06 03 00 00 00",
      "MODE04" : "31 00 00 08 06 04 00 00 00",
      "MODE05" : "31 00 00 08 06 05 00 00 00",
      "MODE06" : "31 00 00 08 06 06 00 00 00",
      "MODE07" : "31 00 00 08 06 07 00 00 00",
      "MODE08" : "31 00 00 08 06 08 00 00 00",
      "MODE09" : "31 00 00 08 06 09 00 00 00",

      ## Zone builder ##
      def getZone(data):
      Zone = 0
      for x in bytearray.fromhex(data):
      Zone += x
      return format(Zone, "04X")[2:]

      ## Checksum builder ##
      def getChecksum(data):
      checksum = 0
      for x in bytearray.fromhex(data):
      checksum += x
      return format(checksum, "04X")[2:]

      ## V6 command builder ##
      def V6CommandBuilder(SessionID1, SessionID2, CycleNR, bulbCommand, Zone, checkSum):
      return "80 00 00 00 11 " + SessionID1 + " " + SessionID2 + " 00 " + CycleNR + " 00 " + bulbCommand + " " + Zone + " 00 " + checkSum

      ## Commandline commands ##
      CMDLINE_INFO = (
      "## Command line options ##\n"
      "Use command line as follow : CMD1 CMD2\n"
      " : CMD1 Bulb zone\n"
      " : CMD2 Bulb command\n"
      "Select the bulb zone : 00 01 02 03 04\n"
      "Bulb on/off : ON OFF NIGHTON WHITEON\n"
      "Mode Speed up/down : SPEEDUP SPEEDDOWN\n"
      "Kelvin warmwhite : WW00 WW25 WW50 WW75 WW100\n"
      "Brightness : DIM00 DIM25 DIM50 DIM75 DIM100\n"
      "Saturation : SATUR00 SATUR25 SATUR50 SATUR75 SATUR100\n"
      "Mode (discomode) : MODE01 MODE02 MODE03 MODE04 MODE05\n"
      " : MODE06 MODE07 MODE08 MODE09\n"
      "Bulb color : COLOR001 COLOR002 COLOR003 COLOR004\n"

      CMDLINE_ZONE = sys.argv[1].strip()
      print "[DEBUG] start command1 :", CMDLINE_ZONE

      CMDLINE_CMD = sys.argv[2].strip()
      print "[DEBUG] start command2 :", CMDLINE_CMD

      print CMDLINE_INFO
      raise SystemExit()
      doLog("Milight Script: Starting... ( " + CMDLINE_ZONE + " " + CMDLINE_CMD + ")")

      ## Start session ##
      Session = False
      for iCount in range(0, UDP_MAX_TRY):
      START_SESSION = "20 00 00 00 16 02 62 3A D5 ED A3 01 AE 08 2D 46 61 41 A7 F6 DC AF D3 E6 00 00 1E"
      doLog("Milight Script: Setting up ibox session...")
      sockServer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      sockServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      sockServer.bind(('', UDP_PORT_RECEIVE))
      sockServer.sendto(bytearray.fromhex(START_SESSION), (IBOX_IP, UDP_PORT_SEND))
      dataReceived, addr = sockServer.recvfrom(1024)
      dataResponse = str(dataReceived.encode('hex')).upper()
      SessionID1 = dataResponse[38:40]
      SessionID2 = dataResponse[40:42]
      print "[DEBUG] received session message :", dataResponse
      print "[DEBUG] sessionID1 :", SessionID1
      print "[DEBUG] sessionID2 :", SessionID2
      Session = True

      except socket.timeout:
      print "[DEBUG] timeout on session start :", START_SESSION
      doLog("Milight Script: Timeout on command... doing a retry")

      except Exception as ex:
      print "[DEBUG] something's wrong :", ex
      doLog("Milight Script: Something's wrong with the session...")

      ## Send bulb command ##
      if Session == True:
      for iCount in range(0, UDP_MAX_TRY):
      CycleNR = format(iCount, "04X")[2:]
      print "[DEBUG] cycle number :", CycleNR

      bulbCommand = iBoxV6Commands(CMDLINE_CMD)
      print "[DEBUG] light command :", bulbCommand

      useZone = getZone(CMDLINE_ZONE)
      print "[DEBUG] zone :", useZone

      Checksum = getChecksum(bulbCommand + " " + useZone + " 00")
      print "[DEBUG] checksum :", Checksum

      sendCommand = V6CommandBuilder(SessionID1, SessionID2, CycleNR, bulbCommand, useZone, Checksum)
      print "[DEBUG] sending command :", sendCommand
      doLog("Milight Script: Sending command: " + sendCommand)

      sockServer.sendto(bytearray.fromhex(sendCommand), (IBOX_IP, UDP_PORT_SEND))
      dataReceived, addr = sockServer.recvfrom(1024)
      dataResponse = str(dataReceived.encode('hex')).upper()
      print "[DEBUG] received message :", dataResponse
      doLog("Milight Script: Receiving response: " + dataResponse)

      except socket.timeout:
      print "[DEBUG] timeout on command :", sendCommand
      doLog("Milight Script: Timeout on command... doing a retry")

      except Exception as ex:
      print "[DEBUG] something's wrong :", ex
      doLog("Milight Script: Something's wrong with te command...")


      doLog("Milight Script: Ready...")

      raise SystemExit()

      Any suggestions would be greatly appreciated.

      Best regards, Bart

  19. I can’t seem to get it to work.  I’ve tried flashing the bin to the esp8266 and all seems to go correct.  But I can never get the device to show its wifi to connect and configure.

    I’ve tried flashing a blank.bin and file and reflashing several time without success. It could be something like a bad wire or board, but have yet to figure it out.

  20. I cannot seem to get my PC to find the wifi to connect to. I have tried erasing and writing a blank.bin file and then resetting and flashing the milight hub. But after a reboot, the wifi never shows up to connect to.

    I’m trying on a Windows 10 machine with NodeMCU and the esp8266 shows a blinking blue light, but I can’t see to figure out why I can’t connect to the board’s wifi to setup to connect to my home wlan.

    1. It’s possible you have a defective ESP8266. Do you have another you could try on? Would also be worth checking serial logs.

  21. Hi, and thanks for u work.

    i think i hab found a Little Bug. My MQTT Broker Said

    U See this „u0022“ always?

    And i miss the „Save“ Button. I want to Save two Groups and it was very tricky

    1. Are you sure this isn’t an issue with your broker? espMH should definitely send " and not the escape sequence.

  22. Hello!

    Could someone provide basic instructions on how to flash the precompiled firmware (.bin file) to nodemcuv2 with Platformio?

    I have downloaded the usb drivers and i see my nodemcu in Platformio.

    I have also no idea where should I put these lines:


    Thank you in advance!

  23. Hi,

    I’m running pre compiled binary 1.8.3 on nodemcu with nrf24. Everything works perfect but there’s an issue with brightness control. I’m trying to control 2 cct receivers via web UI or REST. When controlling single channel it works fine, but when trying to dim or brighten all channels at the same time it instantly crashes every time. What can cause this? Looks like some buffer overflow in nrf?


  24. I’ve now my 4 Devices added. Now i can control my bulbs using the webUI.

    Now i want add those using gateway so i can use them inside Domoticz.

    How do i do this? Tried everything but won’t work.

  25. Hi within the Milight App i turn on and off 2 different bulbs but i see 1 ID:

    Or do i read this different?

  26. I’m using a NRF24L01+PA+LNA with the Nodemcu v3. I can get into the webinterface but nothing happens when sniffing. I checked but I don’t know if my modules are ok. The NRF24L01+PA+LNA was quite cheap (2 US$).

    To provide further information, I flashed the precompiled binaries. Couldn’t get Platformio to work, as I didn’t know where to put the commands:

    I know, I feel stupid. Besides, is it ok that I use the Nodemcu v3 whereas the target board seems v2?

    Please help.

  27. Hi All,

    Installed latest firmware : 1.8.1 (nodemcuv2)

    Connect to the module. Did Wifi Setup. Connect again.

    When i start sniffing and use my MiLIght App controller on iOS to turn on bulbs i don’t see any sniffer information.

    Restart the module didn’t work as well. What do i wrong?

  28. This is a pretty stupid simple question but couldn’t find any clear answers. After going through 8 of the wifi boards I FINALLY got to one that actually works for me. Got my bulbs paired and all that fun stuff. And then I saw there is a firmware update available. So my question is, if I flash the update, are my settings lost and/or paired bulbs disconnected? If so, I think I may just stick with the “If it ain’t broke” strategy.

    1. upgrading firmware should not affect your settings. and it’s generally safe to roll back a version as well.

      You can also back up and restore settings under Admin > Backup.

  29. Couple of quick questions…

    1. Just to confirm, I can add a bulb/fixture without the remote? Is the specific process detailed somewhere?

    2. Is there a way to confirm the radio is hooked up correctly and operational?

    3. Is there a way to make the IP address static?

    Many thank, I’m really looking forward to implementing this to control my exterior lighting.


  30. Hi, Chris

    This firmware is BRILLIANT! Thank you!!

    This weekend I replaced my 2 Bridges with a D1 mini (precompiled bin, latest version, all rgbw bulbs) running 6 virtual hubs (named 0x1 – 0x6).

    I do get two strange effects, though:
    1) In HASS, turning lights on & off works fine, but a change to brightness or color affects ALL currently ‘on’ bulbs.
    2) If I set a bulb to white, the bridge turn on all the lights (states not updated in your interface or HASS)

    On the sniffer, in these cases, I see a second command being issued by device_id 0000 (sometimes twice) after my initial command.

    I deactivated all automations to test this. Commands issued from the bridge’s interface work perfectly with perfect state topics being issued.

    Is this a known issue? Is there a known fix?

    Thanks again


  31. Hi Chris, I installed latest version, 1.8 for nodemecu and notice a strange behaviour
    Sniffing operations seems not so responsive like 1.7
    I’ve already remarked this with dev 1 and dev 2 but I was not so very sure but now a made a simple test with the official release with the order described below.
    Tested with 1.7.1 and everything is right reported in the web interface
    Installed the newest and operation doesn’t apply for so many time (nothing is sniffed)
    Reverted again with previous 1.7.1 release and everything return to te correct efficient status

    Can you make a check?
    Thank you for this so special tricky and work

    1. hi,

      i won’t have time to look for a little while. in the meantime, please open an issue on the github project.

  32. thanks ,

    i’ve order kit to start useing it,know i use Ibox 2 (already full) with domoticz and throught controlicz (alexa)….


    is there any way to link it direct to alexa Echo just like hue bridge ..?

    thanks again

  33. I got everything working great using an LS2 Milight 5 in 1 led strip controller, which is compatible with FUT089 remote.

    In the web application i can control the ledstrips. I would like to use the application, but the old milight app  and the new one  don’t seem to find the ESP hub.

    I configured device id 0x1, port 8888 and protocol 6, buth nothing….

  34. Hi,

    it is possible to use FUT038 and LS2 (both are LED Stripe Controller) with this project?

    I’ve the HW up and running. I played a little bit with it and now I have a device 0xAAC in the puldown list. No idear where it is come from. What I don’t understand is, how to find out the device id for new devices. If I need a original remote/hub? At the monent I’ve only FUT038 and LS2 here.


  35. Hi,

    I would like to controll the FUT038 and LS2. Bouth are Mi-Light LED Stripe Controller.

    It is possible to contoll this LED Stripe controller with the esp8266_milight_hub?

    I don’t know, how to get the device id, or if I need a Mi-Light hub for it before?


    Best regards



  36. Hi Chris,

    Do you know if the newer products from futlight (FUT088 for handheld remote, B0 for wall mounted, FUT04x and LSx for led controllers) are compatible?

    I don’t have any of the ones mentioned but from the pictures B0 and FUT088 seem to suggest they share the same protocol.  They are more similar to FUT089/B8 rather than to FUT092/B4 however FUT089 doesn’t have dedicated keys for R, G, B.

    Is there a thread with all compatible units (remotes, controllers and bulbs)?


  37. Hi Chris,

    I LOVE this project and it has helped me solve the issue of lighting in my house (MR16 bulbs EVERYWHERE).

    I now have about 30 RGB+CCT bulbs in my house.

    Something weird happened last night when I put in an extra 8 bulbs to bring me to about 30. I thought it was a range issue from the controller to the bulbs as it would not turn on/off all of the bulbs in certain areas. I started to move the controller around and I was getting different behaviour. I’ve moved it to a more central point.

    What happened then is that the controller could control all of the bulbs fine but certain states in Home Assistant weren’t being updated. I would turn a group of bulbs off (they would all turn off) but the states would not change in HA (they would stay on).

    The correct commands were being sent over MQTT but for some reason HA was not realising that the bulbs state was off.

    I SEEMED to have fixed this by putting an MQTT state delay in the controller of 1300ms (this seems really long but I have no need for the states to be updated instanaeously in HA). I’m wondering if there are perhaps some settings in the controller I don’t understand for reliability.

    Would getting an NRF module with an antenna help? (my controller is plugged directly into my Pi and I have a really strong wifi AP in my house which is pretty close to the controller)



    1. State updates should get sent out as long as the ESP is working. If you flood it with packets sometimes the ESP becomes much less responsive. As far as I can tell, this is because the receive buffer fills up and TCP backoff mechanisms kick in.

      I think delays help either because the ESP is able to spend more time handling received packets, or because the TCP implementation doesn’t handle responding to receives when it’s being flooded well.

      I think the real fix here is to make these things asynchronous. Someone has a PR up to enable TLS for MQTT, which involves switching to an async MQTT impl. Maybe that’ll be worth trying when it gets merged in (still a few things we’re iterating on).

      Antenna might help, but make sure you have a power source that can handle it. Also make sure you also get a module that has all of the correct caps and stuff. The ones I ordered didn’t and they don’t work. Might be better to just make sure your WiFi is on a channel that’s far away from the bulb’s channels.

    2. I would suggest to try connecting your radio ground to the VIN ground, or alternatively if powered from USB ground to the VIN pin ground.

      Some ESP designs float thier ground, and while not a big problem, causes the propagation of signal to degrade significantly.

      Give it a shot, the worst that could happen is…. nothing

  38. Weird problem!

    So, I have the nodemcu, flashed firmware for Milighthub, added the mqtt in Hass, used the hubID from my remote, and it all seemed to be working.
    Hass shows when I use the remote, and nodemcu is detecting clicks. I got 4 milight bulbs in my living-room and they each have their own group. The setup in config.yaml is the same for every group, only the group-id is different.

    So when I try to switch bulbs on and off in Hass, it works fine for group 1 and 2 but 3 and 4 is not turning on the bulbs. I have gone through the syntax in config to look for errors, removed and reinstalled mqtt, reflashed firmware on nodemcu and tried to find a solution on google, and I simply can’t figure it out.

    Anyone have an idea what could be wrong?

    1. Are you sure they’re paired to the right group? Do they respond to an official milight remote?

  39. Hi, It is possible to order ready to run hardware (I need connect this to raspberry 3b+) ?

  40. Hello Chris,

    Thanks for this post and the software. Using a NodeMCU V2 and a FUT035 (Color Temperature Controller for WW & CW LED Strip) it took only 30 minutes to get it wired, installed and all functions working from the web UI, great ! Configuring MQTT with OpenHUB next…

    I have 2 questions though:

    I need to select RGB+CCT mode and only use Color Temperature and Brightness (and just ignore Hue, Saturation and White) for FUT035 ? Because when I select CTT mode (which seems more logical as it exactly matches the available functions) the Color Temperature will only work in a subrange in the middle between CW and WW, but never 100% CW or 100% WW (sometimes the subrange seems to shift towards the CW or WW ?). In RGB+CCT mode I get the full Color Temperature range (0 = 100% CW and 100 = 100% WW). Is this the expected behaviour (no problem to use it this way) ?
    When I do Start Sniffing, then I can see the commands coming by from both your MiLight gateway using the UI and my FUT006 Remote, so the Sniffing works. But when I use my B2 Remote Controller (, then I don’t see anything in the Sniffer log… Although it does (as the FUT006) control my FUT035 in the same manner. Might it be using a different frequency that the Sniffer doesn’t catch ?

    Thanks and keep up the good work !


    1. CCT doesn’t have “set temp to X” commands, only “increase temp” and “decrease temp” (same deal for brightness).

      The hub hacks around this by ramping it to an extreme and then sending the appropriate number of up/down commands from there. In order to do this, it assumes a range of [0,10], which is the case with the CCT devices I’ve tested with. It’s possible your device uses a different range. Unfortunately kind of hard to add support for this.

      I don’t have a B2 to test with, but I’m a little surprised it doesn’t work. You could try compiling the firmware with DEBUG_PRINTF enabled and check serial logs.

    2. Okay, B2 is definitely not supported. The protocol is slightly different from RGB+CCT. Shouldn’t be too hard to add support.

    3. Hello Chris,

      Sorry for the delay in response.

      I was first trying to get MiLight Hub running with OpenHAB without needing to use EspMilightHub Binding and without any rules, only basic Items and some translations JSONPATH and small JS. At least for my CT LED Strips (don’t have any RGB ones, nor MiLight bulbs yet) via FUT035 Controller I have succeeded using them from OpenHAB with feedback from the FUT006 Remote control (for On/Off state). I might post my setup on the EspMilightHub page later…

      So back to the subject of the B2 controller. As advised I downloaded the MiLight Hub source for the fut091 branch from, installed PlatformIO on Mac and build + burned that version (indeed a breeze, but wow the amount of warnings during compile of the libs ;-)). Compared to the official MiLightHub V1.7.1 I was initially running it seems to support the B2 Remote ! When I do ‘Start Sniffing’ I can now see the B2 commands passing by, no DEBUG_PRINTF needed 🙂 If you want some test data for pressing certain keys, let me know… When I then choose Mode FUT091/B2 and use the sniffed ID I can control the LED Strips from the WEB UI !

      However, there are 2 (minor) issues:

      1. I am missing the Group selection (at least in the Web UI), you might want to add that because now it emits on Group 0 = All Groups. The B2 supports 4 groups. Luckily via MQTT I can address individual groups like

      mosquitto_pub -t milight/commands/0x26FD/fut091/4 -m '{"state":ON}'

      so I think for OpenHAB I will be fine.

      2. Color Temperature seems reversed and some range issue. Using Web UI CW (slider left) or MQTT with “temperature”:1 (0 does nothing) will result in WW. Web UI WW (slider right) or MQTT “temperature”:100 will result in full CW. The color_temp range as seen in MQTT updates/state is 153-370. But pressing the ColorTemp slider on the B2 I see MQTT “color_temp” updates between roughly 175 and 654. As mentioned, happy to make Sniffer Logs.

      One final question for now: will you merge the fut091 branch into the master tree for release in a 1.7.2 version or so (maybe after some tweaks like above) ? I will be happy to test things on my side as far as possible given my HW…


      Henk Demper

    4. Hi Henk,

      Thanks, that’s very helpful.

      Just pushed a fix for the UI bug you noticed.

      Packet logs would be helpful. I noticed that my official milight wifi gateway has support for this remote, but I don’t have a bulb to test with. So a bit hard to test brightness/white temp.


    5. Hi Chris,

      1. GUI fix

      I downloaded (to clean new folder) and flashed (with SUCCESS) the version with the UI bug fixed, rebooted the NodeMCU, but it still appears the same: no group buttons for the FUT091. I can see the code change in index.html (I can even open that in Chrome on Mac and actually see the group buttons Ok), but when I do ‘View Source’ with Chrome on the NodeMCU Web UI, it still says somewhere:

      ... id="group-option" data-for="cct,rgbw,rgb_cct,fut089"

      …so without the fut091 added. Somehow index.html didn’t get into the image to flash, perhaps dist/index.html.gz.h needs to be manually updated by some tool on your side or so ?

      2. Package Sniffer for B2


      – All fut091 packets are 9 bytes long
      – ‘Key’ value changes (random ?) with each touch…
      – Sequence nicely ++ for each touch
      – Note that Brightness slider is L-R-reversed with your Web GUI, but as mentioned gives reversed CW-WW result GUI -> LED’s

      See data at end of this post, let me know if you need more…

      3. MQTT, Group 0 & state vs update

      Hope I can explain this right. For the OpenHAB automation I want the feedback from the LED’s = MiLightHub to update my controls (On/Off and NightMode switches and Brightness/ColorTemp sliders). Currently I use the MQTT ‘state’ topic for that, so that even if I restart OpenHAB I still get the correct state (via MQTT buffering). As I use the same ID in OpenHAB as the actual B2 that works beautifully: if I change for instance the Brightness/ColorTemp on the B2, I see my sliders update in OpenHAB !

      a. But things go wrong when I start to use Group 0 mode. For instance if I turn OFF Group 1, then All lights ON (Group 0), the status of Group 1 doesn’t change. In fact if I THEN try to control Brightness in Group 1, MilightHub thinks Group 1 is still OFF and doesn’t even process it. I have ‘solved’ this by when Group 0 changes ON/OFF state (checking MQTT ‘update’ topic), I propagate that command to all Groups 1-2-3-4 to keep MilightHub in-sync. So that means 4 extra RF commands as well, which are effectively useless, as the lights are already ON or OFF by B2…

      b. But we get another issue when I do on B2 a Brightness Change for ALL = Group 0. Then I do see MQTT ‘updates’ and ‘state’ changes for milight/updates/0x26FD/fut091/0 and milight/states/0x26FD/fut091/0, but the internal MilightHUb status of Group 1-2-3-4 is not altered (not internally and no update/state MQTT changes). Now I can ‘catch’ the Group 0 updates and update my controls… but it does mean if I later control say ColorTemp of Group 1, that I CANNOT use the returned MQTT ‘state’ topic, as the Brightness that was only changed for Group 0 is not reflected in Group 1. Hence the next Group 1 state update contains the old (non-actual) value and my sliders will jump to (the wrong) value. Again I can more or less fix this by updating my controls on MQTT ‘updates’ (and converting with some JS transformation brightness and color_temp to 0-100 range) from both Group 1 AND Group 0. This solves the problem, but then I must forget about MQTT ‘state’, which is a pity for ‘catching in’ in-sync… For Night Mode I still need the bulb_mode from state though (not available in an ‘update’).

      So all in all I think I can make the OpenHAB automation and B2 in perfect sync using a mixture of a. and b solutions above, but for your consideration (perhaps also for others): Would it be sensible for MilightHub to react on Group 0 sniffed (/send) commands by automatically updating the same fields for all groups 1-4 (or 1-8 for FUT089) ? No extra RF commands would need to be send, just updating the internal status… and by that automatically emitting 4/8 extra MQTT ‘updates’ and 4/8 extra ‘states’. That might be overkill (on MQTT level) if you have only 1 bulb, but it would more mimic what is actually going on… Hope you understand ?

      Thanks again,

      Henk Demper

      ----- Group 1 On
      Key : 20
      b1 : 21
      ID : 26FD
      Command : 01
      Argument : 01
      Sequence : 31
      Group : 01
      Checksum : D0

      —– Group 1 Off
      Key : 80
      b1 : 21
      ID : 26FD
      Command : 01
      Argument : 06
      Sequence : 32
      Group : 01
      Checksum : B6

      …skipping Group 2 & 3…

      —– Group 4 On
      Key : 7C
      b1 : 21
      ID : 26FD
      Command : 01
      Argument : 04
      Sequence : 3D
      Group : 04
      Checksum : BE

      —– Group 4 Off
      Key : 08
      b1 : 21
      ID : 26FD
      Command : 01
      Argument : 09
      Sequence : 3E
      Group : 04
      Checksum : 40

      —– All On
      Key : E3
      b1 : 21
      ID : 26FD
      Command : 01
      Argument : 00
      Sequence : D0
      Group : 00
      Checksum : AC

      —– All Off
      Key : F0
      b1 : 21
      ID : 26FD
      Command : 01
      Argument : 05
      Sequence : D1
      Group : 00
      Checksum : A3

      —– Brightness Left (0%, Group 0)
      Key : 04
      b1 : 21
      ID : 26FD
      Command : 02
      Argument : 6D
      Sequence : 51
      Group : 00
      Checksum : B0

      —– Brightness Middle (+/- 50%, Group 0)
      Key : 94
      b1 : 21
      ID : 26FD
      Command : 02
      Argument : F5
      Sequence : 6B
      Group : 00
      Checksum : 82

      —– Brightness Right (100%, Group 0)
      Key : D1
      b1 : 21
      ID : 26FD
      Command : 02
      Argument : 8F
      Sequence : 53
      Group : 00
      Checksum : 11

      —– Color Temperature Left (0%, WW = Yellow, Group 0)
      Key : 27
      b1 : 21
      ID : 26FD
      Command : 03
      Argument : 82
      Sequence : 8A
      Group : 00
      Checksum : 9E

      —– Color Temperature Left (+/- 50%, WW+CW, Group 0)
      Key : 3E
      b1 : 21
      ID : 26FD
      Command : 03
      Argument : 19
      Sequence : B5
      Group : 00
      Checksum : 87

      —– Color Temperature Left (100%, CW = Blue, Group 0)
      Key : FD
      b1 : 21
      ID : 26FD
      Command : 03
      Argument : C8
      Sequence : 8E
      Group : 00
      Checksum : 52

    6. Thanks Henk, the packet logs are helpful.

      I think I’ve got a handle on the structure of the protocol (it’s almost identical to a few others that are already supported), just need confirmation on the brightness/color temp ranges.

      Yes, dist/index.html.h.gz should’ve been committed. The platformio rebuilds it automatically, but if you don’t have the necessary tooling installed locally (node, npm, etc.), it’ll skip it. I just committed it, so if you try again the change should be there.

      Group 0 should already behave as you’re suggesting (relevant source).

      Here’s some testing I did with curl to verify this works as expected.

      I don’t use the remotes in my setup, but in testing I had an MQTT automation that fanned out states for group 0 to all of the individual groups to keep HASS state in sync. Sounds like that’s what you’re suggesting as well.

    7. Hi Chris,

      Indeed the new version with dist/index.html.h.gz updated fixed the Group Web UI issue, likely I don’t have all the tools installed (just installed PlatformIO.Core, nothing more…).

      If you need any testing (like correct CW/WW range) with fut091 on brightness/color temp ranges would you make a new version let me know.

      About Group 0: My bad, I made wrong assumptions on the fact that I didn’t see any MQTT update/state topics being send for Group 1-4/8 when Group 0 is used on B2. After more testing I do see that the internal state for Group 1-4 is updated when Group 0 is changed. That means that in OpenHAB GUI for updating my controls for Group 1 I must listen to MQTT state (or update) topics for BOTH Group 1 AND Group 0. I added the latter and now everything is in-sync when using OpenHAB (Group 1-4) and/or B2 (Group 0-4) 🙂

      I could only find one situation that it would go out-of-sync: Press All OFF on B2, then in OpenHAB turn Group 1 ON and control Brightness. If I then change Brightness on B2 (which is still in Group 0 mode), then the actual lights do change brightness, but this is not reflected in OpenHAB because the Group 0 ‘state’ is not changed (because it is considered OFF). I think I will fix on this side by checking for ‘updates’ on Group 0 (these are changing) instead of ‘states’ to get it perfect…

      Thanks for all the quick updates !


    8. What you’re seeing I think highlights a deeper issue:

      Any update to group 0 is applied to group 0’s state, and then group 0’s state clobbers all of the other groups’ states. Of course it should instead apply the incremental update to each of the individual groups.

      Created this issue in github to track —

      I pushed a change to reverse the ranges for color temp. Let me know if that behaves as expected.

    9. Hello Chris,

      On the Group 0: It’s exactly as you describe in the issue 284. Group 0 ‘state’ is not useful, only the ‘updates’ should be propagated to the groups 1-4/8. Indeed fanning these Group 1-4/8 state/updates via MQTT from MiLightHub might be too heavyweight (delaying), maybe some channels are never used.

      As mentioned in OpenHAB for updating my controls I now listen to both MQTT ‘state’ topics (using level and kelvin 0-100%) of Group 1-4 AND MQTT ‘update’ topics of Group 0 (brightness 0-255 and color_temp 153-370 and then use small JavaScript to bring in range 0-100%). That does the trick and is lightweigth enough. If you would consider the ‘fanning’ strategy in MiLightHub, consider making it an option (that you can leave off) please, so people have the choice to do it in MiLightHub or their automation system…

      On the color_temp path: the reversal works, great 🙂
      The only thing (quickly tested with slider in Web UI) is that although the ranges on the MQTT side are Ok (kelvin 0-100 and color_temp 153-370), there is a slight range error particular on the WW side, resulting in that if you click directly on 100% = WW the LED’s don’t change. I sniffed MiLightHub output vs. B2 looking at ‘Argument’ value (note the colors are reversed left-right on B2, but I took that into consideration in below):

      MiLightHub using Web UI:
      [Left=CW=0%] 0xCD … 0xFE 0xFF 0x00 0x01 … 0x95 [Right=WW=100%]

      [Right=CW] 0xC8 … 0xFE 0xFF 0x00 0x01 … 0x82 [Left=WW]
      (consistent with earlier logs)

      So you see that the range of B2 seems C8…FF 00…82 and MiLightHub currently CD…FF 00…95. The values 83-95 (around WW 100%) will be ignored and this is what I am seeing. So I think the CW 0% value should be changed 0xCD -> 0xC8 and the WW 100% 0x95 -> 0x82 (correct range delta is 0xBA = 186). I will be happy to look into V2PacketFormatter.cpp and/or FUT091PacketFormatter.cpp is you want…

      Almost there…

      Thanks !

    10. Definitely agree MQTT fanning should be optional if we end up adding it.

      Ah, yeah. My FUT092s behaved the same way — had range beyond the remapped [0, 100] values sent via the wifi gateway. The wifi gateway is limited to sending [0, 100] for both brightness and color temp, which leads me to believe the remotes send extra values beyond the range.

      Just pushed a fix to include some buffer on the ends. Values outside of the range should now be remapped to the appropriate extreme. Let me know if that works.

    11. Hi Chris,

      Unfortunately the update didn’t change anything: When I move the MilightHub Web UI ColorTemp Slider with Sniffing enabled, I still see ‘Argument’ values between 0xCD … 0xFF 0x00 … 0x95. To make it right, we have to linearly map the range 0…100 to 0xC8 … 0xFF 0x00 … 0x82 (if we want to follow the B2 range) instead. So that means we have 0x182 – 0xC8 = 0xBA = 186 values to use. In your case you are using 0x195 – 0xCD = 0xCD = 200 values. This is because you have something like ‘interval’, which can only map to factors of 1, 2, etc. I don’t think truncating those 200 – 186 = 14 values is the right way to do it. Why not linearly map between 0-100 and those 186 values ?

      I temp fixed it (for the sending command part) by changing (it now works Ok in Sniffer):

      void FUT091PacketFormatter::updateTemperature(uint8_t value) {
      command(static_cast(FUT091Command::KELVIN), V2PacketFormatter::tov2scale(value, KELVIN_SCALE_MAX, 2, false));

      to (not wanting to change V2PacketFormatter::tov2scale() for now)

      void FUT091PacketFormatter::updateTemperature(uint8_t value) {
      command(static_cast(FUT091Command::KELVIN), (0xC8 + value * 0xBA / 100) & 0xFF );

      I would suggest that you change to the parameters in

      uint8_t endValue, uint8_t interval


      uint8_t startValue, uint8_t endValue

      or so ? Of course, for the feedback we have to go the other way and use similar linear scaling (not factor 2 or so) to map from the received 186 different values back to 0-100 range.

      Don’t know how much this would need refactoring for other FUT/RGB types… ?

      Please advise if I should dive in more or … ?


      Henk Demper

    12. Hi Henk,

      You’re more than welcome to drive this to whatever degree you wish. Don’t let me stop you from digging in 🙂

      This is why I set it up this way:

      • I have an iBox 1, which can be used to send the same commands the remote can programmatically (it supports all remote types).
      • Setting color temp to [0, 100] with the iBox 1 results in the range I have in the firmware: 0xCD..0x95.
      • It has the same behavior for the FUT092 remote type — a range of 100 values.
      • My physical FUT092 remote also sends values outside of this range, like your FUT091 remote does. But the values beyond the extremes in the range sent by the iBox1 put the bulb in a state that is — as far as I can tell — visually equivalent to the iBox.

      If your remote is capable of putting your devices into a state that espMH is not with the current ranges, then I definitely agree something needs to be changed. Is this the case?

    13. Hi Chris,

      If your remote is capable of putting your devices into a state that espMH is not with the current ranges, then I definitely agree something needs to be changed. Is this the case?

      The only issue I have is that if I quickly move the MilightHub Web UI slider (latest FUT091 software) say from 50% to 100%, then only the value of 0x95 is send. My FUT035 LED Controller ignores that value, hence the LED’s stay at 50%. If I slowly scroll back the slider to 99%, then the 0x93 value is send and this value IS accepted and immediately the LED’s goto WW. So at least there is one value (0x95) that is ‘out of range’ (for my FUT035), which will be a problem is the automation sends (only) that 100% value: nothing will happen.

      Looking more carefully at the White and Yellow LED’s at 100% Brightness (you actually need double sunglasses to do so ;-)), you see that not the effective range seems around 10%-90% (Web UI slider range): 0-10% seems all the same: Yellow LED’s are all Off and 90-100% all White LED’s stay off.

      I’m not sure what the ‘best range’ for espMH is to map the 0-100% values to: using ‘the widest ever seen with some remote’ (like from iBox1) or more narrow down to specific remotes (like B2). I don’t think it matters too much as long as:

      1. We can make all all color_temp’s (/levels/colors…) on the LED’s
      2. We don’t send values that do nothing (like the 0x95 above)
      3. We are Ok that when we use a remote like B2 that we can never reach 100% (as feedback) in the automation (because B2 has more limited range)

      I also have an iBox2 (and kind of disliked it, hence the whole MilightHub direction), I will now see (with Sniffer if that works) what the ranges are that iBox2 sends for color_temp for different selected remotes. Standby…

    14. Ok, so I started the Android Mi-Light App that connects to my iBox 2 and selected the FUT091 Remote (image that looks like I then used both the Brightness knob and the ColorTemp slide, seeing these values in MiLightHub sniffer:

      Level knob
      0% … to … 100%
      5F … 00 FF … 97 (down-count)

      ColorTemp slider
      WW (Left) … to … CW (Right)
      8D … 00 FF … C5 (down-count)

      So for ColorTemp compared to my B2 on the WW side it goes a bit ‘further’ than 82, but never reaches the 95 that you are seeing in iBox 1 (I assume also for FUT091 selected ?).

      What a mess, perhaps the Chinese are confusing us to discourage reverse-engineering ?

      So with these different ranges (iBox 1/FUT092, iBox 2 and B2), what shall we agree on for the range to be send/parsed over RF for FUT091/B2 type using MiLightHub ?

      Then you/me can put that in the software…

    15. lol, good stuff. I’ll double-check the ranges from my ibox thing (agree that they’re terrible — just good for reverse engineering purposes).

      You have physical devices to test with, so I defer to you. I would expect some level of symmetry with the other “V2” protocols (RGB+CCT/FUT092, FUT089), but given everything I’ve seen with these nutters, inconsistency wouldn’t surprise me.

    16. Double-checking the ranges from my iBox:

      This is the same that you got on your iBox2, and what I would expect given my experience with FUT092. The range has the same properties:

      • Range of 200 values
      • Increments of 2
      • Not continuous — underflows when it passes 0
      • Values reversed from origin scale
      • Remotes send values outside this range, but have the same effect as the extremes

      Not sure on the last one, as I don’t have hardware to test 🙂

      Obviously I had the endpoint for Kelvin wrong. It should be 0xC5, not 0xCD. Just pushed a fix.

    17. Hi Chris,

      So to summarise:

      Kelvin CW 2700K - WW 6500K Steps
      espMLH [95]... 00 FF ... CD 200
      espMLH+fix 8D ... 00 FF ... C5 200
      B2 82 ... 00 FF ... C8 186
      iBox 8D ... 00 FF ... C5 200
      iBox 2 8D ... 00 FF ... C5 200

      Level 0% 100% Steps
      espMLH 5F ... 00 FF ... 97 200
      B2 6D ... 00 FF ... 97/8F 214/222
      iBox 5F ... 00 FF ... 97 200
      iBox 2 5F ... 00 FF ... 97 200

      – B2 has a bit narrower-than-200 range for Kelvin, hence will not use full 0-100 scale on espMLH
      – B2 has a bit wider-than-200 range for Level, hence will use larger than 0-100 scale on espMLH (truncated ?)
      – For Level, B2 100% level goes to 97 (range 214) and then jumps down to 8F (range 222) at the far right, something with the touch-sensitive surface ?
      – FUT035 Controller ignored value [95] above, doesn’t set any CW
      – This is fixed with new range where the extreme becomes 8D 🙂
      – I think the ‘nice’ added value of using a scale of exactly 200 instead of say 186 or so is that when 2x scaling 0-100 -> 0-200 -> 0-100 range you end up with the same value, with other ranges you might get a slightly different value due to truncation/rounding

      It should be 0xC5, not 0xCD. Just pushed a fix.

      I don’t see the fix pushed (last commit 3 days ago on the fut091 branch), but I changed KELVIN_SCALE_MAX = 0xC5; and confirmed it worked. You might want to make sure it gets pushed eventually…

      And on your last comment (about the Group 0 fix): Yes, would be nice to merge both that fix and the fut091 branch into master in 1.8 release !

      So all is Ok now, I’m happy the way it all behaves 🙂
      Depending on where in the house you stand, not each remote button press is always sniffed/picked up (likely due to range of remote to RF24), but the other way around from espMLH to controllers always seems Ok (using RF24 with antenna).

      One more question without looking into the code to figure out: in the case that espMLH sends a command itself, does it derive the MQTT ‘update’ and ‘state’ topics directly from internal logic OR does it sniff & parse its own send RF24 signal back (like it does for external remotes) ? Just wondering…


      Henk Demper

    18. Oops, I committed, but guess I forgot to push. It’s done now.

      Starting a 1.8.0 branch. Hopefully can have a dev release ready in the next week or two.

      Locally sent packets are passed through the same packet handler that sniffed packets are. I think it’s impossible for the same nRF radio to pick up its own packets. It can only do one thing at a time (there are explicit modes).

  41. It seems I have missed something. Probably simple as noone has posted this issue. I am trying to pair my mi-light bulb with the gateway emulator. How do I do this?

    I only have the gateway emulator.

  42. Nice project! Is it easy to make it that you can just download it on a ESP8266 with the standaard Arduino running on it?

  43. Does anybody know wether (and how) this can be used with homebridge if using the UDP protocol?

    1. Yes, it emulates the official milight hub’s UDP protocol. MQTT and REST are far more reliable, though.

    2. Thank you. Ok so do you mean I could use hombedirge with MQTT or REST as well? Sorry if these questions sound stupid I’m not an experienced developer yet and I don’t completely understand all of how this exactly works.

    3. I have no experience with homebridge, so not sure. I’d imagine homebridge is capable of interacting with arbitrary services, but have nothing to back that up.

  44. First of all, thanks for all the work you’ve done and the time you’ve spent on this. I’m very new (this is my first time) to the whole NRF24L01 + ESP8266 world but despite that I got them working up to a point but have been scratching my head with a little problem now. I can see the web interface and I can sniff packets from other devices (remote and android app), but when I try to spoof one of these deviceIDs, the bulbs don’t get updated with my choice of color or brightness. I might be missing something pretty obvious here, but can’t be sure. I was wondering also, is it better to spoof individual devices or is it better to spoof the official milight bridge and how exactly can I get the deviceID of the bridge?

    Any ideas or suggestion would be really helpful. thanks again!


    1. Hi Chris, thanks for the reply. Unfortunately no I don’t see the ESP sending any commands. When I set a deviceID and enable Sniffing, I don’t see any packets being sent. I’m assuming that means that either my wiring is wrong (though I’ve checked and checked again and it seems right) or my ESP is faulty.

  45. Hello,


    Is there option to clear admin password? I set it and now i can’t log to ui.




    1. The only ways to reset the admin password are:

      1. Do so through the UI / API. You need to know the current password to do this.

      2. Wipe the ESP and reflash the firmware (make sure to erase SPIFFS too).

  46. Hello Chris,

    thanks a lot for this really amazing project.

    Especially the MQTT implementation is a big step forward wrt. the possibilities to integrate this type of lightning system to any home automation solution.

    I’m currently about to switch towards using the Brigde’s MQTT interface for some older RGBW bulbs and a LED controller (Protocoll V5, all RGBW, Bridge is on version 1.7.0-dev3). This will replace the traditional UDP-way that I used for several years now to get a better sync with the usage of remotes (2×1-channel and 3×4-channel).

    After having played around with all of the stuff, there remain some questions and remarks, I kindly ask for help and further info:

    1. The bridge recognizes all of the 4-channel remotes I own without problem, but none of the two 1-channel versions. Is this a general limitation of the openmili-code or due to additional filtering on the bridge?

    2. In some cases, there seem to be a missing link between commands and result. Eg. if a bulb is “OFF” and you click on “Night”, this will lead to an “ON” state and a MQTT message containing both of the info “ON” and “night_mode”.
    When clicking “White” the behaviour is different, the state is not changed (also not for the web interface). From the logical side, one would expect three or more infos (“ON”, “white_mode”, hue-value set corresponding to “white” and at least brightness to a reasonable value (seems not to be fix for each type of bulb, but e.g. 80% would be a good starting point imo).

    3. The selections made for info to be provided in “Settings” seem only to have effect on the REST Api but not the MQTT-JSONs. Could this be changed? Especially having the “level” (and perhaps the RGB-value) also sent via MQTT would really be a nice to have.

    4. It’s not a big issue with MQTT to cope around the problem already mentionned in comment #2047 (also distributing commands on channel 0 to channels 1 to 4), but it seems this also leads to some inconsistent info provided on the web frontend and the REST Api(didn’t to much testing on that, might not be true).

    Once more: You’ve done a great job!

    Kind regards.

    1. Hi,

      1. The bridge recognizes all of the 4-channel remotes I own without problem, but none of the two 1-channel versions. Is this a general limitation of the openmili-code or due to additional filtering on the bridge?

      The code at this point is only loosely based on Henryk’s original. There’s a bunch of additional reverse engineering that I and others have done to support additional protocols.

      If a device is not supported, it’s generally possible to add support. Would just need help getting some of the details.

      Do you have model numbers for these remotes?

      2. In some cases, there seem to be a missing link between commands and result. Eg. if a bulb is “OFF” and you click on “Night”, this will lead to an “ON” state and a MQTT message containing both of the info “ON” and “night_mode”.
      When clicking “White” the behaviour is different, the state is not changed (also not for the web interface). From the logical side, one would expect three or more infos (“ON”, “white_mode”, hue-value set corresponding to “white” and at least brightness to a reasonable value (seems not to be fix for each type of bulb, but e.g. 80% would be a good starting point imo).

      I think I’m not exactly following what’s going on. Could you provide some MQTT logs demonstrating the behavior you’re seeing, and then manually construct the messages you’d expect to see? Might help me understand.

      3. The selections made for info to be provided in “Settings” seem only to have effect on the REST Api but not the MQTT-JSONs. Could this be changed? Especially having the “level” (and perhaps the RGB-value) also sent via MQTT would really be a nice to have.

      MQTT supports all of the same parameters that the REST API does. It does not support anything outside of sending commands to bulbs, though (the /gateways/:device_id/:device_type/:group_id route).

      4. It’s not a big issue with MQTT to cope around the problem already mentionned in comment #2047 (also distributing commands on channel 0 to channels 1 to 4), but it seems this also leads to some inconsistent info provided on the web frontend and the REST Api(didn’t to much testing on that, might not be true).

      State handling for MQTT and REST are handled through the same codepath, so there shouldn’t be any inconsistency there.

      If you have logs or examples I’d be happy to look 🙂

    2. Hi Chris,

      thanks a lot for your detailed response!

      Answering your questions in english is quite hard for me, but I try my very best!

      ad 1: “Do you have model numbers for these remotes?”

      No, there’s no label on them beside a short “2.4 G RF”. At, there’s a picture provided. They look like the ones showed under Milight Remote (the right, coloured 1-channel-model on the right). The working ones are sold there as Milight RGBW Remote – I more or less ought them all together.
      Would flashing an Arduino with Henryks Code and do some sniffing would help?

      ad 2:Please note: my observations are just what I see when using the RGBW type of bulbs I personally own. Might be different whith other harware.
      Using the web-ui provided by the hub and click on the buttons there gets me the following:
      Startet with “OFF”-State and Click on “Night” results in MQTT messages {“state”:”OFF”} and subsequent {“state”:”ON”,”command”:”night_mode”}. So different from my first observation, the night command always turns the bulbs off and then immediately on again (don’t know, if this is really sent out RF-wise). This seems to be a special behavior of the Night function. Then the bulb also is correctly indicated as beeing “ON”.

      If state is “OFF” when ckicking on “White”, the only message I get is {“command”:”white_mode”}, and the indicated state of the milight hub stays as “OFF”. In the real world the behaviour is quite different: The first click on “White” just turns the bulb on again, if it’s off. The colour state and also brightness would be reestablished at the settings the bulb itself had stored. So clicking on “White” when bulb is off should lead to just an “ON”-message.
      Only in case bulb is already turned “ON”, the “White” command leads to a result in reality that is something like {“command”:”white_mode”,”hue”:””}. Seems brightness just stays unchanged with the exeption coming from night mode, then brightness will be set to last level (but as there had not been any change when entering “night mode” this is ok, imo).
      Hope, you can follow my thoughts now, probably it’s best to just make some tests wrt, if this still is confusing.

      ad 3.:
      Might be some kind of misunderstanding. Sending all of the commands towards the esphub works as expected. The other way round is what I was talking about – the updates coming from the hub towards the broker e.g. in case the web interface or a remote is used. In the later case only a subset of the info seems to be sent to the broker (esp. not “level” and rgb values).

      My selections had been (excerpt from “ip/settings”):

      Group state fields:
      0 “state”
      1 “status”
      2 “brightness”
      3 “level”
      4 “hue”
      5 “color”
      6 “mode”
      7 “color_temp”
      8 “bulb_mode”
      9 “computed_color”

      Using the REST API for requesting them, I get all the values back, so they’re there…

      ad 4.: After having played around a little with my HA software, keeping track of group state changes to individual channels ist indeed no real issue. The rest of my irritation was most likely more related to the observation the state beeing not indicated correctly when using the “White” command as described in # 2.

      Kind regards

    3. No, there’s no label on them beside a short “2.4 G RF”. At, there’s a picture provided. They look like the ones showed under Milight Remote (the right, coloured 1-channel-model on the right). The working ones are sold there as Milight RGBW Remote – I more or less ought them all together.
      Would flashing an Arduino with Henryks Code and do some sniffing would help?

      Gotcha. The product list on does a better job of listing model numbers. Can you find it there?

      Henryk’s code at this point is a lot more limited than espMH. It uses a fixed set of RF channels, syncwords, and always expects packets of a certain length. If espMH isn’t seeing your remotes, I don’t think Henryk’s will either.

      For #2, it probably would be easiest if you could supply a script that reproduced your issue.

      What version are you using? I fixed some less-than-desirable state behavior in 1.7.

      Might be some kind of misunderstanding. Sending all of the commands towards the esphub works as expected. The other way round is what I was talking about – the updates coming from the hub towards the broker e.g. in case the web interface or a remote is used. In the later case only a subset of the info seems to be sent to the broker (esp. not “level” and rgb values).

      Which topic are you getting updates on? Note that you’ll want to be looking at the state topic, not the update topic. State is everything, while update only decodes the corresponding packet.

    4. Thank you once more for your feedback!

      The remote looks like the one listed as part of FUT25.

      Used version is “1.7.0-dev3” (D1 mini), so this is quite up to date. Seems not all of the state issues are fixed, as already described.

      Thanks for pointing me to the fact the complete set of values being available under state, hope, I’ll get my client application to extract the relevant info from there.

      Still, it’s a little irritating what’s going on on the broker. E.g. setting level to 70 produces this traffic:
      Client mosqsub/XXXX received PUBLISH (d0, q0, r0, m0, ‘milight/0x63C2/rgbw/4’, … (14 bytes))
      Client mosqsub/XXXX received PUBLISH (d0, q0, r0, m0, ‘milight/updates/0x63C2/rgbw/4’, … (18 bytes))
      The later is the reaction of the hub. I changed the send code of my application to just send {“level”:70}. This seems to make a difference: Then also get the entire state will be updated as described now for hue – there the additional “” have no negative effects, and also the level command itself was also executed.

      Sending a hue command is slightly different (with or without quotes):
      Client mosqsub/XXXX received PUBLISH (d0, q0, r0, m0, ‘milight/0x63C2/rgbw/4’, … (13 bytes))
      Client mosqsub/XXXX received PUBLISH (d0, q0, r0, m0, ‘milight/updates/0x63C2/rgbw/4’, … (11 bytes))
      Client mosqsub/XXXX received PUBLISH (d0, q0, r0, m0, ‘milight/states/0x63C2/rgbw/4’, … (92 bytes))

      Additionally some traffic, when using mode commands:
      Client mosqsub/XXXX received PUBLISH (d0, q0, r0, m0, ‘milight/0x63C2/rgbw/4’, … (22 bytes))
      Client mosqsub/XXXX received PUBLISH (d0, q0, r0, m0, ‘milight/updates/0x63C2/rgbw/4’, … (15 bytes))
      Client mosqsub/XXXX received PUBLISH (d0, q0, r0, m0, ‘milight/updates/0x63C2/rgbw/4’, … (37 bytes))
      Client mosqsub/XXXX received PUBLISH (d0, q0, r0, m0, ‘milight/states/0x63C2/rgbw/4’, … (93 bytes))
      Client mosqsub/XXXX received PUBLISH (d0, q0, r0, m0, ‘milight/0x63C2/rgbw/4’, … (21 bytes))
      Client mosqsub/XXXX received PUBLISH (d0, q0, r0, m0, ‘milight/updates/0x63C2/rgbw/4’, … (24 bytes))

      But still no “ON” reaction nor update to state, when directly switching from “OFF” to “white_mode” with “set_white”, initiated with {“command”:set_white}.

      Thank you for bringing some more light into my unserstanding, what’s going on.

    5. Yeah I think it’s probably best to ignore the updates topic all together. It’s really only useful in a pretty rare set of circumstances. I think the update topic will always send “level” instead of brightness. The field configurations only apply to the state topic.

      That’s a known issue, and it’s unfortunately probably not going to get fixed unless it’s causing major issues. The problem here is that both hue and brightness are being stored in 7 bits, and converted to the appropriate range. This means there will be some collisions and imperfect conversions. The fix would be to store the values at their full resolution. But the underlying protocol uses fewer bits, so the added resolution is not really functional.

      I’ve noticed the same sorts of funny behavior with states for night mode. I’ll try to have that fixed in the 1.7 production release. The fundamental issue, I think, is that “night mode” is really a state in the same way that on/off are, but that’s not the way it’s represented currently. Probably too much work to refactor at this point, but it leaves a bunch of crappy corner cases.

    6. Hi Chris,

      seems using the states data instead of udpates solves a lot of the issues I ran into.

      But still, imo, it’s not the night mode that is causing confusing wrt to the state the bulb really is in. Especially night mode seems to be handled correctly. It’s more white mode that causes confusion, as this some sort of multi functionality.

      Kind regards,


  47. It finally worked!!! I had a lot of problems making the NRFL2041, either Long Range or plain, to work. I simply soldered a 4.7uF 50v electrolitic capacitor between the ground and vin pins, and MAGIC!

    1. Hello, I have just bought NRF24L01+PA+LNA which is the long distance model with antenna. Would you recommend a 4.7uF 50v capacitor for this device or should it work fine without? Thanks in advance