Simple PID Controller

A few months ago I created the Simple PID Controller, a PID control which can be fully configured from the UI!

It’s downloadable from HACS, more information here: GitHub - bvweerd/simple_pid_controller: PID Controller integration for Home Assistant

3 Likes

Hello, all PID controllers I could find for HA were not working, I ended up doing one in automation. Cool you did it, I will surely test it. Purpose is EV charger and inverter control not to blow my circuit braker, not for temperature. Thanks for this!

Good to hear! It’s definitely meant as a generic PID controller, not for temperatures specifically. Hope it works for you!

Doing a PID is easy, having it like it seems (not tested yet) is another thing. I will keep you posted. David. Where are you from?

Hello, Is your PID controller now working correctly for your car charger ?

Yes it is.
It is a drama not to find one that works

Hi, first of all I want to thank you very much for this PID controller. I have only used it for one room in the zone control of my house but it is working perfectly so far. I have one request. If it would be possible to adjust the setpoint to one tenth place? Now I can only enter the whole number 21 or 22, it would be great if I could enter 21.5
Snímka obrazovky 2025-11-17 131804


When I set 21 the window is fine but when I manually enter 21.5 there it is red

Good catch, small type in the code. fixed in v1.5.1, will be available shortly

2 Likes

Hi,

thank you for your great work.
I urgently need a PID Controller, but I don’t understand how this integration works, where I have to put which information to get it up and running.
I need support.

This is my use case:

While loading my solar battery in my house I am not allowed to exceed 17kW power import from the grid.
Since I have a lot of loads switching on an off all the time, I cannot work with a static value for the charging current of my battery and could use a PID controller and set it to setpoint 16 (kW) to provide a charging power close to my limit of 17 kW, but hopefully not exceeding it.

My entity for the power import in kW from the grid is “sensor.power_import”.
That entity can vary theoretically from -10 to 30 but the negative numbers are irrelevant during the time period I am charging the battery.
During that phase the entity varies between 5-20 but I do not want to exceed 17.
I want to control the charging current of my solar battery “number.max_battery_grid_charge_current”.
The value range of that entity is 0 - 30.

How do I have to set this up?

If you could explain this to me I would be very thankful.

1. Install the Integration

First, install the Simple PID Controller in Home Assistant:

  • Go to Settings > Devices & Services
  • Click Add Integration → Search for Simple PID Controller

2. Initial Configuration

When setting up the integration, enter:

  • Name: Battery Grid Charge Controller
  • Input Sensor Entity: sensor.power_import
  • Input Range Min: -10 (your sensor’s minimum)
  • Input Range Max: 30 (your sensor’s maximum)
  • Output Range Min: 0 (minimum charging current)
  • Output Range Max: 30 (maximum charging current)

3. Configure PID Parameters

After setup, go to Settings > Devices & Services → Find your new controller → Click Configure or adjust the entities:

Critical Settings:

  • Setpoint: 16 (kW - your target grid import)
  • Kp: -2.0 (negative for inverse control)
  • Ki: -0.2 (negative for inverse control)
  • Kd: -0.5 (negative for inverse control)
  • Sample Time: 5 seconds (fast response for load changes)
  • Output Min: 0 A
  • Output Max: 30 A
  • Auto Mode: ON
  • Windup Protection: ON (prevents integral windup)

4. Why Negative Gains?

This is an inverse control problem:

  • When grid import increases (approaches 17 kW) → reduce battery charging
  • When grid import decreases (below 16 kW) → increase battery charging

Using negative Kp, Ki, and Kd inverts the controller action to achieve this behavior.

5. Create Automation to Apply Output

The PID controller creates a sensor (e.g., sensor.battery_grid_charge_controller_pid_output) that outputs the calculated charging current. You need an automation to apply this to your battery:

automation:
  - alias: "Apply PID Battery Charging Control"
    trigger:
      - platform: state
        entity_id: sensor.battery_grid_charge_controller_pid_output
    action:
      - service: number.set_value
        target:
          entity_id: number.max_battery_grid_charge_current
        data:
          value: "{{ states('sensor.battery_grid_charge_controller_pid_output') | float }}"

6. Enable Diagnostic Sensors (for tuning)

Go to Settings > Devices & Services → Your controller → Enable these sensors:

  • PID P Contribution
  • PID I Contribution
  • PID D Contribution
  • Error

These help you monitor how the controller responds to your loads.

7. Fine-Tuning

