# HDD Fan control

[![CI status](https://img.shields.io/github/actions/workflow/status/desbma/hddfancontrol/ci.yml)](https://github.com/desbma/hddfancontrol/actions)
[![crates.io version](https://img.shields.io/crates/v/hddfancontrol)](https://crates.io/crates/hddfancontrol)
[![AUR version](https://img.shields.io/aur/version/hddfancontrol.svg?style=flat)](https://aur.archlinux.org/packages/hddfancontrol/)
[![License](https://img.shields.io/github/license/desbma/hddfancontrol.svg?style=flat)](https://github.com/desbma/hddfancontrol/blob/master/LICENSE)

---

Since version 2.0, this tool has been rewritten in Rust. The previous Python version can be found in the [v1 branch](https://github.com/desbma/hddfancontrol/tree/v1). See [Migrating from v1.x](#migrating-from-v1x) for migration.

---

HDD Fan control is a command line tool to dynamically control fan speed according to hard drive temperature on Linux.

This has 3 benefits:

- it allows maintaining your hard drives in the ideal temperature range to have maximum longevity and avoid overheating

Because fans will slow down or stop when not needed:

- it minimizes noise generated by the fans
- it minimizes power consumption at the same time

## Table of content

- [When is this useful?](#when-is-this-useful)
- [Features](#features)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
  - [Distribution packages](#distribution-packages)
  - [From source](#from-source)
- [Configuration](#configuration)
  - [A word of caution](#a-word-of-caution)
  - [Fan configuration](#fan-configuration)
- [Changelog](#changelog)
  - [Migrating from v1.x](#migrating-from-v1x)
- [Command line usage](#command-line-usage)
- [systemd service](#systemd-service)
- [License](#license)

## When is this useful?

HDD Fan control is useful when you have one or several hard drives with one or several fans close to them, and do not want to let the motherboard control the fan speed, because it does so either statically, or using a temperature sensor unrelated to the real drive temperature (either on the CPU or on some other place on the motherboard).

The ideal use case is for a NAS with several hard drives, a low power CPU (ie. ARM or Intel Atom) with passive cooling (no fans), and a chassis with fans close to the hard drive. It that case the CPU will generate less heat than the hard drives and it makes sense to control fan speed according to the main heat source.

## Features

- Can control several fans and/or several drives with a single invocation
- Supports 6 different ways of querying temperature:
  - `hddtemp` invocation
  - `hddtemp` daemon query
  - `hdparm` invocation
  - `smartctl` invocation (SCT)
  - `smartctl` invocation (SMART attributes)
  - `drivetemp` native kernel hwmon
- Can adapt to different fan characteristics
- Can be customized to your needs:
  - to stop fans or run them at full speed at customizable temperatures
  - to never set the fans below a certain speed (useful if the fans controlled by HDD Fan control are the only ones available in the chassis)
- Can also optionally monitor CPU temperature, and control fan speed accordingly

### Temperature logging

`hddfancontrol` can log temperature measures to a JSONL file for example to plot temperatures on a graph.
An example of script to plot the temperature data is [available in the repository](./scripts/plot-temps.py).
This feature is controlled by the cargo feature `temp-log`, enabled by default.
If you don't need this feature and want the program to be as light as possible, you can compile with `--no-default-features`.

## Prerequisites

- A Linux distribution
- A least one SATA/SAS\* hard drive, that supports:
  - Temperature querying
  - Power state querying
- A motherboard which:
  - exposes to the OS a PWM to control fan speed
  - exposes to the OS a sensor to query fan speed

Most motherboards and SATA drives fit these requirements.

\* There has been several reports of `hddfancontrol` working well with SAS drives, however this has been less tested than SATA.

## Installation

### Distribution packages

Some Linux distributions have a hddfancontrol package available in their repository:

- Alpine Linux (testing): [hddfancontrol](https://pkgs.alpinelinux.org/package/edge/testing/x86_64/hddfancontrol)
- Arch Linux (AUR): [hddfancontrol](https://aur.archlinux.org/packages/hddfancontrol/)
- Fedora: [hddfancontrol](https://packages.fedoraproject.org/pkgs/hddfancontrol/hddfancontrol/)

See [GitHub releases](https://github.com/desbma/hddfancontrol/releases) for other packages/binaries built for each tagged version.

### From source

You need a Rust build environment for example from [rustup](https://rustup.rs/).

Run in the current repository:

```
cargo build --release
install -Dm 755 -t /usr/local/bin target/release/hddfancontrol
```

Also install [hdparm](http://sourceforge.net/projects/hdparm/), [smartctl](https://www.smartmontools.org/), [sdparm](https://sg.danny.cz/sg/sdparm.html) (for SAS drive support), and optionally [hddtemp](http://www.guzu.net/linux/hddtemp.php).
On recent Ubuntu and other Debian derivatives: `sudo apt install hdparm sdparm smartmontools`.

See [systemd service](#systemd-service) to easily manage the daemon.

### From [`crates.io`](https://crates.io/)

```
sudo cargo install --root /usr/local hddfancontrol
```

## Configuration

### A word of caution

The default parameters will run fans at 100% speed at temperatures > 50°C, and run them a 20% speed if < 30°C, which corresponds to the usual recommended drive operating temperature. If you are sure that there are no other components in your system that generate significant heat, if you have other fans to cool down your system, or if you have a case optimized for passive cooling, you can set minimum speed to 0%, which will stop the fans if temperature is below the minimum threshold.

**Be aware that a misconfiguration of this tool can lead to a failure to cool down your system properly which can damage components or reduce their lifetime.**

Before using HDD Fan control unmonitored for long period of time, I recommend keeping a minimum fan speed for security, and checking that the temperature of your system stays in reasonable range as expected.

### Fan configuration

To get the start/stop values for the `--pwm` parameter, you can either:

- Use the `pwm-test` command (`hddfancontrol pwm-test ...`), which will run some tests and detect the values at which the fans start and stop. However you need to have previously identified the PWM file (the `--pwm` parameter)
- use the [pwmconfig tool](https://man.archlinux.org/man/pwmconfig.8).

## Changelog

See [detailed changelog](./CHANGELOG.md) for all changes since initial version 2.

### Migrating from v1.x

With version 2, `hddfancontrol` has been completely rewritten in the Rust language. The main changes coming from version 1 are:

- `hddfancontrol` is a compiled binary, and does not require a Python interpreter anymore.
- Command line arguments are slightly changed, and will required to be manually adjusted, either in your `hddfancontrol` invocations, or in the `/etc/conf.d/hddfancontrol` file if you use it through the systemd service. See `hddfancontrol daemon -h` for a reference.
- The auto drive spin down feature has been removed. If you need it, I recommend using [hd-idle](https://github.com/adelolmo/hd-idle) (beware there are several similarly named projects), which works well alongside `hddfancontrol`.

## Command line usage

Run `hddfancontrol -h` to get full command line reference.

As an example, the command line below will instruct HDD Fan control to:

- monitor temperature of drives `/dev/sda` and `/dev/sdb`
- control fan speed using PWM 2 and 3 in `/sys/class/hwmon/hwmon1/device/`
- start both fans using PWM value 200
- consider the fans will stop with PWM value 75
- never run the fans below 10% of their maximum speed
- check temperature at least every minute

`hddfancontrol daemon -d /dev/sda /dev/sdb -p /sys/class/hwmon/hwmon1/device/pwm2:200:75 /sys/class/hwmon/hwmon1/device/pwm3:200:75 --min-fan-speed-prct 10 -i 1min`

## systemd service

A systemd service file is provided to control the daemon easily.
If you installed hddfancontrol from a distribution package, you likely already have it installed, otherwise you can install it from the sources of this repository with:

```
sudo install -Dm 644 ./systemd/hddfancontrol.service /etc/systemd/system/hddfancontrol.service
sudo install -Dm 644 ./systemd/hddfancontrol.conf /etc/conf.d/hddfancontrol
```

Then you need to edit the `HDDFANCONTROL_DAEMON_ARGS` variable in `/etc/conf.d/hddfancontrol` to set the parameters (drives, temperature range...).

You can then start the daemon with `sudo systemctl start hddfancontrol`, see its status with `sudo systemctl status hddfancontrol` and enable automatic startup at boot time with `sudo systemctl enable hddfancontrol`.

## License

[GPLv3](https://www.gnu.org/licenses/gpl-3.0-standalone.html)
