From f10202d9addddca60505019d32abefbec22359b7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 27 Mar 2026 13:32:20 -1000 Subject: [PATCH] [sensor] Use std::array in CalibrateLinearFilter --- esphome/components/sensor/__init__.py | 4 +++- esphome/components/sensor/filter.cpp | 11 ++++------- esphome/components/sensor/filter.h | 22 ++++++++++++++++++---- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/esphome/components/sensor/__init__.py b/esphome/components/sensor/__init__.py index 9f3c1484b0..f7b6b963ba 100644 --- a/esphome/components/sensor/__init__.py +++ b/esphome/components/sensor/__init__.py @@ -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" diff --git a/esphome/components/sensor/filter.cpp b/esphome/components/sensor/filter.cpp index d995ee4111..56f8879628 100644 --- a/esphome/components/sensor/filter.cpp +++ b/esphome/components/sensor/filter.cpp @@ -413,13 +413,10 @@ void HeartbeatFilter::setup() { float HeartbeatFilter::get_setup_priority() const { return setup_priority::HARDWARE; } -CalibrateLinearFilter::CalibrateLinearFilter(std::initializer_list> linear_functions) - : linear_functions_(linear_functions) {} - -optional 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 calibrate_linear_compute(const std::array *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; } diff --git a/esphome/components/sensor/filter.h b/esphome/components/sensor/filter.h index 6a76bd373e..606c820f26 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" @@ -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 calibrate_linear_compute(const std::array *functions, size_t count, float value); + +/// N is set by code generation to match the exact number of calibration segments. +template class CalibrateLinearFilter : public Filter { public: - explicit CalibrateLinearFilter(std::initializer_list> linear_functions); - optional new_value(float value) override; + explicit CalibrateLinearFilter(std::initializer_list> linear_functions) { + size_t i = 0; + for (const auto &f : linear_functions) { + if (i >= N) + break; + this->linear_functions_[i++] = f; + } + } + optional new_value(float value) override { + return calibrate_linear_compute(this->linear_functions_.data(), N, value); + } protected: - FixedVector> linear_functions_; + std::array, N> linear_functions_{}; }; class CalibratePolynomialFilter : public Filter {