Daemon that reads CPU temperature and toggles a fan on GPIO pin 17. Uses hysteresis to avoid rapid on/off cycling.
Polls /sys/class/thermal/thermal_zone0/temp every 1.5 seconds. Fan turns on when temperature crosses threshold + variance, turns off when it drops below threshold - variance. With defaults (55°C threshold, 5°C variance), that means on at 60°C, off at 50°C.
GPIO pin 17 → relay or MOSFET → fan. Nothing else special.
Requires libgpiod. Build with cargo:
cargo build --releaseFor NixOS there's a service.nix that wires everything up. Drop it into your configuration and enable the rpi-fan-control systemd service.
Copy example_configuration.toml to /var/fan_control/config.toml and adjust:
threshold = 55.0 # °C
variance = 5.0 # fan on at threshold+variance, off at threshold-variance
interval_ms = 1500
gpio_line = 17
gpio_chip = "/dev/gpiochip0"
log_path = "/var/log/fan_control.log"All fields are optional, the defaults worked fine for me.
There's an archived-c branch with the original implementation. It's a single C file that runs as a one-shot binary via systemd timer (fires every minute), persisting fan state to /var/log/fanstatus between invocations. It uses pigpio instead of libgpiod. Same hysteresis logic, same defaults. It works, but I decided to rewrite it in Rust because it's blazingly faster. /s