mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01:00
Allow updating pid control params (#1115)
This commit is contained in:
parent
e6f42fa6f0
commit
351ecf9bd4
6 changed files with 92 additions and 0 deletions
|
@ -8,6 +8,7 @@ pid_ns = cg.esphome_ns.namespace('pid')
|
|||
PIDClimate = pid_ns.class_('PIDClimate', climate.Climate, cg.Component)
|
||||
PIDAutotuneAction = pid_ns.class_('PIDAutotuneAction', automation.Action)
|
||||
PIDResetIntegralTermAction = pid_ns.class_('PIDResetIntegralTermAction', automation.Action)
|
||||
PIDSetControlParametersAction = pid_ns.class_('PIDSetControlParametersAction', automation.Action)
|
||||
|
||||
CONF_DEFAULT_TARGET_TEMPERATURE = 'default_target_temperature'
|
||||
|
||||
|
@ -90,3 +91,28 @@ def esp8266_set_frequency_to_code(config, action_id, template_arg, args):
|
|||
cg.add(var.set_positive_output(config[CONF_POSITIVE_OUTPUT]))
|
||||
cg.add(var.set_negative_output(config[CONF_NEGATIVE_OUTPUT]))
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
'climate.pid.set_control_parameters',
|
||||
PIDSetControlParametersAction,
|
||||
automation.maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(PIDClimate),
|
||||
cv.Required(CONF_KP): cv.templatable(cv.float_),
|
||||
cv.Optional(CONF_KI, default=0.0): cv.templatable(cv.float_),
|
||||
cv.Optional(CONF_KD, default=0.0): cv.templatable(cv.float_),
|
||||
})
|
||||
)
|
||||
def set_control_parameters(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
kp_template_ = yield cg.templatable(config[CONF_KP], args, float)
|
||||
cg.add(var.set_kp(kp_template_))
|
||||
|
||||
ki_template_ = yield cg.templatable(config[CONF_KI], args, float)
|
||||
cg.add(var.set_ki(ki_template_))
|
||||
|
||||
kd_template_ = yield cg.templatable(config[CONF_KD], args, float)
|
||||
cg.add(var.set_kd(kd_template_))
|
||||
yield var
|
||||
|
|
|
@ -29,6 +29,9 @@ class PIDClimate : public climate::Climate, public Component {
|
|||
|
||||
float get_output_value() const { return output_value_; }
|
||||
float get_error_value() const { return controller_.error; }
|
||||
float get_kp() { return controller_.kp; }
|
||||
float get_ki() { return controller_.ki; }
|
||||
float get_kd() { return controller_.kd; }
|
||||
float get_proportional_term() const { return controller_.proportional_term; }
|
||||
float get_integral_term() const { return controller_.integral_term; }
|
||||
float get_derivative_term() const { return controller_.derivative_term; }
|
||||
|
@ -101,5 +104,27 @@ template<typename... Ts> class PIDResetIntegralTermAction : public Action<Ts...>
|
|||
PIDClimate *parent_;
|
||||
};
|
||||
|
||||
template<typename... Ts> class PIDSetControlParametersAction : public Action<Ts...> {
|
||||
public:
|
||||
PIDSetControlParametersAction(PIDClimate *parent) : parent_(parent) {}
|
||||
|
||||
void play(Ts... x) {
|
||||
auto kp = this->kp_.value(x...);
|
||||
auto ki = this->ki_.value(x...);
|
||||
auto kd = this->kd_.value(x...);
|
||||
|
||||
this->parent_->set_kp(kp);
|
||||
this->parent_->set_ki(ki);
|
||||
this->parent_->set_kd(kd);
|
||||
}
|
||||
|
||||
protected:
|
||||
TEMPLATABLE_VALUE(float, kp)
|
||||
TEMPLATABLE_VALUE(float, ki)
|
||||
TEMPLATABLE_VALUE(float, kd)
|
||||
|
||||
PIDClimate *parent_;
|
||||
};
|
||||
|
||||
} // namespace pid
|
||||
} // namespace esphome
|
||||
|
|
|
@ -15,6 +15,9 @@ PID_CLIMATE_SENSOR_TYPES = {
|
|||
'DERIVATIVE': PIDClimateSensorType.PID_SENSOR_TYPE_DERIVATIVE,
|
||||
'HEAT': PIDClimateSensorType.PID_SENSOR_TYPE_HEAT,
|
||||
'COOL': PIDClimateSensorType.PID_SENSOR_TYPE_COOL,
|
||||
'KP': PIDClimateSensorType.PID_SENSOR_TYPE_KP,
|
||||
'KI': PIDClimateSensorType.PID_SENSOR_TYPE_KI,
|
||||
'KD': PIDClimateSensorType.PID_SENSOR_TYPE_KD,
|
||||
}
|
||||
|
||||
CONF_CLIMATE_ID = 'climate_id'
|
||||
|
|
|
@ -35,6 +35,18 @@ void PIDClimateSensor::update_from_parent_() {
|
|||
case PID_SENSOR_TYPE_COOL:
|
||||
value = clamp(-this->parent_->get_output_value(), 0.0f, 1.0f);
|
||||
break;
|
||||
case PID_SENSOR_TYPE_KP:
|
||||
value = this->parent_->get_kp();
|
||||
this->publish_state(value);
|
||||
return;
|
||||
case PID_SENSOR_TYPE_KI:
|
||||
value = this->parent_->get_ki();
|
||||
this->publish_state(value);
|
||||
return;
|
||||
case PID_SENSOR_TYPE_KD:
|
||||
value = this->parent_->get_kd();
|
||||
this->publish_state(value);
|
||||
return;
|
||||
default:
|
||||
value = NAN;
|
||||
break;
|
||||
|
|
|
@ -14,6 +14,9 @@ enum PIDClimateSensorType {
|
|||
PID_SENSOR_TYPE_DERIVATIVE,
|
||||
PID_SENSOR_TYPE_HEAT,
|
||||
PID_SENSOR_TYPE_COOL,
|
||||
PID_SENSOR_TYPE_KP,
|
||||
PID_SENSOR_TYPE_KI,
|
||||
PID_SENSOR_TYPE_KD,
|
||||
};
|
||||
|
||||
class PIDClimateSensor : public sensor::Sensor, public Component {
|
||||
|
|
|
@ -169,6 +169,13 @@ api:
|
|||
then:
|
||||
- tm1651.turn_off:
|
||||
id: tm1651_battery
|
||||
- service: pid_set_control_parameters
|
||||
then:
|
||||
- climate.pid.set_control_parameters:
|
||||
id: pid_climate
|
||||
kp: 1.0
|
||||
kd: 1.0
|
||||
ki: 1.0
|
||||
|
||||
wifi:
|
||||
ssid: 'MySSID'
|
||||
|
@ -681,6 +688,17 @@ climate:
|
|||
away_config:
|
||||
default_target_temperature_low: 16°C
|
||||
default_target_temperature_high: 20°C
|
||||
- platform: pid
|
||||
id: pid_climate
|
||||
name: "PID Climate Controller"
|
||||
sensor: ha_hello_world
|
||||
default_target_temperature: 21°C
|
||||
heat_output: my_slow_pwm
|
||||
control_parameters:
|
||||
kp: 0.0
|
||||
ki: 0.0
|
||||
kd: 0.0
|
||||
|
||||
|
||||
cover:
|
||||
- platform: endstop
|
||||
|
@ -761,6 +779,11 @@ output:
|
|||
id: dimmer1
|
||||
gate_pin: GPIO5
|
||||
zero_cross_pin: GPIO12
|
||||
- platform: slow_pwm
|
||||
pin: GPIO5
|
||||
id: my_slow_pwm
|
||||
period: 15s
|
||||
|
||||
|
||||
mcp23017:
|
||||
id: mcp23017_hub
|
||||
|
|
Loading…
Reference in a new issue