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)
|
PIDClimate = pid_ns.class_('PIDClimate', climate.Climate, cg.Component)
|
||||||
PIDAutotuneAction = pid_ns.class_('PIDAutotuneAction', automation.Action)
|
PIDAutotuneAction = pid_ns.class_('PIDAutotuneAction', automation.Action)
|
||||||
PIDResetIntegralTermAction = pid_ns.class_('PIDResetIntegralTermAction', automation.Action)
|
PIDResetIntegralTermAction = pid_ns.class_('PIDResetIntegralTermAction', automation.Action)
|
||||||
|
PIDSetControlParametersAction = pid_ns.class_('PIDSetControlParametersAction', automation.Action)
|
||||||
|
|
||||||
CONF_DEFAULT_TARGET_TEMPERATURE = 'default_target_temperature'
|
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_positive_output(config[CONF_POSITIVE_OUTPUT]))
|
||||||
cg.add(var.set_negative_output(config[CONF_NEGATIVE_OUTPUT]))
|
cg.add(var.set_negative_output(config[CONF_NEGATIVE_OUTPUT]))
|
||||||
yield var
|
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_output_value() const { return output_value_; }
|
||||||
float get_error_value() const { return controller_.error; }
|
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_proportional_term() const { return controller_.proportional_term; }
|
||||||
float get_integral_term() const { return controller_.integral_term; }
|
float get_integral_term() const { return controller_.integral_term; }
|
||||||
float get_derivative_term() const { return controller_.derivative_term; }
|
float get_derivative_term() const { return controller_.derivative_term; }
|
||||||
|
@ -101,5 +104,27 @@ template<typename... Ts> class PIDResetIntegralTermAction : public Action<Ts...>
|
||||||
PIDClimate *parent_;
|
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 pid
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -15,6 +15,9 @@ PID_CLIMATE_SENSOR_TYPES = {
|
||||||
'DERIVATIVE': PIDClimateSensorType.PID_SENSOR_TYPE_DERIVATIVE,
|
'DERIVATIVE': PIDClimateSensorType.PID_SENSOR_TYPE_DERIVATIVE,
|
||||||
'HEAT': PIDClimateSensorType.PID_SENSOR_TYPE_HEAT,
|
'HEAT': PIDClimateSensorType.PID_SENSOR_TYPE_HEAT,
|
||||||
'COOL': PIDClimateSensorType.PID_SENSOR_TYPE_COOL,
|
'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'
|
CONF_CLIMATE_ID = 'climate_id'
|
||||||
|
|
|
@ -35,6 +35,18 @@ void PIDClimateSensor::update_from_parent_() {
|
||||||
case PID_SENSOR_TYPE_COOL:
|
case PID_SENSOR_TYPE_COOL:
|
||||||
value = clamp(-this->parent_->get_output_value(), 0.0f, 1.0f);
|
value = clamp(-this->parent_->get_output_value(), 0.0f, 1.0f);
|
||||||
break;
|
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:
|
default:
|
||||||
value = NAN;
|
value = NAN;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -14,6 +14,9 @@ enum PIDClimateSensorType {
|
||||||
PID_SENSOR_TYPE_DERIVATIVE,
|
PID_SENSOR_TYPE_DERIVATIVE,
|
||||||
PID_SENSOR_TYPE_HEAT,
|
PID_SENSOR_TYPE_HEAT,
|
||||||
PID_SENSOR_TYPE_COOL,
|
PID_SENSOR_TYPE_COOL,
|
||||||
|
PID_SENSOR_TYPE_KP,
|
||||||
|
PID_SENSOR_TYPE_KI,
|
||||||
|
PID_SENSOR_TYPE_KD,
|
||||||
};
|
};
|
||||||
|
|
||||||
class PIDClimateSensor : public sensor::Sensor, public Component {
|
class PIDClimateSensor : public sensor::Sensor, public Component {
|
||||||
|
|
|
@ -169,6 +169,13 @@ api:
|
||||||
then:
|
then:
|
||||||
- tm1651.turn_off:
|
- tm1651.turn_off:
|
||||||
id: tm1651_battery
|
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:
|
wifi:
|
||||||
ssid: 'MySSID'
|
ssid: 'MySSID'
|
||||||
|
@ -681,6 +688,17 @@ climate:
|
||||||
away_config:
|
away_config:
|
||||||
default_target_temperature_low: 16°C
|
default_target_temperature_low: 16°C
|
||||||
default_target_temperature_high: 20°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:
|
cover:
|
||||||
- platform: endstop
|
- platform: endstop
|
||||||
|
@ -761,6 +779,11 @@ output:
|
||||||
id: dimmer1
|
id: dimmer1
|
||||||
gate_pin: GPIO5
|
gate_pin: GPIO5
|
||||||
zero_cross_pin: GPIO12
|
zero_cross_pin: GPIO12
|
||||||
|
- platform: slow_pwm
|
||||||
|
pin: GPIO5
|
||||||
|
id: my_slow_pwm
|
||||||
|
period: 15s
|
||||||
|
|
||||||
|
|
||||||
mcp23017:
|
mcp23017:
|
||||||
id: mcp23017_hub
|
id: mcp23017_hub
|
||||||
|
|
Loading…
Reference in a new issue