mirror of
https://github.com/esphome/esphome.git
synced 2024-11-21 14:38:10 +01:00
[sensor] Make some values templatable (#7735)
This commit is contained in:
parent
c35240ca32
commit
d885d65c9b
4 changed files with 65 additions and 36 deletions
|
@ -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;
|
||||
int8_t accuracy = this->parent_->get_accuracy_decimals();
|
||||
float accuracy_mult = powf(10.0f, accuracy);
|
||||
for (auto filter_value : this->values_to_filter_out_) {
|
||||
if (std::isnan(filter_value.value())) {
|
||||
if (std::isnan(value)) {
|
||||
return {};
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} 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_);
|
||||
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;
|
||||
}
|
||||
}
|
||||
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:
|
||||
|
|
Loading…
Reference in a new issue