diff --git a/esphome/components/sensor/__init__.py b/esphome/components/sensor/__init__.py index ee42011038..bd7306ac28 100644 --- a/esphome/components/sensor/__init__.py +++ b/esphome/components/sensor/__init__.py @@ -242,6 +242,7 @@ CalibrateLinearFilter = sensor_ns.class_("CalibrateLinearFilter", Filter) CalibratePolynomialFilter = sensor_ns.class_("CalibratePolynomialFilter", Filter) SensorInRangeCondition = sensor_ns.class_("SensorInRangeCondition", Filter) ClampFilter = sensor_ns.class_("ClampFilter", Filter) +RoundFilter = sensor_ns.class_("RoundFilter", Filter) validate_unit_of_measurement = cv.string_strict validate_accuracy_decimals = cv.int_ @@ -702,6 +703,23 @@ async def clamp_filter_to_code(config, filter_id): ) +@FILTER_REGISTRY.register( + "round", + RoundFilter, + cv.maybe_simple_value( + { + cv.Required(CONF_ACCURACY_DECIMALS): cv.uint8_t, + }, + key=CONF_ACCURACY_DECIMALS, + ), +) +async def round_filter_to_code(config, filter_id): + return cg.new_Pvariable( + filter_id, + config[CONF_ACCURACY_DECIMALS], + ) + + async def build_filters(config): return await cg.build_registry_list(FILTER_REGISTRY, config) diff --git a/esphome/components/sensor/filter.cpp b/esphome/components/sensor/filter.cpp index 6323023d50..af67a60754 100644 --- a/esphome/components/sensor/filter.cpp +++ b/esphome/components/sensor/filter.cpp @@ -445,5 +445,14 @@ optional ClampFilter::new_value(float value) { return value; } +RoundFilter::RoundFilter(uint8_t precision) : precision_(precision) {} +optional RoundFilter::new_value(float value) { + if (std::isfinite(value)) { + float accuracy_mult = powf(10.0f, this->precision_); + return roundf(accuracy_mult * value) / accuracy_mult; + } + return value; +} + } // namespace sensor } // namespace esphome diff --git a/esphome/components/sensor/filter.h b/esphome/components/sensor/filter.h index 46aeefac56..d4239837b6 100644 --- a/esphome/components/sensor/filter.h +++ b/esphome/components/sensor/filter.h @@ -419,5 +419,14 @@ class ClampFilter : public Filter { float max_{NAN}; }; +class RoundFilter : public Filter { + public: + explicit RoundFilter(uint8_t precision); + optional new_value(float value) override; + + protected: + uint8_t precision_; +}; + } // namespace sensor } // namespace esphome