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