Files
2026-10-26 00:30:59 +01:00

110 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Lian Li wireless fan tools
Proof-of-concept tools for the Lian Li UNI FAN SL-INF Wireless kit (SLV3 TX `0416:8040`, RX `0416:8041`).
Protocol from [sgtaziz/lian-li-linux](https://github.com/sgtaziz/lian-li-linux) (MIT); compression is
[tinyuz](https://github.com/sisong/tinyuz) (MIT).
Only one program can use a dongle at a time: quit SignalRGB (it holds the TX) and L-Connect before
running anything that opens the TX.
| File | What it does |
|---|---|
| `lianli_poc.py` | `scan` / `color RRGGBB` / `demo`. Needs `pip install --user pyusb libusb-package`. |
| `tuzc.exe` | tinyuz compressor used by `lianli_poc.py` (stdin to stdout, round-trip checked). |
| `tuzd.exe` | reference tinyuz decoder, `tuzd <size>`, used by the tests. |
| `tuz.js` | JavaScript tinyuz encoder (same code is inlined in the plugin). |
| `LianLi_Wireless_SLINF_PoC.js` | SignalRGB plugin source. Installed copy: `Documents\WhirlwindFX\Plugins`. |
| `test/tuz_test.js` | `node test/tuz_test.js`: JS encoder vs reference decoder, no hardware. |
| `test/js_tuz_on_fan.py` | sends JS-compressed frames to the fan (needs TX free). |
| `test/watch_rx.py` | `python test/watch_rx.py [seconds]`: watches the fan's effect id via the RX only; works while SignalRGB runs. |
| `build-src/` | sources for `tuzc.exe` / `tuzd.exe`. |
## Using it with SignalRGB
SignalRGB has no support for the wireless Lian Li kits. `LianLi_Wireless_SLINF_PoC.js` is a custom
plugin that drives one SL-INF wireless fan through the TX dongle.
### 1. Pair the fan
The fan must already be bound to your TX dongle. This is done once in L-Connect 3; after that L-Connect
can be uninstalled or must at least stay closed while SignalRGB runs.
### 2. Find your fan's address
Quit SignalRGB first (it holds the TX dongle), then:
```bash
python lianli_poc.py scan
```
```
TX master 16:e5:90:62:32:dc channel 8 firmware 16
RX hears 1 device(s):
device e8:b5:62:62:32:e1 SL-INF Wireless x1
bound to this TX: yes channel 8 rx slot 1
```
Copy the `device` address, the `rx slot` and the fan count (`x1`) into the top of the plugin:
```js
const FAN_MAC = [0xe8, 0xb5, 0x62, 0x62, 0x32, 0xe1];
const FAN_RX_SLOT = 1;
const FAN_COUNT = 1;
```
The values in the repo are for the original fan; a different or re-paired fan needs new values.
### 3. Install the plugin
Copy the plugin into SignalRGB's user plugin folder and restart SignalRGB (it only loads plugins at
startup):
```bash
cp LianLi_Wireless_SLINF_PoC.js "$USERPROFILE/Documents/WhirlwindFX/Plugins/"
```
The fan shows up as **Lian Li SL-INF Wireless (PoC)**. Place and resize it on the Layouts page so it
sits where the fan is in your case.
### 4. Settings
| Setting | Default | What it does |
|---|---|---|
| Lighting Mode | Canvas | `Canvas` follows the active effect, `Forced` shows Forced Color. |
| Forced Color | `#009bde` | Colour used in Forced mode. |
| Shutdown Color | `#8000ff` | Colour the fan keeps after SignalRGB closes or the PC shuts down. |
| Update Interval (ms) | 200 | Minimum time between uploads to the fan (100–2000). |
### Limitations
- Every colour change is a full compressed upload over the 2.4 GHz link, so the fan updates a few
times per second at most. Static colours and slow effects look fine; fast and audio effects step.
- Frames are only sent when the colours actually change.
- The 44 LEDs per fan are mapped as three rings (centre 8, inner 10, outer 8), mirrored on both
sides of the fan.
- One fan group only, at the address set in the plugin. There is no discovery: a SignalRGB plugin can
open only one USB device, and fan discovery needs the RX dongle.
- While SignalRGB runs, `lianli_poc.py` and `test/js_tuz_on_fan.py` can't open the TX dongle.
### Troubleshooting
- **Fan not listed:** check SignalRGB's log in `%LOCALAPPDATA%\WhirlwindFX\SignalRgb\Logs` for
`Custom Plugin File Loaded` and for errors from the `0416:8040` engine thread.
- **Listed but the fan doesn't change:** run `python test/watch_rx.py 10` while SignalRGB runs. A
new effect id appearing every second or so means uploads are reaching the fan. If the id never
changes, the address in the plugin is probably wrong or L-Connect has the dongle.
- **Back to normal:** delete the plugin from `Documents\WhirlwindFX\Plugins` and restart SignalRGB.
The fan keeps the Shutdown Color until something else sets it.
## Rebuilding tuzc.exe / tuzd.exe
Clone `https://github.com/sisong/tinyuz` and `https://github.com/sisong/HDiffPatch` into `build-src/`, then with MinGW g++:
```bash
cd build-src
F="-O2 -DNDEBUG -D_HPATCH_IS_USED_MULTITHREAD=0 -D_IS_USED_MULTITHREAD=0 -IHDiffPatch/libParallel"
gcc $F -c tinyuz/decompress/tuz_dec.c -o tuz_dec.o
g++ $F -static -o ../tuzc.exe tuzc_main.cpp tuz_wrapper.cpp tuz_dec.o tinyuz/compress/tuz_enc.cpp tinyuz/compress/tuz_enc_private/*.cpp HDiffPatch/libHDiffPatch/HDiff/private_diff/libdivsufsort/divsufsort.cpp -x c HDiffPatch/libHDiffPatch/HPatch/patch.c
gcc -O2 -D_IS_RUN_MEM_SAFE_CHECK=1 -o ../tuzd.exe tuzd_main.c tinyuz/decompress/tuz_dec.c
```