Close

Command And Control

A project log for Reverse-Engineering the milight on-air protocol

Mi-Light/Limitless LED are a type of RGB(W) LED lamps with standard light bulb sockets and a proprietary 2.4GHz radio control protocol

henryk-pltzHenryk Plötz 05/27/2015 at 11:047 Comments

When entering a short test sequence on my remote this is what my receiver displays (a dot means an exact repetition of the previous packet):

All on:
07 B0 F2 EA 35 90 01 B9 AC F9 ..........................
07 B0 F2 EA 35 90 00 B9 74 E0 ..

Color red:
07 B0 F2 EA 04 90 0F BA 6E 01 
07 B0 F2 EA 04 90 0F BB E7 10 
07 B0 F2 EA 04 90 0F BC 58 64 
07 B0 F2 EA 04 90 0F BD D1 75 
07 B0 F2 EA 04 90 0F BE 4A 47 
07 B0 F2 EA 04 90 0F BF C3 56 
07 B0 F2 EA 04 90 0F C0 B3 DD 
07 B0 F2 EA 04 90 0F C1 3A CC 
07 B0 F2 EA 04 90 0F C2 A1 FE 
07 B0 F2 EA 04 90 0F C3 28 EF 
07 B0 F2 EA 04 90 0F C4 97 9B 
07 B0 F2 EA 04 90 0F C5 1E 8A 
07 B0 F2 EA 04 90 0F C6 85 B8 
07 B0 F2 EA 04 90 0F C7 0C A9 
07 B0 F2 EA 04 90 0F C8 FB 51 
07 B0 F2 EA 04 90 0F C9 72 40 
07 B0 F2 EA 04 90 0F CA E9 72 
07 B0 F2 EA 04 90 0F CB 60 63 
07 B0 F2 EA 04 90 0F CC DF 17 
07 B0 F2 EA 04 90 0F CD 56 06 
07 B0 F2 EA 04 90 0F CE CD 34 
07 B0 F2 EA 04 90 0F CF 44 25 
07 B0 F2 EA 04 90 00 CF 8C A6 ............................

Group 1 on:
07 B0 F2 EA 04 91 03 D0 4E 3E .............................
07 B0 F2 EA 04 91 03 D1 C7 2F .............................

Group 1 white:
07 B0 F2 EA 04 91 13 D2 CD 88 .............................
07 B0 F2 EA 04 91 13 D3 44 99 .............................

Color green:
07 B0 F2 EA 7D 91 0F D4 EC 72 
07 B0 F2 EA 7D 91 0F D5 65 63 
07 B0 F2 EA 7D 91 0F D6 FE 51 
07 B0 F2 EA 7D 91 0F D7 77 40 
07 B0 F2 EA 7D 91 0F D8 80 B8 
07 B0 F2 EA 7D 91 0F D9 09 A9 
07 B0 F2 EA 7D 91 0F DA 92 9B 
07 B0 F2 EA 7D 91 0F DB 1B 8A 
07 B0 F2 EA 7D 91 0F DC A4 FE 
07 B0 F2 EA 7D 91 0F DD 2D EF 
07 B0 F2 EA 7D 91 0F DE B6 DD 
07 B0 F2 EA 7D 91 0F DF 3F CC 
07 B0 F2 EA 7D 91 0F E0 4B 05 
07 B0 F2 EA 7D 91 0F E1 C2 14 
07 B0 F2 EA 7D 91 0F E2 59 26 
07 B0 F2 EA 7D 91 0F E3 D0 37 
07 B0 F2 EA 7D 91 0F E4 6F 43 
07 B0 F2 EA 7D 91 0F E5 E6 52 
07 B0 F2 EA 7D 91 0F E6 7D 60 
07 B0 F2 EA 7D 91 0F E7 F4 71 
07 B0 F2 EA 7D 91 0F E8 03 89 
07 B0 F2 EA 7D 91 0F E9 8A 98 
07 B0 F2 EA 7D 91 00 E9 42 1B ............................

Group 1 off:
07 B0 F2 EA 7D 91 04 EA B9 4E .............................

I already know that the first byte is length, the last two bytes are CRC and the one before that is a packet ID that is incremented for each distinct packet (but kept the same for resends). That leaves 6 bytes in the middle: In my first preliminary assessment they seem to be:

