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.1.tar.gz (54.4 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.1-py3-none-any.whl (30.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: truefan-0.9.1.tar.gz
  • Upload date:
  • Size: 54.4 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.1.tar.gz
Algorithm Hash digest
SHA256 9d9e92faf65b686700553fabe2ef189f7c30b7527d2d99dd4f7a861f2fee92bb
MD5 3f911e146956653fa45823ebed8422f0
BLAKE2b-256 933f5155a7937a1bb12b0688f3ac274e2cb7bd9ce757d210d5962888d4161849

See more details on using hashes here.

Provenance

The following attestation bundles were made for truefan-0.9.1.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.1-py3-none-any.whl.

File metadata

  • Download URL: truefan-0.9.1-py3-none-any.whl
  • Upload date:
  • Size: 30.4 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 696507e2b8c2f66d64a5c2715f428d6c7f70da482c839fad595cb47ac4d715e8
MD5 f52dda6215ffbb867ab599adda4a832e
BLAKE2b-256 5fc7f95b836344d2a9ea97ef0459f7db826ba159a886f1944cfe4697fc7bd499

See more details on using hashes here.

Provenance

The following attestation bundles were made for truefan-0.9.1-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