mirror of
https://github.com/esphome/esphome.git
synced 2026-05-28 04:55:48 +08:00
[sensor] Drop Component from filter classes, use self-keyed scheduler (#16132)
This commit is contained in:
@@ -266,7 +266,7 @@ StreamingMovingAverageFilter = sensor_ns.class_("StreamingMovingAverageFilter",
|
|||||||
ExponentialMovingAverageFilter = sensor_ns.class_(
|
ExponentialMovingAverageFilter = sensor_ns.class_(
|
||||||
"ExponentialMovingAverageFilter", Filter
|
"ExponentialMovingAverageFilter", Filter
|
||||||
)
|
)
|
||||||
ThrottleAverageFilter = sensor_ns.class_("ThrottleAverageFilter", Filter, cg.Component)
|
ThrottleAverageFilter = sensor_ns.class_("ThrottleAverageFilter", Filter)
|
||||||
LambdaFilter = sensor_ns.class_("LambdaFilter", Filter)
|
LambdaFilter = sensor_ns.class_("LambdaFilter", Filter)
|
||||||
StatelessLambdaFilter = sensor_ns.class_("StatelessLambdaFilter", Filter)
|
StatelessLambdaFilter = sensor_ns.class_("StatelessLambdaFilter", Filter)
|
||||||
OffsetFilter = sensor_ns.class_("OffsetFilter", Filter)
|
OffsetFilter = sensor_ns.class_("OffsetFilter", Filter)
|
||||||
@@ -283,8 +283,8 @@ ThrottleWithPriorityNanFilter = sensor_ns.class_(
|
|||||||
TimeoutFilterBase = sensor_ns.class_("TimeoutFilterBase", Filter, cg.Component)
|
TimeoutFilterBase = sensor_ns.class_("TimeoutFilterBase", Filter, cg.Component)
|
||||||
TimeoutFilterLast = sensor_ns.class_("TimeoutFilterLast", TimeoutFilterBase)
|
TimeoutFilterLast = sensor_ns.class_("TimeoutFilterLast", TimeoutFilterBase)
|
||||||
TimeoutFilterConfigured = sensor_ns.class_("TimeoutFilterConfigured", TimeoutFilterBase)
|
TimeoutFilterConfigured = sensor_ns.class_("TimeoutFilterConfigured", TimeoutFilterBase)
|
||||||
DebounceFilter = sensor_ns.class_("DebounceFilter", Filter, cg.Component)
|
DebounceFilter = sensor_ns.class_("DebounceFilter", Filter)
|
||||||
HeartbeatFilter = sensor_ns.class_("HeartbeatFilter", Filter, cg.Component)
|
HeartbeatFilter = sensor_ns.class_("HeartbeatFilter", Filter)
|
||||||
DeltaFilter = sensor_ns.class_("DeltaFilter", Filter)
|
DeltaFilter = sensor_ns.class_("DeltaFilter", Filter)
|
||||||
OrFilter = sensor_ns.class_("OrFilter", Filter)
|
OrFilter = sensor_ns.class_("OrFilter", Filter)
|
||||||
CalibrateLinearFilter = sensor_ns.class_("CalibrateLinearFilter", Filter)
|
CalibrateLinearFilter = sensor_ns.class_("CalibrateLinearFilter", Filter)
|
||||||
@@ -567,9 +567,7 @@ async def exponential_moving_average_filter_to_code(config, filter_id):
|
|||||||
"throttle_average", ThrottleAverageFilter, cv.positive_time_period_milliseconds
|
"throttle_average", ThrottleAverageFilter, cv.positive_time_period_milliseconds
|
||||||
)
|
)
|
||||||
async def throttle_average_filter_to_code(config, filter_id):
|
async def throttle_average_filter_to_code(config, filter_id):
|
||||||
var = cg.new_Pvariable(filter_id, config)
|
return cg.new_Pvariable(filter_id, config)
|
||||||
await cg.register_component(var, {})
|
|
||||||
return var
|
|
||||||
|
|
||||||
|
|
||||||
@FILTER_REGISTRY.register("lambda", LambdaFilter, cv.returning_lambda)
|
@FILTER_REGISTRY.register("lambda", LambdaFilter, cv.returning_lambda)
|
||||||
@@ -698,13 +696,10 @@ HEARTBEAT_SCHEMA = cv.Schema(
|
|||||||
async def heartbeat_filter_to_code(config, filter_id):
|
async def heartbeat_filter_to_code(config, filter_id):
|
||||||
if isinstance(config, dict):
|
if isinstance(config, dict):
|
||||||
var = cg.new_Pvariable(filter_id, config[CONF_PERIOD])
|
var = cg.new_Pvariable(filter_id, config[CONF_PERIOD])
|
||||||
await cg.register_component(var, {})
|
|
||||||
cg.add(var.set_optimistic(config[CONF_OPTIMISTIC]))
|
cg.add(var.set_optimistic(config[CONF_OPTIMISTIC]))
|
||||||
return var
|
return var
|
||||||
|
|
||||||
var = cg.new_Pvariable(filter_id, config)
|
return cg.new_Pvariable(filter_id, config)
|
||||||
await cg.register_component(var, {})
|
|
||||||
return var
|
|
||||||
|
|
||||||
|
|
||||||
TIMEOUT_SCHEMA = cv.maybe_simple_value(
|
TIMEOUT_SCHEMA = cv.maybe_simple_value(
|
||||||
@@ -738,9 +733,7 @@ async def timeout_filter_to_code(config, filter_id):
|
|||||||
"debounce", DebounceFilter, cv.positive_time_period_milliseconds
|
"debounce", DebounceFilter, cv.positive_time_period_milliseconds
|
||||||
)
|
)
|
||||||
async def debounce_filter_to_code(config, filter_id):
|
async def debounce_filter_to_code(config, filter_id):
|
||||||
var = cg.new_Pvariable(filter_id, config)
|
return cg.new_Pvariable(filter_id, config)
|
||||||
await cg.register_component(var, {})
|
|
||||||
return var
|
|
||||||
|
|
||||||
|
|
||||||
CONF_DATAPOINTS = "datapoints"
|
CONF_DATAPOINTS = "datapoints"
|
||||||
|
|||||||
@@ -13,11 +13,6 @@ namespace esphome::sensor {
|
|||||||
|
|
||||||
static const char *const TAG = "sensor.filter";
|
static const char *const TAG = "sensor.filter";
|
||||||
|
|
||||||
// Filter scheduler IDs.
|
|
||||||
// Each filter is its own Component instance, so the scheduler scopes
|
|
||||||
// IDs by component pointer — no risk of collisions between instances.
|
|
||||||
constexpr uint32_t FILTER_ID = 0;
|
|
||||||
|
|
||||||
// Filter
|
// Filter
|
||||||
void Filter::input(float value) {
|
void Filter::input(float value) {
|
||||||
ESP_LOGVV(TAG, "Filter(%p)::input(%f)", this, value);
|
ESP_LOGVV(TAG, "Filter(%p)::input(%f)", this, value);
|
||||||
@@ -185,8 +180,9 @@ optional<float> ThrottleAverageFilter::new_value(float value) {
|
|||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
void ThrottleAverageFilter::setup() {
|
void ThrottleAverageFilter::initialize(Sensor *parent, Filter *next) {
|
||||||
this->set_interval(FILTER_ID, this->time_period_, [this]() {
|
Filter::initialize(parent, next);
|
||||||
|
App.scheduler.set_interval(this, this->time_period_, [this]() {
|
||||||
ESP_LOGVV(TAG, "ThrottleAverageFilter(%p)::interval(sum=%f, n=%i)", this, this->sum_, this->n_);
|
ESP_LOGVV(TAG, "ThrottleAverageFilter(%p)::interval(sum=%f, n=%i)", this, this->sum_, this->n_);
|
||||||
if (this->n_ == 0) {
|
if (this->n_ == 0) {
|
||||||
if (this->have_nan_)
|
if (this->have_nan_)
|
||||||
@@ -199,7 +195,6 @@ void ThrottleAverageFilter::setup() {
|
|||||||
this->have_nan_ = false;
|
this->have_nan_ = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
float ThrottleAverageFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
|
|
||||||
|
|
||||||
// LambdaFilter
|
// LambdaFilter
|
||||||
LambdaFilter::LambdaFilter(lambda_filter_t lambda_filter) : lambda_filter_(std::move(lambda_filter)) {}
|
LambdaFilter::LambdaFilter(lambda_filter_t lambda_filter) : lambda_filter_(std::move(lambda_filter)) {}
|
||||||
@@ -362,13 +357,12 @@ optional<float> TimeoutFilterConfigured::new_value(float value) {
|
|||||||
|
|
||||||
// DebounceFilter
|
// DebounceFilter
|
||||||
optional<float> DebounceFilter::new_value(float value) {
|
optional<float> DebounceFilter::new_value(float value) {
|
||||||
this->set_timeout(FILTER_ID, this->time_period_, [this, value]() { this->output(value); });
|
App.scheduler.set_timeout(this, this->time_period_, [this, value]() { this->output(value); });
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
DebounceFilter::DebounceFilter(uint32_t time_period) : time_period_(time_period) {}
|
DebounceFilter::DebounceFilter(uint32_t time_period) : time_period_(time_period) {}
|
||||||
float DebounceFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
|
|
||||||
|
|
||||||
// HeartbeatFilter
|
// HeartbeatFilter
|
||||||
HeartbeatFilter::HeartbeatFilter(uint32_t time_period) : time_period_(time_period), last_input_(NAN) {}
|
HeartbeatFilter::HeartbeatFilter(uint32_t time_period) : time_period_(time_period), last_input_(NAN) {}
|
||||||
@@ -384,8 +378,9 @@ optional<float> HeartbeatFilter::new_value(float value) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeartbeatFilter::setup() {
|
void HeartbeatFilter::initialize(Sensor *parent, Filter *next) {
|
||||||
this->set_interval(FILTER_ID, this->time_period_, [this]() {
|
Filter::initialize(parent, next);
|
||||||
|
App.scheduler.set_interval(this, this->time_period_, [this]() {
|
||||||
ESP_LOGVV(TAG, "HeartbeatFilter(%p)::interval(has_value=%s, last_input=%f)", this, YESNO(this->has_value_),
|
ESP_LOGVV(TAG, "HeartbeatFilter(%p)::interval(has_value=%s, last_input=%f)", this, YESNO(this->has_value_),
|
||||||
this->last_input_);
|
this->last_input_);
|
||||||
if (!this->has_value_)
|
if (!this->has_value_)
|
||||||
@@ -395,8 +390,6 @@ void HeartbeatFilter::setup() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
float HeartbeatFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
|
|
||||||
|
|
||||||
optional<float> calibrate_linear_compute(const std::array<float, 3> *functions, size_t count, float value) {
|
optional<float> calibrate_linear_compute(const std::array<float, 3> *functions, size_t count, float value) {
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
if (!std::isfinite(functions[i][2]) || value < functions[i][2])
|
if (!std::isfinite(functions[i][2]) || value < functions[i][2])
|
||||||
|
|||||||
@@ -254,16 +254,14 @@ class ExponentialMovingAverageFilter : public Filter {
|
|||||||
*
|
*
|
||||||
* It takes the average of all the values received in a period of time.
|
* It takes the average of all the values received in a period of time.
|
||||||
*/
|
*/
|
||||||
class ThrottleAverageFilter : public Filter, public Component {
|
class ThrottleAverageFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
explicit ThrottleAverageFilter(uint32_t time_period);
|
explicit ThrottleAverageFilter(uint32_t time_period);
|
||||||
|
|
||||||
void setup() override;
|
void initialize(Sensor *parent, Filter *next) override;
|
||||||
|
|
||||||
optional<float> new_value(float value) override;
|
optional<float> new_value(float value) override;
|
||||||
|
|
||||||
float get_setup_priority() const override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float sum_{0.0f};
|
float sum_{0.0f};
|
||||||
unsigned int n_{0};
|
unsigned int n_{0};
|
||||||
@@ -454,25 +452,22 @@ class TimeoutFilterConfigured : public TimeoutFilterBase {
|
|||||||
// Total: 8 (base) + 4 = 12 bytes + vtable ptr + Component overhead
|
// Total: 8 (base) + 4 = 12 bytes + vtable ptr + Component overhead
|
||||||
};
|
};
|
||||||
|
|
||||||
class DebounceFilter : public Filter, public Component {
|
class DebounceFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
explicit DebounceFilter(uint32_t time_period);
|
explicit DebounceFilter(uint32_t time_period);
|
||||||
|
|
||||||
optional<float> new_value(float value) override;
|
optional<float> new_value(float value) override;
|
||||||
|
|
||||||
float get_setup_priority() const override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32_t time_period_;
|
uint32_t time_period_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HeartbeatFilter : public Filter, public Component {
|
class HeartbeatFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
explicit HeartbeatFilter(uint32_t time_period);
|
explicit HeartbeatFilter(uint32_t time_period);
|
||||||
|
|
||||||
void setup() override;
|
void initialize(Sensor *parent, Filter *next) override;
|
||||||
optional<float> new_value(float value) override;
|
optional<float> new_value(float value) override;
|
||||||
float get_setup_priority() const override;
|
|
||||||
|
|
||||||
void set_optimistic(bool optimistic) { this->optimistic_ = optimistic; }
|
void set_optimistic(bool optimistic) { this->optimistic_ = optimistic; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user