[sensor] Use std::array in CalibrateLinearFilter

This commit is contained in:
J. Nick Koston
2026-03-27 13:32:20 -10:00
parent a075f63b59
commit f10202d9ad
3 changed files with 25 additions and 12 deletions
+3 -1
View File
@@ -784,7 +784,9 @@ async def calibrate_linear_filter_to_code(config, filter_id):
linear_functions = [[k, b, float("NaN")]]
elif config[CONF_METHOD] == "exact":
linear_functions = map_linear(x, y)
return cg.new_Pvariable(filter_id, linear_functions)
return cg.new_Pvariable(
filter_id, cg.TemplateArguments(len(linear_functions)), linear_functions
)
CONF_DEGREE = "degree"
+4 -7
View File
@@ -413,13 +413,10 @@ void HeartbeatFilter::setup() {
float HeartbeatFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
CalibrateLinearFilter::CalibrateLinearFilter(std::initializer_list<std::array<float, 3>> linear_functions)
: linear_functions_(linear_functions) {}
optional<float> CalibrateLinearFilter::new_value(float value) {
for (const auto &f : this->linear_functions_) {
if (!std::isfinite(f[2]) || value < f[2])
return (value * f[0]) + f[1];
optional<float> calibrate_linear_compute(const std::array<float, 3> *functions, size_t count, float value) {
for (size_t i = 0; i < count; i++) {
if (!std::isfinite(functions[i][2]) || value < functions[i][2])
return (value * functions[i][0]) + functions[i][1];
}
return NAN;
}
+18 -4
View File
@@ -3,6 +3,7 @@
#include "esphome/core/defines.h"
#ifdef USE_SENSOR_FILTER
#include <array>
#include <utility>
#include <vector>
#include "esphome/core/automation.h"
@@ -489,13 +490,26 @@ class OrFilter : public Filter {
bool has_value_{false};
};
class CalibrateLinearFilter : public Filter {
/// Non-template helper for linear calibration (implementation in filter.cpp)
optional<float> calibrate_linear_compute(const std::array<float, 3> *functions, size_t count, float value);
/// N is set by code generation to match the exact number of calibration segments.
template<size_t N> class CalibrateLinearFilter : public Filter {
public:
explicit CalibrateLinearFilter(std::initializer_list<std::array<float, 3>> linear_functions);
optional<float> new_value(float value) override;
explicit CalibrateLinearFilter(std::initializer_list<std::array<float, 3>> linear_functions) {
size_t i = 0;
for (const auto &f : linear_functions) {
if (i >= N)
break;
this->linear_functions_[i++] = f;
}
}
optional<float> new_value(float value) override {
return calibrate_linear_compute(this->linear_functions_.data(), N, value);
}
protected:
FixedVector<std::array<float, 3>> linear_functions_;
std::array<std::array<float, 3>, N> linear_functions_{};
};
class CalibratePolynomialFilter : public Filter {