mirror of
https://github.com/esphome/esphome.git
synced 2025-07-28 14:16:40 +00:00
[binary_sensor] initial state refactor (#8648)
Co-authored-by: Zsombor Welker <flaktack@welker.hu>
This commit is contained in:
parent
8cd62c0308
commit
087ff865a7
@ -15,21 +15,17 @@ void BinarySensor::publish_state(bool state) {
|
|||||||
if (!this->publish_dedup_.next(state))
|
if (!this->publish_dedup_.next(state))
|
||||||
return;
|
return;
|
||||||
if (this->filter_list_ == nullptr) {
|
if (this->filter_list_ == nullptr) {
|
||||||
this->send_state_internal(state, false);
|
this->send_state_internal(state);
|
||||||
} else {
|
} else {
|
||||||
this->filter_list_->input(state, false);
|
this->filter_list_->input(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void BinarySensor::publish_initial_state(bool state) {
|
void BinarySensor::publish_initial_state(bool state) {
|
||||||
if (!this->publish_dedup_.next(state))
|
this->has_state_ = false;
|
||||||
return;
|
this->publish_state(state);
|
||||||
if (this->filter_list_ == nullptr) {
|
|
||||||
this->send_state_internal(state, true);
|
|
||||||
} else {
|
|
||||||
this->filter_list_->input(state, true);
|
|
||||||
}
|
}
|
||||||
}
|
void BinarySensor::send_state_internal(bool state) {
|
||||||
void BinarySensor::send_state_internal(bool state, bool is_initial) {
|
bool is_initial = !this->has_state_;
|
||||||
if (is_initial) {
|
if (is_initial) {
|
||||||
ESP_LOGD(TAG, "'%s': Sending initial state %s", this->get_name().c_str(), ONOFF(state));
|
ESP_LOGD(TAG, "'%s': Sending initial state %s", this->get_name().c_str(), ONOFF(state));
|
||||||
} else {
|
} else {
|
||||||
|
@ -67,7 +67,7 @@ class BinarySensor : public EntityBase, public EntityBase_DeviceClass {
|
|||||||
|
|
||||||
// ========== INTERNAL METHODS ==========
|
// ========== INTERNAL METHODS ==========
|
||||||
// (In most use cases you won't need these)
|
// (In most use cases you won't need these)
|
||||||
void send_state_internal(bool state, bool is_initial);
|
void send_state_internal(bool state);
|
||||||
|
|
||||||
/// Return whether this binary sensor has outputted a state.
|
/// Return whether this binary sensor has outputted a state.
|
||||||
virtual bool has_state() const;
|
virtual bool has_state() const;
|
||||||
|
@ -9,37 +9,37 @@ namespace binary_sensor {
|
|||||||
|
|
||||||
static const char *const TAG = "sensor.filter";
|
static const char *const TAG = "sensor.filter";
|
||||||
|
|
||||||
void Filter::output(bool value, bool is_initial) {
|
void Filter::output(bool value) {
|
||||||
if (!this->dedup_.next(value))
|
if (!this->dedup_.next(value))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this->next_ == nullptr) {
|
if (this->next_ == nullptr) {
|
||||||
this->parent_->send_state_internal(value, is_initial);
|
this->parent_->send_state_internal(value);
|
||||||
} else {
|
} else {
|
||||||
this->next_->input(value, is_initial);
|
this->next_->input(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Filter::input(bool value, bool is_initial) {
|
void Filter::input(bool value) {
|
||||||
auto b = this->new_value(value, is_initial);
|
auto b = this->new_value(value);
|
||||||
if (b.has_value()) {
|
if (b.has_value()) {
|
||||||
this->output(*b, is_initial);
|
this->output(*b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<bool> DelayedOnOffFilter::new_value(bool value, bool is_initial) {
|
optional<bool> DelayedOnOffFilter::new_value(bool value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
this->set_timeout("ON_OFF", this->on_delay_.value(), [this, is_initial]() { this->output(true, is_initial); });
|
this->set_timeout("ON_OFF", this->on_delay_.value(), [this]() { this->output(true); });
|
||||||
} else {
|
} else {
|
||||||
this->set_timeout("ON_OFF", this->off_delay_.value(), [this, is_initial]() { this->output(false, is_initial); });
|
this->set_timeout("ON_OFF", this->off_delay_.value(), [this]() { this->output(false); });
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
float DelayedOnOffFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
|
float DelayedOnOffFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||||
|
|
||||||
optional<bool> DelayedOnFilter::new_value(bool value, bool is_initial) {
|
optional<bool> DelayedOnFilter::new_value(bool value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
this->set_timeout("ON", this->delay_.value(), [this, is_initial]() { this->output(true, is_initial); });
|
this->set_timeout("ON", this->delay_.value(), [this]() { this->output(true); });
|
||||||
return {};
|
return {};
|
||||||
} else {
|
} else {
|
||||||
this->cancel_timeout("ON");
|
this->cancel_timeout("ON");
|
||||||
@ -49,9 +49,9 @@ optional<bool> DelayedOnFilter::new_value(bool value, bool is_initial) {
|
|||||||
|
|
||||||
float DelayedOnFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
|
float DelayedOnFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||||
|
|
||||||
optional<bool> DelayedOffFilter::new_value(bool value, bool is_initial) {
|
optional<bool> DelayedOffFilter::new_value(bool value) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
this->set_timeout("OFF", this->delay_.value(), [this, is_initial]() { this->output(false, is_initial); });
|
this->set_timeout("OFF", this->delay_.value(), [this]() { this->output(false); });
|
||||||
return {};
|
return {};
|
||||||
} else {
|
} else {
|
||||||
this->cancel_timeout("OFF");
|
this->cancel_timeout("OFF");
|
||||||
@ -61,11 +61,11 @@ optional<bool> DelayedOffFilter::new_value(bool value, bool is_initial) {
|
|||||||
|
|
||||||
float DelayedOffFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
|
float DelayedOffFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||||
|
|
||||||
optional<bool> InvertFilter::new_value(bool value, bool is_initial) { return !value; }
|
optional<bool> InvertFilter::new_value(bool value) { return !value; }
|
||||||
|
|
||||||
AutorepeatFilter::AutorepeatFilter(std::vector<AutorepeatFilterTiming> timings) : timings_(std::move(timings)) {}
|
AutorepeatFilter::AutorepeatFilter(std::vector<AutorepeatFilterTiming> timings) : timings_(std::move(timings)) {}
|
||||||
|
|
||||||
optional<bool> AutorepeatFilter::new_value(bool value, bool is_initial) {
|
optional<bool> AutorepeatFilter::new_value(bool value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
// Ignore if already running
|
// Ignore if already running
|
||||||
if (this->active_timing_ != 0)
|
if (this->active_timing_ != 0)
|
||||||
@ -101,7 +101,7 @@ void AutorepeatFilter::next_timing_() {
|
|||||||
|
|
||||||
void AutorepeatFilter::next_value_(bool val) {
|
void AutorepeatFilter::next_value_(bool val) {
|
||||||
const AutorepeatFilterTiming &timing = this->timings_[this->active_timing_ - 2];
|
const AutorepeatFilterTiming &timing = this->timings_[this->active_timing_ - 2];
|
||||||
this->output(val, false); // This is at least the second one so not initial
|
this->output(val);
|
||||||
this->set_timeout("ON_OFF", val ? timing.time_on : timing.time_off, [this, val]() { this->next_value_(!val); });
|
this->set_timeout("ON_OFF", val ? timing.time_on : timing.time_off, [this, val]() { this->next_value_(!val); });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,18 +109,18 @@ float AutorepeatFilter::get_setup_priority() const { return setup_priority::HARD
|
|||||||
|
|
||||||
LambdaFilter::LambdaFilter(std::function<optional<bool>(bool)> f) : f_(std::move(f)) {}
|
LambdaFilter::LambdaFilter(std::function<optional<bool>(bool)> f) : f_(std::move(f)) {}
|
||||||
|
|
||||||
optional<bool> LambdaFilter::new_value(bool value, bool is_initial) { return this->f_(value); }
|
optional<bool> LambdaFilter::new_value(bool value) { return this->f_(value); }
|
||||||
|
|
||||||
optional<bool> SettleFilter::new_value(bool value, bool is_initial) {
|
optional<bool> SettleFilter::new_value(bool value) {
|
||||||
if (!this->steady_) {
|
if (!this->steady_) {
|
||||||
this->set_timeout("SETTLE", this->delay_.value(), [this, value, is_initial]() {
|
this->set_timeout("SETTLE", this->delay_.value(), [this, value]() {
|
||||||
this->steady_ = true;
|
this->steady_ = true;
|
||||||
this->output(value, is_initial);
|
this->output(value);
|
||||||
});
|
});
|
||||||
return {};
|
return {};
|
||||||
} else {
|
} else {
|
||||||
this->steady_ = false;
|
this->steady_ = false;
|
||||||
this->output(value, is_initial);
|
this->output(value);
|
||||||
this->set_timeout("SETTLE", this->delay_.value(), [this]() { this->steady_ = true; });
|
this->set_timeout("SETTLE", this->delay_.value(), [this]() { this->steady_ = true; });
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,11 @@ class BinarySensor;
|
|||||||
|
|
||||||
class Filter {
|
class Filter {
|
||||||
public:
|
public:
|
||||||
virtual optional<bool> new_value(bool value, bool is_initial) = 0;
|
virtual optional<bool> new_value(bool value) = 0;
|
||||||
|
|
||||||
void input(bool value, bool is_initial);
|
void input(bool value);
|
||||||
|
|
||||||
void output(bool value, bool is_initial);
|
void output(bool value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend BinarySensor;
|
friend BinarySensor;
|
||||||
@ -30,7 +30,7 @@ class Filter {
|
|||||||
|
|
||||||
class DelayedOnOffFilter : public Filter, public Component {
|
class DelayedOnOffFilter : public Filter, public Component {
|
||||||
public:
|
public:
|
||||||
optional<bool> new_value(bool value, bool is_initial) override;
|
optional<bool> new_value(bool value) override;
|
||||||
|
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ class DelayedOnOffFilter : public Filter, public Component {
|
|||||||
|
|
||||||
class DelayedOnFilter : public Filter, public Component {
|
class DelayedOnFilter : public Filter, public Component {
|
||||||
public:
|
public:
|
||||||
optional<bool> new_value(bool value, bool is_initial) override;
|
optional<bool> new_value(bool value) override;
|
||||||
|
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ class DelayedOnFilter : public Filter, public Component {
|
|||||||
|
|
||||||
class DelayedOffFilter : public Filter, public Component {
|
class DelayedOffFilter : public Filter, public Component {
|
||||||
public:
|
public:
|
||||||
optional<bool> new_value(bool value, bool is_initial) override;
|
optional<bool> new_value(bool value) override;
|
||||||
|
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ class DelayedOffFilter : public Filter, public Component {
|
|||||||
|
|
||||||
class InvertFilter : public Filter {
|
class InvertFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
optional<bool> new_value(bool value, bool is_initial) override;
|
optional<bool> new_value(bool value) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AutorepeatFilterTiming {
|
struct AutorepeatFilterTiming {
|
||||||
@ -86,7 +86,7 @@ class AutorepeatFilter : public Filter, public Component {
|
|||||||
public:
|
public:
|
||||||
explicit AutorepeatFilter(std::vector<AutorepeatFilterTiming> timings);
|
explicit AutorepeatFilter(std::vector<AutorepeatFilterTiming> timings);
|
||||||
|
|
||||||
optional<bool> new_value(bool value, bool is_initial) override;
|
optional<bool> new_value(bool value) override;
|
||||||
|
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ class LambdaFilter : public Filter {
|
|||||||
public:
|
public:
|
||||||
explicit LambdaFilter(std::function<optional<bool>(bool)> f);
|
explicit LambdaFilter(std::function<optional<bool>(bool)> f);
|
||||||
|
|
||||||
optional<bool> new_value(bool value, bool is_initial) override;
|
optional<bool> new_value(bool value) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::function<optional<bool>(bool)> f_;
|
std::function<optional<bool>(bool)> f_;
|
||||||
@ -110,7 +110,7 @@ class LambdaFilter : public Filter {
|
|||||||
|
|
||||||
class SettleFilter : public Filter, public Component {
|
class SettleFilter : public Filter, public Component {
|
||||||
public:
|
public:
|
||||||
optional<bool> new_value(bool value, bool is_initial) override;
|
optional<bool> new_value(bool value) override;
|
||||||
|
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user