Use Twinkly offline with Home Assistant

Twinkly string lights on a tree

When the annual holiday is coming up, it's not just a good time to bring the year to a close - technical gadgets should not be neglected either. One such gimmick is the programmable RGB fairy lights from Twinkly. These are available in various shapes (stars, hearts, candles, pearls) and lengths (100, 250, 400 or 600 LEDs) and can be controlled via WLAN.

Unfortunately, the manufacturer has only provided for this via its own app. This takes over the initial WLAN configuration and controls the light chain via a HTTP API. Another function is the creation of your own animations. Unfortunately, an account is incomprehensibly required for this.

Fortunately, the products have already been in production for some time, which is why the API has been documented via reverse engineering. In addition to the API, the xled project has also documented further technical details and developed command line applications to enable use without a manufacturer app.

Onboarding

One option is to carry out the initial WLAN configuration via BLE (Bluetooth Low Energy). To do this, the MAC address of the Bluetooth interface must first be read out. This should be found by holding down the button on the controller for 5 seconds:

1# bluetoothctl 
2[bluetooth]# scan on
3[bluetooth]# SetDiscoveryFilter success
4[bluetooth]# hci0 type 7 discovering on
5[bluetooth]# Discovery started
6[bluetooth]# [NEW] Device xx:xx:xx:xx:xx:xx Twinkly_xxxxxD

The xled-shell repository contains an application for configuring the network:

 1$ ./configure-wifi-over-bluetooth-sta xx:xx:xx:xx:xx:xx 'SSID' 'PASSPHRASE'
 2#1 Getting the Wi-Fi list.
 3#2 ?
 4#3 Setting opmode to WiFi
 5#4 Gettting WiFi status
 6#5 ?
 7#6 Sending SSID
 8#7 Sending password
 9#8 Switching to STA mode
10#9 Switching WiFi status
11#10 Disconnecting from BLE GATT link
Notice 💡

SSID and PASSPHRASE still need to be replaced by corresponding values.

This does not work reliably with some devices. In this case, it may help to reset the device to factory settings to activate an integrated Access Point. To do this, the device must be plugged in with the button pressed - the button must be pressed until the LED confirms the process.

A WLAN network Twinkly_xxxx should then appear - the default password is Twinkly2019. After the connection has been established, the MAC address of the WLAN adapter must be read out:

1$ ./get 192.168.4.1 gestalt | jq -r .mac
2xx:xx:xx:xx:xx:xx

The MAC address is now used to encrypt the SSID and the passphrase via an additional script:

1$ ./encrypt.py 'xx:xx:xx:xx:xx:xx' 'SSID' 'PASSPHRASE'
2Encrypted SSID: ...
3Encrypted password: ...

The encrypted information now only needs to be sent to the controller via POST request:

1$ echo '{"mode":1,"station":{"dhcp":1,"encssid":"XXX","encpassword":"XXX"}}' | ./post-json 192.168.4.1 network/status
2POST network/status
3{
4"code": 1000
5}

The device should then appear in the WLAN network.

Home Assistant integration

There is a Twinkly integration for Home Assistant, but it has a rather annoying bug: the device is displayed as offline if no custom animation (movie) has been created.

Faulty Twinkly integration

The workaround is to create an animation. If you don't want to use the app, it helps to install the xled_plus package. This contains some ready-made animations - these are created on the controller by executing them:

1$ pip3 install --user xled_plus
2$ python3 -m xled_plus.samples.day8
3$ python3 -m xled_plus.samples.day12
4$ python3 -m xled_plus.samples.day13
5$ python3 -m xled_plus.samples.day24

Creating your own animations is more difficult without the app - a look at the source code of the examples can serve as a source of inspiration. The colorsphere package also contains a rudimentary editor:

1$ pip3 install --user colorsphere
2$ python3 -m xled_plus.xled_colorcontrol

The controller then appears in Home Assistant and can be controlled from there. In addition to the brightness, individual colours or created animations can be selected:

Functional Twinkly integration

Translations: