Headless controller for Flydigi cooling pads (BS1 / BS2 / BS2 Pro) over Bluetooth LE. Replaces the official Flydigi Space Station app for two jobs: driving the fan from CPU temperature ("smart mode") and controlling the RGB.
The BLE protocol was reverse-engineered from BLEServiceController.dll. Full
wire-level reference: see PROTOCOL.md.
-
Windows, Python 3.10+
-
pip install -r requirements.txt(bleak, HardwareMonitor) -
CPU temperature is read via LibreHardwareMonitor, which needs the PawnIO kernel driver and administrator privileges:
winget install PawnIO
Without admin/PawnIO the fan falls back to a fixed mid-range RPM.
Run an elevated terminal.
python -m flydigi_cooler # auto-detect, fan follows CPU temp
python -m flydigi_cooler --mode performance --power 9v --interval 2
python -m flydigi_cooler --address E4:66:E5:15:97:0A # device already paired in Windows
python -m flydigi_cooler --off # stop the fan
| Option | Values | Default |
|---|---|---|
--model |
auto, bs1, bs2, bs2pro | auto |
--mode |
silent, performance, custom | performance |
--power |
5v, 9v, 20v | 9v |
--interval |
seconds between RPM pushes | 2 |
--address |
MAC, when scan can't see a connected pad | — |
The device has no temperature sensor; the host must push RPM continuously or the
fan stops. The loop is OpenDevice → StartSmart → every interval: temp → curve → FanSpeedSetting.
python -m flydigi_cooler --rgb on | off
python -m flydigi_cooler --rgb-temp # 4-step temperature color (native)
python -m flydigi_cooler --rgb-smooth # smooth gradient (see note)
python -m flydigi_cooler --rgb-effect solid --rgb-color ff0080
python -m flydigi_cooler --rgb-effect running --rgb-color 00ff00 [--rgb-order 0,1,2,3,4]
python -m flydigi_cooler --rgb-effect leds --rgb-leds ff0000,00ff00,0000ff,ffff00,00ffff
python -m flydigi_cooler --rgb-effect preset --rgb-preset 2
python -m flydigi_cooler --rgb-calibrate # map physical LED order
Notes:
--rgb-tempis the native scheme: one command per change (0x44), no flicker, four colors (green/yellow/orange/red by CPU temp).--rgb-smoothcomputes an arbitrary HSV color from temperature. Arbitrary colors require a full 306-byte buffer upload; the strip blanks briefly during the upload, so frequent color changes flicker. This is a hardware limit, not a bug — use--rgb-tempif flicker matters.- The pad exposes a framebuffer of 10 slots. Physical slot order is firmware
internal: run
--rgb-calibrateonce, note the order, then pass it to--rgb-orderfor a correct running light. --rgb-preset Nreplays the device's own baked effects (extracted from the app).
Task Scheduler: create a task, Run with highest privileges, trigger At log
on, action pythonw.exe <path>\run_hidden.pyw, and clear Start only on AC
power. Defaults (address, mode, power, RGB) are set at the top of run_hidden.pyw.
flydigi_cooler/
protocol.py frame codec, command IDs, response parsers
models.py model registry, RPM ranges, name/MAC matching
curves.py temperature -> RPM curves (from the app config)
temperature.py CPU temperature via LibreHardwareMonitor
rgb.py RGB config/frame builders, presets, effects
controller.py connection, control loop, reconnect
__main__.py CLI
run_hidden.pyw windowless launcher for autostart
PROTOCOL.md protocol reference
no CPU temperature— not elevated, or PawnIO/HardwareMonitor missing.- Frequent
disconnected— the Windows BLE stack drops the link; the controller reconnects automatically. --log-level DEBUGprints every frame and response in hex.