ESPHome 2025.12.2
Loading...
Searching...
No Matches
filter.cpp
Go to the documentation of this file.
1#include "filter.h"
2
3#include "binary_sensor.h"
4
6
7static const char *const TAG = "sensor.filter";
8
9void Filter::output(bool value) {
10 if (this->next_ == nullptr) {
11 this->parent_->send_state_internal(value);
12 } else {
13 this->next_->input(value);
14 }
15}
16void Filter::input(bool value) {
17 if (!this->dedup_.next(value))
18 return;
19 auto b = this->new_value(value);
20 if (b.has_value()) {
21 this->output(*b);
22 }
23}
24
25void TimeoutFilter::input(bool value) {
26 this->set_timeout("timeout", this->timeout_delay_.value(), [this]() { this->parent_->invalidate_state(); });
27 // we do not de-dup here otherwise changes from invalid to valid state will not be output
28 this->output(value);
29}
30
32 if (value) {
33 this->set_timeout("ON_OFF", this->on_delay_.value(), [this]() { this->output(true); });
34 } else {
35 this->set_timeout("ON_OFF", this->off_delay_.value(), [this]() { this->output(false); });
36 }
37 return {};
38}
39
41
43 if (value) {
44 this->set_timeout("ON", this->delay_.value(), [this]() { this->output(true); });
45 return {};
46 } else {
47 this->cancel_timeout("ON");
48 return false;
49 }
50}
51
53
55 if (!value) {
56 this->set_timeout("OFF", this->delay_.value(), [this]() { this->output(false); });
57 return {};
58 } else {
59 this->cancel_timeout("OFF");
60 return true;
61 }
62}
63
65
66optional<bool> InvertFilter::new_value(bool value) { return !value; }
67
68AutorepeatFilter::AutorepeatFilter(std::initializer_list<AutorepeatFilterTiming> timings) : timings_(timings) {}
69
71 if (value) {
72 // Ignore if already running
73 if (this->active_timing_ != 0)
74 return {};
75
76 this->next_timing_();
77 return true;
78 } else {
79 this->cancel_timeout("TIMING");
80 this->cancel_timeout("ON_OFF");
81 this->active_timing_ = 0;
82 return false;
83 }
84}
85
87 // Entering this method
88 // 1st time: starts waiting the first delay
89 // 2nd time: starts waiting the second delay and starts toggling with the first time_off / _on
90 // last time: no delay to start but have to bump the index to reflect the last
91 if (this->active_timing_ < this->timings_.size())
92 this->set_timeout("TIMING", this->timings_[this->active_timing_].delay, [this]() { this->next_timing_(); });
93
94 if (this->active_timing_ <= this->timings_.size()) {
95 this->active_timing_++;
96 }
97
98 if (this->active_timing_ == 2)
99 this->next_value_(false);
100
101 // Leaving this method: if the toggling is started, it has to use [active_timing_ - 2] for the intervals
102}
103
105 const AutorepeatFilterTiming &timing = this->timings_[this->active_timing_ - 2];
106 this->output(val); // This is at least the second one so not initial
107 this->set_timeout("ON_OFF", val ? timing.time_on : timing.time_off, [this, val]() { this->next_value_(!val); });
108}
109
111
112LambdaFilter::LambdaFilter(std::function<optional<bool>(bool)> f) : f_(std::move(f)) {}
113
114optional<bool> LambdaFilter::new_value(bool value) { return this->f_(value); }
115
117 if (!this->steady_) {
118 this->set_timeout("SETTLE", this->delay_.value(), [this, value]() {
119 this->steady_ = true;
120 this->output(value);
121 });
122 return {};
123 } else {
124 this->steady_ = false;
125 this->output(value);
126 this->set_timeout("SETTLE", this->delay_.value(), [this]() { this->steady_ = true; });
127 return value;
128 }
129}
130
132
133} // namespace esphome::binary_sensor
bool cancel_timeout(const std::string &name)
Cancel a timeout function.
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
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:907
float get_setup_priority() const override
Definition filter.cpp:110
AutorepeatFilter(std::initializer_list< AutorepeatFilterTiming > timings)
Definition filter.cpp:68
FixedVector< AutorepeatFilterTiming > timings_
Definition filter.h:98
optional< bool > new_value(bool value) override
Definition filter.cpp:70
float get_setup_priority() const override
Definition filter.cpp:64
optional< bool > new_value(bool value) override
Definition filter.cpp:54
TemplatableValue< uint32_t > delay_
Definition filter.h:72
optional< bool > new_value(bool value) override
Definition filter.cpp:42
TemplatableValue< uint32_t > delay_
Definition filter.h:60
float get_setup_priority() const override
Definition filter.cpp:52
TemplatableValue< uint32_t > on_delay_
Definition filter.h:47
float get_setup_priority() const override
Definition filter.cpp:40
optional< bool > new_value(bool value) override
Definition filter.cpp:31
TemplatableValue< uint32_t > off_delay_
Definition filter.h:48
virtual void input(bool value)
Definition filter.cpp:16
virtual optional< bool > new_value(bool value)=0
Deduplicator< bool > dedup_
Definition filter.h:24
void output(bool value)
Definition filter.cpp:9
optional< bool > new_value(bool value) override
Definition filter.cpp:66
LambdaFilter(std::function< optional< bool >(bool)> f)
Definition filter.cpp:112
std::function< optional< bool >(bool)> f_
Definition filter.h:109
optional< bool > new_value(bool value) override
Definition filter.cpp:114
float get_setup_priority() const override
Definition filter.cpp:131
TemplatableValue< uint32_t > delay_
Definition filter.h:136
optional< bool > new_value(bool value) override
Definition filter.cpp:116
void input(bool value) override
Definition filter.cpp:25
TemplatableValue< uint32_t > timeout_delay_
Definition filter.h:34
mopeka_std_values val[4]
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition component.cpp:80
void IRAM_ATTR HOT delay(uint32_t ms)
Definition core.cpp:31