# that the 'solar out' temperature is still higher than the ambient reading
# from the 'solar in'. So before turning the pump on, ensure the bypass
# valve is open, to allow water to flow directly back to the pool. By the
-# time the control value is permitted to change state again in five minutes,
+# time the control valve is permitted to change state again in five minutes,
# both sensors should be reporting the true water temperature.
substitutions:
esphome:
name: pool
on_boot:
+ # Timezone is set at 220; see https://github.com/esphome/issues/issues/6840#issuecomment-2783475202
+ priority: 210
then:
- script.execute:
id: pump_default
time_t now = ::time(NULL);
bool cur_state = id(valve_output).state;
bool want_state = cur_state;
- if (cur_state) {
+ if (intemp < 5.0) {
+ // If approaching freezing, open the bypass valve and leave it open.
+ // Probably best to turn the pump off in that case too, not that it
+ // should ever actually be allowed to freeze in the pipes with the
+ // pump still active!
+ want_state = false;
+ id(frost_protection) = true;
+ id(pool_pump).turn_off();
+ } else if (cur_state) {
// Only turn off if the output has got all the way down below the input temp
want_state = outtemp >= intemp;
} else {
if (t.hour >= 17 && t.hour < 19 && !want_state && id(pool_pump).state &&
now > id(pump_last_manual_change) + 600 &&
now > id(control_valve_last_change) + 600) {
- ESP_LOGD("control_value", "Cold for ten minutes. Turning pump off for the night");
+ ESP_LOGD("control_valve", "Cold for ten minutes. Turning pump off for the night");
id(pool_pump).turn_off();
}
// Turn pump on if it's warm enough, between 7:30am and 10am (when it comes on anyway).
- if (((t.hour == 7 && t.minute >= 30) || t.hour > 8) &&
- t.hour < 10 && outtemp >= 20.0 && !id(pool_pump).state) {
- ESP_LOGD("control_value", "Roof temperature over 20°C. Turning pump ON and valve OFF.");
+ if (((t.hour == 7 && t.minute >= 30) || t.hour >= 8) &&
+ t.hour < 10 && outtemp >= 20.0 && !id(pool_pump).state &&
+ now > id(pump_last_manual_change) + 600) {
+ ESP_LOGD("control_valve", "Roof temperature over 20°C. Turning pump ON and valve OFF.");
id(pool_pump).turn_on();
+ id(control_valve_last_change) = now;
+ id(valve_output).turn_off();
+ }
+
+ // Turn pump on if it was too cold at 10am but is now warm enough, before 5pm.
+ if (id(frost_protection) && t.hour >= 10 && t.hour < 17 && !id(pool_pump).state &&
+ now > id(pump_last_manual_change) + 600 && intemp > 5.0) {
+ ESP_LOGD("control_valve", "Frost protection cancelled; turning pump ON and valve OFF.");
+ id(frost_protection) = false;
+ id(pool_pump).turn_on();
+ id(control_valve_last_change) = now;
id(valve_output).turn_off();
}
return;
then:
lambda: |-
static bool done = false;
- ESP_LOGD("pump_default", "Invoked with force = %s, done = %s", force ? "true" : "false", done ? "true" : "false");
+ ESP_LOGD("pump_default", "Invoked with force = %s, done = %s, intemp %f", force ? "true" : "false", done ? "true" : "false", id(solar_in).state);
if (force || !done) {
auto t = id(sntp_time).now();
+ auto intemp = id(solar_in).state;
if (t.is_valid()) {
ESP_LOGD("pump_default", "Setting pump switch at %dh", t.hour);
- if (t.hour >= 10 && t.hour < 17)
+ if (t.hour >= 10 && t.hour < 17) {
+ if (intemp < 5.0) {
+ ESP_LOGD("pump_default", "Frost protection at %f °C", intemp);
+ id(frost_protection) = true;
+ id(pool_pump).turn_off();
+ return; // without setting 'done'
+ }
id(pool_pump).turn_on();
- else
+ } else {
id(pool_pump).turn_off();
+ }
done = true;
} else {
ESP_LOGD("pump_default", "Time not valid");
restore_value: no
initial_value: '0'
+ - id: frost_protection
+ type: bool
+ restore_value: no
+ initial_value: 'false'
+
time:
- platform: sntp
on_time:
case 518: /* Pool pump switch */
id(pump_last_manual_change) = ::time(NULL);
+ id(frost_protection) = false;
if (nvalue)
id(pool_pump).turn_on();
else