mirror of
https://github.com/esphome/esphome.git
synced 2025-07-31 07:36:35 +00:00
[sensor] Add new filter: `throttle_with_priority
` (#9937)
This commit is contained in:
parent
14dd48f9c3
commit
374858efeb
@ -256,6 +256,7 @@ OffsetFilter = sensor_ns.class_("OffsetFilter", Filter)
|
||||
MultiplyFilter = sensor_ns.class_("MultiplyFilter", Filter)
|
||||
FilterOutValueFilter = sensor_ns.class_("FilterOutValueFilter", Filter)
|
||||
ThrottleFilter = sensor_ns.class_("ThrottleFilter", Filter)
|
||||
ThrottleWithPriorityFilter = sensor_ns.class_("ThrottleWithPriorityFilter", Filter)
|
||||
TimeoutFilter = sensor_ns.class_("TimeoutFilter", Filter, cg.Component)
|
||||
DebounceFilter = sensor_ns.class_("DebounceFilter", Filter, cg.Component)
|
||||
HeartbeatFilter = sensor_ns.class_("HeartbeatFilter", Filter, cg.Component)
|
||||
@ -595,6 +596,25 @@ async def throttle_filter_to_code(config, filter_id):
|
||||
return cg.new_Pvariable(filter_id, config)
|
||||
|
||||
|
||||
TIMEOUT_WITH_PRIORITY_SCHEMA = cv.maybe_simple_value(
|
||||
{
|
||||
cv.Required(CONF_TIMEOUT): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_VALUE, default="nan"): cv.ensure_list(cv.float_),
|
||||
},
|
||||
key=CONF_TIMEOUT,
|
||||
)
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register(
|
||||
"throttle_with_priority",
|
||||
ThrottleWithPriorityFilter,
|
||||
TIMEOUT_WITH_PRIORITY_SCHEMA,
|
||||
)
|
||||
async def throttle_with_priority_filter_to_code(config, filter_id):
|
||||
template_ = [await cg.templatable(x, [], float) for x in config[CONF_VALUE]]
|
||||
return cg.new_Pvariable(filter_id, config[CONF_TIMEOUT], template_)
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register(
|
||||
"heartbeat", HeartbeatFilter, cv.positive_time_period_milliseconds
|
||||
)
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "filter.h"
|
||||
#include <cmath>
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "sensor.h"
|
||||
@ -332,6 +333,40 @@ optional<float> ThrottleFilter::new_value(float value) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// ThrottleWithPriorityFilter
|
||||
ThrottleWithPriorityFilter::ThrottleWithPriorityFilter(uint32_t min_time_between_inputs,
|
||||
std::vector<TemplatableValue<float>> prioritized_values)
|
||||
: min_time_between_inputs_(min_time_between_inputs), prioritized_values_(std::move(prioritized_values)) {}
|
||||
|
||||
optional<float> ThrottleWithPriorityFilter::new_value(float value) {
|
||||
bool is_prioritized_value = false;
|
||||
int8_t accuracy = this->parent_->get_accuracy_decimals();
|
||||
float accuracy_mult = powf(10.0f, accuracy);
|
||||
const uint32_t now = App.get_loop_component_start_time();
|
||||
// First, determine if the new value is one of the prioritized values
|
||||
for (auto prioritized_value : this->prioritized_values_) {
|
||||
if (std::isnan(prioritized_value.value())) {
|
||||
if (std::isnan(value)) {
|
||||
is_prioritized_value = true;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
float rounded_prioritized_value = roundf(accuracy_mult * prioritized_value.value());
|
||||
float rounded_value = roundf(accuracy_mult * value);
|
||||
if (rounded_prioritized_value == rounded_value) {
|
||||
is_prioritized_value = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Finally, determine if the new value should be throttled and pass it through if not
|
||||
if (this->last_input_ == 0 || now - this->last_input_ >= min_time_between_inputs_ || is_prioritized_value) {
|
||||
this->last_input_ = now;
|
||||
return value;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
// DeltaFilter
|
||||
DeltaFilter::DeltaFilter(float delta, bool percentage_mode)
|
||||
: delta_(delta), current_delta_(delta), percentage_mode_(percentage_mode), last_value_(NAN) {}
|
||||
|
@ -314,6 +314,20 @@ class ThrottleFilter : public Filter {
|
||||
uint32_t min_time_between_inputs_;
|
||||
};
|
||||
|
||||
/// Same as 'throttle' but will immediately publish values contained in `value_to_prioritize`.
|
||||
class ThrottleWithPriorityFilter : public Filter {
|
||||
public:
|
||||
explicit ThrottleWithPriorityFilter(uint32_t min_time_between_inputs,
|
||||
std::vector<TemplatableValue<float>> prioritized_values);
|
||||
|
||||
optional<float> new_value(float value) override;
|
||||
|
||||
protected:
|
||||
uint32_t last_input_{0};
|
||||
uint32_t min_time_between_inputs_;
|
||||
std::vector<TemplatableValue<float>> prioritized_values_;
|
||||
};
|
||||
|
||||
class TimeoutFilter : public Filter, public Component {
|
||||
public:
|
||||
explicit TimeoutFilter(uint32_t time_period, TemplatableValue<float> new_value);
|
||||
|
Loading…
x
Reference in New Issue
Block a user