diff --git a/esphome/components/sensor/__init__.py b/esphome/components/sensor/__init__.py index 2275027004..277718e46c 100644 --- a/esphome/components/sensor/__init__.py +++ b/esphome/components/sensor/__init__.py @@ -596,7 +596,7 @@ async def throttle_filter_to_code(config, filter_id): return cg.new_Pvariable(filter_id, config) -TIMEOUT_WITH_PRIORITY_SCHEMA = cv.maybe_simple_value( +THROTTLE_WITH_PRIORITY_SCHEMA = cv.maybe_simple_value( { cv.Required(CONF_TIMEOUT): cv.positive_time_period_milliseconds, cv.Optional(CONF_VALUE, default="nan"): cv.Any( @@ -610,7 +610,7 @@ TIMEOUT_WITH_PRIORITY_SCHEMA = cv.maybe_simple_value( @FILTER_REGISTRY.register( "throttle_with_priority", ThrottleWithPriorityFilter, - TIMEOUT_WITH_PRIORITY_SCHEMA, + THROTTLE_WITH_PRIORITY_SCHEMA, ) async def throttle_with_priority_filter_to_code(config, filter_id): if not isinstance(config[CONF_VALUE], list): @@ -631,7 +631,9 @@ async def heartbeat_filter_to_code(config, filter_id): TIMEOUT_SCHEMA = cv.maybe_simple_value( { cv.Required(CONF_TIMEOUT): cv.positive_time_period_milliseconds, - cv.Optional(CONF_VALUE, default="nan"): cv.templatable(cv.float_), + cv.Optional(CONF_VALUE, default="nan"): cv.Any( + "last", cv.templatable(cv.float_) + ), }, key=CONF_TIMEOUT, ) @@ -639,8 +641,11 @@ TIMEOUT_SCHEMA = cv.maybe_simple_value( @FILTER_REGISTRY.register("timeout", TimeoutFilter, TIMEOUT_SCHEMA) async def timeout_filter_to_code(config, filter_id): - template_ = await cg.templatable(config[CONF_VALUE], [], float) - var = cg.new_Pvariable(filter_id, config[CONF_TIMEOUT], template_) + if config[CONF_VALUE] == "last": + var = cg.new_Pvariable(filter_id, config[CONF_TIMEOUT]) + else: + template_ = await cg.templatable(config[CONF_VALUE], [], float) + var = cg.new_Pvariable(filter_id, config[CONF_TIMEOUT], template_) await cg.register_component(var, {}) return var diff --git a/esphome/components/sensor/filter.cpp b/esphome/components/sensor/filter.cpp index f077ad2416..3241ae28af 100644 --- a/esphome/components/sensor/filter.cpp +++ b/esphome/components/sensor/filter.cpp @@ -417,12 +417,17 @@ void OrFilter::initialize(Sensor *parent, Filter *next) { // TimeoutFilter optional TimeoutFilter::new_value(float value) { - this->set_timeout("timeout", this->time_period_, [this]() { this->output(this->value_.value()); }); + if (this->value_.has_value()) { + this->set_timeout("timeout", this->time_period_, [this]() { this->output(this->value_.value().value()); }); + } else { + this->set_timeout("timeout", this->time_period_, [this, value]() { this->output(value); }); + } return value; } -TimeoutFilter::TimeoutFilter(uint32_t time_period, TemplatableValue new_value) - : time_period_(time_period), value_(std::move(new_value)) {} +TimeoutFilter::TimeoutFilter(uint32_t time_period) : time_period_(time_period) {} +TimeoutFilter::TimeoutFilter(uint32_t time_period, const TemplatableValue &new_value) + : time_period_(time_period), value_(new_value) {} float TimeoutFilter::get_setup_priority() const { return setup_priority::HARDWARE; } // DebounceFilter diff --git a/esphome/components/sensor/filter.h b/esphome/components/sensor/filter.h index 5765c9a081..49d83e5b4b 100644 --- a/esphome/components/sensor/filter.h +++ b/esphome/components/sensor/filter.h @@ -330,7 +330,8 @@ class ThrottleWithPriorityFilter : public Filter { class TimeoutFilter : public Filter, public Component { public: - explicit TimeoutFilter(uint32_t time_period, TemplatableValue new_value); + explicit TimeoutFilter(uint32_t time_period); + explicit TimeoutFilter(uint32_t time_period, const TemplatableValue &new_value); optional new_value(float value) override; @@ -338,7 +339,7 @@ class TimeoutFilter : public Filter, public Component { protected: uint32_t time_period_; - TemplatableValue value_; + optional> value_; }; class DebounceFilter : public Filter, public Component { diff --git a/tests/components/template/common.yaml b/tests/components/template/common.yaml index 6b7c7ddea1..ae7dc98e57 100644 --- a/tests/components/template/common.yaml +++ b/tests/components/template/common.yaml @@ -153,6 +153,9 @@ sensor: - timeout: timeout: 1h value: 20.0 + - timeout: + timeout: 1min + value: last - timeout: timeout: 1d - to_ntc_resistance: