Skip to main content

Fan control daemon for TrueNAS

Project description

truefan

Fan control daemon for TrueNAS SCALE systems on Supermicro X11 boards. Reads temperatures from IPMI, SMART, NVMe, and lm-sensors, then adjusts fan duty cycles via IPMI raw commands to keep things cool with minimal noise.

Features

  • Auto-detection of sensors and fans — classifies by type (cpu, drive, nvme, ambient, other) and applies per-class interpolation curves.
  • Self-calibrating — learns each fan's setpoint table by ramping duty down and recording RPMs. Can be recalibrated as fans age or collect dust.
  • Failsafe — fans go to 100% on crash, total sensor class failure, or stalled fan. The watchdog parent restarts the daemon automatically.
  • Netdata metrics — per-sensor thermal load, per-zone duty, per-fan target RPM, and daemon restart count via statsd.

Requirements

  • Python 3.11+
  • ipmitool
  • smartctl (smartmontools) — for SATA/SAS drive temps
  • nvme-cli — for NVMe temps
  • lm-sensors — for kernel-exposed sensors
  • Supermicro X11 motherboard with IPMI

Install

TrueNAS SCALE doesn't ship ensurepip, so create the venv without it and bootstrap pip manually:

python3 -m venv --without-pip /mnt/pool1/venvs/truefan
source /mnt/pool1/venvs/truefan/bin/activate
curl -sS https://bootstrap.pypa.io/get-pip.py | python3
pip install truefan

Put the venv on a pool — the boot drive is wiped on OS updates.

Quick start

# Detect sensors, calibrate fans, write config
sudo truefan init

# Start the daemon
sudo truefan run

# Show detected sensors and current readings
truefan sensors

# Re-calibrate after cleaning or replacing fans
sudo truefan recalibrate

# Reload config without restarting
sudo truefan reload

Configuration

truefan init generates a truefan.toml with sensible defaults. Example:

poll_interval_seconds = 15
spindown_window_seconds = 180

[curves.drive]
temp_low = 30
temp_high = 45
duty_low = 25
duty_high = 100
fan_zones = ["peripheral"]

# Per-sensor overrides for components that run hotter than their class
[curves.sensor.lmsensors-mlx5-pci-0200-sensor0]
temp_low = 60
temp_high = 95

# Learned via calibration — duty % = expected RPM
[fans.FAN1]
zone = "cpu"

[fans.FAN1.setpoints]
25 = 320
30 = 450
40 = 620
50 = 780
100 = 1500

Use --config PATH with any command to specify an alternate config location.

Running on boot

TrueNAS SCALE's Init/Shutdown Scripts (under System > Advanced) run commands at boot and shutdown. Use tmux to run the daemon in a detachable session you can attach to later for debugging.

Add a script (Type: Command, When: Post Init):

tmux new-session -d -s truefan '/mnt/pool1/venvs/truefan/bin/truefan run 2>&1 | tee /var/log/truefan.log'

To check on the daemon: tmux attach -t truefan. Detach with Ctrl-b d.

How it works

Each sensor class has a temperature-to-duty curve. Between temp_low and temp_high, duty is linearly interpolated; hardware-reported thermal limits override temp_high when available. The hottest sensor in each fan zone sets the duty. A spindown window prevents rapid cycling.

If a fan stalls, the zone goes to 100% and the lowest setpoint is removed so the minimum duty rises going forward.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

truefan-0.9.0.tar.gz (52.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

truefan-0.9.0-py3-none-any.whl (30.0 kB view details)

Uploaded Python 3

File details

Details for the file truefan-0.9.0.tar.gz.

File metadata

  • Download URL: truefan-0.9.0.tar.gz
  • Upload date:
  • Size: 52.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for truefan-0.9.0.tar.gz
Algorithm Hash digest
SHA256 7a2c271a4439b2edfb23fc8b072e0477b35d3a80f98a72b66fb9b46f56911e93
MD5 e1ca74cdc13e8f3f8d65a6d708e53bc8
BLAKE2b-256 e8c9a63f72d2536f54c3844c6eb6fd38402817a10640d763dfa8b33180f25744

See more details on using hashes here.

Provenance

The following attestation bundles were made for truefan-0.9.0.tar.gz:

Publisher: ci.yml on zvea/truefan

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file truefan-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: truefan-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 30.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for truefan-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8d6a684f7e9b0c5b0464ba8977080abb9044c9897dcf43e00ae938fa0d833c7e
MD5 c269a10f4c9e74b9146dea6b7f692eb7
BLAKE2b-256 1a0a93a972c551ec519b4e2b9e5183f0bfb3692b58daec9335bd5efd7317f0ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for truefan-0.9.0-py3-none-any.whl:

Publisher: ci.yml on zvea/truefan

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page