ESPHome 2025.9.0-dev
Loading...
Searching...
No Matches
filter.cpp
Go to the documentation of this file.
1#include "filter.h"
2#include <cmath>
4#include "esphome/core/hal.h"
5#include "esphome/core/log.h"
6#include "sensor.h"
7
8namespace esphome {
9namespace sensor {
10
11static const char *const TAG = "sensor.filter";
12
13// Filter
14void Filter::input(float value) {
15 ESP_LOGVV(TAG, "Filter(%p)::input(%f)", this, value);
16 optional<float> out = this->new_value(value);
17 if (out.has_value())
18 this->output(*out);
19}
20void Filter::output(float value) {
21 if (this->next_ == nullptr) {
22 ESP_LOGVV(TAG, "Filter(%p)::output(%f) -> SENSOR", this, value);
24 } else {
25 ESP_LOGVV(TAG, "Filter(%p)::output(%f) -> %p", this, value, this->next_);
26 this->next_->input(value);
27 }
28}
29void Filter::initialize(Sensor *parent, Filter *next) {
30 ESP_LOGVV(TAG, "Filter(%p)::initialize(parent=%p next=%p)", this, parent, next);
31 this->parent_ = parent;
32 this->next_ = next;
33}
34
35// MedianFilter
36MedianFilter::MedianFilter(size_t window_size, size_t send_every, size_t send_first_at)
37 : send_every_(send_every), send_at_(send_every - send_first_at), window_size_(window_size) {}
38void MedianFilter::set_send_every(size_t send_every) { this->send_every_ = send_every; }
39void MedianFilter::set_window_size(size_t window_size) { this->window_size_ = window_size; }
41 while (this->queue_.size() >= this->window_size_) {
42 this->queue_.pop_front();
43 }
44 this->queue_.push_back(value);
45 ESP_LOGVV(TAG, "MedianFilter(%p)::new_value(%f)", this, value);
46
47 if (++this->send_at_ >= this->send_every_) {
48 this->send_at_ = 0;
49
50 float median = NAN;
51 if (!this->queue_.empty()) {
52 // Copy queue without NaN values
53 std::vector<float> median_queue;
54 median_queue.reserve(this->queue_.size());
55 for (auto v : this->queue_) {
56 if (!std::isnan(v)) {
57 median_queue.push_back(v);
58 }
59 }
60
61 sort(median_queue.begin(), median_queue.end());
62
63 size_t queue_size = median_queue.size();
64 if (queue_size) {
65 if (queue_size % 2) {
66 median = median_queue[queue_size / 2];
67 } else {
68 median = (median_queue[queue_size / 2] + median_queue[(queue_size / 2) - 1]) / 2.0f;
69 }
70 }
71 }
72
73 ESP_LOGVV(TAG, "MedianFilter(%p)::new_value(%f) SENDING %f", this, value, median);
74 return median;
75 }
76 return {};
77}
78
79// SkipInitialFilter
80SkipInitialFilter::SkipInitialFilter(size_t num_to_ignore) : num_to_ignore_(num_to_ignore) {}
82 if (num_to_ignore_ > 0) {
84 ESP_LOGV(TAG, "SkipInitialFilter(%p)::new_value(%f) SKIPPING, %zu left", this, value, num_to_ignore_);
85 return {};
86 }
87
88 ESP_LOGV(TAG, "SkipInitialFilter(%p)::new_value(%f) SENDING", this, value);
89 return value;
90}
91
92// QuantileFilter
93QuantileFilter::QuantileFilter(size_t window_size, size_t send_every, size_t send_first_at, float quantile)
94 : send_every_(send_every), send_at_(send_every - send_first_at), window_size_(window_size), quantile_(quantile) {}
95void QuantileFilter::set_send_every(size_t send_every) { this->send_every_ = send_every; }
96void QuantileFilter::set_window_size(size_t window_size) { this->window_size_ = window_size; }
97void QuantileFilter::set_quantile(float quantile) { this->quantile_ = quantile; }
99 while (this->queue_.size() >= this->window_size_) {
100 this->queue_.pop_front();
101 }
102 this->queue_.push_back(value);
103 ESP_LOGVV(TAG, "QuantileFilter(%p)::new_value(%f), quantile:%f", this, value, this->quantile_);
104
105 if (++this->send_at_ >= this->send_every_) {
106 this->send_at_ = 0;
107
108 float result = NAN;
109 if (!this->queue_.empty()) {
110 // Copy queue without NaN values
111 std::vector<float> quantile_queue;
112 for (auto v : this->queue_) {
113 if (!std::isnan(v)) {
114 quantile_queue.push_back(v);
115 }
116 }
117
118 sort(quantile_queue.begin(), quantile_queue.end());
119
120 size_t queue_size = quantile_queue.size();
121 if (queue_size) {
122 size_t position = ceilf(queue_size * this->quantile_) - 1;
123 ESP_LOGVV(TAG, "QuantileFilter(%p)::position: %zu/%zu", this, position + 1, queue_size);
124 result = quantile_queue[position];
125 }
126 }
127
128 ESP_LOGVV(TAG, "QuantileFilter(%p)::new_value(%f) SENDING %f", this, value, result);
129 return result;
130 }
131 return {};
132}
133
134// MinFilter
135MinFilter::MinFilter(size_t window_size, size_t send_every, size_t send_first_at)
136 : send_every_(send_every), send_at_(send_every - send_first_at), window_size_(window_size) {}
137void MinFilter::set_send_every(size_t send_every) { this->send_every_ = send_every; }
138void MinFilter::set_window_size(size_t window_size) { this->window_size_ = window_size; }
140 while (this->queue_.size() >= this->window_size_) {
141 this->queue_.pop_front();
142 }
143 this->queue_.push_back(value);
144 ESP_LOGVV(TAG, "MinFilter(%p)::new_value(%f)", this, value);
145
146 if (++this->send_at_ >= this->send_every_) {
147 this->send_at_ = 0;
148
149 float min = NAN;
150 for (auto v : this->queue_) {
151 if (!std::isnan(v)) {
152 min = std::isnan(min) ? v : std::min(min, v);
153 }
154 }
155
156 ESP_LOGVV(TAG, "MinFilter(%p)::new_value(%f) SENDING %f", this, value, min);
157 return min;
158 }
159 return {};
160}
161
162// MaxFilter
163MaxFilter::MaxFilter(size_t window_size, size_t send_every, size_t send_first_at)
164 : send_every_(send_every), send_at_(send_every - send_first_at), window_size_(window_size) {}
165void MaxFilter::set_send_every(size_t send_every) { this->send_every_ = send_every; }
166void MaxFilter::set_window_size(size_t window_size) { this->window_size_ = window_size; }
168 while (this->queue_.size() >= this->window_size_) {
169 this->queue_.pop_front();
170 }
171 this->queue_.push_back(value);
172 ESP_LOGVV(TAG, "MaxFilter(%p)::new_value(%f)", this, value);
173
174 if (++this->send_at_ >= this->send_every_) {
175 this->send_at_ = 0;
176
177 float max = NAN;
178 for (auto v : this->queue_) {
179 if (!std::isnan(v)) {
180 max = std::isnan(max) ? v : std::max(max, v);
181 }
182 }
183
184 ESP_LOGVV(TAG, "MaxFilter(%p)::new_value(%f) SENDING %f", this, value, max);
185 return max;
186 }
187 return {};
188}
189
190// SlidingWindowMovingAverageFilter
192 size_t send_first_at)
193 : send_every_(send_every), send_at_(send_every - send_first_at), window_size_(window_size) {}
194void SlidingWindowMovingAverageFilter::set_send_every(size_t send_every) { this->send_every_ = send_every; }
195void SlidingWindowMovingAverageFilter::set_window_size(size_t window_size) { this->window_size_ = window_size; }
197 while (this->queue_.size() >= this->window_size_) {
198 this->queue_.pop_front();
199 }
200 this->queue_.push_back(value);
201 ESP_LOGVV(TAG, "SlidingWindowMovingAverageFilter(%p)::new_value(%f)", this, value);
202
203 if (++this->send_at_ >= this->send_every_) {
204 this->send_at_ = 0;
205
206 float sum = 0;
207 size_t valid_count = 0;
208 for (auto v : this->queue_) {
209 if (!std::isnan(v)) {
210 sum += v;
211 valid_count++;
212 }
213 }
214
215 float average = NAN;
216 if (valid_count) {
217 average = sum / valid_count;
218 }
219
220 ESP_LOGVV(TAG, "SlidingWindowMovingAverageFilter(%p)::new_value(%f) SENDING %f", this, value, average);
221 return average;
222 }
223 return {};
224}
225
226// ExponentialMovingAverageFilter
227ExponentialMovingAverageFilter::ExponentialMovingAverageFilter(float alpha, size_t send_every, size_t send_first_at)
228 : alpha_(alpha), send_every_(send_every), send_at_(send_every - send_first_at) {}
230 if (!std::isnan(value)) {
231 if (this->first_value_) {
232 this->accumulator_ = value;
233 this->first_value_ = false;
234 } else {
235 this->accumulator_ = (this->alpha_ * value) + (1.0f - this->alpha_) * this->accumulator_;
236 }
237 }
238
239 const float average = std::isnan(value) ? value : this->accumulator_;
240 ESP_LOGVV(TAG, "ExponentialMovingAverageFilter(%p)::new_value(%f) -> %f", this, value, average);
241
242 if (++this->send_at_ >= this->send_every_) {
243 ESP_LOGVV(TAG, "ExponentialMovingAverageFilter(%p)::new_value(%f) SENDING %f", this, value, average);
244 this->send_at_ = 0;
245 return average;
246 }
247 return {};
248}
249void ExponentialMovingAverageFilter::set_send_every(size_t send_every) { this->send_every_ = send_every; }
250void ExponentialMovingAverageFilter::set_alpha(float alpha) { this->alpha_ = alpha; }
251
252// ThrottleAverageFilter
253ThrottleAverageFilter::ThrottleAverageFilter(uint32_t time_period) : time_period_(time_period) {}
254
256 ESP_LOGVV(TAG, "ThrottleAverageFilter(%p)::new_value(value=%f)", this, value);
257 if (std::isnan(value)) {
258 this->have_nan_ = true;
259 } else {
260 this->sum_ += value;
261 this->n_++;
262 }
263 return {};
264}
266 this->set_interval("throttle_average", this->time_period_, [this]() {
267 ESP_LOGVV(TAG, "ThrottleAverageFilter(%p)::interval(sum=%f, n=%i)", this, this->sum_, this->n_);
268 if (this->n_ == 0) {
269 if (this->have_nan_)
270 this->output(NAN);
271 } else {
272 this->output(this->sum_ / this->n_);
273 this->sum_ = 0.0f;
274 this->n_ = 0;
275 }
276 this->have_nan_ = false;
277 });
278}
280
281// LambdaFilter
282LambdaFilter::LambdaFilter(lambda_filter_t lambda_filter) : lambda_filter_(std::move(lambda_filter)) {}
284void LambdaFilter::set_lambda_filter(const lambda_filter_t &lambda_filter) { this->lambda_filter_ = lambda_filter; }
285
287 auto it = this->lambda_filter_(value);
288 ESP_LOGVV(TAG, "LambdaFilter(%p)::new_value(%f) -> %f", this, value, it.value_or(INFINITY));
289 return it;
290}
291
292// OffsetFilter
293OffsetFilter::OffsetFilter(TemplatableValue<float> offset) : offset_(std::move(offset)) {}
294
295optional<float> OffsetFilter::new_value(float value) { return value + this->offset_.value(); }
296
297// MultiplyFilter
298MultiplyFilter::MultiplyFilter(TemplatableValue<float> multiplier) : multiplier_(std::move(multiplier)) {}
299
300optional<float> MultiplyFilter::new_value(float value) { return value * this->multiplier_.value(); }
301
302// FilterOutValueFilter
304 : values_to_filter_out_(std::move(values_to_filter_out)) {}
305
307 int8_t accuracy = this->parent_->get_accuracy_decimals();
308 float accuracy_mult = powf(10.0f, accuracy);
309 for (auto filter_value : this->values_to_filter_out_) {
310 if (std::isnan(filter_value.value())) {
311 if (std::isnan(value)) {
312 return {};
313 }
314 continue;
315 }
316 float rounded_filter_out = roundf(accuracy_mult * filter_value.value());
317 float rounded_value = roundf(accuracy_mult * value);
318 if (rounded_filter_out == rounded_value) {
319 return {};
320 }
321 }
322 return value;
323}
324
325// ThrottleFilter
326ThrottleFilter::ThrottleFilter(uint32_t min_time_between_inputs) : min_time_between_inputs_(min_time_between_inputs) {}
328 const uint32_t now = App.get_loop_component_start_time();
329 if (this->last_input_ == 0 || now - this->last_input_ >= min_time_between_inputs_) {
330 this->last_input_ = now;
331 return value;
332 }
333 return {};
334}
335
336// ThrottleWithPriorityFilter
338 std::vector<TemplatableValue<float>> prioritized_values)
339 : min_time_between_inputs_(min_time_between_inputs), prioritized_values_(std::move(prioritized_values)) {}
340
342 bool is_prioritized_value = false;
343 int8_t accuracy = this->parent_->get_accuracy_decimals();
344 float accuracy_mult = powf(10.0f, accuracy);
345 const uint32_t now = App.get_loop_component_start_time();
346 // First, determine if the new value is one of the prioritized values
347 for (auto prioritized_value : this->prioritized_values_) {
348 if (std::isnan(prioritized_value.value())) {
349 if (std::isnan(value)) {
350 is_prioritized_value = true;
351 break;
352 }
353 continue;
354 }
355 float rounded_prioritized_value = roundf(accuracy_mult * prioritized_value.value());
356 float rounded_value = roundf(accuracy_mult * value);
357 if (rounded_prioritized_value == rounded_value) {
358 is_prioritized_value = true;
359 break;
360 }
361 }
362 // Finally, determine if the new value should be throttled and pass it through if not
363 if (this->last_input_ == 0 || now - this->last_input_ >= min_time_between_inputs_ || is_prioritized_value) {
364 this->last_input_ = now;
365 return value;
366 }
367 return {};
368}
369
370// DeltaFilter
371DeltaFilter::DeltaFilter(float delta, bool percentage_mode)
372 : delta_(delta), current_delta_(delta), last_value_(NAN), percentage_mode_(percentage_mode) {}
374 if (std::isnan(value)) {
375 if (std::isnan(this->last_value_)) {
376 return {};
377 } else {
378 return this->last_value_ = value;
379 }
380 }
381 float diff = fabsf(value - this->last_value_);
382 if (std::isnan(this->last_value_) || (diff > 0.0f && diff >= this->current_delta_)) {
383 if (this->percentage_mode_) {
384 this->current_delta_ = fabsf(value * this->delta_);
385 }
386 return this->last_value_ = value;
387 }
388 return {};
389}
390
391// OrFilter
392OrFilter::OrFilter(std::vector<Filter *> filters) : filters_(std::move(filters)), phi_(this) {}
393OrFilter::PhiNode::PhiNode(OrFilter *or_parent) : or_parent_(or_parent) {}
394
396 if (!this->or_parent_->has_value_) {
397 this->or_parent_->output(value);
398 this->or_parent_->has_value_ = true;
399 }
400
401 return {};
402}
404 this->has_value_ = false;
405 for (Filter *filter : this->filters_)
406 filter->input(value);
407
408 return {};
409}
410void OrFilter::initialize(Sensor *parent, Filter *next) {
411 Filter::initialize(parent, next);
412 for (Filter *filter : this->filters_) {
413 filter->initialize(parent, &this->phi_);
414 }
415 this->phi_.initialize(parent, nullptr);
416}
417
418// TimeoutFilter
420 if (this->value_.has_value()) {
421 this->set_timeout("timeout", this->time_period_, [this]() { this->output(this->value_.value().value()); });
422 } else {
423 this->set_timeout("timeout", this->time_period_, [this, value]() { this->output(value); });
424 }
425 return value;
426}
427
428TimeoutFilter::TimeoutFilter(uint32_t time_period) : time_period_(time_period) {}
429TimeoutFilter::TimeoutFilter(uint32_t time_period, const TemplatableValue<float> &new_value)
430 : time_period_(time_period), value_(new_value) {}
432
433// DebounceFilter
435 this->set_timeout("debounce", this->time_period_, [this, value]() { this->output(value); });
436
437 return {};
438}
439
440DebounceFilter::DebounceFilter(uint32_t time_period) : time_period_(time_period) {}
442
443// HeartbeatFilter
444HeartbeatFilter::HeartbeatFilter(uint32_t time_period) : time_period_(time_period), last_input_(NAN) {}
445
447 ESP_LOGVV(TAG, "HeartbeatFilter(%p)::new_value(value=%f)", this, value);
448 this->last_input_ = value;
449 this->has_value_ = true;
450
451 return {};
452}
454 this->set_interval("heartbeat", this->time_period_, [this]() {
455 ESP_LOGVV(TAG, "HeartbeatFilter(%p)::interval(has_value=%s, last_input=%f)", this, YESNO(this->has_value_),
456 this->last_input_);
457 if (!this->has_value_)
458 return;
459
460 this->output(this->last_input_);
461 });
462}
464
466 for (std::array<float, 3> f : this->linear_functions_) {
467 if (!std::isfinite(f[2]) || value < f[2])
468 return (value * f[0]) + f[1];
469 }
470 return NAN;
471}
472
474 float res = 0.0f;
475 float x = 1.0f;
476 for (float coefficient : this->coefficients_) {
477 res += x * coefficient;
478 x *= value;
479 }
480 return res;
481}
482
483ClampFilter::ClampFilter(float min, float max, bool ignore_out_of_range)
484 : min_(min), max_(max), ignore_out_of_range_(ignore_out_of_range) {}
486 if (std::isfinite(value)) {
487 if (std::isfinite(this->min_) && value < this->min_) {
488 if (this->ignore_out_of_range_) {
489 return {};
490 } else {
491 return this->min_;
492 }
493 }
494
495 if (std::isfinite(this->max_) && value > this->max_) {
496 if (this->ignore_out_of_range_) {
497 return {};
498 } else {
499 return this->max_;
500 }
501 }
502 }
503 return value;
504}
505
506RoundFilter::RoundFilter(uint8_t precision) : precision_(precision) {}
508 if (std::isfinite(value)) {
509 float accuracy_mult = powf(10.0f, this->precision_);
510 return roundf(accuracy_mult * value) / accuracy_mult;
511 }
512 return value;
513}
514
515RoundMultipleFilter::RoundMultipleFilter(float multiple) : multiple_(multiple) {}
517 if (std::isfinite(value)) {
518 return value - remainderf(value, this->multiple_);
519 }
520 return value;
521}
522
524 if (!std::isfinite(value)) {
525 return NAN;
526 }
527 double k = 273.15;
528 // https://de.wikipedia.org/wiki/Steinhart-Hart-Gleichung#cite_note-stein2_s4-3
529 double t = value + k;
530 double y = (this->a_ - 1 / (t)) / (2 * this->c_);
531 double x = sqrt(pow(this->b_ / (3 * this->c_), 3) + y * y);
532 double resistance = exp(pow(x - y, 1 / 3.0) - pow(x + y, 1 / 3.0));
533 return resistance;
534}
535
537 if (!std::isfinite(value)) {
538 return NAN;
539 }
540 double lr = log(double(value));
541 double v = this->a_ + this->b_ * lr + this->c_ * lr * lr * lr;
542 double temp = float(1.0 / v - 273.15);
543 return temp;
544}
545
546} // namespace sensor
547} // namespace esphome
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
void set_interval(const std::string &name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a unique name.
Definition component.cpp:89
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
bool has_value() const
Definition optional.h:92
optional< float > new_value(float value) override
Definition filter.cpp:465
std::vector< std::array< float, 3 > > linear_functions_
Definition filter.h:416
optional< float > new_value(float value) override
Definition filter.cpp:473
ClampFilter(float min, float max, bool ignore_out_of_range)
Definition filter.cpp:483
optional< float > new_value(float value) override
Definition filter.cpp:485
optional< float > new_value(float value) override
Definition filter.cpp:434
float get_setup_priority() const override
Definition filter.cpp:441
DebounceFilter(uint32_t time_period)
Definition filter.cpp:440
DeltaFilter(float delta, bool percentage_mode)
Definition filter.cpp:371
optional< float > new_value(float value) override
Definition filter.cpp:373
optional< float > new_value(float value) override
Definition filter.cpp:229
ExponentialMovingAverageFilter(float alpha, size_t send_every, size_t send_first_at)
Definition filter.cpp:227
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
std::vector< TemplatableValue< float > > values_to_filter_out_
Definition filter.h:303
FilterOutValueFilter(std::vector< TemplatableValue< float > > values_to_filter_out)
Definition filter.cpp:303
optional< float > new_value(float value) override
Definition filter.cpp:306
HeartbeatFilter(uint32_t time_period)
Definition filter.cpp:444
optional< float > new_value(float value) override
Definition filter.cpp:446
float get_setup_priority() const override
Definition filter.cpp:463
const lambda_filter_t & get_lambda_filter() const
Definition filter.cpp:283
LambdaFilter(lambda_filter_t lambda_filter)
Definition filter.cpp:282
lambda_filter_t lambda_filter_
Definition filter.h:271
void set_lambda_filter(const lambda_filter_t &lambda_filter)
Definition filter.cpp:284
optional< float > new_value(float value) override
Definition filter.cpp:286
void set_send_every(size_t send_every)
Definition filter.cpp:165
void set_window_size(size_t window_size)
Definition filter.cpp:166
std::deque< float > queue_
Definition filter.h:174
optional< float > new_value(float value) override
Definition filter.cpp:167
MaxFilter(size_t window_size, size_t send_every, size_t send_first_at)
Construct a MaxFilter.
Definition filter.cpp:163
void set_send_every(size_t send_every)
Definition filter.cpp:38
void set_window_size(size_t window_size)
Definition filter.cpp:39
MedianFilter(size_t window_size, size_t send_every, size_t send_first_at)
Construct a MedianFilter.
Definition filter.cpp:36
optional< float > new_value(float value) override
Definition filter.cpp:40
std::deque< float > queue_
Definition filter.h:100
void set_window_size(size_t window_size)
Definition filter.cpp:138
void set_send_every(size_t send_every)
Definition filter.cpp:137
MinFilter(size_t window_size, size_t send_every, size_t send_first_at)
Construct a MinFilter.
Definition filter.cpp:135
std::deque< float > queue_
Definition filter.h:146
optional< float > new_value(float value) override
Definition filter.cpp:139
optional< float > new_value(float value) override
Definition filter.cpp:300
MultiplyFilter(TemplatableValue< float > multiplier)
Definition filter.cpp:298
TemplatableValue< float > multiplier_
Definition filter.h:292
optional< float > new_value(float value) override
Definition filter.cpp:295
OffsetFilter(TemplatableValue< float > offset)
Definition filter.cpp:293
TemplatableValue< float > offset_
Definition filter.h:282
optional< float > new_value(float value) override
Definition filter.cpp:395
PhiNode(OrFilter *or_parent)
Definition filter.cpp:393
std::vector< Filter * > filters_
Definition filter.h:404
optional< float > new_value(float value) override
Definition filter.cpp:403
void initialize(Sensor *parent, Filter *next) override
Definition filter.cpp:410
OrFilter(std::vector< Filter * > filters)
Definition filter.cpp:392
void set_window_size(size_t window_size)
Definition filter.cpp:96
void set_send_every(size_t send_every)
Definition filter.cpp:95
std::deque< float > queue_
Definition filter.h:71
void set_quantile(float quantile)
Definition filter.cpp:97
optional< float > new_value(float value) override
Definition filter.cpp:98
QuantileFilter(size_t window_size, size_t send_every, size_t send_first_at, float quantile)
Construct a QuantileFilter.
Definition filter.cpp:93
RoundFilter(uint8_t precision)
Definition filter.cpp:506
optional< float > new_value(float value) override
Definition filter.cpp:507
optional< float > new_value(float value) override
Definition filter.cpp:516
Base-class for all sensors.
Definition sensor.h:59
void internal_send_state_to_frontend(float state)
Definition sensor.cpp:100
int8_t get_accuracy_decimals()
Get the accuracy in decimals, using the manual override if set.
Definition sensor.cpp:25
SkipInitialFilter(size_t num_to_ignore)
Construct a SkipInitialFilter.
Definition filter.cpp:80
optional< float > new_value(float value) override
Definition filter.cpp:81
optional< float > new_value(float value) override
Definition filter.cpp:196
SlidingWindowMovingAverageFilter(size_t window_size, size_t send_every, size_t send_first_at)
Construct a SlidingWindowMovingAverageFilter.
Definition filter.cpp:191
optional< float > new_value(float value) override
Definition filter.cpp:255
ThrottleAverageFilter(uint32_t time_period)
Definition filter.cpp:253
float get_setup_priority() const override
Definition filter.cpp:279
ThrottleFilter(uint32_t min_time_between_inputs)
Definition filter.cpp:326
optional< float > new_value(float value) override
Definition filter.cpp:327
std::vector< TemplatableValue< float > > prioritized_values_
Definition filter.h:328
ThrottleWithPriorityFilter(uint32_t min_time_between_inputs, std::vector< TemplatableValue< float > > prioritized_values)
Definition filter.cpp:337
optional< float > new_value(float value) override
Definition filter.cpp:341
optional< float > new_value(float value) override
Definition filter.cpp:419
TimeoutFilter(uint32_t time_period)
Definition filter.cpp:428
float get_setup_priority() const override
Definition filter.cpp:431
optional< float > new_value(float value) override
Definition filter.cpp:523
optional< float > new_value(float value) override
Definition filter.cpp:536
float position
Definition cover.h:0
std::function< optional< float >(float)> lambda_filter_t
Definition filter.h:252
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition component.cpp:49
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
Application App
Global storage of Application pointer - only one Application can exist.
uint16_t x
Definition tt21100.cpp:5
uint16_t y
Definition tt21100.cpp:6