How can I sync a PID controller to mqtt?

Hello, I am the new one trying to build 2 temperature regulations in mycodo (one for mashing and one for fermenting).

I like to use mqtt as a central platform between all inputs and outputs which results in my question:

How can I:

  • enable/disable a PID controller by mqtt topic subscription
  • publish the setpoint of the PID to a mqtt topic
  • change the setpoint of the PID from a subscribed mqtt topic
    ?

Any hints are welcome, I have no fear of python code if necessary so if you have a starting point for me…

Maecki

1 Like

I would use a Conditional Controller. First, create a PID Controller and tune it. Create an MQTT Input for the PID enable/disable commands, which we will use a value of 1 enabling and 0 disabling. Create an MQTT Input that will be used to set the PID setpoint. We will use Python in the Conditional to publish the setpoint.

For the Conditional Controller, add a Measurement (Single, Last) condition and set it to the MQTT Input that receives the PID enable/disable value, and add another Measurement (Single, Last) condition and set it to the MQTT Input that receives the PID setpoint value. Set the Max Age of these measurements to something slightly longer than the Period of the Conditional. Set the Period of the Conditional to something reasonable but quick like 60 seconds.

Here is the Conditional Statement code that should integrate everything:

import paho.mqtt.publish as publish

pid_id = "ID_OF_PID_TO_CONTROL"

mqtt_publish_hostname = "localhost"
mqtt_publish_client_id = "client_publish"
mqtt_publish_keepalive = 60
mqtt_publish_topic_pid_setpoint = "pid_setpoint"
mqtt_publish_auth_dict = None
# Uncomment to use authentication
# mqtt_publish_auth_dict = {
#     "username": "username",
#     "password": "password"
# }

def publish_setpoint(setpoint):
    publish.single(
        mqtt_publish_topic_pid_setpoint,
        setpoint,
        hostname=mqtt_publish_hostname,
        port=1883,
        client_id=mqtt_publish_client_id,
        keepalive=mqtt_publish_keepalive,
        auth=mqtt_publish_auth_dict)

mqtt_subscribe_pid_control_value = self.condition("{abcd1234}")
mqtt_subscribe_pid_setpoint = self.condition("{qwer5678}")

if mqtt_subscribe_pid_control_value is not None:
    if mqtt_subscribe_pid_control_value == 1:
        control.controller_activate(pid_id)  # Activate PID
        # Alternatively you can Resume the PID (doesn't reset P, I, and D values)
        # control.pid_resume(pid_id)  
    elif mqtt_subscribe_pid_control_value == 0:
        control.controller_deactivate(pid_id)  # Dectivate PID
        # Alternatively you can Pause the PID (doesn't reset P, I, and D values)
        # control.pid_pause(pid_id)

if mqtt_subscribe_pid_setpoint is not None:
    control.pid_set(pid_id, "setpoint", mqtt_subscribe_pid_setpoint)  # Set PID setpoint

current_pid_setpoint = control.pid_get(pid_id, "setpoint")
publish_setpoint(current_pid_setpoint)
1 Like

Thx, you‘re great, man!

I‘ll give this a try.

Maecki

1 Like

Works like a charm!

Thank you

Maecki

1 Like