PLAYBULB candles are smart LED candles that can be controlled by mobile Android/iOS devices. The official apps are good enough but I’d like to be able to control these candles using say a STACK Box or a NINJA SPHERE (when I’ll get them). The candles are Bluetooth Smart (aka Bluetooth Low Energy or BLE) devices so that shouldn’t be too complicated.
I just started playing with the candles and I’ll show you in this post how to control them using a computer with a BLE adapter. You’ll only need a Linux PC (should also work on a Mac) with integrated Bluetooth 4.0 or a USB BLE adapter (tested with this one but this one should also work). I used Santoku Linux on VirtualBox for my tests because it comes with BlueZ, the tool we are going to use to interact with the candle.
Turn the candle on then open a terminal and type in the following command to scan for BLE devices:
$ sudo hcitool lescan
The candle should appear in the list of devices:
LE Scan ... AC:E6:4B:06:6F:CD (unknown) AC:E6:4B:06:6F:CD PLAYBULB CANDLE
We can then use the mac address of the candle to enter interactive mode using gatttool:
$ gatttool -b AC:E6:4B:06:6F:CD -I
And connect to the candle:
[ ][AC:E6:4B:06:6F:CD][LE]> connect
Now that we are connected, we just need to write the right value to the right characteristic to do something useful with the candle. Using an Android device with the official app, I captured the communication to find out what data is sent when the app is used. For example, here’s the command to turn the candle on and set the color to red:
> char-write-cmd 0x0016 00FF0000
0X0016 is the handle to indicate what characteristic we want to write to and 00FF0000 is the value. FF0000 is the hex code for the color red so to set the candle to green (#00FF00) we just need to send the following command:
> char-write-cmd 0x0016 0000FF00
After capturing a few more packets, I figured out how to set an effect. We have to use another handle and the value format is slightly different. Here’s how we can set the candle effect on with the color blue:
> char-write-cmd 0x0014 000000FF04000100
The first eight bytes (000000FF) indicate that we want to set blue (#0000FF) as a static color. The next byte (04) indicates that we want the candle effect on. I don’t know yet what the next byte is used for but we can also choose the effect speed using the next one (01).
Here are a few other examples on how to use gatttool to control the candle.
Flashing effect, green color, lower speed:
> char-write-cmd 0x0014 0000FF0000001F00
Pulse effect, blue color, lower speed:
> char-write-cmd 0x0014 000000FF01001F00
Rainbow effect, highest speed:
> char-write-cmd 0x0014 0100000002000100
Rainbow effect fade, lower speed:
> char-write-cmd 0x0014 0100000003002600
To turn the candle off, it seems we just need to use this command:
> char-write-cmd 0x0016 00000000
This data could be used to control the candles through any BLE central device but also to develop alternate apps for Android/iOS.
Thanks for posting this! I’ve taken the commands you figured out, and used them with a python script and gattool’s undocumented non-interactive mode to demonstrate using a Playbulb as an ambient display of IMAP mailbox status. Video here!
LikeLike
Thanks for the explanation how to intercept the commands and your analysis!
I just received my Kickstarter Playbulb Rainbow, and the commands are slightly different:
Format for the effects is: 0x0019 WWRRGGBBMM??SS?? where the questionmarks are still unknown to me, but MM is the effect mode (00 = Flash solid color, 01 = Pulse solid color, 02 = Rainbow, 03 = Rainbow with fading effect). SS is the speed, from 00 to ff.
For solid colors the command is: 0x001b WWRRGGBB
LikeLiked by 1 person
Hey Patrick,
did find out any more commands? Sadly I don’t have a BLE sniffer and can’t find it out by myself. I’m working on a python script to control my candle and bulb via my raspberry.
Thanks for your help
LikeLike
Did you have any issues with Host is down or Connection refused errors? I have a Playbulb Rainbow and have tried both Bluez v4.99 and v5.35. v4.99 gives me the Host is down error, v5.35 gives Connection refused. I can see lescan and see the device with both version.
Any ideas? There aren’t many sites talking about hacking these bulbs and I’ve read everything I can.
Thanks.
LikeLike
Nice blog, was trying to do it myself but I’m glad you beat me to it!
LikeLike
Nevermind. I got this working with a fresh install of Raspbian Jessie and Bluez 5.23. Works like a charm. I have a Playbulb Rainbow, so I’m using the commands Patrick lists above.
LikeLike
Hi,
Your commands do not work under macOS Sierra. You said you can write your own apps for the Playbulbs. How exactly does it work?
Best regards
Philipp Vogel
LikeLike
Hi,
You need Bluez for this to work and as far as I know Bluez is for Linux only. If you want to develop your own app, you’ll have to learn how to develop Android or iOS apps and use the information on this blog.
You can use pretty much any BLE device (phone, pc, mac etc.) to control these bulbs. Here’s a nice tutorial on how you can control them with a Puck.js (http://www.puck-js.com/) : https://www.espruino.com/Puck.js+and+Bluetooth+Lightbulbs
Cheers,
Pierre
LikeLike
Thanks for this article, really cool! However, I have the Playbulb Sphere and these commands wouldn’t work…did a little digging around and you need to change the handle to 0x001b to adjust colours on this particular model – then just use the hex colours as described in the article.
More info here:
https://github.com/Phhere/Playbulb/issues/1
LikeLike
I don’t have a Sphere but thanks for sharing this.
LikeLike
Mipow Playbulb BTL201
After several days of debugging and playing around with gatttool I have almost find out the meaning and functionality of handles of the MIPOW Playbulb BTL201 (Version 2 BTL201_v2).
I have written an expect-scripts that gives me more features, e.g. smooth wake-program with blue colors or doze-programm with red colors or dia-effects (little pause between switching colors). These things are of course not build in the playbulb. They are controlled by an INTEL NUC or Raspberry pi.
I want to share my results. Find here everything that I have found out about the Playbulb by MIPOW.
Device Information
Handle 0x28 – The product id of the bulb
Encoded in ASCII, you must transform hex to ascii
Default value: „BTL201“
Get: char-read-hnd 28
Characteristic value/descriptor: 42 54 4c 32 30 31
Set: n/a
Handle 0x2C – The product id of the bulb incl. Version
Encoded in ASCII, you must transform hex to ascii
Default value: „BTL201_v2“
Get: char-read-hnd 2c
Characteristic value/descriptor: 42 54 4c 32 30 31 5f 76 32
Set: n/a
Handle 0x30 – The vendor of the bulb
Encoded in ASCII, you must transform hex to ascii
Default value: „Mipow Limited“
Get: char-read-hnd 2e
Characteristic value/descriptor: 4d 69 70 6f 77 20 4c 69 6d 69 74 65 64
Set: n/a
Handle 0x2E – The software version of the bulb
Encoded in ASCII, you must transform hex to ascii
Default value: „Application version 2.4.3.26“
Get: char-read-hnd 2e
Characteristic value/descriptor: 41 70 70 6c 69 63 61 74 69 6f 6e 20 76 65 72 73 69 6f 6e 20 32 2e 34 2e 33 2e 32 36
Set: n/a
Handle 0x2A – Microprocessor of bulb
Encoded in ASCII, you must transform hex to ascii
Default value: „CSR101x A05“
Get: char-read-hnd 2a
Characteristic value/descriptor: 43 53 52 31 30 31 78 20 41 30 35
Set: n/a
Handle 0x03 / 0x21 – The given name of the bulb
Default value: “MIPOW SMART BULB”
Get: char-read-hnd 3
Characteristic value/descriptor: 4d 49 50 4f 57 20 53 4d 41 52 54 20 42 55 4c 42
Set: char-write-req 3 4142434445464748494a4b4c4d4e4f
Set: char-write-req 12 4142434445464748494a4b4c4d4e4f
Note: This seems to be the only value that will be kept after you have disconnected the bulb from power.
Color
Handle 0x1B – Color of bulb
The color of the bulb. Can also be used in order to read current color, in case that effect or runs or timer is on.
Get: char-read-hnd 1b
Characteristic value/descriptor: ff 00 00 00
Set: char-write-cmd 1b ff000000
Setting the color deactivates a running effect. Set all colors to zero in order to turn bulb off.
Byte 1: White in hex (0 – ff)
Byte 2: Red in hex (0 – ff)
Byte 3: Green in hex (0 – ff)
Byte 4: Blue in hex (0 – ff)
Effects
The bulb has four effects, i.e. blink, pulse, smooth rainbow, hard rainbow.
Note: Although according the app there is an additional effect called „candle“ It does not work with my bulb.
Handle 0x19 – effect of bulb
The effect of the bulb.
Get: char-read-hnd 19
Characteristic value/descriptor: 00 00 00 00 ff 00 00 00
Set: char-write-cmd 19 00000000ff00ff00
Byte: 1 to 4: Color of effect, current color, values are persisted even if effect stops (can be written in order to remember previous color after bulb has been soft-turned off in order to be able to toggle to colors before – must be programmed by yourself of course)
Byte 5: Effect (blink=00, pulse=01, hard rainbow=02, smooth rainbow=03, halt=ff)
Byte 6: no special meaning, always „ff“, use „00“ if you set handle
Byte 7: Delay of the effect
Byte 8: no special meaning, always „ff“, use „00“ if you set handle
More about delay of effect
1. Delay for smooth rainbow effect
The value is the delay in ms for every single step.
Example: Delay is 255 (ff)
– It takes exactly 6:30 min (390 sec.) for one sequence with fading and changing all 6 colors (red → yellow → green → magenta → blue → cyan)
– The fading from 0 to 255 takes 65 seconds
– It takes 0,255 secs for one step with delay of 255
2. Delay for hard rainbow effect
The value is the hold value in seconds for each color (red → yellow → green → magenta → blue → cyan)
Example: Delay is 255 (ff)
– It takes exactly 15,3 sec. for one sequence and all 6 colors (red → yellow → green → magenta → blue → cyan)
– one color will be displayed for 2,55 secs with hold of 255
– numeric value for effect is hold in 1/10s
3. Delay for pulse effect
The value is the delay in ms for every single step.
Example: Pulse with hold 255 (ff)
– The fading from 0 to 255 takes 65 seconds
– Therefore the fading from 0 to 255 and back takes 130secs.
– It takes 0,255 secs for one step with hold of 255
4. Delay for blink effect
The value is the period in seconds for each state (on, off).
Example: Blink with hold 255
– 10 on/off-turns take 51 seconds
– 1 turn takes 5,1 seconds
– Hold of 255 means 2,55 seconds on and another 2,55 seconds off
Read current timers
The MIPOW Playbulb has 4 timers and an internal clock (maybe a good chance to feed a Raspberry Pi since it does not have its own realtime clock).
Note that information about timers are read from 2 different handles.
Handle 0x1f – Status and starting times of timers
Get: char-write-req 1f
Characteristic value/descriptor: 04 ff ff 04 ff ff 04 ff ff 04 ff ff 00 00
Set: (see chapter „write new timer)
Timer 1:
Byte 1: Timer type (00 – wake-up timer, 02 – doze timer, 04 – deactivated timer)
Byte 2 and 3: Time of the timer in hex (hh mm), „ff“ if timer is deactivated
Timer 2:
ident. timer 1 but in bytes 4 to 6
Timer 3:
ident. timer 1 but in bytes 7 to 9
Timer 3:
ident. timer 1 but in bytes 10 to 12
Clock:
Byte 13 and 14: Current time (hh mm) in hex, does not run if neither random mode nor at least one timer is active!
Handle 0x13 – Color and running time of timers
Get: char-write-req 13
Characteristic value/descriptor: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Set: (see chapter „write new timer)
Timer 1:
Byte 1 to 4: Color of this timer (values for white, red, green blue)
Byte 5: Delay of timer effect (in app called „minutes“ but this seems to be wrong)
Timer 2:
ident. timer 1 but in bytes 6 to 10
Timer 3:
ident. timer 1 but in bytes 11 to 15
Timer 4:
ident. timer 1 but in bytes 16 to 20
Write new timer
The MIPOW Playbulb has 4 timers and an internal clock. In order to set a new timer only one handle must be written in request-mode (instead of command mode)
Write to Handle 0x1f
Set: char-write-req 1f 00010013120002030000000000
Byte 1: Number of timer that you want to set (value 01 to 04) – stored in handle 0x1f
Byte 2: Timer type (00 – wake-up timer, 02 – doze timer, 04 – deactivated timer) – stored in handle 0x1f
Byte 3: (meaning is unclear, value will be written to handle 0x15 byte 1), use prob. random values, e.g. „1b“, „31“
Byte 4: set current time minutes of internal clock in hex – afterwards available in handle 0x1f byte 14 and handle 0x15 byte 2, clock runs automatically
Byte 5: set current time hours of internal clock in hex – afterwards available in handle 0x1f byte 13 and handle 0x15 byte 3, clock runs automatically
Byte 6: Minutes of starting time in hex – stored in handle 0x1f
Byte 7: Hours of starting time in hex – stored in handle 0x1f
Bytes 8 – 11: Color of this timer (values for white, red, green blue) – stored in handle 0x13
Byte 12: Delay of timer effect (in app called „minutes“ but this seems to be wrong) – stored in handle 13
Random mode (called „security“ in app)
The bulb has a build-in functionality to turn on and off in a certain period. It is called „Security“ in app.
Note that handle must be written in request-mode (instead of command mode)
Get: char-read-hnd 15
Characteristic value/descriptor: 17 12 12 01 02 03 04 05 06 ff 00 00 00
Set: char-write-req 15 000312ffffffffffff00000000
Byte 1: Meaning is unclear, if random mode or timer is active value is different from „00“
Bytes 2 – 3: Current time in hex (mm hh)
Bytes 4 – 5: Starting time of random mode (hh mm) in hex
Bytes 6 to 7: Ending time of random mode (hh mm) in hex
Byte 8: Min. interval (in minutes) in hex
Byte 9: Max. interval (in minutes) in hex
Byte 10 – 13: Color security mode (white red green blue)
Example:
char-write-req 15 000312ffffffffffff00000000
sets time to 18:48 and turns security function off
Internal clock
The MIPOW Playbulb has an internal clock. This is probably a good chance to feed a Raspberry Pi since it does not have its own realtime clock.
However, in order to
Password (n/a)
Although according the app it should be possible to set a password for the bulb it does not work with my bulb.
Factory Reset
The official app has a button for factory reset. I am not sure if the apps sets all values manually or calls something of the bulb.
BTW: The bulb forgets everything after you have disconnected it from power. Therefore this is simular to a factory reset. It seems that the „given name“ of the bulb is the only thing that is still available after loss of power.
—-
Best regards,
Heckie
PS: Maybe I will also post my expect script in future. But I haven’t finally programmed timers and security functionally yet.
LikeLike
Thanks for sharing this!
LikeLike
Actually I found some mistakes. Please correct them or simply refer to the correct version that I have shared in github: https://github.com/Heckie75/Mipow-Playbulb-BTL201/blob/master/mipow-playbulb-btl201-bt-api.md
There you can also find the “full-featured” shell script (also still under development) in order to control the bulb: https://github.com/Heckie75/Mipow-Playbulb-BTL201
LikeLike
Hi, for Mac what did you mean by ~”should also work on a Mac”? Macs don’t have hcitool or gatttool.
LikeLike
Yeah I didn’t know back then that Bluez was only for Linux.
LikeLike
Hello,
none of the `char-write-cmd`s are working for me. The PLAYBULB CANDLE doesn’t react to them. Please advise.
LikeLike
You could try to control the candle with one of the nRF apps (nRF Connect or Toolbox for Android and iOS). Maybe you have a new revision of the candle with a different configuration. Please read this if you don’t know how to use these apps: https://www.espruino.com/Puck.js+and+Bluetooth+Lightbulbs
LikeLike