ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
filter.h
Go to the documentation of this file.
1#pragma once
2
4#ifdef USE_SENSOR_FILTER
5
6#include <array>
7#include <utility>
8#include <vector>
12
13namespace esphome::sensor {
14
15class Sensor;
16
22class Filter {
23 public:
33 virtual optional<float> new_value(float value) = 0;
34
36 virtual void initialize(Sensor *parent, Filter *next);
37
38 void input(float value);
39
40 void output(float value);
41
42 protected:
43 friend Sensor;
44
45 Filter *next_{nullptr};
46 Sensor *parent_{nullptr};
47};
48
55 public:
56 SlidingWindowFilter(uint16_t window_size, uint16_t send_every, uint16_t send_first_at);
57
58 optional<float> new_value(float value) final;
59
60 protected:
62 virtual float compute_result() = 0;
63
66 uint16_t send_every_;
67 uint16_t send_at_;
68};
69
75 public:
77
78 protected:
81 template<typename Compare> float find_extremum_() {
82 float result = NAN;
83 Compare comp;
84 for (float v : this->window_) {
85 if (!std::isnan(v)) {
86 result = std::isnan(result) ? v : (comp(v, result) ? v : result);
87 }
88 }
89 return result;
90 }
91};
92
107
113 public:
123 explicit QuantileFilter(size_t window_size, size_t send_every, size_t send_first_at, float quantile);
124
125 void set_quantile(float quantile) { this->quantile_ = quantile; }
126
127 protected:
128 float compute_result() override;
130};
131
137 public:
146 using SortedWindowFilter::SortedWindowFilter;
147
148 protected:
149 float compute_result() override;
150};
151
156class SkipInitialFilter : public Filter {
157 public:
162 explicit SkipInitialFilter(size_t num_to_ignore);
163
164 optional<float> new_value(float value) override;
165
166 protected:
168};
169
174class MinFilter : public MinMaxFilter {
175 public:
184 using MinMaxFilter::MinMaxFilter;
185
186 protected:
187 float compute_result() override;
188};
189
194class MaxFilter : public MinMaxFilter {
195 public:
204 using MinMaxFilter::MinMaxFilter;
205
206 protected:
207 float compute_result() override;
208};
209
216 public:
226
227 protected:
228 float compute_result() override;
229};
230
237 public:
238 ExponentialMovingAverageFilter(float alpha, uint16_t send_every, uint16_t send_first_at);
239
240 optional<float> new_value(float value) override;
241
242 void set_send_every(uint16_t send_every);
243 void set_alpha(float alpha);
244
245 protected:
246 float accumulator_{NAN};
247 float alpha_;
248 uint16_t send_every_;
249 uint16_t send_at_;
250 bool first_value_{true};
251};
252
258 public:
259 explicit ThrottleAverageFilter(uint32_t time_period);
260
261 void initialize(Sensor *parent, Filter *next) override;
262
263 optional<float> new_value(float value) override;
264
265 protected:
266 float sum_{0.0f};
268 // Sample count packed with NaN-seen flag in a single 32-bit word.
269 // n_ is bounded by YAML cap on time_period_ (24 h) × max plausible source
270 // rate (1 kHz) = 86.4M ≪ 2^31, so 31 bits has 25x headroom.
271 uint32_t n_ : 31 {0};
273};
274
275using lambda_filter_t = std::function<optional<float>(float)>;
276
284class LambdaFilter : public Filter {
285 public:
286 explicit LambdaFilter(lambda_filter_t lambda_filter);
287
288 optional<float> new_value(float value) override;
289
290 const lambda_filter_t &get_lambda_filter() const;
291 void set_lambda_filter(const lambda_filter_t &lambda_filter);
292
293 protected:
295};
296
303 public:
304 explicit StatelessLambdaFilter(optional<float> (*lambda_filter)(float)) : lambda_filter_(lambda_filter) {}
305
306 optional<float> new_value(float value) override { return this->lambda_filter_(value); }
307
308 protected:
309 optional<float> (*lambda_filter_)(float);
310};
311
313class OffsetFilter : public Filter {
314 public:
315 explicit OffsetFilter(TemplatableFn<float> offset);
316
317 optional<float> new_value(float value) override;
318
319 protected:
321};
322
324class MultiplyFilter : public Filter {
325 public:
326 explicit MultiplyFilter(TemplatableFn<float> multiplier);
327 optional<float> new_value(float value) override;
328
329 protected:
331};
332
334bool value_list_matches_any(Sensor *parent, float sensor_value, const TemplatableFn<float> *values, size_t count);
335
344template<size_t N> class ValueListFilter : public Filter {
345 protected:
346 explicit ValueListFilter(std::initializer_list<TemplatableFn<float>> values) {
347 init_array_from(this->values_, values);
348 }
349
351 bool value_matches_any_(float sensor_value) {
352 return value_list_matches_any(this->parent_, sensor_value, this->values_.data(), N);
353 }
354
355 std::array<TemplatableFn<float>, N> values_{};
356};
357
359template<size_t N> class FilterOutValueFilter : public ValueListFilter<N> {
360 public:
361 explicit FilterOutValueFilter(std::initializer_list<TemplatableFn<float>> values_to_filter_out)
362 : ValueListFilter<N>(values_to_filter_out) {}
363
364 optional<float> new_value(float value) override {
365 if (this->value_matches_any_(value))
366 return {}; // Filter out
367 return value; // Pass through
368 }
369};
370
371class ThrottleFilter : public Filter {
372 public:
373 explicit ThrottleFilter(uint32_t min_time_between_inputs);
374
375 optional<float> new_value(float value) override;
376
377 protected:
380};
381
383optional<float> throttle_with_priority_new_value(Sensor *parent, float value, const TemplatableFn<float> *values,
384 size_t count, uint32_t &last_input, uint32_t min_time_between_inputs);
385
387template<size_t N> class ThrottleWithPriorityFilter : public ValueListFilter<N> {
388 public:
389 explicit ThrottleWithPriorityFilter(uint32_t min_time_between_inputs,
390 std::initializer_list<TemplatableFn<float>> prioritized_values)
391 : ValueListFilter<N>(prioritized_values), min_time_between_inputs_(min_time_between_inputs) {}
392
393 optional<float> new_value(float value) override {
394 return throttle_with_priority_new_value(this->parent_, value, this->values_.data(), N, this->last_input_,
395 this->min_time_between_inputs_);
396 }
397
398 protected:
401};
402
406 public:
407 explicit ThrottleWithPriorityNanFilter(uint32_t min_time_between_inputs);
408
409 optional<float> new_value(float value) override;
410
411 protected:
414};
415
416// Base class for timeout filters - contains common loop logic.
417//
418// Why this intentionally inherits Component (and does NOT use the self-keyed
419// `App.scheduler.set_timeout(this, ...)` pattern that the other Filter classes
420// migrated to):
421//
422// Timeout filters re-arm on every input, so on devices with many sensors
423// using timeout filters (e.g. multi-LD2450 boards) every armed filter would
424// require a live SchedulerItem in RAM at the same time. A SchedulerItem is
425// substantially larger than the Component bookkeeping bytes carried by this
426// class, so paying the Component cost per filter (one-time, BSS) is cheaper
427// than paying for a SchedulerItem per filter (live, while armed). #11922
428// is the original symptom and switchover to the loop-based design; #16173
429// attempted to migrate this onto the scheduler and was closed for exactly
430// this reason — even if the scheduler pool were unbounded, RAM per armed
431// filter would still be dominated by the SchedulerItem itself, not by
432// anything we can shrink in the scheduler.
433//
434// The loop-based design has additional advantages on top of the RAM win:
435// `enable_loop()` / `disable_loop()` partitions the cost away when no
436// timeout is armed; while armed, work is a single timestamp compare per
437// active filter, with no per-input scheduler cancel/insert path.
438//
439// Don't try to migrate this class onto the self-keyed scheduler. The math
440// doesn't work — at scale, this design is the smaller one.
441class TimeoutFilterBase : public Filter, public Component {
442 public:
443 void loop() override;
444 float get_setup_priority() const override;
445
446 protected:
447 explicit TimeoutFilterBase(uint32_t time_period) : time_period_(time_period) { this->disable_loop(); }
448 virtual float get_output_value() = 0;
449
450 uint32_t time_period_; // 4 bytes (timeout duration in ms)
451 uint32_t timeout_start_time_{0}; // 4 bytes (when the timeout was started)
452 // Total base: 8 bytes
453};
454
455// Timeout filter for "last" mode - outputs the last received value after timeout
457 public:
458 explicit TimeoutFilterLast(uint32_t time_period) : TimeoutFilterBase(time_period) {}
459
460 optional<float> new_value(float value) override;
461
462 protected:
463 float get_output_value() override { return this->pending_value_; }
464 float pending_value_{0}; // 4 bytes (value to output when timeout fires)
465 // Total: 8 (base) + 4 = 12 bytes + vtable ptr + Component overhead
466};
467
468// Timeout filter with configured value - evaluates TemplatableValue after timeout
470 public:
473
474 optional<float> new_value(float value) override;
475
476 protected:
477 float get_output_value() override { return this->value_.value(); }
478 TemplatableFn<float> value_; // 4 bytes (configured output value, can be lambda)
479 // Total: 8 (base) + 4 = 12 bytes + vtable ptr + Component overhead
480};
481
482class DebounceFilter : public Filter {
483 public:
484 explicit DebounceFilter(uint32_t time_period);
485
486 optional<float> new_value(float value) override;
487
488 protected:
490};
491
492class HeartbeatFilter : public Filter {
493 public:
494 explicit HeartbeatFilter(uint32_t time_period);
495
496 void initialize(Sensor *parent, Filter *next) override;
497 optional<float> new_value(float value) override;
498
499 void set_optimistic(bool optimistic) { this->optimistic_ = optimistic; }
500
501 protected:
504 bool has_value_{false};
505 bool optimistic_{false};
506};
507
508class DeltaFilter : public Filter {
509 public:
510 explicit DeltaFilter(float min_a0, float min_a1, float max_a0, float max_a1);
511
512 void set_baseline(float (*fn)(float));
513
514 optional<float> new_value(float value) override;
515
516 protected:
517 // These values represent linear equations for the min and max values but in practice only one of a0 and a1 will be
518 // non-zero Each limit is calculated as fabs(a0 + value * a1)
519
521 // default baseline is the previous value
522 float (*baseline_)(float) = [](float last_value) { return last_value; };
523
524 float last_value_{NAN};
525};
526
528void or_filter_initialize(Filter **filters, size_t count, Sensor *parent, Filter *phi);
529optional<float> or_filter_new_value(Filter **filters, size_t count, float value, bool &has_value);
530
532template<size_t N> class OrFilter : public Filter {
533 public:
534 explicit OrFilter(std::initializer_list<Filter *> filters) { init_array_from(this->filters_, filters); }
535
536 void initialize(Sensor *parent, Filter *next) override {
537 Filter::initialize(parent, next);
538 or_filter_initialize(this->filters_.data(), N, parent, &this->phi_);
539 }
540
541 optional<float> new_value(float value) override {
542 return or_filter_new_value(this->filters_.data(), N, value, this->has_value_);
543 }
544
545 protected:
546 class PhiNode : public Filter {
547 public:
548 PhiNode(OrFilter *or_parent) : or_parent_(or_parent) {}
549 optional<float> new_value(float value) override {
550 if (!this->or_parent_->has_value_) {
551 this->or_parent_->output(value);
552 this->or_parent_->has_value_ = true;
553 }
554 return {};
555 }
556
557 protected:
559 };
560
561 std::array<Filter *, N> filters_{};
563 bool has_value_{false};
564};
565
567optional<float> calibrate_linear_compute(const std::array<float, 3> *functions, size_t count, float value);
568
570template<size_t N> class CalibrateLinearFilter : public Filter {
571 public:
572 explicit CalibrateLinearFilter(std::initializer_list<std::array<float, 3>> linear_functions) {
573 init_array_from(this->linear_functions_, linear_functions);
574 }
575 optional<float> new_value(float value) override {
576 return calibrate_linear_compute(this->linear_functions_.data(), N, value);
577 }
578
579 protected:
580 std::array<std::array<float, 3>, N> linear_functions_{};
581};
582
584optional<float> calibrate_polynomial_compute(const float *coefficients, size_t count, float value);
585
587template<size_t N> class CalibratePolynomialFilter : public Filter {
588 public:
589 explicit CalibratePolynomialFilter(std::initializer_list<float> coefficients) {
590 init_array_from(this->coefficients_, coefficients);
591 }
592 optional<float> new_value(float value) override {
593 return calibrate_polynomial_compute(this->coefficients_.data(), N, value);
594 }
595
596 protected:
597 std::array<float, N> coefficients_{};
598};
599
600class ClampFilter : public Filter {
601 public:
602 ClampFilter(float min, float max, bool ignore_out_of_range);
603 optional<float> new_value(float value) override;
604
605 protected:
606 float min_{NAN};
607 float max_{NAN};
609};
610
611class RoundFilter : public Filter {
612 public:
613 explicit RoundFilter(uint8_t precision);
614 optional<float> new_value(float value) override;
615
616 protected:
617 uint8_t precision_;
618};
619
621 public:
622 explicit RoundMultipleFilter(float multiple);
623 optional<float> new_value(float value) override;
624
625 protected:
627};
628
629template<uint8_t Digits> class RoundSignificantDigitsFilter : public Filter {
630 public:
631 optional<float> new_value(float value) override {
632 if (std::isfinite(value)) {
633 if (value == 0.0f)
634 return 0.0f;
635 float factor = pow10_int(Digits - 1 - ilog10(value));
636 return roundf(value * factor) / factor;
637 }
638 return value;
639 }
640};
641
643 public:
644 ToNTCResistanceFilter(double a, double b, double c) : a_(a), b_(b), c_(c) {}
645 optional<float> new_value(float value) override;
646
647 protected:
648 double a_;
649 double b_;
650 double c_;
651};
652
654 public:
655 ToNTCTemperatureFilter(double a, double b, double c) : a_(a), b_(b), c_(c) {}
656 optional<float> new_value(float value) override;
657
658 protected:
659 double a_;
660 double b_;
661 double c_;
662};
663
669class StreamingFilter : public Filter {
670 public:
671 StreamingFilter(uint16_t window_size, uint16_t send_first_at);
672
673 optional<float> new_value(float value) final;
674
675 protected:
677 virtual void process_value(float value) = 0;
678
680 virtual float compute_batch_result() = 0;
681
683 virtual void reset_batch() = 0;
684
685 uint16_t window_size_;
686 uint16_t count_{0};
688 bool first_send_{true};
689};
690
696 public:
698
699 protected:
700 void process_value(float value) override;
701 float compute_batch_result() override;
702 void reset_batch() override;
703
704 float current_min_{NAN};
705};
706
712 public:
714
715 protected:
716 void process_value(float value) override;
717 float compute_batch_result() override;
718 void reset_batch() override;
719
720 float current_max_{NAN};
721};
722
728 public:
730
731 protected:
732 void process_value(float value) override;
733 float compute_batch_result() override;
734 void reset_batch() override;
735
736 float sum_{0.0f};
737 size_t valid_count_{0};
738};
739
740} // namespace esphome::sensor
741
742#endif // USE_SENSOR_FILTER
void disable_loop()
Disable this component's loop.
Fixed-capacity circular buffer - allocates once at runtime, never reallocates.
Definition helpers.h:390
Fixed-capacity vector - allocates once at runtime, never reallocates This avoids std::vector template...
Definition helpers.h:529
Function-pointer-only templatable storage (4 bytes on 32-bit).
Definition automation.h:19
T value(X... x) const
Definition automation.h:58
N is set by code generation to match the exact number of calibration segments.
Definition filter.h:570
CalibrateLinearFilter(std::initializer_list< std::array< float, 3 > > linear_functions)
Definition filter.h:572
std::array< std::array< float, 3 >, N > linear_functions_
Definition filter.h:580
optional< float > new_value(float value) override
Definition filter.h:575
N is set by code generation to match the exact number of polynomial coefficients.
Definition filter.h:587
optional< float > new_value(float value) override
Definition filter.h:592
CalibratePolynomialFilter(std::initializer_list< float > coefficients)
Definition filter.h:589
std::array< float, N > coefficients_
Definition filter.h:597
ClampFilter(float min, float max, bool ignore_out_of_range)
Definition filter.cpp:411
optional< float > new_value(float value) override
Definition filter.cpp:413
optional< float > new_value(float value) override
Definition filter.cpp:359
DebounceFilter(uint32_t time_period)
Definition filter.cpp:365
void set_baseline(float(*fn)(float))
Definition filter.cpp:283
DeltaFilter(float min_a0, float min_a1, float max_a0, float max_a1)
Definition filter.cpp:280
optional< float > new_value(float value) override
Definition filter.cpp:285
float(* baseline_)(float)
Definition filter.h:522
Simple exponential moving average filter.
Definition filter.h:236
optional< float > new_value(float value) override
Definition filter.cpp:147
ExponentialMovingAverageFilter(float alpha, uint16_t send_every, uint16_t send_first_at)
Definition filter.cpp:145
Apply a filter to sensor values such as moving average.
Definition filter.h:22
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:23
virtual void initialize(Sensor *parent, Filter *next)
Initialize this filter, please note this can be called more than once.
Definition filter.cpp:32
void input(float value)
Definition filter.cpp:17
A simple filter that only forwards the filter chain if it doesn't receive value_to_filter_out.
Definition filter.h:359
FilterOutValueFilter(std::initializer_list< TemplatableFn< float > > values_to_filter_out)
Definition filter.h:361
optional< float > new_value(float value) override
Definition filter.h:364
HeartbeatFilter(uint32_t time_period)
Definition filter.cpp:368
optional< float > new_value(float value) override
Definition filter.cpp:370
void initialize(Sensor *parent, Filter *next) override
Definition filter.cpp:381
void set_optimistic(bool optimistic)
Definition filter.h:499
This class allows for creation of simple template filters.
Definition filter.h:284
const lambda_filter_t & get_lambda_filter() const
Definition filter.cpp:201
LambdaFilter(lambda_filter_t lambda_filter)
Definition filter.cpp:200
lambda_filter_t lambda_filter_
Definition filter.h:294
void set_lambda_filter(const lambda_filter_t &lambda_filter)
Definition filter.cpp:202
optional< float > new_value(float value) override
Definition filter.cpp:204
Simple max filter.
Definition filter.h:194
float compute_result() override
Definition filter.cpp:129
Simple median filter.
Definition filter.h:136
float compute_result() override
Definition filter.cpp:73
Simple min filter.
Definition filter.h:174
float compute_result() override
Definition filter.cpp:126
Base class for Min/Max filters.
Definition filter.h:74
float find_extremum_()
Helper to find min or max value in window, skipping NaN values Usage: find_extremum_<std::less<float>...
Definition filter.h:81
A simple filter that multiplies to each value it receives by multiplier.
Definition filter.h:324
TemplatableFn< float > multiplier_
Definition filter.h:330
optional< float > new_value(float value) override
Definition filter.cpp:218
MultiplyFilter(TemplatableFn< float > multiplier)
Definition filter.cpp:216
A simple filter that adds offset to each value it receives.
Definition filter.h:313
optional< float > new_value(float value) override
Definition filter.cpp:213
TemplatableFn< float > offset_
Definition filter.h:320
OffsetFilter(TemplatableFn< float > offset)
Definition filter.cpp:211
optional< float > new_value(float value) override
Definition filter.h:549
PhiNode(OrFilter *or_parent)
Definition filter.h:548
N is set by code generation to match the exact number of filters configured in YAML.
Definition filter.h:532
std::array< Filter *, N > filters_
Definition filter.h:561
void initialize(Sensor *parent, Filter *next) override
Definition filter.h:536
optional< float > new_value(float value) override
Definition filter.h:541
OrFilter(std::initializer_list< Filter * > filters)
Definition filter.h:534
Simple quantile filter.
Definition filter.h:112
float compute_result() override
Definition filter.cpp:112
void set_quantile(float quantile)
Definition filter.h:125
QuantileFilter(size_t window_size, size_t send_every, size_t send_first_at, float quantile)
Construct a QuantileFilter.
Definition filter.cpp:109
RoundFilter(uint8_t precision)
Definition filter.cpp:430
optional< float > new_value(float value) override
Definition filter.cpp:431
optional< float > new_value(float value) override
Definition filter.cpp:440
optional< float > new_value(float value) override
Definition filter.h:631
Base-class for all sensors.
Definition sensor.h:47
SkipInitialFilter(size_t num_to_ignore)
Construct a SkipInitialFilter.
Definition filter.cpp:96
optional< float > new_value(float value) override
Definition filter.cpp:97
Base class for filters that use a sliding window of values.
Definition filter.h:54
FixedRingBuffer< float > window_
Sliding window ring buffer - automatically overwrites oldest values when full.
Definition filter.h:65
optional< float > new_value(float value) final
Definition filter.cpp:44
SlidingWindowFilter(uint16_t window_size, uint16_t send_every, uint16_t send_first_at)
Definition filter.cpp:39
uint16_t send_every_
Send result every N values.
Definition filter.h:66
virtual float compute_result()=0
Called by new_value() to compute the filtered result from the current window.
uint16_t send_at_
Counter for send_every.
Definition filter.h:67
Simple sliding window moving average filter.
Definition filter.h:215
Base class for filters that need a sorted window (Median, Quantile).
Definition filter.h:98
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:59
Optimized lambda filter for stateless lambdas (no capture).
Definition filter.h:302
optional< float >(* lambda_filter_)(float)
Definition filter.h:309
optional< float > new_value(float value) override
Definition filter.h:306
StatelessLambdaFilter(optional< float >(*lambda_filter)(float))
Definition filter.h:304
Base class for streaming filters (batch windows where window_size == send_every).
Definition filter.h:669
StreamingFilter(uint16_t window_size, uint16_t send_first_at)
Definition filter.cpp:471
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.
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:474
Streaming max filter for batch windows (window_size == send_every).
Definition filter.h:711
void process_value(float value) override
Definition filter.cpp:514
float compute_batch_result() override
Definition filter.cpp:521
Streaming min filter for batch windows (window_size == send_every).
Definition filter.h:695
float compute_batch_result() override
Definition filter.cpp:509
void process_value(float value) override
Definition filter.cpp:502
Streaming moving average filter for batch windows (window_size == send_every).
Definition filter.h:727
void process_value(float value) override
Definition filter.cpp:526
Simple throttle average filter.
Definition filter.h:257
optional< float > new_value(float value) override
Definition filter.cpp:173
ThrottleAverageFilter(uint32_t time_period)
Definition filter.cpp:171
void initialize(Sensor *parent, Filter *next) override
Definition filter.cpp:183
ThrottleFilter(uint32_t min_time_between_inputs)
Definition filter.cpp:245
optional< float > new_value(float value) override
Definition filter.cpp:246
Same as 'throttle' but will immediately publish values contained in value_to_prioritize.
Definition filter.h:387
optional< float > new_value(float value) override
Definition filter.h:393
ThrottleWithPriorityFilter(uint32_t min_time_between_inputs, std::initializer_list< TemplatableFn< float > > prioritized_values)
Definition filter.h:389
Specialization of ThrottleWithPriorityFilter for the common "prioritize NaN" case: skips the Templata...
Definition filter.h:405
optional< float > new_value(float value) override
Definition filter.cpp:270
ThrottleWithPriorityNanFilter(uint32_t min_time_between_inputs)
Definition filter.cpp:268
TimeoutFilterBase(uint32_t time_period)
Definition filter.h:447
float get_setup_priority() const override
Definition filter.cpp:334
TimeoutFilterConfigured(uint32_t time_period, const TemplatableFn< float > &new_value)
Definition filter.h:471
TemplatableFn< float > value_
Definition filter.h:478
optional< float > new_value(float value) override
Definition filter.cpp:349
float get_output_value() override
Definition filter.h:463
TimeoutFilterLast(uint32_t time_period)
Definition filter.h:458
optional< float > new_value(float value) override
Definition filter.cpp:337
optional< float > new_value(float value) override
Definition filter.cpp:447
ToNTCResistanceFilter(double a, double b, double c)
Definition filter.h:644
optional< float > new_value(float value) override
Definition filter.cpp:460
ToNTCTemperatureFilter(double a, double b, double c)
Definition filter.h:655
Base class for filters that compare sensor values against a fixed list of configured values.
Definition filter.h:344
ValueListFilter(std::initializer_list< TemplatableFn< float > > values)
Definition filter.h:346
bool value_matches_any_(float sensor_value)
Check if sensor value matches any configured value (with accuracy rounding)
Definition filter.h:351
std::array< TemplatableFn< float >, N > values_
Definition filter.h:355
optional< float > throttle_with_priority_new_value(Sensor *parent, float value, const TemplatableFn< float > *values, size_t count, uint32_t &last_input, uint32_t min_time_between_inputs)
Non-template helper for ThrottleWithPriorityFilter (implementation in filter.cpp)
Definition filter.cpp:256
void or_filter_initialize(Filter **filters, size_t count, Sensor *parent, Filter *phi)
Non-template helpers for OrFilter (implementation in filter.cpp)
Definition filter.cpp:306
bool value_list_matches_any(Sensor *parent, float sensor_value, const TemplatableFn< float > *values, size_t count)
Non-template helper for value matching (implementation in filter.cpp)
Definition filter.cpp:221
optional< float > calibrate_polynomial_compute(const float *coefficients, size_t count, float value)
Non-template helper for polynomial calibration (implementation in filter.cpp)
Definition filter.cpp:401
optional< float > calibrate_linear_compute(const std::array< float, 3 > *functions, size_t count, float value)
Non-template helper for linear calibration (implementation in filter.cpp)
Definition filter.cpp:393
std::function< optional< float >(float)> lambda_filter_t
Definition filter.h:275
optional< float > or_filter_new_value(Filter **filters, size_t count, float value, bool &has_value)
Definition filter.cpp:313
int8_t ilog10(float value)
Compute floor(log10(fabs(value))) using iterative comparison.
Definition helpers.cpp:415
void init_array_from(std::array< T, N > &dest, std::initializer_list< T > src)
Initialize a std::array from an initializer_list.
Definition helpers.h:512
float pow10_int(int8_t exp)
Compute 10^exp using iterative multiplication/division.
Definition helpers.h:752
static void uint32_t