mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	[sensor] Make some values templatable (#7735)
This commit is contained in:
		| @@ -335,19 +335,28 @@ def sensor_schema( | ||||
|     return SENSOR_SCHEMA.extend(schema) | ||||
|  | ||||
|  | ||||
| @FILTER_REGISTRY.register("offset", OffsetFilter, cv.float_) | ||||
| @FILTER_REGISTRY.register("offset", OffsetFilter, cv.templatable(cv.float_)) | ||||
| async def offset_filter_to_code(config, filter_id): | ||||
|     return cg.new_Pvariable(filter_id, config) | ||||
|     template_ = await cg.templatable(config, [], float) | ||||
|     return cg.new_Pvariable(filter_id, template_) | ||||
|  | ||||
|  | ||||
| @FILTER_REGISTRY.register("multiply", MultiplyFilter, cv.float_) | ||||
| @FILTER_REGISTRY.register("multiply", MultiplyFilter, cv.templatable(cv.float_)) | ||||
| async def multiply_filter_to_code(config, filter_id): | ||||
|     return cg.new_Pvariable(filter_id, config) | ||||
|     template_ = await cg.templatable(config, [], float) | ||||
|     return cg.new_Pvariable(filter_id, template_) | ||||
|  | ||||
|  | ||||
| @FILTER_REGISTRY.register("filter_out", FilterOutValueFilter, cv.float_) | ||||
| @FILTER_REGISTRY.register( | ||||
|     "filter_out", | ||||
|     FilterOutValueFilter, | ||||
|     cv.Any(cv.templatable(cv.float_), [cv.templatable(cv.float_)]), | ||||
| ) | ||||
| async def filter_out_filter_to_code(config, filter_id): | ||||
|     return cg.new_Pvariable(filter_id, config) | ||||
|     if not isinstance(config, list): | ||||
|         config = [config] | ||||
|     template_ = [await cg.templatable(x, [], float) for x in config] | ||||
|     return cg.new_Pvariable(filter_id, template_) | ||||
|  | ||||
|  | ||||
| QUANTILE_SCHEMA = cv.All( | ||||
| @@ -573,7 +582,7 @@ async def heartbeat_filter_to_code(config, filter_id): | ||||
| TIMEOUT_SCHEMA = cv.maybe_simple_value( | ||||
|     { | ||||
|         cv.Required(CONF_TIMEOUT): cv.positive_time_period_milliseconds, | ||||
|         cv.Optional(CONF_VALUE, default="nan"): cv.float_, | ||||
|         cv.Optional(CONF_VALUE, default="nan"): cv.templatable(cv.float_), | ||||
|     }, | ||||
|     key=CONF_TIMEOUT, | ||||
| ) | ||||
| @@ -581,7 +590,8 @@ TIMEOUT_SCHEMA = cv.maybe_simple_value( | ||||
|  | ||||
| @FILTER_REGISTRY.register("timeout", TimeoutFilter, TIMEOUT_SCHEMA) | ||||
| async def timeout_filter_to_code(config, filter_id): | ||||
|     var = cg.new_Pvariable(filter_id, config[CONF_TIMEOUT], config[CONF_VALUE]) | ||||
|     template_ = await cg.templatable(config[CONF_VALUE], [], float) | ||||
|     var = cg.new_Pvariable(filter_id, config[CONF_TIMEOUT], template_) | ||||
|     await cg.register_component(var, {}) | ||||
|     return var | ||||
|  | ||||
|   | ||||
| @@ -288,36 +288,36 @@ optional<float> LambdaFilter::new_value(float value) { | ||||
| } | ||||
|  | ||||
| // OffsetFilter | ||||
| OffsetFilter::OffsetFilter(float offset) : offset_(offset) {} | ||||
| OffsetFilter::OffsetFilter(TemplatableValue<float> offset) : offset_(std::move(offset)) {} | ||||
|  | ||||
| optional<float> OffsetFilter::new_value(float value) { return value + this->offset_; } | ||||
| optional<float> OffsetFilter::new_value(float value) { return value + this->offset_.value(); } | ||||
|  | ||||
| // MultiplyFilter | ||||
| MultiplyFilter::MultiplyFilter(float multiplier) : multiplier_(multiplier) {} | ||||
| MultiplyFilter::MultiplyFilter(TemplatableValue<float> multiplier) : multiplier_(std::move(multiplier)) {} | ||||
|  | ||||
| optional<float> MultiplyFilter::new_value(float value) { return value * this->multiplier_; } | ||||
| optional<float> MultiplyFilter::new_value(float value) { return value * this->multiplier_.value(); } | ||||
|  | ||||
| // FilterOutValueFilter | ||||
| FilterOutValueFilter::FilterOutValueFilter(float value_to_filter_out) : value_to_filter_out_(value_to_filter_out) {} | ||||
| FilterOutValueFilter::FilterOutValueFilter(std::vector<TemplatableValue<float>> values_to_filter_out) | ||||
|     : values_to_filter_out_(std::move(values_to_filter_out)) {} | ||||
|  | ||||
| optional<float> FilterOutValueFilter::new_value(float value) { | ||||
|   if (std::isnan(this->value_to_filter_out_)) { | ||||
|     if (std::isnan(value)) { | ||||
|       return {}; | ||||
|     } else { | ||||
|       return value; | ||||
|     } | ||||
|   } else { | ||||
|   int8_t accuracy = this->parent_->get_accuracy_decimals(); | ||||
|   float accuracy_mult = powf(10.0f, accuracy); | ||||
|     float rounded_filter_out = roundf(accuracy_mult * this->value_to_filter_out_); | ||||
|   for (auto filter_value : this->values_to_filter_out_) { | ||||
|     if (std::isnan(filter_value.value())) { | ||||
|       if (std::isnan(value)) { | ||||
|         return {}; | ||||
|       } | ||||
|       continue; | ||||
|     } | ||||
|     float rounded_filter_out = roundf(accuracy_mult * filter_value.value()); | ||||
|     float rounded_value = roundf(accuracy_mult * value); | ||||
|     if (rounded_filter_out == rounded_value) { | ||||
|       return {}; | ||||
|     } else { | ||||
|     } | ||||
|   } | ||||
|   return value; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| // ThrottleFilter | ||||
| @@ -383,11 +383,12 @@ void OrFilter::initialize(Sensor *parent, Filter *next) { | ||||
|  | ||||
| // TimeoutFilter | ||||
| optional<float> TimeoutFilter::new_value(float value) { | ||||
|   this->set_timeout("timeout", this->time_period_, [this]() { this->output(this->value_); }); | ||||
|   this->set_timeout("timeout", this->time_period_, [this]() { this->output(this->value_.value()); }); | ||||
|   return value; | ||||
| } | ||||
|  | ||||
| TimeoutFilter::TimeoutFilter(uint32_t time_period, float new_value) : time_period_(time_period), value_(new_value) {} | ||||
| TimeoutFilter::TimeoutFilter(uint32_t time_period, TemplatableValue<float> new_value) | ||||
|     : time_period_(time_period), value_(std::move(new_value)) {} | ||||
| float TimeoutFilter::get_setup_priority() const { return setup_priority::HARDWARE; } | ||||
|  | ||||
| // DebounceFilter | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include <vector> | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/core/helpers.h" | ||||
| #include "esphome/core/automation.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace sensor { | ||||
| @@ -273,34 +274,33 @@ class LambdaFilter : public Filter { | ||||
| /// A simple filter that adds `offset` to each value it receives. | ||||
| class OffsetFilter : public Filter { | ||||
|  public: | ||||
|   explicit OffsetFilter(float offset); | ||||
|   explicit OffsetFilter(TemplatableValue<float> offset); | ||||
|  | ||||
|   optional<float> new_value(float value) override; | ||||
|  | ||||
|  protected: | ||||
|   float offset_; | ||||
|   TemplatableValue<float> offset_; | ||||
| }; | ||||
|  | ||||
| /// A simple filter that multiplies to each value it receives by `multiplier`. | ||||
| class MultiplyFilter : public Filter { | ||||
|  public: | ||||
|   explicit MultiplyFilter(float multiplier); | ||||
|  | ||||
|   explicit MultiplyFilter(TemplatableValue<float> multiplier); | ||||
|   optional<float> new_value(float value) override; | ||||
|  | ||||
|  protected: | ||||
|   float multiplier_; | ||||
|   TemplatableValue<float> multiplier_; | ||||
| }; | ||||
|  | ||||
| /// A simple filter that only forwards the filter chain if it doesn't receive `value_to_filter_out`. | ||||
| class FilterOutValueFilter : public Filter { | ||||
|  public: | ||||
|   explicit FilterOutValueFilter(float value_to_filter_out); | ||||
|   explicit FilterOutValueFilter(std::vector<TemplatableValue<float>> values_to_filter_out); | ||||
|  | ||||
|   optional<float> new_value(float value) override; | ||||
|  | ||||
|  protected: | ||||
|   float value_to_filter_out_; | ||||
|   std::vector<TemplatableValue<float>> values_to_filter_out_; | ||||
| }; | ||||
|  | ||||
| class ThrottleFilter : public Filter { | ||||
| @@ -316,8 +316,7 @@ class ThrottleFilter : public Filter { | ||||
|  | ||||
| class TimeoutFilter : public Filter, public Component { | ||||
|  public: | ||||
|   explicit TimeoutFilter(uint32_t time_period, float new_value); | ||||
|   void set_value(float new_value) { this->value_ = new_value; } | ||||
|   explicit TimeoutFilter(uint32_t time_period, TemplatableValue<float> new_value); | ||||
|  | ||||
|   optional<float> new_value(float value) override; | ||||
|  | ||||
| @@ -325,7 +324,7 @@ class TimeoutFilter : public Filter, public Component { | ||||
|  | ||||
|  protected: | ||||
|   uint32_t time_period_; | ||||
|   float value_; | ||||
|   TemplatableValue<float> value_; | ||||
| }; | ||||
|  | ||||
| class DebounceFilter : public Filter, public Component { | ||||
|   | ||||
| @@ -9,6 +9,25 @@ sensor: | ||||
|         return 0.0; | ||||
|       } | ||||
|     update_interval: 60s | ||||
|     filters: | ||||
|       - offset: 10 | ||||
|       - multiply: 1 | ||||
|       - offset: !lambda return 10; | ||||
|       - multiply: !lambda return 2; | ||||
|       - filter_out: | ||||
|           - 10 | ||||
|           - 20 | ||||
|           - !lambda return 10; | ||||
|       - filter_out: 10 | ||||
|       - filter_out: !lambda return NAN; | ||||
|       - timeout: | ||||
|           timeout: 10s | ||||
|           value: !lambda return 10; | ||||
|       - timeout: | ||||
|           timeout: 1h | ||||
|           value: 20.0 | ||||
|       - timeout: | ||||
|           timeout: 1d | ||||
|  | ||||
| esphome: | ||||
|   on_boot: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user