Skip to content

wKoja/thrustmaster-led-linux

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

thrustmaster-led-linux

Native Linux daemon that drives the RPM LEDs on Thrustmaster racing wheel rims using live telemetry from racing sims running under Wine/Proton. No SimHub, no Windows tools — just a Python daemon talking HID to the wheel.

Tested on the Thrustmaster TS-PC Racer with the Ferrari 488 Challenge Edition wheel rim (15 RPM LEDs). Should work with any Thrustmaster base supported by hid-tmff2 — the LED protocol is a property of the rim, not the base.

Supported wheel bases

PID Base
B66E T300RS (PS3 normal)
B66F T300RS (PS3 advanced)
B66D T300RS (PS4)
B669 TX
B689 TS-PC Racer
B692 TS-XW
B696 T248
B6FF T818

The daemon auto-detects any of these by scanning /sys/class/hidraw/ for VID 044F and a known PID.

How it works

Racing Sim (Wine/Proton)          e.g. AC, AMS2, ACC, ...
  |  Windows shared memory        game-specific format
  v
simshmbridge (*bridge.exe)        runs in Wine, maps Win SHM -> /dev/shm/
  |
simd (systemd user service)       auto-detects game, maps to common format
  |  writes /dev/shm/SIMAPI.DAT
  v
tm-led-daemon (Python 3.11+)      reads SimData from SIMAPI.DAT
  |  Maps RPM % -> LED count (0-15)
  |  Blinks all LEDs at redline
  v
Thrustmaster wheel -> RPM LEDs    64-byte HID packets to /dev/hidrawN

Any game that simd supports works automatically — no per-game code in the daemon.

Supported games

Any game with a simshmbridge bridge works. Currently tested:

  • Assetto Corsa
  • Automobilista 2

Other games with simshmbridge support (rFactor 2, Le Mans Ultimate, RaceRoom) should work but are untested.

Dependencies

  • Python 3.11+
  • Thrustmaster wheel base with a rim that has RPM LEDs (see supported bases above)
  • hid-tmff2 — kernel driver (DKMS, handles FFB and mode switch)
  • simd — cross-sim telemetry mapping daemon
  • simapi — shared library used by simd
  • simshmbridge — bridge executables for each game (included as submodule)
  • x86_64-w64-mingw32-gcc — mingw-w64 cross compiler (to build bridge .exe files)

Quick start

git clone --recursive https://github.com/<user>/thrustmaster-led-linux.git
cd thrustmaster-led-linux/tm-led-daemon
./setup.sh

The setup script builds the simshmbridge bridges, generates a simd config, installs the udev rule and systemd service. You still need to:

  1. Install simd and simapi (Arch AUR: yay -S simapi-git simd-git)
  2. Set Steam launch options for each game (the script prints the exact commands)
  3. Configure in-game settings if needed (e.g. AMS2 shared memory settings)

See tm-led-daemon/README.md for detailed setup instructions.

Configuration

Edit tm-led-daemon/config.toml:

[device]
game = "simapi"             # "simapi" (recommended) or "ac"

[led]
brightness = 20             # 0-100
shift_begin = 0.70          # RPM % where LEDs start lighting
shift_point = 0.95          # RPM % where LEDs start blinking
blink_rate_hz = 8           # blink speed at redline
poll_rate_hz = 60           # LED update rate

Auto-start lifecycle

The daemon starts and stops automatically with the wheel:

  • Plug/attach: udev detects VID 044F with a known PID, starts tm-led-daemon.service (systemd user unit)
  • Unplug/detach: daemon detects /dev/hidrawN disappeared, exits cleanly
  • No restart loop: service has Restart=no — udev starts it fresh on next plug

The correct hidraw device is auto-detected by scanning /sys/class/hidraw/ for the matching VID:PID.

Usage

To run manually:

python3 tm-led-daemon/daemon.py          # normal operation
python3 tm-led-daemon/daemon.py --test   # test LEDs (no game needed)
python3 tm-led-daemon/daemon.py --demo   # simulate RPM sweep (no game needed)

Project structure

thrustmaster-led-linux/
├── tm-led-daemon/              # Python daemon — drives wheel LEDs from telemetry
│   ├── daemon.py               # main entry point
│   ├── led.py                  # hidraw LED control, auto-detect by VID:PID
│   ├── telemetry.py            # telemetry readers (SimAPI, HTTP relay)
│   └── config.toml             # runtime configuration
├── TMLedRelay/                 # CSP Lua app — AC-only alternative telemetry source
│   └── TMLedRelay.lua          # reads telemetry in-game, POSTs to daemon
├── documentation/
│   ├── REPORT.md               # FFB replug bug: root cause and fix
│   └── DRIVER_ANALYSIS.md      # Windows driver reverse-engineering (Ghidra)
└── simshmbridge/               # git submodule: bridges game shared memory to /dev/shm/

LED protocol

The wheel rim LEDs are controlled via 64-byte HID output reports to /dev/hidrawN:

Command Byte 3 Data Description
LED update 0x02 2 bytes (LE bitmask) Each bit = one LED, 15 total
Brightness 0x10 1 byte (0-100) LED brightness level

Full packet: {0x60, 0x00, 0x41, command, data..., 0x00...} (64 bytes)

Protocol source: Prodigal.Knight's SimHub plugin

You may also find useful

  • FFB replug bug report — root cause analysis of the open_mode=0 fix for FFB breaking after replug/usbip
  • Windows driver analysis — Ghidra reverse-engineering of the full Thrustmaster Windows driver stack (FFB, LEDs, display, motor tuning, firmware update)

License

GPLv3 — see LICENSE.

About

Daemon for handling LED lights in Thrustmaster racing wheels

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors