110 lines
4.9 KiB
Markdown
110 lines
4.9 KiB
Markdown
# 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
|
||
```
|