mirror of
https://github.com/esphome/esphome.git
synced 2026-06-02 19:18:20 +08:00
[sensor] Use std::array in OrFilter (#15262)
This commit is contained in:
@@ -620,7 +620,7 @@ async def delta_filter_to_code(config, filter_id):
|
|||||||
@FILTER_REGISTRY.register("or", OrFilter, validate_filters)
|
@FILTER_REGISTRY.register("or", OrFilter, validate_filters)
|
||||||
async def or_filter_to_code(config, filter_id):
|
async def or_filter_to_code(config, filter_id):
|
||||||
filters = await build_filters(config)
|
filters = await build_filters(config)
|
||||||
return cg.new_Pvariable(filter_id, filters)
|
return cg.new_Pvariable(filter_id, cg.TemplateArguments(len(filters)), filters)
|
||||||
|
|
||||||
|
|
||||||
@FILTER_REGISTRY.register(
|
@FILTER_REGISTRY.register(
|
||||||
|
|||||||
@@ -295,32 +295,20 @@ optional<float> DeltaFilter::new_value(float value) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// OrFilter
|
// OrFilter helpers
|
||||||
OrFilter::OrFilter(std::initializer_list<Filter *> filters) : filters_(filters), phi_(this) {}
|
void or_filter_initialize(Filter **filters, size_t count, Sensor *parent, Filter *phi) {
|
||||||
OrFilter::PhiNode::PhiNode(OrFilter *or_parent) : or_parent_(or_parent) {}
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
filters[i]->initialize(parent, phi);
|
||||||
optional<float> OrFilter::PhiNode::new_value(float value) {
|
|
||||||
if (!this->or_parent_->has_value_) {
|
|
||||||
this->or_parent_->output(value);
|
|
||||||
this->or_parent_->has_value_ = true;
|
|
||||||
}
|
}
|
||||||
|
phi->initialize(parent, nullptr);
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
optional<float> OrFilter::new_value(float value) {
|
|
||||||
this->has_value_ = false;
|
|
||||||
for (auto *filter : this->filters_)
|
|
||||||
filter->input(value);
|
|
||||||
|
|
||||||
|
optional<float> or_filter_new_value(Filter **filters, size_t count, float value, bool &has_value) {
|
||||||
|
has_value = false;
|
||||||
|
for (size_t i = 0; i < count; i++)
|
||||||
|
filters[i]->input(value);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
void OrFilter::initialize(Sensor *parent, Filter *next) {
|
|
||||||
Filter::initialize(parent, next);
|
|
||||||
for (auto *filter : this->filters_) {
|
|
||||||
filter->initialize(parent, &this->phi_);
|
|
||||||
}
|
|
||||||
this->phi_.initialize(parent, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeoutFilterBase - shared loop logic
|
// TimeoutFilterBase - shared loop logic
|
||||||
void TimeoutFilterBase::loop() {
|
void TimeoutFilterBase::loop() {
|
||||||
|
|||||||
@@ -489,26 +489,42 @@ class DeltaFilter : public Filter {
|
|||||||
float last_value_{NAN};
|
float last_value_{NAN};
|
||||||
};
|
};
|
||||||
|
|
||||||
class OrFilter : public Filter {
|
/// Non-template helpers for OrFilter (implementation in filter.cpp)
|
||||||
|
void or_filter_initialize(Filter **filters, size_t count, Sensor *parent, Filter *phi);
|
||||||
|
optional<float> or_filter_new_value(Filter **filters, size_t count, float value, bool &has_value);
|
||||||
|
|
||||||
|
/// N is set by code generation to match the exact number of filters configured in YAML.
|
||||||
|
template<size_t N> class OrFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
explicit OrFilter(std::initializer_list<Filter *> filters);
|
explicit OrFilter(std::initializer_list<Filter *> filters) { init_array_from(this->filters_, filters); }
|
||||||
|
|
||||||
void initialize(Sensor *parent, Filter *next) override;
|
void initialize(Sensor *parent, Filter *next) override {
|
||||||
|
Filter::initialize(parent, next);
|
||||||
|
or_filter_initialize(this->filters_.data(), N, parent, &this->phi_);
|
||||||
|
}
|
||||||
|
|
||||||
optional<float> new_value(float value) override;
|
optional<float> new_value(float value) override {
|
||||||
|
return or_filter_new_value(this->filters_.data(), N, value, this->has_value_);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class PhiNode : public Filter {
|
class PhiNode : public Filter {
|
||||||
public:
|
public:
|
||||||
PhiNode(OrFilter *or_parent);
|
PhiNode(OrFilter *or_parent) : or_parent_(or_parent) {}
|
||||||
optional<float> new_value(float value) override;
|
optional<float> new_value(float value) override {
|
||||||
|
if (!this->or_parent_->has_value_) {
|
||||||
|
this->or_parent_->output(value);
|
||||||
|
this->or_parent_->has_value_ = true;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
OrFilter *or_parent_;
|
OrFilter *or_parent_;
|
||||||
};
|
};
|
||||||
|
|
||||||
FixedVector<Filter *> filters_;
|
std::array<Filter *, N> filters_{};
|
||||||
PhiNode phi_;
|
PhiNode phi_{this};
|
||||||
bool has_value_{false};
|
bool has_value_{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user