diff --git a/esphome/components/sensor/__init__.py b/esphome/components/sensor/__init__.py index bd7306ac28..b3bf533695 100644 --- a/esphome/components/sensor/__init__.py +++ b/esphome/components/sensor/__init__.py @@ -16,6 +16,7 @@ from esphome.const import ( CONF_FROM, CONF_ICON, CONF_ID, + CONF_IGNORE_OUT_OF_RANGE, CONF_ON_RAW_VALUE, CONF_ON_VALUE, CONF_ON_VALUE_RANGE, @@ -688,6 +689,7 @@ CLAMP_SCHEMA = cv.All( { cv.Optional(CONF_MIN_VALUE, default="NaN"): cv.float_, cv.Optional(CONF_MAX_VALUE, default="NaN"): cv.float_, + cv.Optional(CONF_IGNORE_OUT_OF_RANGE, default=False): cv.boolean, } ), validate_clamp, @@ -700,6 +702,7 @@ async def clamp_filter_to_code(config, filter_id): filter_id, config[CONF_MIN_VALUE], config[CONF_MAX_VALUE], + config[CONF_IGNORE_OUT_OF_RANGE], ) diff --git a/esphome/components/sensor/filter.cpp b/esphome/components/sensor/filter.cpp index af67a60754..d1cb8d1c4b 100644 --- a/esphome/components/sensor/filter.cpp +++ b/esphome/components/sensor/filter.cpp @@ -434,13 +434,25 @@ optional CalibratePolynomialFilter::new_value(float value) { return res; } -ClampFilter::ClampFilter(float min, float max) : min_(min), max_(max) {} +ClampFilter::ClampFilter(float min, float max, bool ignore_out_of_range) + : min_(min), max_(max), ignore_out_of_range_(ignore_out_of_range) {} optional ClampFilter::new_value(float value) { if (std::isfinite(value)) { - if (std::isfinite(this->min_) && value < this->min_) - return this->min_; - if (std::isfinite(this->max_) && value > this->max_) - return this->max_; + if (std::isfinite(this->min_) && value < this->min_) { + if (this->ignore_out_of_range_) { + return {}; + } else { + return this->min_; + } + } + + if (std::isfinite(this->max_) && value > this->max_) { + if (this->ignore_out_of_range_) { + return {}; + } else { + return this->max_; + } + } } return value; } diff --git a/esphome/components/sensor/filter.h b/esphome/components/sensor/filter.h index d4239837b6..fa78f2fa46 100644 --- a/esphome/components/sensor/filter.h +++ b/esphome/components/sensor/filter.h @@ -411,12 +411,13 @@ class CalibratePolynomialFilter : public Filter { class ClampFilter : public Filter { public: - ClampFilter(float min, float max); + ClampFilter(float min, float max, bool ignore_out_of_range); optional new_value(float value) override; protected: float min_{NAN}; float max_{NAN}; + bool ignore_out_of_range_; }; class RoundFilter : public Filter { diff --git a/esphome/const.py b/esphome/const.py index 9e0bd4da0a..47eedc24b7 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -335,6 +335,7 @@ CONF_IDLE_LEVEL = "idle_level" CONF_IDLE_TIME = "idle_time" CONF_IF = "if" CONF_IGNORE_EFUSE_MAC_CRC = "ignore_efuse_mac_crc" +CONF_IGNORE_OUT_OF_RANGE = "ignore_out_of_range" CONF_IGNORE_STRAPPING_WARNING = "ignore_strapping_warning" CONF_IIR_FILTER = "iir_filter" CONF_ILLUMINANCE = "illuminance"