This is not a proper "command" set. This is just the current state of the remote control, transmitted in the most unimaginative way possible. By looking at the lower nibble of the CMD byte I can map it to the buttons on the remote as follows:

Now you know why they can't have more channels or additional features: There simply aren't any button codes left. Two more rules seem to apply:

The value of the sliders are as follows:

There's one additional peculiarity: The very first byte immediately after the length seems to also encode information. For my remote it is 0xB0 most of the time, except when repeatedly pressing disco mode: Then it increments up to 0xB8 and overflows back to 0xB0. This value is kept when pressing other buttons, but reset on touching the color wheel. The value seems to directly select a disco mode. I was wondering before how that worked: switching disco mode on independent bulbs, then doing an "all on", and pressing disco mode again would select the same disco mode on all bulbs. That wouldn't be possible if the only information the remote transmitted was "next disco mode", because then the bulbs would easily desynchronize with respect to what the current mode was. The modes are:

ModeDescription
0Smooth color fading
1Fade white on and off
2Fade red, green, blue, white on an off
3Jump between red, green, blue, yellow, purple, cyan, white
4Random colors and brightnesses
5Fade red on and off, blink red
6Fade green on and off, blink green
7Fade blue on and off, blink blue
8All of the above, in order

I'm not entirely sure yet if the 0xB0 is part of the remote/gateway ID (meaning the ID would have 20 bits) or something else entirely (making for an ID of 16 bits).

Discussions

Auto Bot wrote 06/18/2016 at 16:11 point

I just found a description of the commands that also explains the B0 and B8 values (actually it's one command byte which is either B0 or B8 and two remote control identification bytes).

Just scroll to "SPI COMMANDSET 2.4Ghz RF Over-the-Air Protocol - Remote Control Commands using PL1176 (or compatible LT9800)" on http://www.limitlessled.com/dev/

  Are you sure? yes | no

xvolte wrote 02/13/2016 at 23:50 point

Hello!

Thanks for your work !!

Could you / or anyone reading this, please post the sequences to link and unlink ? (of course, i didn't buy the remote, only the bulbs and the radio controller for my raspberry pi 2)

It works fine with the 1st bulb.

However, i tried to link my 2nd bulb by sending "B0 F2 EA 04 91 05" to link it to group 2, but it has link to group 1, i don't know why...

Now i'm trying to unlink but it fails .... my bulbs are milight RGBW 6w.

Thank you very much in advance !

PS : To unlink, the box says : Long press the (i) button of the linked zone immediatly once you switch on the light bulb. the unlink is done once the light blinks 9 times.

So i need a way to emulate this, but I couldn't manage to do it so far

  Are you sure? yes | no

markus-mi wrote 05/27/2015 at 15:25 point

@erantimus: It would be glad, if you could share your code with us.

  Are you sure? yes | no

erantimus wrote 05/27/2015 at 12:18 point

I did the same thing a while back (knew I should've written it up), and the ID on my WiFi bridge is 0xB81587. For example, a zone 1 off command (ignore the 0x32, it's the PL1167 FILL-FIFO command).

['0x32', '0x07', '0xB8', '0x15', '0x87', '0x00', '0x01', '0x04', '0x02']

But with RGB commands, the ID becomes 0xB01587:

['0x32', '0x07', '0xB0', '0x15', '0x87', '0x1E', '0x50', '0x0F', '0x6E']

I wrote a little code that works with the LT8900 (and the PL1167, they're identical) to control the bulbs in my house using an ESP8266 as the host. I'll see if I can put that code up on github somewhere.

  Are you sure? yes | no

Henryk Plötz wrote 05/27/2015 at 13:17 point

Ah, yes, looking at the commands my gateway sends it's true: sometimes the byte is 0xB0 (color, white), sometimes it is 0xB8 (group/all on/off). So it's probably ignored/don't care for non-disco commands.

  Are you sure? yes | no

markus-mi wrote 06/07/2015 at 07:30 point

Can you share your Code? Henryks version with the nrf24 works, but isn't reliable.

  Are you sure? yes | no

fototakas wrote 09/24/2015 at 07:19 point

@erantimus:

Could you please share the code how control bulbs using ESP8266 as a host.

Thank you in advance!

  Are you sure? yes | no