This is a Python library and CLI to control BLE LED curtains.
You can also control the curtains from your browser using a single page app.
The browser app is a standalone single page application that works entirely in the browser using the Web Bluetooth API. No server required!
The app is automatically deployed to GitHub Pages: Open Curtain Control App
Simply open the link in a supported browser (Chrome, Edge, or Opera) and start controlling your curtains!
- Build the browser app:
npm install
npm run build- Open the app locally:
python3 -m http.server 8080 --directory distThen open http://localhost:8080 in your browser.
-
Characteristic UUID: The UUID field is prepopulated with the common UUID
49535343-8841-43f4-a8d4-ecbe34729bb3. You can change it if your device uses a different UUID. -
Device Name Prefix (Optional): Leave empty to see all BLE devices, or enter a name prefix (e.g., "Hello Fairy") to filter devices. This will match any device whose name starts with the specified text, so "Hello Fairy" will match "Hello Fairy-7df1", "Hello Fairy-a2b3", etc.
-
Connect: Click "Connect" to open the browser's device picker showing all available BLE devices (or filtered by name prefix if specified).
-
Power Control: Use the On/Off buttons to turn the curtain lights on or off.
-
Animated Presets: Select a preset number (1-109) and adjust the brightness slider (0-255). Click "Apply Preset" or simply change the sliders to apply immediately when connected.
-
Pause Animation: Click "Pause Animation" to pause the current effect.
Note: The Web Bluetooth API is supported in Chrome, Edge, and Opera browsers. It requires a secure context (HTTPS or localhost).
The app is automatically built and deployed to GitHub Pages when changes are pushed to the main branch. The workflow:
- Installs dependencies with
npm install - Builds the app with
npm run build - Deploys the
dist/folder to GitHub Pages
No server-side code is needed - everything runs entirely in your browser!
You can turn on debugging messages by setting the environment variable LOG_LEVEL to DEBUG.
LOG_LEVEL=DEBUG uv run curtains FF:44:10:22:75:68 --char-uuid 49535343-8841-43f4-a8d4-ecbe34729bb3 write 030701000003E803E8uv syncuv run curtains scanGet the device address of the ones called Hello Fairy.
Mine is FF:44:10:22:75:68.
This lists UUIDs, Characteristics and Properties of a specific device.
uv run curtains FF:44:10:22:75:68 connectOn:
uv run curtains FF:44:10:22:75:68 onOff:
uv run curtains FF:44:10:22:75:68 offUse the write command to send raw payloads. Device address goes first; --char-uuid may be omitted (defaults to the common control UUID).
Red:
uv run curtains FF:44:10:22:75:68 write 030701000003E803E8White:
uv run curtains FF:44:10:22:75:68 write 0307010000000003E8uv run curtains FF:44:10:22:75:68 preset 2 --brightness 255 --speed 10Where 2 is the preset animation type from 1 to 109. --brightness is brightness level from 0 (low brightness, but not off) to 255 (high brightness). The optional --speed parameter controls animation speed from 0 (slow) to 10 (fast), with a default of 10.
Use the pixel command with subcommands: single, clear, fill, draw.
Set single LED at coordinates (x,y) to a named color:
uv run curtains FF:44:10:22:75:68 pixel single 10 10 redClear LEDs (controller-dependent):
uv run curtains FF:44:10:22:75:68 pixel clearFill starting from an offset:
uv run curtains FF:44:10:22:75:68 pixel fill blue --offset 0Enter drawing mode:
uv run curtains FF:44:10:22:75:68 pixel draw