esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
411 stars 26 forks source link

General purpose PID-Controller (or something similar) #1871

Open RubenKelevra opened 1 year ago

RubenKelevra commented 1 year ago

Please describe your use case for this integration and alternatives you've tried:

I'm using ESPHome to control the fan speed of an Ikea Förnuftig air cleaner and read the sensor data of an Ikea Vindriktning PM2.5 sensor.

To control the air cleaner with the sensor data I'm using a PID-Controller (a custom component) inside of Home Assistant.

This solution isn't stable.

Describe the problem you have/What new integration you would like I would really like to access just the sensor data via Home Assistant as Hub with the air cleaner and have a general purpose PID-Controller which runs on the ESP8266.

The Climate PID Controller could maybe be repurposed for this, but I'm really not sure if reading PM2.5 particle counts and reinterpret them as °C is the right thing to move forward here.


I'm also planning to integrate my exhaust hood as well as the exhaust fan in the bathroom into the home automation. For both I would need a controller which can interpret the VOC and humidity readings (and compare the humidity readings against a baseline reading from the hallway) and select the right fan speed based on that.

I would like to use a PID-Controller for this as well. Say substract the baseline humidity from the local sensor reading in the bathroom and the kitchen and multiply it with the VOC sensor reading. And set a target of "5" or something like this in the PID controller.

Additional context

nagyrobi commented 1 year ago

To control the air cleaner with the sensor data I'm using a PID-Controller (a custom component) inside of Home Assistant. This solution isn't stable.

In what aspect is not stable?

davey commented 1 year ago

I'd like to confirm that need for a general purpose / generic PID controller directly on the ESP, independent of a central hub like Homeassistant: currently the Climate PID controller can only work with a temperature/°C, but it would be really great to be able to use it for e.g. basic humidity control - or basically for anything with a float sensor and one (e.g. increase something, like heating) or two (increase and decrease something, like heating and cooling) float outputs.

SeByDocKy commented 1 year ago

Definitively a must to be done for ESPhome !!!! Planning to use ESPhome for solar power diverter regulation. Here my target will be current (A)

nagyrobi commented 1 year ago

A quite complex thing to think about. The current PID climate uses the ziegler-nichols tuning rule, which seems good for temperature regulation.

This may not be appropriate for other applications, several other rules exist like tyreus-luyben, ciancone-marlin, pessen etc. A generic PID controller should be able to be parametrised in a very flexible way, to support any kind of rule, even completely custom.


RubenKelevra commented 1 year ago

To control the air cleaner with the sensor data I'm using a PID-Controller (a custom component) inside of Home Assistant. This solution isn't stable.

In what aspect is not stable?

I would consider it an alpha/beta not stable.

RubenKelevra commented 1 year ago

Hey @patrickcollins12, saw your recent contribution to the Climate PID in the changelog, thanks a lot!

Maybe you have fun having a go at this too? :)

patrickcollins12 commented 1 year ago

I'm happy to look into it. Could be challenging because PID is a subclass of Climate and so assumes much more than just temperature (cool, warm, etc).

patrickcollins12 commented 1 year ago

Definitively a must to be done for ESPhome !!!! Planning to use ESPhome for solar power diverter regulation. Here my target will be current (A)

@SeByDocKy what would you want it to do? What would be the sensor and what would it control?

SeByDocKy commented 1 year ago

Definitively a must to be done for ESPhome !!!! Planning to use ESPhome for solar power diverter regulation. Here my target will be current (A)

@SeByDocKy what would you want it to do? What would be the sensor and what would it control?

the sensor would be either a DC/AC current sensor I controlling the power P output of a AC dimmer. Mathematiccally speaking, I would like to do something like

Max P st I_lower_bound<I<I_upper_bound where I is the DC current input/output of a battery for example.

Let's clarify more. If the system produces the AC power P_k (to a pure resistive load) such as P_k < Psolar_k then I_k > I_upperbound.... so I can increase P such P{k+1} = aP'{k}, a > 1.. If P{k+1} < Psolar_k, I can continue to increase P else (I__{k+1} < I_lowerbound), I have to apply P{k+1} = b_P'{k}, b < 1 and so on ...

We did that with a pure arduino code : https://github.com/bidouilleurs/routeur_solaire

But I would like to use ESPhome instead...

patrickcollins12 commented 1 year ago

I think we would need a totally new component. GenericPID(?). It would be very similar to PIDClimate in functionality. I need to duplicate to ensure that PIDClimate maintains backward compatibility.

SeByDocKy commented 1 year ago

I think we would need a totally new component. GenericPID(?). It would be very similar to PIDClimate in functionality. I need to duplicate to ensure that PIDClimate maintains backward compatibility.

Sound an excellent idea....

patrickcollins12 commented 1 year ago

I've been working on this for a couple nights. I'm probably 30% complete. This is how the config would look. Before I continue, I welcome your input.

