diff --git a/esphome/components/sensor/filter.cpp b/esphome/components/sensor/filter.cpp index 7afc43b8aa..e59625a267 100644 --- a/esphome/components/sensor/filter.cpp +++ b/esphome/components/sensor/filter.cpp @@ -222,15 +222,6 @@ MultiplyFilter::MultiplyFilter(TemplatableValue multiplier) : multiplier_ optional MultiplyFilter::new_value(float value) { return value * this->multiplier_.value(); } -bool throttle_check_and_update(uint32_t &last_input, uint32_t min_time_between_inputs) { - const uint32_t now = App.get_loop_component_start_time(); - if (last_input == 0 || now - last_input >= min_time_between_inputs) { - last_input = now; - return true; - } - return false; -} - // ValueListFilter helper (non-template, shared by all ValueListFilter instantiations) bool value_list_matches_any(Sensor *parent, float sensor_value, const TemplatableValue *values, size_t count) { int8_t accuracy = parent->get_accuracy_decimals(); @@ -266,6 +257,17 @@ optional ThrottleFilter::new_value(float value) { return {}; } +// ThrottleWithPriorityFilter helper (non-template, keeps App access in .cpp) +optional throttle_with_priority_new_value(Sensor *parent, float value, const TemplatableValue *values, + size_t count, uint32_t &last_input, uint32_t min_time_between_inputs) { + const uint32_t now = App.get_loop_component_start_time(); + if (last_input == 0 || now - last_input >= min_time_between_inputs || + value_list_matches_any(parent, value, values, count)) { + last_input = now; + return value; + } + return {}; +} // DeltaFilter DeltaFilter::DeltaFilter(float min_a0, float min_a1, float max_a0, float max_a1) : min_a0_(min_a0), min_a1_(min_a1), max_a0_(max_a0), max_a1_(max_a1) {} diff --git a/esphome/components/sensor/filter.h b/esphome/components/sensor/filter.h index 9e97ad432a..cb4abd154a 100644 --- a/esphome/components/sensor/filter.h +++ b/esphome/components/sensor/filter.h @@ -332,10 +332,6 @@ class MultiplyFilter : public Filter { /// Non-template helper for value matching (implementation in filter.cpp) bool value_list_matches_any(Sensor *parent, float sensor_value, const TemplatableValue *values, size_t count); -/// Returns true if throttle should allow the value through (time expired or first input). -/// Updates last_input in-place. Implementation in filter.cpp (accesses App without circular include). -bool throttle_check_and_update(uint32_t &last_input, uint32_t min_time_between_inputs); - /** Base class for filters that compare sensor values against a fixed list of configured values. * * Templated on N (the number of values) so the list is stored inline in a std::array, @@ -382,6 +378,10 @@ class ThrottleFilter : public Filter { uint32_t min_time_between_inputs_; }; +/// Non-template helper for ThrottleWithPriorityFilter (implementation in filter.cpp) +optional throttle_with_priority_new_value(Sensor *parent, float value, const TemplatableValue *values, + size_t count, uint32_t &last_input, uint32_t min_time_between_inputs); + /// Same as 'throttle' but will immediately publish values contained in `value_to_prioritize`. template class ThrottleWithPriorityFilter : public ValueListFilter { public: @@ -390,11 +390,8 @@ template class ThrottleWithPriorityFilter : public ValueListFilter : ValueListFilter(prioritized_values), min_time_between_inputs_(min_time_between_inputs) {} optional new_value(float value) override { - if (throttle_check_and_update(this->last_input_, this->min_time_between_inputs_) || - this->value_matches_any_(value)) { - return value; - } - return {}; + return throttle_with_priority_new_value(this->parent_, value, this->values_.data(), N, this->last_input_, + this->min_time_between_inputs_); } protected: diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 4e2049c4c6..4aabb607dd 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -503,7 +503,7 @@ template::max()> /// Initialize a std::array from an initializer_list. Uses memcpy for trivially copyable types (optimal codegen), /// falls back to element-wise copy for non-trivially copyable types (e.g. TemplatableValue). -/// N is set by code generation; ESPHOME_DEBUG_ASSERT catches mismatches in debug/integration tests. +/// N is set by code generation; assert catches mismatches in debug/integration tests. template inline void init_array_from(std::array &dest, std::initializer_list src) { #ifdef ESPHOME_DEBUG assert(src.size() == N);