Working in Progress
This article is still a work in progress, which means it will be updated in the future. Images may be missing captions or alt-texts. There might also be some language weirdness.
I’ve had a Moonside Lighthouse lying around for some time. It’s a pretty nice-looking light fixture, however, there was no way to integrate it into my Homeassistant setup. I’ve had a shot at reverse engineering it’s communication and here are my results:
Trying the network route
Lighthouse is able to join your WiFi-Network for remote control, because of that I was hoping to find some open network port using Nmap. A quick scan showed nothing, meaning that this way is likely a dead end.
However, this digging surfaced one interesting piece of information about its MAC Address, which belongs to the Espressif MAC range (meaning it’s likely something ESPy).
Internet
There also exists a public API which enables you to control the fixture remotely. I was unable to get it working, also I would like to be able to control my light locally. I have not explored this route further.
Bluethooth
After it became clear that networking is sadly not an option I started looking into Bluethooth. The App uses BLE to talk to the lamp. My first attempt was to use the nRF Connect tool to reads its characteristics.
None of these characteristics were helpful, except one which piqued my interest., “Nordic UART Service”, I’ve never heard of that before, though it seems fairly helpful. Using the nRF toolbox I was able to connect to it via BLE UART. That itself worked fine, however, brute-forcing commands were not useful as there was no response to anything.
Snooping the traffic
The next logical step was to snoop on the traffic between the android app and the hardware counterpart. That proved to be not as easy as it sounds, in the end, I used Wireshark to look at the traffic.
First step was to enable Bluetooth Snooping in the developer settings. Then after some debugging and using this command:
db shell su -c "'nc -s 127.0.0.1 -p 8872 -L system/bin/tail -f -c +0 data/misc/bluetooth/logs/btsnoop_hci.log'"
The interface showed up in Wireshark. Though you need to android dump androiddump module for Wireshark.
Info
It seems like your device needs to be rooted for this to work, I’ve seen contradicting information about that, however.
Finally, I was able to see communication with a device called Espressi_2a:9d:5a, which looks suspiciously like the device in question.
Deconstructing the communication
The became apparent that the app talks in clear text with the light fixture. These commands started showing up:
Command | Description |
---|---|
LEDOFF | Turns the light off |
LEDON | Turns the light on |
BRIGHXXX | Brightness, replace XXX with number (max: 120, min:0) |
COLORRRRGGGBBB XXX | Sets the colour, replace R with red value, G with green value and B with blue value (0-255), optional X brightness argument |
THEME.???????? | Sets a theme |
PIXEL,ID,XXX COLOR? | Set a pixel, where ID is the pixel (0-89), XXX is the brightness and COLOR is the colour in an unknown format |
MODEPIXEL | Applies pixel settings |
Mind you the values of for example the ID range might be different between devices, however I will probably not buy more devices just to prove my theory.
Some things are also just unknown. I do not understand how sound-enabled modes work (yet!). It sends some number string and that’s it. I was also unable to figure out the COLOR format for pixel setting, it is six digits ranging from 0-9.
Themes
Themes are a whole different topic. They are way more configurable than the app gives you options. Here is a list of the themes from the app:
Theme name | Themenick |
---|---|
RAINBOW1.20, | Rainbow One |
FIRE1.20, | Night Fire |
THEME.THEME1.162,255,174,255,85,90, | Blue Raspberry |
THEME.WAVE1.255,0,0,255,0,255, | Pink Ball |
THEME.BEAT1.255,0,0,0,255,0,0,0,255, | Dancing Beat |
THEME.GRADIENT2.0,255,0,20,65,20,200,200,200, | Green Land |
THEME.THEME3.0,0,200,0,100,200,100,0,200,200,0,0,200,06,100,120,200,0, | Candy Mix |
THEME.THEME1.255,0,0,0,0,255, | My Moon |
THEME.BEAT2.255,255,0,0,0,255, | Bouning Stars |
THEME.GRADIENT1.0,255,0,255,0,0, | Christmas Blend |
THEME.RAINBOW3.0, | Blending Rainbow |
THEME.THEME2.138,35,135,242,113,33, | Wire Tap |
THEME.COLORDROP1.10,100,255,200,200,200, | Raining Blue |
THEME.TWINKLE1.255,0,0,0,0,255, | Twinkle Star |
THEME.FIRE2.0,0,0,0,255,0,200,0,0,255,0,0, | Green Fire |
THEME.GRADIENT2.145,3,245,255,25,194,191,176,187, | Purple Cake |
THEME.GRADIENT1.150,0,255,255,214,243, | Purple Dream |
THEME.LAVA1.200,0,0,50,0,0,0,0,255, | Blue Lava |
THEME.LAVA1.20,255,2,255,100,0,255,0,60, | MacMac |
THEME.THEME1.168,255,120,120,255,214, | Summer Glow |
THEME.BEAT2.7,200,249,13,34,135, | Dancing Ocean |
THEME.PALETTE2.0,0,200,0,100,200,100,0,200,200,0,0,2006,0,100,120,200,0, | Colorful Swinging |
THEME.GRADIENT1.255,80,0,0,0,0, | Late OJ |
THEME.BEAT1.255,190,100,255,190,100, | Shining Beat |
THEME.GRADIENT1.255,208,50,100,100,100, | Margo |
THEME.RAINBOW2.20, | Rising Rainbow |
THEME.THEME5.200,20,150,0,60,255, | Vibrant City |
THEME.COLORDROP1.0,255,0,255,8,130, | Rose Drop |
THEME.FIRE2.0,0,0,31,255,110,155,252,212,255,255,255, | Ghost Fire |
THEME.GRADIENT1.255,0,0,200,200,200, | Pink Dawn |
THEME.PULSING1.255,0,20,20,20,255, | Super Pulsing |
THEME.PULSING1.115,255,182,250,255,204, | Super Limeade |
THEME.GRADIENT1.147,71,255,255,102,50, | Galaxy Purple |
THEME.GRADIENT2.255,0,0,50,190,10,0,160,200, | Nemo Green |
THEME.LAVA1.0,183,255,0,0,0,255,255,255, | Cool Sky |
THEME.THEME1.0,0,255,255,0,255, | Distant Night |
THEME.FIRE2.0,0,0,255,0,0,0,255,0,0,0,255, | Rainbow Fire |
THEME.GRADIENT2.255,0,0,80,20,0,200,200,200, | Volcano Ice Cream |
THEME.THEME1.255,0,0,0,255,0, | Wild Watermelon |
THEME.TWINKLE1.255,0,0,0,180,0, | Twinkle Christmas |
THEME.GRADIENT2.255,66,20,255,66,20,8,217,255, | Ali |
THEME.GRADIENT1.198,255,221,247,45,50, | Megatron |
THEME.GRADIENT1.255,0,0,0,50,200, | Blue Raspberry |
THEME.GRADIENT1.0,255,0,200,200,200, Wizard | Vibe Beat |
THEME.THEME4.255,50,0,0,90,220, | Orange Ocean |
THEME.GRADIENT2.0,255,0,255,0,0,100,0,0, | Jingle Bell |
THEME.LAVA1.255,25,0,100,30,0,255,150,0, | Glowing Lava |
THEME.GRADIENT2.59,250,229,255,85,0,255,0,20, | Celebration Candy |
THEME.GRADIENT2.0,0,255,30,102,128,255,255,255, | Ice Mountain |
THEME.GRADIENT1.86,255,119,98,38,210, | Magic Blend |
THEME.GRADIENT1.255,255,30,36,255,65, | Martini |
THEME.PALETTE1.0, | Color Wheel |
THEME.LAVA1.255,0,0,60,60,60,0,255,0, | Christmas Snow |
THEME.GRADIENT1.195,255,210,2,9,19, | Petrol |
THEME.GRADIENT1.0,150,255,200,200,200, | Aqua Wave |
THEME.FIRE2.0,0,0,255,0,0,0,0,255,255,255,255, | Magic Fire |
THEME.GRADIENT2.8,175,212,178,37,247,242,12,188, | WaterShine |
Sound-activated modes seem to be variations of themes. These have yet to be mapped. However, they commonly start with M and another number following that. After that, there are colour arguments again.
Modifiying theme data
There are a few theme “keywords” which can then be mixed with arguments. These are: THEME1, THEME2, THEME3, THEME4, THEME5, WAVE1, BEAT1, BEAT2, BEAT3, GRADIENT1, GRADIENT2, RAINBOW1, RAINBOW2, RAINBOW3, TWINKLE1, FIRE2, COLORDROP1, LAVA1, COLORDROP1, PULSING1
Following these theme keywords are blocks of colour, most in this format: (yes they end in a ,
)
THEME.THEME1.RRR1,GGG1,BBB1,RRR2,GGG2,BBB2,
It seems like every theme’s colour values change different aspects of the effect. (more will be added below over time)
Theme | Description |
---|---|
FIRE2.BBB,BBB,BBB,111,111,111,222,222,222,333,333,333 | B is the “background” or base colour of the effect, you can leave it with 0s, meaning it will stay off. The rest 1-3 are other effect colours. |
Building a smart home interface
I’ve built a basic Sketch which connects to the WiFi network. Have a look below! (I will continue working on this sketch)
(If there is nothing above this text make sure to enable experience cookies!)
Recent Comments