ESPHome 2026.1.0-dev
Loading...
Searching...
No Matches
filter.h
Go to the documentation of this file.
1#pragma once
2
3#include <queue>
4#include <utility>
5#include <vector>
9
10namespace esphome {
11namespace sensor {
12
13class Sensor;
14
20class Filter {
21 public:
31 virtual optional<float> new_value(float value) = 0;
32
34 virtual void initialize(Sensor *parent, Filter *next);
35
36 void input(float value);
37
38 void output(float value);
39
40 protected:
41 friend Sensor;
42
43 Filter *next_{nullptr};
44 Sensor *parent_{nullptr};
45};
46
53 public:
54 SlidingWindowFilter(size_t window_size, size_t send_every, size_t send_first_at);
55
56 optional<float> new_value(float value) final;
57
58 protected:
60 virtual float compute_result() = 0;
61
65 size_t window_head_{0};
66 size_t window_count_{0};
67 size_t window_size_;
68 size_t send_every_;
69 size_t send_at_;
70};
71
77 public:
79
80 protected:
83 template<typename Compare> float find_extremum_() {
84 float result = NAN;
85 Compare comp;
86 for (size_t i = 0; i < this->window_count_; i++) {
87 float v = this->window_[i];
88 if (!std::isnan(v)) {
89 result = std::isnan(result) ? v : (comp(v, result) ? v : result);
90 }
91 }
92 return result;
93 }
94};
95
110
116 public:
126 explicit QuantileFilter(size_t window_size, size_t send_every, size_t send_first_at, float quantile);
127
128 void set_quantile(float quantile) { this->quantile_ = quantile; }
129
130 protected:
131 float compute_result() override;
133};
134
140 public:
149 using SortedWindowFilter::SortedWindowFilter;
150
151 protected:
152 float compute_result() override;
153};
154
159class SkipInitialFilter : public Filter {
160 public:
165 explicit SkipInitialFilter(size_t num_to_ignore);
166
167 optional<float> new_value(float value) override;
168
169 protected:
171};
172
177class MinFilter : public MinMaxFilter {
178 public:
187 using MinMaxFilter::MinMaxFilter;
188
189 protected:
190 float compute_result() override;
191};
192
197class MaxFilter : public MinMaxFilter {
198 public:
207 using MinMaxFilter::MinMaxFilter;
208
209 protected:
210 float compute_result() override;
211};
212
219 public:
229
230 protected:
231 float compute_result() override;
232};
233
240 public:
241 ExponentialMovingAverageFilter(float alpha, size_t send_every, size_t send_first_at);
242
243 optional<float> new_value(float value) override;
244
245 void set_send_every(size_t send_every);
246 void set_alpha(float alpha);
247
248 protected:
249 float accumulator_{NAN};
250 float alpha_;
252 size_t send_at_;
253 bool first_value_{true};
254};
255
260class ThrottleAverageFilter : public Filter, public Component {
261 public:
262 explicit ThrottleAverageFilter(uint32_t time_period);
263
264 void setup() override;
265
266 optional<float> new_value(float value) override;
267
268 float get_setup_priority() const override;
269
270 protected:
271 float sum_{0.0f};
272 unsigned int n_{0};
273 uint32_t time_period_;
274 bool have_nan_{false};
275};
276
277using lambda_filter_t = std::function<optional<float>(float)>;
278
286class LambdaFilter : public Filter {
287 public:
288 explicit LambdaFilter(lambda_filter_t lambda_filter);
289
290 optional<float> new_value(float value) override;
291
292 const lambda_filter_t &get_lambda_filter() const;
293 void set_lambda_filter(const lambda_filter_t &lambda_filter);
294
295 protected:
297};
298
305 public:
306 explicit StatelessLambdaFilter(optional<float> (*lambda_filter)(float)) : lambda_filter_(lambda_filter) {}
307
308 optional<float> new_value(float value) override { return this->lambda_filter_(value); }
309
310 protected:
312};
313
315class OffsetFilter : public Filter {
316 public:
317 explicit OffsetFilter(TemplatableValue<float> offset);
318
319 optional<float> new_value(float value) override;
320
321 protected:
323};
324
326class MultiplyFilter : public Filter {
327 public:
328 explicit MultiplyFilter(TemplatableValue<float> multiplier);
329 optional<float> new_value(float value) override;
330
331 protected:
333};
334
341class ValueListFilter : public Filter {
342 protected:
343 explicit ValueListFilter(std::initializer_list<TemplatableValue<float>> values);
344
346 bool value_matches_any_(float sensor_value);
347
349};
350
353 public:
354 explicit FilterOutValueFilter(std::initializer_list<TemplatableValue<float>> values_to_filter_out);
355
356 optional<float> new_value(float value) override;
357};
358
359class ThrottleFilter : public Filter {
360 public:
361 explicit ThrottleFilter(uint32_t min_time_between_inputs);
362
363 optional<float> new_value(float value) override;
364
365 protected:
366 uint32_t last_input_{0};
368};
369
372 public:
373 explicit ThrottleWithPriorityFilter(uint32_t min_time_between_inputs,
374 std::initializer_list<TemplatableValue<float>> prioritized_values);
375
376 optional<float> new_value(float value) override;
377
378 protected:
379 uint32_t last_input_{0};
381};
382
383// Base class for timeout filters - contains common loop logic
384class TimeoutFilterBase : public Filter, public Component {
385 public:
386 void loop() override;
387 float get_setup_priority() const override;
388
389 protected:
390 explicit TimeoutFilterBase(uint32_t time_period) : time_period_(time_period) { this->disable_loop(); }
391 virtual float get_output_value() = 0;
392
393 uint32_t time_period_; // 4 bytes (timeout duration in ms)
394 uint32_t timeout_start_time_{0}; // 4 bytes (when the timeout was started)
395 // Total base: 8 bytes
396};
397
398// Timeout filter for "last" mode - outputs the last received value after timeout
400 public:
401 explicit TimeoutFilterLast(uint32_t time_period) : TimeoutFilterBase(time_period) {}
402
403 optional<float> new_value(float value) override;
404
405 protected:
406 float get_output_value() override { return this->pending_value_; }
407 float pending_value_{0}; // 4 bytes (value to output when timeout fires)
408 // Total: 8 (base) + 4 = 12 bytes + vtable ptr + Component overhead
409};
410
411// Timeout filter with configured value - evaluates TemplatableValue after timeout
413 public:
414 explicit TimeoutFilterConfigured(uint32_t time_period, const TemplatableValue<float> &new_value)
415 : TimeoutFilterBase(time_period), value_(new_value) {}
416
417 optional<float> new_value(float value) override;
418
419 protected:
420 float get_output_value() override { return this->value_.value(); }
421 TemplatableValue<float> value_; // 16 bytes (configured output value, can be lambda)
422 // Total: 8 (base) + 16 = 24 bytes + vtable ptr + Component overhead
423};
424
425class DebounceFilter : public Filter, public Component {
426 public:
427 explicit DebounceFilter(uint32_t time_period);
428
429 optional<float> new_value(float value) override;
430
431 float get_setup_priority() const override;
432
433 protected:
434 uint32_t time_period_;
435};
436
437class HeartbeatFilter : public Filter, public Component {
438 public:
439 explicit HeartbeatFilter(uint32_t time_period);
440
441 void setup() override;
442 optional<float> new_value(float value) override;
443 float get_setup_priority() const override;
444
445 void set_optimistic(bool optimistic) { this->optimistic_ = optimistic; }
446
447 protected:
448 uint32_t time_period_;
450 bool has_value_{false};
451 bool optimistic_{false};
452};
453
454class DeltaFilter : public Filter {
455 public:
456 explicit DeltaFilter(float delta, bool percentage_mode);
457
458 optional<float> new_value(float value) override;
459
460 protected:
461 float delta_;
463 float last_value_{NAN};
465};
466
467class OrFilter : public Filter {
468 public:
469 explicit OrFilter(std::initializer_list<Filter *> filters);
470
471 void initialize(Sensor *parent, Filter *next) override;
472
473 optional<float> new_value(float value) override;
474
475 protected:
476 class PhiNode : public Filter {
477 public:
478 PhiNode(OrFilter *or_parent);
479 optional<float> new_value(float value) override;
480
481 protected:
483 };
484
487 bool has_value_{false};
488};
489
491 public:
492 explicit CalibrateLinearFilter(std::initializer_list<std::array<float, 3>> linear_functions);
493 optional<float> new_value(float value) override;
494
495 protected:
497};
498
500 public:
501 explicit CalibratePolynomialFilter(std::initializer_list<float> coefficients);
502 optional<float> new_value(float value) override;
503
504 protected:
506};
507
508class ClampFilter : public Filter {
509 public:
510 ClampFilter(float min, float max, bool ignore_out_of_range);
511 optional<float> new_value(float value) override;
512
513 protected:
514 float min_{NAN};
515 float max_{NAN};
517};
518
519class RoundFilter : public Filter {
520 public:
521 explicit RoundFilter(uint8_t precision);
522 optional<float> new_value(float value) override;
523
524 protected:
525 uint8_t precision_;
526};
527
529 public:
530 explicit RoundMultipleFilter(float multiple);
531 optional<float> new_value(float value) override;
532
533 protected:
535};
536
538 public:
539 ToNTCResistanceFilter(double a, double b, double c) : a_(a), b_(b), c_(c) {}
540 optional<float> new_value(float value) override;
541
542 protected:
543 double a_;
544 double b_;
545 double c_;
546};
547
549 public:
550 ToNTCTemperatureFilter(double a, double b, double c) : a_(a), b_(b), c_(c) {}
551 optional<float> new_value(float value) override;
552
553 protected:
554 double a_;
555 double b_;
556 double c_;
557};
558
564class StreamingFilter : public Filter {
565 public:
566 StreamingFilter(size_t window_size, size_t send_first_at);
567
568 optional<float> new_value(float value) final;
569
570 protected:
572 virtual void process_value(float value) = 0;
573
575 virtual float compute_batch_result() = 0;
576
578 virtual void reset_batch() = 0;
579
581 size_t count_{0};
583 bool first_send_{true};
584};
585
591 public:
593
594 protected:
595 void process_value(float value) override;
596 float compute_batch_result() override;
597 void reset_batch() override;
598
599 float current_min_{NAN};
600};
601
607 public:
609
610 protected:
611 void process_value(float value) override;
612 float compute_batch_result() override;
613 void reset_batch() override;
614
615 float current_max_{NAN};
616};
617
623 public:
625
626 protected:
627 void process_value(float value) override;
628 float compute_batch_result() override;
629 void reset_batch() override;
630
631 float sum_{0.0f};
632 size_t valid_count_{0};
633};
634
635} // namespace sensor
636} // namespace esphome
void disable_loop()
Disable this component's loop.
Fixed-capacity vector - allocates once at runtime, never reallocates This avoids std::vector template...
Definition helpers.h:184
FixedVector< std::array< float, 3 > > linear_functions_
Definition filter.h:496
optional< float > new_value(float value) override
Definition filter.cpp:420
CalibrateLinearFilter(std::initializer_list< std::array< float, 3 > > linear_functions)
Definition filter.cpp:417
CalibratePolynomialFilter(std::initializer_list< float > coefficients)
Definition filter.cpp:428
optional< float > new_value(float value) override
Definition filter.cpp:431
ClampFilter(float min, float max, bool ignore_out_of_range)
Definition filter.cpp:441
optional< float > new_value(float value) override
Definition filter.cpp:443
optional< float > new_value(float value) override
Definition filter.cpp:381
float get_setup_priority() const override
Definition filter.cpp:388
DebounceFilter(uint32_t time_period)
Definition filter.cpp:387
DeltaFilter(float delta, bool percentage_mode)
Definition filter.cpp:295
optional< float > new_value(float value) override
Definition filter.cpp:297
Simple exponential moving average filter.
Definition filter.h:239
optional< float > new_value(float value) override
Definition filter.cpp:158
ExponentialMovingAverageFilter(float alpha, size_t send_every, size_t send_first_at)
Definition filter.cpp:156
Apply a filter to sensor values such as moving average.
Definition filter.h:20
virtual optional< float > new_value(float value)=0
This will be called every time the filter receives a new value.
void output(float value)
Definition filter.cpp:20
virtual void initialize(Sensor *parent, Filter *next)
Initialize this filter, please note this can be called more than once.
Definition filter.cpp:29
void input(float value)
Definition filter.cpp:14
A simple filter that only forwards the filter chain if it doesn't receive value_to_filter_out.
Definition filter.h:352
optional< float > new_value(float value) override
Definition filter.cpp:261
FilterOutValueFilter(std::initializer_list< TemplatableValue< float > > values_to_filter_out)
Definition filter.cpp:258
HeartbeatFilter(uint32_t time_period)
Definition filter.cpp:391
optional< float > new_value(float value) override
Definition filter.cpp:393
void set_optimistic(bool optimistic)
Definition filter.h:445
float get_setup_priority() const override
Definition filter.cpp:415
This class allows for creation of simple template filters.
Definition filter.h:286
const lambda_filter_t & get_lambda_filter() const
Definition filter.cpp:212
LambdaFilter(lambda_filter_t lambda_filter)
Definition filter.cpp:211
lambda_filter_t lambda_filter_
Definition filter.h:296
void set_lambda_filter(const lambda_filter_t &lambda_filter)
Definition filter.cpp:213
optional< float > new_value(float value) override
Definition filter.cpp:215
Simple max filter.
Definition filter.h:197
float compute_result() override
Definition filter.cpp:139
Simple median filter.
Definition filter.h:139
float compute_result() override
Definition filter.cpp:83
Simple min filter.
Definition filter.h:177
float compute_result() override
Definition filter.cpp:136
Base class for Min/Max filters.
Definition filter.h:76
float find_extremum_()
Helper to find min or max value in window, skipping NaN values Usage: find_extremum_<std::less<float>...
Definition filter.h:83
A simple filter that multiplies to each value it receives by multiplier.
Definition filter.h:326
optional< float > new_value(float value) override
Definition filter.cpp:229
MultiplyFilter(TemplatableValue< float > multiplier)
Definition filter.cpp:227
TemplatableValue< float > multiplier_
Definition filter.h:332
A simple filter that adds offset to each value it receives.
Definition filter.h:315
optional< float > new_value(float value) override
Definition filter.cpp:224
OffsetFilter(TemplatableValue< float > offset)
Definition filter.cpp:222
TemplatableValue< float > offset_
Definition filter.h:322
optional< float > new_value(float value) override
Definition filter.cpp:319
PhiNode(OrFilter *or_parent)
Definition filter.cpp:317
OrFilter(std::initializer_list< Filter * > filters)
Definition filter.cpp:316
optional< float > new_value(float value) override
Definition filter.cpp:327
void initialize(Sensor *parent, Filter *next) override
Definition filter.cpp:334
FixedVector< Filter * > filters_
Definition filter.h:485
Simple quantile filter.
Definition filter.h:115
float compute_result() override
Definition filter.cpp:122
void set_quantile(float quantile)
Definition filter.h:128
QuantileFilter(size_t window_size, size_t send_every, size_t send_first_at, float quantile)
Construct a QuantileFilter.
Definition filter.cpp:119
RoundFilter(uint8_t precision)
Definition filter.cpp:464
optional< float > new_value(float value) override
Definition filter.cpp:465
optional< float > new_value(float value) override
Definition filter.cpp:474
Base-class for all sensors.
Definition sensor.h:43
SkipInitialFilter(size_t num_to_ignore)
Construct a SkipInitialFilter.
Definition filter.cpp:106
optional< float > new_value(float value) override
Definition filter.cpp:107
Base class for filters that use a sliding window of values.
Definition filter.h:52
size_t window_head_
Index where next value will be written.
Definition filter.h:65
size_t window_size_
Maximum window size.
Definition filter.h:67
optional< float > new_value(float value) final
Definition filter.cpp:42
size_t window_count_
Number of valid values in window (0 to window_size_)
Definition filter.h:66
FixedVector< float > window_
Access the sliding window values (ring buffer implementation) Use: for (size_t i = 0; i < window_coun...
Definition filter.h:64
size_t send_at_
Counter for send_every.
Definition filter.h:69
size_t send_every_
Send result every N values.
Definition filter.h:68
virtual float compute_result()=0
Called by new_value() to compute the filtered result from the current window.
SlidingWindowFilter(size_t window_size, size_t send_every, size_t send_first_at)
Definition filter.cpp:36
Simple sliding window moving average filter.
Definition filter.h:218
Base class for filters that need a sorted window (Median, Quantile).
Definition filter.h:101
FixedVector< float > get_window_values_()
Helper to get non-NaN values from the window (not sorted - caller will use nth_element) Returns empty...
Definition filter.cpp:68
Optimized lambda filter for stateless lambdas (no capture).
Definition filter.h:304
optional< float >(* lambda_filter_)(float)
Definition filter.h:311
optional< float > new_value(float value) override
Definition filter.h:308
StatelessLambdaFilter(optional< float >(*lambda_filter)(float))
Definition filter.h:306
Base class for streaming filters (batch windows where window_size == send_every).
Definition filter.h:564
virtual void process_value(float value)=0
Called by new_value() to process each value in the batch.
virtual float compute_batch_result()=0
Called by new_value() to compute the result after collecting window_size values.
StreamingFilter(size_t window_size, size_t send_first_at)
Definition filter.cpp:505
virtual void reset_batch()=0
Called by new_value() to reset internal state after sending a result.
optional< float > new_value(float value) final
Definition filter.cpp:508
Streaming max filter for batch windows (window_size == send_every).
Definition filter.h:606
void process_value(float value) override
Definition filter.cpp:548
float compute_batch_result() override
Definition filter.cpp:555
Streaming min filter for batch windows (window_size == send_every).
Definition filter.h:590
float compute_batch_result() override
Definition filter.cpp:543
void process_value(float value) override
Definition filter.cpp:536
Streaming moving average filter for batch windows (window_size == send_every).
Definition filter.h:622
void process_value(float value) override
Definition filter.cpp:560
Simple throttle average filter.
Definition filter.h:260
optional< float > new_value(float value) override
Definition filter.cpp:184
ThrottleAverageFilter(uint32_t time_period)
Definition filter.cpp:182
float get_setup_priority() const override
Definition filter.cpp:208
ThrottleFilter(uint32_t min_time_between_inputs)
Definition filter.cpp:268
optional< float > new_value(float value) override
Definition filter.cpp:269
Same as 'throttle' but will immediately publish values contained in value_to_prioritize.
Definition filter.h:371
optional< float > new_value(float value) override
Definition filter.cpp:283
ThrottleWithPriorityFilter(uint32_t min_time_between_inputs, std::initializer_list< TemplatableValue< float > > prioritized_values)
Definition filter.cpp:279
TimeoutFilterBase(uint32_t time_period)
Definition filter.h:390
float get_setup_priority() const override
Definition filter.cpp:356
TemplatableValue< float > value_
Definition filter.h:421
TimeoutFilterConfigured(uint32_t time_period, const TemplatableValue< float > &new_value)
Definition filter.h:414
optional< float > new_value(float value) override
Definition filter.cpp:371
float get_output_value() override
Definition filter.h:406
TimeoutFilterLast(uint32_t time_period)
Definition filter.h:401
optional< float > new_value(float value) override
Definition filter.cpp:359
optional< float > new_value(float value) override
Definition filter.cpp:481
ToNTCResistanceFilter(double a, double b, double c)
Definition filter.h:539
optional< float > new_value(float value) override
Definition filter.cpp:494
ToNTCTemperatureFilter(double a, double b, double c)
Definition filter.h:550
Base class for filters that compare sensor values against a list of configured values.
Definition filter.h:341
ValueListFilter(std::initializer_list< TemplatableValue< float > > values)
Definition filter.cpp:232
FixedVector< TemplatableValue< float > > values_
Definition filter.h:348
bool value_matches_any_(float sensor_value)
Check if sensor value matches any configured value (with accuracy rounding)
Definition filter.cpp:234
std::function< optional< float >(float)> lambda_filter_t
Definition filter.h:277
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7