ESPHome 2026.5.0-dev
Loading...
Searching...
No Matches
filter.cpp
Go to the documentation of this file.
2#ifdef USE_BINARY_SENSOR_FILTER
3
4#include "filter.h"
5
6#include "binary_sensor.h"
7
9
10static const char *const TAG = "sensor.filter";
11
12// Timeout IDs for filter classes.
13// Each filter is its own Component instance, so the scheduler scopes
14// IDs by component pointer — no risk of collisions between instances.
16// AutorepeatFilter needs two distinct IDs (both timeouts on the same component)
19
20void Filter::output(bool value) {
21 if (this->next_ == nullptr) {
22 this->parent_->send_state_internal(value);
23 } else {
24 this->next_->input(value);
25 }
26}
27void Filter::input(bool value) {
28 if (!this->dedup_.next(value))
29 return;
30 auto b = this->new_value(value);
31 if (b.has_value()) {
32 this->output(*b);
33 }
34}
35
36void TimeoutFilter::input(bool value) {
37 this->set_timeout(FILTER_TIMEOUT_ID, this->timeout_delay_.value(), [this]() { this->parent_->invalidate_state(); });
38 // we do not de-dup here otherwise changes from invalid to valid state will not be output
39 this->output(value);
40}
41
42optional<bool> DelayedOnOffFilter::new_value(bool value) {
43 if (value) {
44 this->set_timeout(FILTER_TIMEOUT_ID, this->on_delay_.value(), [this]() { this->output(true); });
45 } else {
46 this->set_timeout(FILTER_TIMEOUT_ID, this->off_delay_.value(), [this]() { this->output(false); });
47 }
48 return {};
49}
50
52
53optional<bool> DelayedOnFilter::new_value(bool value) {
54 if (value) {
55 this->set_timeout(FILTER_TIMEOUT_ID, this->delay_.value(), [this]() { this->output(true); });
56 return {};
57 } else {
58 this->cancel_timeout(FILTER_TIMEOUT_ID);
59 return false;
60 }
61}
62
64
65optional<bool> DelayedOffFilter::new_value(bool value) {
66 if (!value) {
67 this->set_timeout(FILTER_TIMEOUT_ID, this->delay_.value(), [this]() { this->output(false); });
68 return {};
69 } else {
70 this->cancel_timeout(FILTER_TIMEOUT_ID);
71 return true;
72 }
73}
74
76
77optional<bool> InvertFilter::new_value(bool value) { return !value; }
78
79// AutorepeatFilterBase
80optional<bool> AutorepeatFilterBase::new_value(bool value) {
81 if (value) {
82 if (this->active_timing_ != 0)
83 return {};
84 this->next_timing_();
85 return true;
86 } else {
87 this->cancel_timeout(AUTOREPEAT_TIMING_ID);
88 this->cancel_timeout(AUTOREPEAT_ON_OFF_ID);
89 this->active_timing_ = 0;
90 return false;
91 }
92}
93
96 this->set_timeout(AUTOREPEAT_TIMING_ID, this->timings_[this->active_timing_].delay,
97 [this]() { this->next_timing_(); });
98 }
99 if (this->active_timing_ <= this->timings_count_) {
100 this->active_timing_++;
101 }
102 if (this->active_timing_ == 2)
103 this->next_value_(false);
104}
105
107 const AutorepeatFilterTiming &timing = this->timings_[this->active_timing_ - 2];
108 this->output(val);
109 this->set_timeout(AUTOREPEAT_ON_OFF_ID, val ? timing.time_on : timing.time_off,
110 [this, val]() { this->next_value_(!val); });
111}
112
114
115LambdaFilter::LambdaFilter(std::function<optional<bool>(bool)> f) : f_(std::move(f)) {}
116
117optional<bool> LambdaFilter::new_value(bool value) { return this->f_(value); }
118
119optional<bool> SettleFilter::new_value(bool value) {
120 if (!this->steady_) {
121 this->set_timeout(FILTER_TIMEOUT_ID, this->delay_.value(), [this, value]() {
122 this->steady_ = true;
123 this->output(value);
124 });
125 return {};
126 } else {
127 this->steady_ = false;
128 this->set_timeout(FILTER_TIMEOUT_ID, this->delay_.value(), [this]() { this->steady_ = true; });
129 return value;
130 }
131}
132
134
135} // namespace esphome::binary_sensor
136
137#endif // USE_BINARY_SENSOR_FILTER
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") void set_timeout(const std voi set_timeout)(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition component.h:510
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") bool cancel_timeout(const std boo cancel_timeout)(const char *name)
Cancel a timeout function.
Definition component.h:532
bool next(T value)
Feeds the next item in the series to the deduplicator and returns false if this is a duplicate.
Definition helpers.h:1988
T value(X... x) const
Definition automation.h:79
optional< bool > new_value(bool value) override
Definition filter.cpp:80
float get_setup_priority() const override
Definition filter.cpp:113
const AutorepeatFilterTiming * timings_
Definition filter.h:105
void send_state_internal(bool new_state)
float get_setup_priority() const override
Definition filter.cpp:75
optional< bool > new_value(bool value) override
Definition filter.cpp:65
TemplatableFn< uint32_t > delay_
Definition filter.h:77
optional< bool > new_value(bool value) override
Definition filter.cpp:53
TemplatableFn< uint32_t > delay_
Definition filter.h:65
float get_setup_priority() const override
Definition filter.cpp:63
TemplatableFn< uint32_t > on_delay_
Definition filter.h:52
TemplatableFn< uint32_t > off_delay_
Definition filter.h:53
float get_setup_priority() const override
Definition filter.cpp:51
optional< bool > new_value(bool value) override
Definition filter.cpp:42
virtual void input(bool value)
Definition filter.cpp:27
virtual optional< bool > new_value(bool value)=0
Deduplicator< bool > dedup_
Definition filter.h:29
void output(bool value)
Definition filter.cpp:20
optional< bool > new_value(bool value) override
Definition filter.cpp:77
LambdaFilter(std::function< optional< bool >(bool)> f)
Definition filter.cpp:115
std::function< optional< bool >(bool)> f_
Definition filter.h:131
optional< bool > new_value(bool value) override
Definition filter.cpp:117
TemplatableFn< uint32_t > delay_
Definition filter.h:158
float get_setup_priority() const override
Definition filter.cpp:133
optional< bool > new_value(bool value) override
Definition filter.cpp:119
TemplatableFn< uint32_t > timeout_delay_
Definition filter.h:39
void input(bool value) override
Definition filter.cpp:36
mopeka_std_values val[3]
constexpr uint32_t AUTOREPEAT_TIMING_ID
Definition filter.cpp:17
constexpr uint32_t AUTOREPEAT_ON_OFF_ID
Definition filter.cpp:18
constexpr uint32_t FILTER_TIMEOUT_ID
Definition filter.cpp:15
constexpr float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition component.h:40
void HOT delay(uint32_t ms)
Definition core.cpp:28
static void uint32_t