diff --git a/esphome/components/sensor/__init__.py b/esphome/components/sensor/__init__.py index 9f3c1484b0..0cd812fcd6 100644 --- a/esphome/components/sensor/__init__.py +++ b/esphome/components/sensor/__init__.py @@ -822,7 +822,7 @@ async def calibrate_polynomial_filter_to_code(config, filter_id): # Column vector b = [[v] for v in y] res = [v[0] for v in _lstsq(a, b)] - return cg.new_Pvariable(filter_id, res) + return cg.new_Pvariable(filter_id, cg.TemplateArguments(len(res)), res) def validate_clamp(config): diff --git a/esphome/components/sensor/filter.cpp b/esphome/components/sensor/filter.cpp index d995ee4111..29cffd348e 100644 --- a/esphome/components/sensor/filter.cpp +++ b/esphome/components/sensor/filter.cpp @@ -424,14 +424,11 @@ optional CalibrateLinearFilter::new_value(float value) { return NAN; } -CalibratePolynomialFilter::CalibratePolynomialFilter(std::initializer_list coefficients) - : coefficients_(coefficients) {} - -optional CalibratePolynomialFilter::new_value(float value) { +optional calibrate_polynomial_compute(const float *coefficients, size_t count, float value) { float res = 0.0f; float x = 1.0f; - for (const auto &coefficient : this->coefficients_) { - res += x * coefficient; + for (size_t i = 0; i < count; i++) { + res += x * coefficients[i]; x *= value; } return res; diff --git a/esphome/components/sensor/filter.h b/esphome/components/sensor/filter.h index 6a76bd373e..0dc7fc85dd 100644 --- a/esphome/components/sensor/filter.h +++ b/esphome/components/sensor/filter.h @@ -3,6 +3,7 @@ #include "esphome/core/defines.h" #ifdef USE_SENSOR_FILTER +#include #include #include #include "esphome/core/automation.h" @@ -498,13 +499,26 @@ class CalibrateLinearFilter : public Filter { FixedVector> linear_functions_; }; -class CalibratePolynomialFilter : public Filter { +/// Non-template helper for polynomial calibration (implementation in filter.cpp) +optional calibrate_polynomial_compute(const float *coefficients, size_t count, float value); + +/// N is set by code generation to match the exact number of polynomial coefficients. +template class CalibratePolynomialFilter : public Filter { public: - explicit CalibratePolynomialFilter(std::initializer_list coefficients); - optional new_value(float value) override; + explicit CalibratePolynomialFilter(std::initializer_list coefficients) { + size_t i = 0; + for (float c : coefficients) { + if (i >= N) + break; + this->coefficients_[i++] = c; + } + } + optional new_value(float value) override { + return calibrate_polynomial_compute(this->coefficients_.data(), N, value); + } protected: - FixedVector coefficients_; + std::array coefficients_{}; }; class ClampFilter : public Filter {