mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Update the delta filter to take a percentage value as well as an absolute value (#4391)
This commit is contained in:
		| @@ -466,9 +466,21 @@ async def lambda_filter_to_code(config, filter_id): | ||||
|     return cg.new_Pvariable(filter_id, lambda_) | ||||
|  | ||||
|  | ||||
| @FILTER_REGISTRY.register("delta", DeltaFilter, cv.float_) | ||||
| def validate_delta(config): | ||||
|     try: | ||||
|         return (cv.positive_float(config), False) | ||||
|     except cv.Invalid: | ||||
|         pass | ||||
|     try: | ||||
|         return (cv.percentage(config), True) | ||||
|     except cv.Invalid: | ||||
|         pass | ||||
|     raise cv.Invalid("Delta filter requires a positive number or percentage value.") | ||||
|  | ||||
|  | ||||
| @FILTER_REGISTRY.register("delta", DeltaFilter, validate_delta) | ||||
| async def delta_filter_to_code(config, filter_id): | ||||
|     return cg.new_Pvariable(filter_id, config) | ||||
|     return cg.new_Pvariable(filter_id, *config) | ||||
|  | ||||
|  | ||||
| @FILTER_REGISTRY.register("or", OrFilter, validate_filters) | ||||
|   | ||||
| @@ -315,19 +315,23 @@ optional<float> ThrottleFilter::new_value(float value) { | ||||
| } | ||||
|  | ||||
| // DeltaFilter | ||||
| DeltaFilter::DeltaFilter(float min_delta) : min_delta_(min_delta), last_value_(NAN) {} | ||||
| DeltaFilter::DeltaFilter(float delta, bool percentage_mode) | ||||
|     : delta_(delta), current_delta_(delta), percentage_mode_(percentage_mode), last_value_(NAN) {} | ||||
| optional<float> DeltaFilter::new_value(float value) { | ||||
|   if (std::isnan(value)) { | ||||
|     if (std::isnan(this->last_value_)) { | ||||
|       return {}; | ||||
|     } else { | ||||
|       if (this->percentage_mode_) { | ||||
|         this->current_delta_ = fabsf(value * this->delta_); | ||||
|       } | ||||
|       return this->last_value_ = value; | ||||
|     } | ||||
|   } | ||||
|   if (std::isnan(this->last_value_)) { | ||||
|     return this->last_value_ = value; | ||||
|   if (std::isnan(this->last_value_) || fabsf(value - this->last_value_) >= this->current_delta_) { | ||||
|     if (this->percentage_mode_) { | ||||
|       this->current_delta_ = fabsf(value * this->delta_); | ||||
|     } | ||||
|   if (fabsf(value - this->last_value_) >= this->min_delta_) { | ||||
|     return this->last_value_ = value; | ||||
|   } | ||||
|   return {}; | ||||
|   | ||||
| @@ -325,12 +325,14 @@ class HeartbeatFilter : public Filter, public Component { | ||||
|  | ||||
| class DeltaFilter : public Filter { | ||||
|  public: | ||||
|   explicit DeltaFilter(float min_delta); | ||||
|   explicit DeltaFilter(float delta, bool percentage_mode); | ||||
|  | ||||
|   optional<float> new_value(float value) override; | ||||
|  | ||||
|  protected: | ||||
|   float min_delta_; | ||||
|   float delta_; | ||||
|   float current_delta_; | ||||
|   bool percentage_mode_; | ||||
|   float last_value_{NAN}; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1097,7 +1097,7 @@ def possibly_negative_percentage(value): | ||||
|     if isinstance(value, str): | ||||
|         try: | ||||
|             if value.endswith("%"): | ||||
|                 has_percent_sign = False | ||||
|                 has_percent_sign = True | ||||
|                 value = float(value[:-1].rstrip()) / 100.0 | ||||
|             else: | ||||
|                 value = float(value) | ||||
|   | ||||
| @@ -392,6 +392,7 @@ sensor: | ||||
|       - heartbeat: 5s | ||||
|       - debounce: 0.1s | ||||
|       - delta: 5.0 | ||||
|       - delta: 1% | ||||
|       - or: | ||||
|           - throttle: 1s | ||||
|           - delta: 5.0 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user