# this is the existing climate pid
climate:
  - platform: pid
    id: console_thermostat_old
    name: "Console Fan Thermostat"

    sensor: console_fan_temperature

    default_target_temperature: 21
    cool_output: console_fan_speed

    control_parameters:
      kp: 0.0
      ki: 0.0
      kd: 0.0

# this is the new generic pid, note increase/decrease output

pid_control:
  - id: humidity_controller
    name: "Bathroom Humidity Controller"

    sensor: bathroom_humidity_sensor

    default_target: 60
    decrease_output: bathroom_fan
    increase_output: shower_heat

    control_parameters:
      kp: 0.0
      ki: 0.0
      kd: 0.0

  - id: second_controller
    default_target: 22
    increase_output: increase_auger_speed
    sensor: bbq_sensor
    control_parameters:
      kp: 0.0
      ki: 0.0
      kd: 0.0
SeByDocKy commented 1 year ago

I've been working on this for a couple nights. I'm probably 30% complete. This is how the config would look. Before I continue, I welcome your input.

# this is the existing climate pid
climate:
  - platform: pid
    id: console_thermostat_old
    name: "Console Fan Thermostat"

    sensor: console_fan_temperature

    default_target_temperature: 21
    cool_output: console_fan_speed

    control_parameters:
      kp: 0.0
      ki: 0.0
      kd: 0.0

# this is the new generic pid, note increase/decrease output

pid_control:
  - id: humidity_controller
    name: "Bathroom Humidity Controller"

    sensor: bathroom_humidity_sensor

    default_target: 60
    decrease_output: bathroom_fan
    increase_output: shower_heat

    control_parameters:
      kp: 0.0
      ki: 0.0
      kd: 0.0

  - id: second_controller
    default_target: 22
    increase_output: increase_auger_speed
    sensor: bbq_sensor
    control_parameters:
      kp: 0.0
      ki: 0.0
      kd: 0.0

Sound great and clear for me :)

SeByDocKy commented 1 year ago

Thinking about your futur general PID controller, came in my mind three additions (that are important for my futur project with):

i) the possibility to enable/disable a PID_controller , for example with (public) methods $id_pid.set_enable/$id_pid.set_disable or with a internal state that can be changed with lambda. I have to explain: I plain to code a general solar power diverter for both ongrid ior offgrid system. The first one need to control the AC current flow while the second need to control the DC current flow. If I define two general PID controllers only one can be active at a time so I need to enable one and disable the second (and vise and versa)

ii) The ossibility to control (kp,ki,kd) with for example a esphome number object (in slider mode). It would allow to fine tune these parameters without requiering each time to recompile and flash OTA after a change

iii) and the last : add a (set of) condition(s) that need to be true to increase the output field (pointing to some binary_sensors) ans defined for example like: pid_condition_to_increase:

.In the same way, condition to recpect to decrease :

pid_condition_to_decrease:

Why it can be great to have that ? For my futur power diverter and for grid-tied system, the regulation must be done on the DC current.... but also you have to stop to increase the output as soon as you start to pick up some energy from the grid (inverter takes power from solar then from battery then from the grid if first of two are not enough)

I hope I was clear enough ..... Anyway thanks to work on this very important futur new integration

patrickcollins12 commented 1 year ago

Thanks @SeByDocKy I appreciate this input.

  1. I hadn't considered an enable/disable mechanism. I agree this is critical. You get this for free in PIDClimate because all climate devices have an on/off mechanism, so it makes sense to build it in here. I'll add this to the list.

  2. I built an example here of how to wire a Number template to kp,ki,kd. So I think you'll get this functionality for free. Although it is 1-directional. Thoughts?

  3. This feels specific to your use case and not common in PID controllers. I would encourage you to use the enable/disable feature to control this. Thoughts?

SeByDocKy commented 1 year ago

Thanks @SeByDocKy I appreciate this input.

  1. I hadn't considered an enable/disable mechanism. I agree this is critical. You get this for free in PIDClimate because all climate devices have an on/off mechanism, so it makes sense to build it in here. I'll add this to the list.
  2. I built an example here of how to wire a Number template to kp,ki,kd. So I think you'll get this functionality for free. Although it is 1-directional. Thoughts?
  3. This feels specific to your use case and not common in PID controllers. I would encourage you to use the enable/disable feature to control this. Thoughts?

Hello, any news of ypur general PID developpent ?

Sébastien

patrickcollins12 commented 1 year ago

I have not made further progress since I started a new job. But I hope to get back to it soon.

SeByDocKy commented 1 year ago

I have not made further progress since I started a new job. But I hope to get back to it soon.

Great news :)

Tuckie commented 2 months ago

Any updates on this? Looking for something to regulate water pressure with a pressure sensor and a pump.

bzumik1 commented 2 months ago

Hi @patrickcollins12 any progress? I am also loooking for something similar :)