Wled_Fan_Controller/usermods/GPU_Fan_Controller/readme.md
dawie e2d1a8f74f Update readme with visual curve editor documentation
- Added visual curve editor section
- Updated config documentation for flat curve structure
- Added curve editor troubleshooting
- Added mode API endpoint documentation
2026-01-30 18:54:17 +02:00

6.5 KiB

GPU Fan Controller Usermod

This usermod allows WLED to control PWM PC fans based on GPU temperature data received from an external source (typically a Python script running on your PC).

Features

  • Web API Integration: Receives GPU temperature via HTTP API
  • Fixed Speed Mode: Set a constant fan speed (0-100%)
  • Temperature Curve Mode: Automatically adjusts fan speed based on temperature
  • Visual Curve Editor: Interactive web-based graph editor at /gpu-fan.htm
  • Up to 5 Curve Points: Define custom temperature-to-speed mappings
  • Safety Fallback: Automatically runs at 100% if temperature data is lost
  • WLED UI Integration: Control and monitor from the WLED web interface
  • Live Temperature Display: See current GPU temp and fan speed in real-time

Hardware Requirements

  • ESP32 development board (ESP32 Dev Module recommended)
  • 4-pin PWM PC fan (12V)
  • 12V power supply for the fan
  • Common ground connection between ESP32 and power supply

Wiring

Fan Pin Connection
GND (Black) ESP32 GND + 12V PSU GND
+12V (Yellow) 12V Power Supply +
PWM (Blue) ESP32 GPIO 13 (configurable)
TACH (Green) Not used

Important:

  • Connect 12V power supply GND to ESP32 GND (common ground)
  • DO NOT connect +12V to any ESP32 pins

Installation

  1. Copy the GPU_Fan_Controller folder to wled00/usermods/

  2. Create or edit platformio_override.ini in the WLED root directory:

[env:esp32dev_gpu_fan]
extends = env:esp32dev
build_flags = ${env:esp32dev.build_flags}
  -D USERMOD_GPU_FAN_CONTROLLER
  -D PWM_FAN_PIN=13
custom_usermods = GPU_Fan_Controller
  1. Build and upload:
pio run -e esp32dev_gpu_fan -t upload
  1. Upload the custom page (optional but recommended):
pio run -e esp32dev_gpu_fan -t uploadfs

Option 2: Manual Integration

  1. Copy GPU_Fan_Controller.cpp to wled00/usermods/GPU_Fan_Controller/

  2. Add to your build flags:

-D USERMOD_GPU_FAN_CONTROLLER

Visual Curve Editor

Access the visual curve editor at: http://YOUR_WLED_IP/gpu-fan.htm

Curve Editor Screenshot

Features:

  • Drag points on the graph to adjust temperature/speed mappings
  • Live temperature indicator shows current GPU temp on the graph
  • Real-time updates - see fan speed change as you adjust
  • Table view for precise value entry
  • Add/remove points - use 2-5 curve points
  • Mode toggle - switch between Fixed and Curve modes

Configuration

Via WLED Web Interface

Navigate to Config → Usermods to configure:

  • enabled: Enable/disable the fan controller
  • pwm-pin: GPIO pin for PWM output (default: 13)
  • mode: 0 = Fixed, 1 = Curve
  • fixed-speed: Speed percentage when in fixed mode
  • timeout-ms: Temperature timeout in milliseconds (default: 10000)
  • curve-t1 to curve-t5: Temperature points (°C)
  • curve-s1 to curve-s5: Speed points (%)
  • curve-points: Number of curve points to use (2-5)

Via JSON API

{
  "GPU-Fan": {
    "enabled": true,
    "mode": 1,
    "fixed-speed": 50,
    "curve-points": 4,
    "curve-t1": 30, "curve-s1": 30,
    "curve-t2": 50, "curve-s2": 50,
    "curve-t3": 70, "curve-s3": 75,
    "curve-t4": 85, "curve-s4": 100
  }
}

API Endpoints

Update Temperature

Send GPU temperature to the controller:

POST /json/state
Content-Type: application/json

{
  "GPU-Fan": {
    "temperature": 65.5
  }
}

Set Manual Speed

POST /json/state
Content-Type: application/json

{
  "GPU-Fan": {
    "speed": 75
  }
}

Set Mode

POST /json/state
Content-Type: application/json

{
  "GPU-Fan": {
    "mode": 1
  }
}

Where mode: 0 = Fixed, 1 = Curve

Get Status

GET /json/info

Response includes GPU temperature, fan speed, and mode in the "u" (user) object.

Python GPU Monitor Script

Use the included gpu_temp_monitor.py script to send GPU temperatures to the ESP32:

Installation

pip install requests nvidia-ml-py
# OR for multi-vendor support:
pip install requests gpustat

Usage

# Basic usage
python gpu_temp_monitor.py --wled-ip 192.168.1.100

# Specify GPU type
python gpu_temp_monitor.py --wled-ip 192.168.1.100 --gpu-type nvidia

# Custom update interval
python gpu_temp_monitor.py --wled-ip 192.168.1.100 --interval 3

Running as a Service

Windows (Task Scheduler)

Create a batch file and add to startup:

@echo off
python C:\path\to\gpu_temp_monitor.py --wled-ip 192.168.1.100

Linux (systemd)

Create /etc/systemd/system/gpu-fan-monitor.service:

[Unit]
Description=GPU Fan Controller Monitor
After=network.target

[Service]
Type=simple
User=yourusername
ExecStart=/usr/bin/python3 /path/to/gpu_temp_monitor.py --wled-ip 192.168.1.100
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable gpu-fan-monitor
sudo systemctl start gpu-fan-monitor

Temperature Curve

The default curve provides quiet operation at low temperatures and aggressive cooling at high temperatures:

Temperature Fan Speed
≤30°C 30%
50°C 50%
70°C 75%
≥85°C 100%

Speeds between points are linearly interpolated.

Troubleshooting

Fan not spinning

  1. Check wiring connections
  2. Verify the fan is PWM-compatible (4-pin)
  3. Check that 12V power supply is adequate
  4. Try a different GPIO pin

Temperature not updating

  1. Check the Python script is running
  2. Verify ESP32 IP address is correct
  3. Check firewall settings
  4. Test with: curl -X POST http://ESP32_IP/json/state -H "Content-Type: application/json" -d '{"GPU-Fan":{"temperature":50}}'

Curve not saving

  1. Make sure to click "Save" in the curve editor
  2. Check the browser console for errors
  3. Try refreshing the page and re-saving

WLED doesn't show the usermod

  1. Ensure the build flag -D USERMOD_GPU_FAN_CONTROLLER is set
  2. Rebuild and re-upload the firmware
  3. Check serial output for initialization messages

Technical Details

  • PWM Frequency: 25kHz (Intel 4-pin fan specification)
  • PWM Resolution: 8-bit (0-255)
  • Default GPIO: 13 (configurable)
  • Update Interval: 2 seconds
  • Safety Timeout: 10 seconds (runs at 100% if no temperature data)
  • Max Curve Points: 5

License

This usermod is released under the same license as WLED (MIT).

Credits