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