Skip to content

Temperature PID

The Temperature PID module provides closed-loop PID thermostat control that automatically adjusts fan speed to maintain a target temperature. It creates a climate entity in Home Assistant that acts as a thermostat — set your desired temperature and the controller handles the rest.

PID stands for Proportional-Integral-Derivative, three terms that work together:

  • Proportional (P): Reacts to the current temperature error. The further the temperature is from the target, the faster the fans spin. This is the primary driver of fan speed.
  • Integral (I): Corrects for persistent offset over time. If the P term alone can’t quite reach the target, the I term slowly increases fan speed to close the gap.
  • Derivative (D): Dampens rapid temperature changes. If temperature is rising quickly, the D term increases fan speed preemptively. Usually left at 0 for fan control since temperature changes are slow.

Choose PID when you need precise temperature maintenance with automatic adjustment — for example, keeping a server closet at exactly 25 C. PID is the most capable temperature module but requires more configuration than the alternatives.

For simpler setups, consider Temperature Linear (three-zone mapping) or Temperature Curve (custom multi-point profile). See the modules overview for a comparison table.

VariableDefaultDescription
friendly_name"Fancontroller"Device name prefix for all entities
kp"3.0"Proportional gain (UI scale, x100)
ki"0.005"Integral gain (UI scale, x100)
kd"0.0"Derivative gain (UI scale, x100)
max_integral"0.0"Maximum integral term (0 = unlimited)
output_averaging_samples"1"Output smoothing samples
derivative_averaging_samples"5"Derivative smoothing samples
EntityDescriptionDefault
ThermostatPID-controlled climate entityTarget 30 C, range 20-50 C
EntityRangeStepDefaultDescription
PID kp0 — 500.13.0Proportional gain (UI scale)
PID ki0 — 0.20.0010.005Integral gain (UI scale)
PID kd0 — 20010.0Derivative gain (UI scale)
PID Deadband Threshold Low0 — 5 C0.050.25How far below target before PID reacts
PID Deadband Threshold High0 — 5 C0.050.25How far above target before PID reacts
PID Deadband ki Multiplier0 — 0.20.010.04Ki scaling inside deadband (0.04 = 4% of normal Ki)
Fan Minimum Speed0 — 30%10Minimum fan speed enforced by PID (0 = fans can stop)
EntityUnitDescription
P term%Current proportional contribution
I term%Current integral contribution
D term%Current derivative contribution
Output value%Combined PID output (fan speed)
Error valueCDifference between actual and target temperature
Is in deadband0/1Whether temperature is within deadband range
EntityDefaultDescription
PID Control Fan 1ONEnable PID control for fan 1
PID Control Fan 2ONEnable PID control for fan 2
PID Control Fan 3ONEnable PID control for fan 3
PID Control Fan 4ONEnable PID control for fan 4
EntityDescription
Fan Manual OverrideBypasses PID and sets fan speed directly. Turning off resets the PID integral term.
EntityDescription
PID Climate AutotuneStarts ESPHome’s automatic PID parameter calculation
packages:
temperature_pid:
url: https://github.com/zeroflow/wifi-fancontroller
ref: main
files:
- path: modules/temperature_pid.yaml
vars:
friendly_name: "My Fan Controller"
packages:
temperature_pid:
url: https://github.com/zeroflow/wifi-fancontroller
ref: main
files:
- path: modules/temperature_pid.yaml
vars:
friendly_name: "Server Rack"
kp: "5.0"
ki: "0.01"
kd: "0.0"
ParameterUI Value (HA)Internal ValueUI Range
kp3.00.030 — 50
ki0.0050.000050 — 0.2
kd0.00.00 — 200

To convert: Internal = UI / 100

Getting started:

  • Set your target temperature in the thermostat entity and observe the behavior for 10-15 minutes
  • Watch the P term sensor in HA — it should react proportionally to temperature changes
  • Watch the I term sensor — it should slowly climb if the P term alone can’t reach the target
  • The output value sensor shows the combined fan speed percentage

When to use Autotune:

  • Press the PID Climate Autotune button to let the controller calculate parameters automatically
  • Autotune works best when the system is at a steady state (fans running, temperature stable)
  • After autotune completes, the new parameters are saved to flash and persist across reboots

Manual tuning:

  • Increase kp if fans react too slowly to temperature changes
  • Increase ki if the temperature settles slightly above or below the target
  • Leave kd at 0 unless you see oscillation — temperature changes are usually slow enough that derivative control isn’t needed

Deadband:

  • The default deadband is +/- 0.25 C around the target temperature
  • Inside the deadband, Ki is scaled to 4% of its normal value (ki_multiplier = 0.04), which prevents integral windup while allowing slow drift correction
  • Increase the deadband thresholds if fans cycle on/off too frequently near the target

Based on work by patrickcollins12/esphome-fan-controller.