Start with the suggested values and observe:

  • If the controller is too aggressive (oscillates): Reduce the magnitude of Kp, increase Kd
  • If the controller is too slow to respond: Increase the magnitude of Kp
  • If there’s steady-state error (settles above/below 16 kW): Increase the magnitude of Ki
  • If loads change very frequently: Consider increasing Sample Time to 10-15 seconds

8. Safety Considerations

  • The controller will try to keep grid import at 16 kW, but sudden large loads may briefly exceed 17 kW
  • Consider setting Output Max to something like 28 A instead of 30 A to leave a safety margin
  • Monitor the system for a few days and adjust as needed

Expected Behavior

With this setup:

  • Grid import at 14 kW → PID increases charging current
  • Grid import at 16 kW → PID holds steady
  • Grid import at 18 kW → PID reduces charging current
  • Large sudden load (e.g., +5 kW) → PID quickly reduces battery charging to compensate
3 Likes

Absolutely awesome!

Thank you so much.
I will implement that later today, but with these detailed informations it will work for sure.

My main problem was, that I didn’t know how to set the target.
Now, with the automation, it’s crystal clear.

Thank you :pray:

Hi, thank you for this integration,
I have a simmilair question about the PID settings.
I want to use my excess solar power to heat up a hot water boiler.
So the setpoint will be -10 (allow 10 watt`s up to the grid)
0 to 100 for output control (pwm thyristor control)
Maximum output is 2000 watts.

So the PID controller must keep the flow back into the grid to about -10 watts.
The excess solar power is between -10 and -2200 watt`s, do i also need the negative PID settings ?

This is what I assume you’re aiming at:

  • Your sensor reads negative values (e.g., -1000W = 1000W to grid)
  • Your setpoint is -10W (target: 10W to grid)
  • When sensor = -1000W and setpoint = -10W, error = -990W
  • You want the heater to increase power to consume that excess
  • With negative Kp, negative error → output increases

Configuration:

  • Input range: -2200 to 0 (or -2200 to -10)
  • Output range: 0 to 100
  • Setpoint: -10
  • Start with: Kp = -1.0, Ki = -0.1, Kd = -0.05 (then tune)

I ran into some small problems, somehow the PID controller would not accept negative numbers for min / max input range, so i made a template to mirror the numbers coming from my P1 meter.
So -50 watt to the grid is mirrirored to +50 and i use that entity as the input for the PID controller.
The main problem is that is reacts way to agressive, even with a P of 0.0001.
When more than 50 watt`s is detected the controller shoots out 100%, therefore the heating element pulls 2000 watts, the automation sees that and cuts off the PID (i have a relay between the thyristor and the live 230V power, so the thyristor is not always onder the230 volts).
How do i decrease this agressive behaviour ?

Have you turned off all fancy pid features like the windup protection, prop mode, etc? Long sample time?

Have you enabled your diagnostics sensors to see what is contributing to your output?

If you use the download diagnostics, and give that to an ai model with reference to the github project it might also give you some decent hints

I’ve played with the settings and found out:
Kp 0,05
Ki 0,1
Kd -0,1

But what helped the must was reducing the output, now at 50% maximum.
At 100% when for example, 400watt was going back into the grid the Simple PID would steer out 100%, feeding the boiler with about 2000 watts, this results in a occilating system, high load, low feedback, high load, low feedback.
By lowering the output the system reacts a whole lot within boundaries.
I am still not sure what changes if i adjust the Ki and Kd values.
For now in this time of year it works, i’ll keep on experimenting when there is more solar output during the day.

Well,
After putting my results in AI some points became clear to me.
I wanted to have a “zero on the meter” type of load adjustment from the pid.

AI told me to play with the Ki only, set Kp and Kd to zero, and set Ki to a very low setting 0,001.
Setpoint is 50 (watt solar export).

As AI explained, with a low Ki the pid will increase or decrease the output very slow, in tiny steps.
As the sun came up yesterday the solar panels started to produce power.
As soon as the exported power was above 50 the pid started, from 0 slowly increasing the power to my electrical heater.
I could see the increased power lowering the export until it was about equal to the value of 50.
While the sun was getting higher and higher more power was produced, the pid kept increasing the power to the heater, keeping the export low to about 50 watts.
When a load inside the house became active (induction cooking, boiler) the export was stopped and the pid was reducing the power to the heater.
So still some more testing has to be done, but its looking good so far.

Good to hear, happy tuning!