mirror of
https://github.com/esphome/esphome.git
synced 2026-09-02 11:06:04 +00:00
[sensor] Pack ThrottleAverageFilter have_nan_ into n_ bitfield
Saves 4 B per ThrottleAverageFilter instance (28 B → 24 B on 32-bit). have_nan_ is a single boolean that previously cost 4 B due to padding; fold it into the high bit of n_ as a 31-bit + 1-bit bitfield. To guarantee n_ cannot overflow under realistic configurations, cap the YAML time_period at 24 h. At a pessimistic 1 kHz source rate the counter peaks at 86.4M, leaving 25x headroom against 2^31. Anyone needing multi-day rolling averages should be using a different filtering strategy anyway. Breaking change: configurations with throttle_average periods longer than 24 h will now fail validation. No real-world configs are expected to use such values.
This commit is contained in:
@@ -564,7 +564,12 @@ async def exponential_moving_average_filter_to_code(config, filter_id):
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register(
|
||||
"throttle_average", ThrottleAverageFilter, cv.positive_time_period_milliseconds
|
||||
"throttle_average",
|
||||
ThrottleAverageFilter,
|
||||
cv.All(
|
||||
cv.positive_time_period_milliseconds,
|
||||
cv.Range(max=cv.TimePeriod(hours=24)),
|
||||
),
|
||||
)
|
||||
async def throttle_average_filter_to_code(config, filter_id):
|
||||
var = cg.new_Pvariable(filter_id, config)
|
||||
|
||||
@@ -266,9 +266,12 @@ class ThrottleAverageFilter : public Filter, public Component {
|
||||
|
||||
protected:
|
||||
float sum_{0.0f};
|
||||
unsigned int n_{0};
|
||||
uint32_t time_period_;
|
||||
bool have_nan_{false};
|
||||
// Sample count packed with NaN-seen flag in a single 32-bit word.
|
||||
// n_ is bounded by YAML cap on time_period_ (24 h) × max plausible source
|
||||
// rate (1 kHz) = 86.4M ≪ 2^31, so 31 bits has 25x headroom.
|
||||
uint32_t n_ : 31 {0};
|
||||
uint32_t have_nan_ : 1 {0};
|
||||
};
|
||||
|
||||
using lambda_filter_t = std::function<optional<float>(float)>;
|
||||
|
||||
Reference in New Issue
Block a user