mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +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_) |     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): | 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) | @FILTER_REGISTRY.register("or", OrFilter, validate_filters) | ||||||
|   | |||||||
| @@ -315,19 +315,23 @@ optional<float> ThrottleFilter::new_value(float value) { | |||||||
| } | } | ||||||
|  |  | ||||||
| // DeltaFilter | // 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) { | optional<float> DeltaFilter::new_value(float value) { | ||||||
|   if (std::isnan(value)) { |   if (std::isnan(value)) { | ||||||
|     if (std::isnan(this->last_value_)) { |     if (std::isnan(this->last_value_)) { | ||||||
|       return {}; |       return {}; | ||||||
|     } else { |     } else { | ||||||
|  |       if (this->percentage_mode_) { | ||||||
|  |         this->current_delta_ = fabsf(value * this->delta_); | ||||||
|  |       } | ||||||
|       return this->last_value_ = value; |       return this->last_value_ = value; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   if (std::isnan(this->last_value_)) { |   if (std::isnan(this->last_value_) || fabsf(value - this->last_value_) >= this->current_delta_) { | ||||||
|     return this->last_value_ = value; |     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 this->last_value_ = value; | ||||||
|   } |   } | ||||||
|   return {}; |   return {}; | ||||||
|   | |||||||
| @@ -325,12 +325,14 @@ class HeartbeatFilter : public Filter, public Component { | |||||||
|  |  | ||||||
| class DeltaFilter : public Filter { | class DeltaFilter : public Filter { | ||||||
|  public: |  public: | ||||||
|   explicit DeltaFilter(float min_delta); |   explicit DeltaFilter(float delta, bool percentage_mode); | ||||||
|  |  | ||||||
|   optional<float> new_value(float value) override; |   optional<float> new_value(float value) override; | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   float min_delta_; |   float delta_; | ||||||
|  |   float current_delta_; | ||||||
|  |   bool percentage_mode_; | ||||||
|   float last_value_{NAN}; |   float last_value_{NAN}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1097,7 +1097,7 @@ def possibly_negative_percentage(value): | |||||||
|     if isinstance(value, str): |     if isinstance(value, str): | ||||||
|         try: |         try: | ||||||
|             if value.endswith("%"): |             if value.endswith("%"): | ||||||
|                 has_percent_sign = False |                 has_percent_sign = True | ||||||
|                 value = float(value[:-1].rstrip()) / 100.0 |                 value = float(value[:-1].rstrip()) / 100.0 | ||||||
|             else: |             else: | ||||||
|                 value = float(value) |                 value = float(value) | ||||||
|   | |||||||
| @@ -392,6 +392,7 @@ sensor: | |||||||
|       - heartbeat: 5s |       - heartbeat: 5s | ||||||
|       - debounce: 0.1s |       - debounce: 0.1s | ||||||
|       - delta: 5.0 |       - delta: 5.0 | ||||||
|  |       - delta: 1% | ||||||
|       - or: |       - or: | ||||||
|           - throttle: 1s |           - throttle: 1s | ||||||
|           - delta: 5.0 |           - delta: 5.0 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user