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.

A screenshot made in the nRF connect app showing three services. The first being a "Generic Attribute" with UUID: 0x1801.
The next one being a "Generic Access" with the UUID 0x1800.
The last one is "Nordic UART Service" with UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
A screenshot from the nRF connect app where the first service ("Generic Access") was expanded. It's shows three attributes, "Device Name", "Apperance" and "Central Address Resolution". The device name is "MOONSIDE-T1", apperance is "[0] Unknown", address resoultion is not supported.

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:

CommandDescription
LEDOFFTurns the light off
LEDONTurns the light on
BRIGHXXXBrightness, replace XXX with number (max: 120, min:0)
COLORRRRGGGBBB XXXSets 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
MODEPIXELApplies 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 nameThemenick
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, WizardVibe 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
All themes

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)

ThemeDescription
FIRE2.BBB,BBB,BBB,111,111,111,222,222,222,333,333,333B 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!)