Cloud LED (or any WS2812B LED Strip) Websocket Controller
Raspberry Pi Websocket controller for WS2812b LED strip. Used for a light up cloud build, hence the name, but will work anything using that LED strip
- cloud-leds - for solid color and off modes
- audio-reactive-led-strip - for sound mode
Been tested on Model B+ and 4B, but has targets for all and should work on any.
Hardware
Parts
- Raspberry Pi
- WS2812B LED Strip
- Level Shifter
- Additional 5V Power Supply (if needed)
Build
Follow the Adafruit guide on wiring NeoPixels. I used a level shifting chip with no issues. For my 250 LED setup, I have decently large 5V power supply in addition to the RPi 4 supply, and it has trouble powering all LEDs at higher brightness. This is why the default max brightness of the solid color mode is 25%.
Installation
Docker
On a Raspberry Pi with docker and docker-compose installed.
git clone https://github.com/drakeapps/cloud-led-controller
cd cloud-led-controller
cp .env-sample .env ;# edit as needed
make rpi ;# change based on your version: rpi|rpi2|rpi3|rpi4|rpi4-64
docker-compose up -d server
If you're wanting to be able to still play sound from the pi, the docker version will not work. It will take over control of /dev/snd
Not Docker
From a clean Rasberry Pi OS install
sudo apt-get update && apt-get install -y \
python3 python3-pip python3-dev python3-setuptools build-essential git python3-pyaudio python3-numpy python3-scipy python3-venv
sudo cp build/asound.conf /etc/asound.conf
sudo sed -i "s|defaults.ctl.card 0|defaults.ctl.card 1|g" /usr/share/alsa/alsa.conf
sudo sed -i "s|defaults.pcm.card 0|defaults.pcm.card 1|g" /usr/share/alsa/alsa.conf
# uncomment next two lines if wanting to use venv
# python3 -m venv venv
# source venv/bin/activate
sudo pip3 install -r requirements.txt
sudo python3 server.py ;# plus whatever command line options
Configuration
List of the command line options
The important one is n_pixels
representing the length of LED strip. This needs to be an even number even if you have an odd number of LEDs. Most of these options are passed to the respective audio or solid led classes.
If using docker, edit the .env
file to match these options, but in uppercase as shown in .env-sample
SSL
The Websocket server was not written to support SSL. In order to use SSL, we place an nginx reverse proxy in front of it.
Place your fullchain.pem
and privkey.pem
in /var/opt/ssl
or whatever mount point you put in docker-compose.yml
Start the docker container:
docker-compose up -d ssl
Browsers and SSL websockets are very picky. I highly recommend using a legit SSL cert (like letsencrypt) on a valid domain. I use this gist to get a wildcard cert on my cloudflare managed DNS.
Web UI
Included is a small react web interface. This doesn't need to be run on the same device as the websocket server.
Visit ip-address/config
first to setup the websocket server location, port, and ssl.
Building/Running
Docker
docker-compose up -d webui
Building
cd web-ui
npm i
npm run build
This builds the html and js files. You'll then need to serve them via your preferred web server.
A simple, yet insecure, way to serve the files is with http-server
npx http-server dist --proxy http://localhost:8080\?
Homekit / Homebridge
MQTT
MQTT is well supported in the Homebridge world. Rather than write my own websocket plugin, a Websocket/MQTT wrapper/proxy will accomplish the same thing and need much less support.
This connects to both the websocket server and MQTT broker, reading and sending the relevant messages to each service.
From MQTT:
soundLight/setOn
- true|falsergbLight/setOn
- true|falsergbLight/setRGB
- R,G,B
To MQTT:
soundLight/getOn
- true|falsergbLight/getOn
- true|falsergbLight/getRGB
- R,G,B
You will need an MQTT broker. This can be run on the pi or a separate server. I'm running eclipse-mosquitto on a separate server.
Install/Running
Docker
There are 2 docker-compose targets for both MQTT proxies. They are the same image with different command
parameters. Edit the .env
file to specify your MQTT broker hostname and your WebSocket URL.
docker-compose up -d mqtt-sound
docker-compose up -d mqtt-color
Not Docker
cd mqtt-websocket-proxy
npm i
# for the sound proxy
node sound.js --mqttHost mqtt-broker.local --wsURL wss://cloud-pi.local:443
# for the color proxy
node color.js --mqttHost mqtt-broker.local --wsURL wss://cloud-pi.local:443
Additional command line arguments are available and shown in sound.js and color.js
Homebridge
Install homebridge-mqttthing
Add these accessories in config.json
, editing url
to point to your MQTT broker. Change the names of the light as desired.
{
"accessory": "mqttthing",
"type": "lightbulb",
"name": "SoundCloud",
"url": "mqtt://o.xrho.com",
"topics": {
"getOn": "soundLight/getOn",
"setOn": "soundLight/setOn"
}
},
{
"accessory": "mqttthing",
"type": "lightbulb",
"name": "Cloud",
"url": "mqtt://o.xrho.com",
"topics": {
"getOn": "rgbLight/getOn",
"setOn": "rgbLight/setOn",
"getRGB": "rgbLight/getRGB",
"setRGB": "rgbLight/setRGB"
}
},
This will add two lights, SoundCloud
for the sound reactive mode and Cloud
for standard RGB mode. Like the websocket output, this will turn off on if the other is turned on.