mirror of
https://github.com/m5stack/esphome.git
synced 2026-05-20 11:52:52 -07:00
[thermostat] General clean-up, optimization, properly support "auto" mode (#10561)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
co-authored by
Jesse Hills
parent
e218f16f0f
commit
d9f625e5c8
@@ -32,6 +32,7 @@ from esphome.const import (
|
||||
CONF_FAN_WITH_COOLING,
|
||||
CONF_FAN_WITH_HEATING,
|
||||
CONF_HEAT_ACTION,
|
||||
CONF_HEAT_COOL_MODE,
|
||||
CONF_HEAT_DEADBAND,
|
||||
CONF_HEAT_MODE,
|
||||
CONF_HEAT_OVERRUN,
|
||||
@@ -150,7 +151,7 @@ def generate_comparable_preset(config, name):
|
||||
def validate_thermostat(config):
|
||||
# verify corresponding action(s) exist(s) for any defined climate mode or action
|
||||
requirements = {
|
||||
CONF_AUTO_MODE: [
|
||||
CONF_HEAT_COOL_MODE: [
|
||||
CONF_COOL_ACTION,
|
||||
CONF_HEAT_ACTION,
|
||||
CONF_MIN_COOLING_OFF_TIME,
|
||||
@@ -540,6 +541,9 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.Optional(CONF_FAN_ONLY_MODE): automation.validate_automation(
|
||||
single=True
|
||||
),
|
||||
cv.Optional(CONF_HEAT_COOL_MODE): automation.validate_automation(
|
||||
single=True
|
||||
),
|
||||
cv.Optional(CONF_HEAT_MODE): automation.validate_automation(single=True),
|
||||
cv.Optional(CONF_OFF_MODE): automation.validate_automation(single=True),
|
||||
cv.Optional(CONF_FAN_MODE_ON_ACTION): automation.validate_automation(
|
||||
@@ -644,7 +648,6 @@ async def to_code(config):
|
||||
var = await climate.new_climate(config)
|
||||
await cg.register_component(var, config)
|
||||
|
||||
heat_cool_mode_available = CONF_HEAT_ACTION in config and CONF_COOL_ACTION in config
|
||||
two_points_available = CONF_HEAT_ACTION in config and (
|
||||
CONF_COOL_ACTION in config
|
||||
or (config[CONF_FAN_ONLY_COOLING] and CONF_FAN_ONLY_ACTION in config)
|
||||
@@ -739,11 +742,6 @@ async def to_code(config):
|
||||
var.get_idle_action_trigger(), [], config[CONF_IDLE_ACTION]
|
||||
)
|
||||
|
||||
if heat_cool_mode_available is True:
|
||||
cg.add(var.set_supports_heat_cool(True))
|
||||
else:
|
||||
cg.add(var.set_supports_heat_cool(False))
|
||||
|
||||
if CONF_COOL_ACTION in config:
|
||||
await automation.build_automation(
|
||||
var.get_cool_action_trigger(), [], config[CONF_COOL_ACTION]
|
||||
@@ -780,6 +778,7 @@ async def to_code(config):
|
||||
await automation.build_automation(
|
||||
var.get_auto_mode_trigger(), [], config[CONF_AUTO_MODE]
|
||||
)
|
||||
cg.add(var.set_supports_auto(True))
|
||||
if CONF_COOL_MODE in config:
|
||||
await automation.build_automation(
|
||||
var.get_cool_mode_trigger(), [], config[CONF_COOL_MODE]
|
||||
@@ -800,6 +799,11 @@ async def to_code(config):
|
||||
var.get_heat_mode_trigger(), [], config[CONF_HEAT_MODE]
|
||||
)
|
||||
cg.add(var.set_supports_heat(True))
|
||||
if CONF_HEAT_COOL_MODE in config:
|
||||
await automation.build_automation(
|
||||
var.get_heat_cool_mode_trigger(), [], config[CONF_HEAT_COOL_MODE]
|
||||
)
|
||||
cg.add(var.set_supports_heat_cool(True))
|
||||
if CONF_OFF_MODE in config:
|
||||
await automation.build_automation(
|
||||
var.get_off_mode_trigger(), [], config[CONF_OFF_MODE]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,9 +6,9 @@
|
||||
#include "esphome/components/climate/climate.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
#include <array>
|
||||
#include <cinttypes>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace esphome {
|
||||
namespace thermostat {
|
||||
@@ -24,6 +24,7 @@ enum ThermostatClimateTimerIndex : uint8_t {
|
||||
TIMER_HEATING_OFF = 7,
|
||||
TIMER_HEATING_ON = 8,
|
||||
TIMER_IDLE_ON = 9,
|
||||
TIMER_COUNT = 10,
|
||||
};
|
||||
|
||||
enum OnBootRestoreFrom : uint8_t {
|
||||
@@ -131,6 +132,7 @@ class ThermostatClimate : public climate::Climate, public Component {
|
||||
Trigger<> *get_dry_mode_trigger() const;
|
||||
Trigger<> *get_fan_only_mode_trigger() const;
|
||||
Trigger<> *get_heat_mode_trigger() const;
|
||||
Trigger<> *get_heat_cool_mode_trigger() const;
|
||||
Trigger<> *get_off_mode_trigger() const;
|
||||
Trigger<> *get_fan_mode_on_trigger() const;
|
||||
Trigger<> *get_fan_mode_off_trigger() const;
|
||||
@@ -163,9 +165,10 @@ class ThermostatClimate : public climate::Climate, public Component {
|
||||
/// Returns the fan mode that is locked in (check fan_mode_change_delayed(), first!)
|
||||
climate::ClimateFanMode locked_fan_mode();
|
||||
/// Set point and hysteresis validation
|
||||
bool hysteresis_valid(); // returns true if valid
|
||||
bool hysteresis_valid(); // returns true if valid
|
||||
bool limit_setpoints_for_heat_cool(); // returns true if set points should be further limited within visual range
|
||||
void validate_target_temperature();
|
||||
void validate_target_temperatures();
|
||||
void validate_target_temperatures(bool pin_target_temperature_high);
|
||||
void validate_target_temperature_low();
|
||||
void validate_target_temperature_high();
|
||||
|
||||
@@ -241,12 +244,28 @@ class ThermostatClimate : public climate::Climate, public Component {
|
||||
bool supplemental_cooling_required_();
|
||||
bool supplemental_heating_required_();
|
||||
|
||||
void dump_preset_config_(const char *preset_name, const ThermostatClimateTargetTempConfig &config,
|
||||
bool is_default_preset);
|
||||
void dump_preset_config_(const char *preset_name, const ThermostatClimateTargetTempConfig &config);
|
||||
|
||||
/// Minimum allowable duration in seconds for action timers
|
||||
const uint8_t min_timer_duration_{1};
|
||||
|
||||
/// Store previously-known states
|
||||
///
|
||||
/// These are used to determine when a trigger/action needs to be called
|
||||
climate::ClimateFanMode prev_fan_mode_{climate::CLIMATE_FAN_ON};
|
||||
climate::ClimateMode prev_mode_{climate::CLIMATE_MODE_OFF};
|
||||
climate::ClimateSwingMode prev_swing_mode_{climate::CLIMATE_SWING_OFF};
|
||||
|
||||
/// The current supplemental action
|
||||
climate::ClimateAction supplemental_action_{climate::CLIMATE_ACTION_OFF};
|
||||
|
||||
/// Default standard preset to use on start up
|
||||
climate::ClimatePreset default_preset_{};
|
||||
|
||||
/// If set to DEFAULT_PRESET then the default preset is always used. When MEMORY prior
|
||||
/// state will attempt to be restored if possible
|
||||
OnBootRestoreFrom on_boot_restore_from_{OnBootRestoreFrom::MEMORY};
|
||||
|
||||
/// Whether the controller supports auto/cooling/drying/fanning/heating.
|
||||
///
|
||||
/// A false value for any given attribute means that the controller has no such action
|
||||
@@ -362,9 +381,15 @@ class ThermostatClimate : public climate::Climate, public Component {
|
||||
Trigger<> *supplemental_heat_action_trigger_{nullptr};
|
||||
Trigger<> *heat_mode_trigger_{nullptr};
|
||||
|
||||
/// The trigger to call when the controller should switch to heat/cool mode.
|
||||
///
|
||||
/// In heat/cool mode, the controller will enable heating/cooling as necessary and switch
|
||||
/// to idle when the temperature is within the thresholds/set points.
|
||||
Trigger<> *heat_cool_mode_trigger_{nullptr};
|
||||
|
||||
/// The trigger to call when the controller should switch to auto mode.
|
||||
///
|
||||
/// In auto mode, the controller will enable heating/cooling as necessary and switch
|
||||
/// In auto mode, the controller will enable heating/cooling as supported/necessary and switch
|
||||
/// to idle when the temperature is within the thresholds/set points.
|
||||
Trigger<> *auto_mode_trigger_{nullptr};
|
||||
|
||||
@@ -438,35 +463,21 @@ class ThermostatClimate : public climate::Climate, public Component {
|
||||
Trigger<> *prev_mode_trigger_{nullptr};
|
||||
Trigger<> *prev_swing_mode_trigger_{nullptr};
|
||||
|
||||
/// If set to DEFAULT_PRESET then the default preset is always used. When MEMORY prior
|
||||
/// state will attempt to be restored if possible
|
||||
OnBootRestoreFrom on_boot_restore_from_{OnBootRestoreFrom::MEMORY};
|
||||
|
||||
/// Store previously-known states
|
||||
///
|
||||
/// These are used to determine when a trigger/action needs to be called
|
||||
climate::ClimateAction supplemental_action_{climate::CLIMATE_ACTION_OFF};
|
||||
climate::ClimateFanMode prev_fan_mode_{climate::CLIMATE_FAN_ON};
|
||||
climate::ClimateMode prev_mode_{climate::CLIMATE_MODE_OFF};
|
||||
climate::ClimateSwingMode prev_swing_mode_{climate::CLIMATE_SWING_OFF};
|
||||
|
||||
/// Default standard preset to use on start up
|
||||
climate::ClimatePreset default_preset_{};
|
||||
/// Default custom preset to use on start up
|
||||
std::string default_custom_preset_{};
|
||||
|
||||
/// Climate action timers
|
||||
std::vector<ThermostatClimateTimer> timer_{
|
||||
{false, 0, 0, std::bind(&ThermostatClimate::cooling_max_run_time_timer_callback_, this)},
|
||||
{false, 0, 0, std::bind(&ThermostatClimate::cooling_off_timer_callback_, this)},
|
||||
{false, 0, 0, std::bind(&ThermostatClimate::cooling_on_timer_callback_, this)},
|
||||
{false, 0, 0, std::bind(&ThermostatClimate::fan_mode_timer_callback_, this)},
|
||||
{false, 0, 0, std::bind(&ThermostatClimate::fanning_off_timer_callback_, this)},
|
||||
{false, 0, 0, std::bind(&ThermostatClimate::fanning_on_timer_callback_, this)},
|
||||
{false, 0, 0, std::bind(&ThermostatClimate::heating_max_run_time_timer_callback_, this)},
|
||||
{false, 0, 0, std::bind(&ThermostatClimate::heating_off_timer_callback_, this)},
|
||||
{false, 0, 0, std::bind(&ThermostatClimate::heating_on_timer_callback_, this)},
|
||||
{false, 0, 0, std::bind(&ThermostatClimate::idle_on_timer_callback_, this)},
|
||||
std::array<ThermostatClimateTimer, TIMER_COUNT> timer_{
|
||||
ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::cooling_max_run_time_timer_callback_, this)),
|
||||
ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::cooling_off_timer_callback_, this)),
|
||||
ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::cooling_on_timer_callback_, this)),
|
||||
ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::fan_mode_timer_callback_, this)),
|
||||
ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::fanning_off_timer_callback_, this)),
|
||||
ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::fanning_on_timer_callback_, this)),
|
||||
ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::heating_max_run_time_timer_callback_, this)),
|
||||
ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::heating_off_timer_callback_, this)),
|
||||
ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::heating_on_timer_callback_, this)),
|
||||
ThermostatClimateTimer(false, 0, 0, std::bind(&ThermostatClimate::idle_on_timer_callback_, this)),
|
||||
};
|
||||
|
||||
/// The set of standard preset configurations this thermostat supports (Eg. AWAY, ECO, etc)
|
||||
|
||||
@@ -424,6 +424,7 @@ CONF_HEAD = "head"
|
||||
CONF_HEADING = "heading"
|
||||
CONF_HEARTBEAT = "heartbeat"
|
||||
CONF_HEAT_ACTION = "heat_action"
|
||||
CONF_HEAT_COOL_MODE = "heat_cool_mode"
|
||||
CONF_HEAT_DEADBAND = "heat_deadband"
|
||||
CONF_HEAT_MODE = "heat_mode"
|
||||
CONF_HEAT_OVERRUN = "heat_overrun"
|
||||
|
||||
Reference in New Issue
Block a user