10 static const char *
const TAG =
"sensor.filter";
14 ESP_LOGVV(TAG,
"Filter(%p)::input(%f)",
this, value);
20 if (this->
next_ ==
nullptr) {
21 ESP_LOGVV(TAG,
"Filter(%p)::output(%f) -> SENSOR",
this, value);
24 ESP_LOGVV(TAG,
"Filter(%p)::output(%f) -> %p",
this, value, this->
next_);
29 ESP_LOGVV(TAG,
"Filter(%p)::initialize(parent=%p next=%p)",
this, parent, next);
36 : send_every_(send_every), send_at_(send_every - send_first_at), window_size_(window_size) {}
43 this->
queue_.push_back(value);
44 ESP_LOGVV(TAG,
"MedianFilter(%p)::new_value(%f)",
this, value);
50 if (!this->
queue_.empty()) {
52 std::vector<float> median_queue;
53 for (
auto v : this->
queue_) {
55 median_queue.push_back(v);
59 sort(median_queue.begin(), median_queue.end());
61 size_t queue_size = median_queue.size();
64 median = median_queue[queue_size / 2];
66 median = (median_queue[queue_size / 2] + median_queue[(queue_size / 2) - 1]) / 2.0f;
71 ESP_LOGVV(TAG,
"MedianFilter(%p)::new_value(%f) SENDING %f",
this, value, median);
87 this->
queue_.push_back(value);
88 ESP_LOGVV(TAG,
"QuantileFilter(%p)::new_value(%f), quantile:%f",
this, value, this->
quantile_);
94 if (!this->
queue_.empty()) {
96 std::vector<float> quantile_queue;
97 for (
auto v : this->
queue_) {
99 quantile_queue.push_back(v);
103 sort(quantile_queue.begin(), quantile_queue.end());
105 size_t queue_size = quantile_queue.size();
108 ESP_LOGVV(TAG,
"QuantileFilter(%p)::position: %d/%d",
this, position + 1, queue_size);
113 ESP_LOGVV(TAG,
"QuantileFilter(%p)::new_value(%f) SENDING %f",
this, value, result);
128 this->
queue_.push_back(value);
129 ESP_LOGVV(TAG,
"MinFilter(%p)::new_value(%f)",
this, value);
135 for (
auto v : this->
queue_) {
136 if (!std::isnan(v)) {
137 min = std::isnan(min) ? v : std::min(min, v);
141 ESP_LOGVV(TAG,
"MinFilter(%p)::new_value(%f) SENDING %f",
this, value, min);
156 this->
queue_.push_back(value);
157 ESP_LOGVV(TAG,
"MaxFilter(%p)::new_value(%f)",
this, value);
163 for (
auto v : this->
queue_) {
164 if (!std::isnan(v)) {
165 max = std::isnan(max) ? v : std::max(max, v);
169 ESP_LOGVV(TAG,
"MaxFilter(%p)::new_value(%f) SENDING %f",
this, value, max);
177 size_t send_first_at)
185 this->
queue_.push_back(value);
186 ESP_LOGVV(TAG,
"SlidingWindowMovingAverageFilter(%p)::new_value(%f)",
this, value);
192 size_t valid_count = 0;
193 for (
auto v : this->
queue_) {
194 if (!std::isnan(v)) {
202 average = sum / valid_count;
205 ESP_LOGVV(TAG,
"SlidingWindowMovingAverageFilter(%p)::new_value(%f) SENDING %f",
this, value, average);
215 if (!std::isnan(value)) {
224 const float average = std::isnan(value) ? value : this->
accumulator_;
225 ESP_LOGVV(TAG,
"ExponentialMovingAverageFilter(%p)::new_value(%f) -> %f",
this, value, average);
228 ESP_LOGVV(TAG,
"ExponentialMovingAverageFilter(%p)::new_value(%f) SENDING %f",
this, value, average);
241 ESP_LOGVV(TAG,
"ThrottleAverageFilter(%p)::new_value(value=%f)",
this, value);
242 if (!std::isnan(value)) {
250 ESP_LOGVV(TAG,
"ThrottleAverageFilter(%p)::interval(sum=%f, n=%i)",
this, this->
sum_, this->
n_);
269 ESP_LOGVV(TAG,
"LambdaFilter(%p)::new_value(%f) -> %f",
this, value, it.value_or(INFINITY));
288 if (std::isnan(value)) {
295 float accuracy_mult = powf(10.0f, accuracy);
297 float rounded_value = roundf(accuracy_mult * value);
298 if (rounded_filter_out == rounded_value) {
309 const uint32_t now =
millis();
320 if (std::isnan(value)) {
347 filter->input(value);
354 filter->initialize(parent, &this->
phi_);
361 this->set_timeout(
"debounce", this->time_period_, [
this, value]() { this->
output(value); });
373 ESP_LOGVV(TAG,
"HeartbeatFilter(%p)::new_value(value=%f)",
this, value);
381 ESP_LOGVV(TAG,
"HeartbeatFilter(%p)::interval(has_value=%s, last_input=%f)",
this, YESNO(this->
has_value_),
397 for (
float coefficient : this->coefficients_) {
398 res += x * coefficient;
MultiplyFilter(float multiplier)
optional< float > new_value(float value) override
lambda_filter_t lambda_filter_
void set_quantile(float quantile)
optional< float > new_value(float value) override
void set_interval(const std::string &name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a unique name.
void set_send_every(size_t send_every)
uint32_t min_time_between_inputs_
const lambda_filter_t & get_lambda_filter() const
std::deque< float > queue_
PhiNode(OrFilter *or_parent)
std::vector< Filter * > filters_
optional< float > new_value(float value) override
ThrottleFilter(uint32_t min_time_between_inputs)
void set_send_every(size_t send_every)
std::deque< float > queue_
void set_send_every(size_t send_every)
MaxFilter(size_t window_size, size_t send_every, size_t send_first_at)
Construct a MaxFilter.
void set_window_size(size_t window_size)
float get_setup_priority() const override
optional< float > new_value(float value) override
uint32_t IRAM_ATTR HOT millis()
optional< float > new_value(float value) override
optional< float > new_value(float value) override
virtual optional< float > new_value(float value)=0
This will be called every time the filter receives a new value.
optional< float > new_value(float value) override
OrFilter(std::vector< Filter *> filters)
DebounceFilter(uint32_t time_period)
void set_window_size(size_t window_size)
float value_to_filter_out_
optional< float > new_value(float value) override
HeartbeatFilter(uint32_t time_period)
float get_setup_priority() const override
optional< float > new_value(float value) override
OffsetFilter(float offset)
ThrottleAverageFilter(uint32_t time_period)
void set_alpha(float alpha)
virtual void initialize(Sensor *parent, Filter *next)
Initialize this filter, please note this can be called more than once.
void initialize(Sensor *parent, Filter *next) override
optional< float > new_value(float value) override
void set_lambda_filter(const lambda_filter_t &lambda_filter)
void set_send_every(size_t send_every)
optional< float > new_value(float value) override
optional< float > new_value(float value) override
ExponentialMovingAverageFilter(float alpha, size_t send_every, size_t send_first_at)
optional< float > new_value(float value) override
std::deque< float > queue_
std::deque< float > queue_
LambdaFilter(lambda_filter_t lambda_filter)
void set_window_size(size_t window_size)
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
optional< float > new_value(float value) override
std::function< optional< float >(float)> lambda_filter_t
void internal_send_state_to_frontend(float state)
void set_send_every(size_t send_every)
DeltaFilter(float min_delta)
FilterOutValueFilter(float value_to_filter_out)
QuantileFilter(size_t window_size, size_t send_every, size_t send_first_at, float quantile)
Construct a QuantileFilter.
Apply a filter to sensor values such as moving average.
SlidingWindowMovingAverageFilter(size_t window_size, size_t send_every, size_t send_first_at)
Construct a SlidingWindowMovingAverageFilter.
MinFilter(size_t window_size, size_t send_every, size_t send_first_at)
Construct a MinFilter.
int8_t get_accuracy_decimals()
Get the accuracy in decimals, using the manual override if set.
float get_setup_priority() const override
optional< float > new_value(float value) override
CalibrateLinearFilter(float slope, float bias)
Base-class for all sensors.
optional< float > new_value(float value) override
optional< float > new_value(float value) override
void set_window_size(size_t window_size)
optional< float > new_value(float value) override