The Simple PID Controller is a Home Assistant integration for real-time PID control with UI-based tuning and diagnostics.
- Features
- Installation
- Configuration
- Entities Overview
- PID Tuning Guide
- More details and extended documentation
- Example PID Graph
- Support & Development
- Service Actions
- Live PID tuning via Number entities.
- Diagnostics for P, I, and D terms (optional).
- Switch to toggle auto mode and proportional-on-measurement.
- Configurable output limits, setpoint, and sample time.
| Platform | Entity | Purpose |
|---|---|---|
| Sensor | PID Output |
Current controller output as percentage |
| Sensor | PID P Contribution |
Proportional term value (diagnostic) |
| Sensor | PID I Contribution |
Integral term value (diagnostic) |
| Sensor | PID D Contribution |
Derivative term value (diagnostic) |
| Number | Kp, Ki, Kd |
PID gain parameters |
| Number | Setpoint |
Desired target value |
| Number | Output Min / Max |
Controller output limits |
| Number | Sample Time |
PID evaluation interval |
| Switch | Auto Mode |
Toggle automatic control |
| Switch | Proportional on Measurement |
Change proportional mode |
| Switch | Windup Protection |
Toggle windup protection |
💡 All entities are editable via the UI in Settings > Devices & Services > [Your Controller] > Options.
- In Home Assistant UI, navigate to HACS > Integrations
- Click the three-dot menu (⋮) and select Custom repositories
- Add:
Select Integration as type
https://github.com/bvweerd/simple_pid_controller - Search for Simple PID Controller and install
- Restart Home Assistant
- Download or clone this repository
- Copy
simple_pid_controllerto/config/custom_components/ - Restart Home Assistant
To remove the Simple PID Controller, navigate to Settings > Devices & Services, select Simple PID Controller, and click Delete. If installed manually, delete the custom_components/simple_pid_controller directory and restart Home Assistant.
The controller is configured through the UI using the Config Flow {% term config_flow %}.
- Go to Settings > Devices & Services
- Click Add Integration and choose Simple PID Controller
- Enter:
- Name: e.g., "Heater Controller"
- Sensor Entity: e.g.,
sensor.living_room_temperature
- Submit and finish setup
Default Range:
The controller’s setpoint range defaults to 0.0 – 100.0. To customize this range, select the integration in Settings > Devices & Services, click Options, adjust Range Min and Range Max, and save.
| Platform | Entity Suffix | Description |
|---|---|---|
| Sensor | PID Output |
Current controller output (%). |
| Sensor | PID P/I/D Contribution |
Diagnostic terms. Disabled by default. |
| Number | Kp, Ki, Kd |
PID gains. |
| Number | Setpoint |
Desired system target. |
| Number | Output Min / Output Max |
Min/max control limits. |
| Number | Sample Time |
PID evaluation rate in seconds. |
| Switch | Auto Mode |
Enable/disable PID automation. |
| Switch | Proportional on Measurement |
Use measurement instead of error for P term. |
| Switch | Windup Protection |
Toggle windup protection |
A PID controller continuously corrects the difference between a setpoint and measured value using:
- P (Proportional): reacts to present error
- I (Integral): compensates for past error
- D (Derivative): predicts future error trends
1. Manual (Trial & Error)
- Set
KiandKdto 0 - Start with small
Kp(e.g., 1.0) - Increase
Kpuntil oscillations appear - Halve that
Kpvalue - Increase
Kito reduce steady-state error - Add
Kdto smooth out oscillations
2. Ziegler–Nichols Method
- Set
Ki = 0,Kd = 0, increaseKpuntil sustained oscillations - Measure:
- Ku = critical gain
- Pu = oscillation period
- Apply:
Kp = 0.6 × KuKi = 1.2 × Ku / PuKd = 0.075 × Ku × Pu
Several reported issues stem from the interaction between the integral term and the controller's configured limits. Keep the following points in mind when tuning:
- Integral sensor shows the clamped output – The integration exposes a diagnostic entity for the I contribution. When
Output Min/Output Maxare set, the value you see in the UI is the clamped contribution after limits are applied. This means that withKi = 0the integral value will simply remain at the boundary (e.g.Output Min = 3results inI = 3). This is expected behaviour and not a sign that the integral is "stuck". - Choose a suitable start value – When the controller is initialised it sets the integral term to the configured start value, but still clamps it within your
Output Min/Output Maxrange. If you want the controller to begin from0, select the PID Start Value optionzero_start(or call thesimple_pid_controller.set_outputservice with thepresetparameter) and temporarily widen the output range if needed. Otherwise the integral will be forced to the lowest allowed value. - Ki must be non-zero to change the integral – Setting
Ki = 0effectively freezes the integral term. Use a small but non-zero value if you need the controller to move away from the clamp over time. You can combine this with Windup Protection (toggle entity) to prevent large overshoots once the setpoint is reached.
If your process requires a non-zero minimum output (for example, EV charging currents that must stay above 6 A), start your tuning with:
PID Start Value = zero_startso the controller can compute from a neutral baseline.- A modest proportional gain (
Kp) that does not immediately drive the output below the minimum. - A small integral gain (
Ki) to let the controller move away from the clamped value without causing overshoot.
These steps help avoid the "integral stuck at minimum" effect while keeping the controller within the bounds your hardware requires.
-
Initialization
- On startup (or when options change), we set up a single
sample_timevalue (in seconds). - We register a periodic callback with Home Assistant’s scheduler (
async_track_time_intervalorDataUpdateCoordinator) using that samesample_time.
- On startup (or when options change), we set up a single
-
Coordinator Tick
- Every
sample_timeseconds, Home Assistant’s scheduler invokes our update method. - We immediately read the current process variable (e.g. temperature sensor) and pass it to the PID logic.
- Every
-
PID Logic & Output
- The PID algorithm calculates the Proportional, Integral, and Derivative terms and writes the result to your target entity (e.g. a heater or set-point).
-
Adjusting Sample Time
- Changing
sample_timein your integration options takes effect at the end of the current interval—no Home Assistant restart is required. - On the next tick, the coordinator will use the new interval.
- Changing
The integration is based on simple-pid https://pypi.org/project/simple-pid/
Read the user guide here: https://simple-pid.readthedocs.io/en/latest/user_guide.html#user-guide
Here's an example output showing the controller responding to a setpoint:
- GitHub Repository: https://github.com/bvweerd/simple_pid_controller
- Issues & Bugs: Report here
The integration provides a simple_pid_controller.set_output service to adjust the controller output directly.
| Field | Description |
|---|---|
entity_id |
PID output sensor entity to control (may be provided via target) |
preset |
Optional preset: zero_start, last_known_value, or startup_value |
value |
Optional manual value between configured Output Min and Output Max |
- When Auto Mode is off, the last output value is updated to the chosen value.
- When Auto Mode is on, the PID restarts from the new value and the coordinator refreshes.
- Exactly one PID output sensor entity must be targeted.
Example using target:
service: simple_pid_controller.set_output
target:
entity_id: sensor.spid_x_pid_output
data:
value: 200Example using target:
action: simple_pid_controller.set_output
target:
entity_id: sensor.spid_x_pid_output
data:
value: 200