mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 00:18:11 +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)
|
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):
|
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):
|
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):
|
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(
|
QUANTILE_SCHEMA = cv.All(
|
||||||
|
@ -573,7 +582,7 @@ async def heartbeat_filter_to_code(config, filter_id):
|
||||||
TIMEOUT_SCHEMA = cv.maybe_simple_value(
|
TIMEOUT_SCHEMA = cv.maybe_simple_value(
|
||||||
{
|
{
|
||||||
cv.Required(CONF_TIMEOUT): cv.positive_time_period_milliseconds,
|
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,
|
key=CONF_TIMEOUT,
|
||||||
)
|
)
|
||||||
|
@ -581,7 +590,8 @@ TIMEOUT_SCHEMA = cv.maybe_simple_value(
|
||||||
|
|
||||||
@FILTER_REGISTRY.register("timeout", TimeoutFilter, TIMEOUT_SCHEMA)
|
@FILTER_REGISTRY.register("timeout", TimeoutFilter, TIMEOUT_SCHEMA)
|
||||||
async def timeout_filter_to_code(config, filter_id):
|
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, {})
|
await cg.register_component(var, {})
|
||||||
return var
|
return var
|
||||||
|
|
||||||
|
|
|
@ -288,37 +288,37 @@ optional<float> LambdaFilter::new_value(float value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// OffsetFilter
|
// 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::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::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) {
|
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();
|
int8_t accuracy = this->parent_->get_accuracy_decimals();
|
||||||
float accuracy_mult = powf(10.0f, accuracy);
|
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);
|
float rounded_value = roundf(accuracy_mult * value);
|
||||||
if (rounded_filter_out == rounded_value) {
|
if (rounded_filter_out == rounded_value) {
|
||||||
return {};
|
return {};
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ThrottleFilter
|
// ThrottleFilter
|
||||||
ThrottleFilter::ThrottleFilter(uint32_t min_time_between_inputs) : min_time_between_inputs_(min_time_between_inputs) {}
|
ThrottleFilter::ThrottleFilter(uint32_t min_time_between_inputs) : min_time_between_inputs_(min_time_between_inputs) {}
|
||||||
|
@ -383,11 +383,12 @@ void OrFilter::initialize(Sensor *parent, Filter *next) {
|
||||||
|
|
||||||
// TimeoutFilter
|
// TimeoutFilter
|
||||||
optional<float> TimeoutFilter::new_value(float value) {
|
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;
|
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; }
|
float TimeoutFilter::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||||
|
|
||||||
// DebounceFilter
|
// DebounceFilter
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
|
#include "esphome/core/automation.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace sensor {
|
namespace sensor {
|
||||||
|
@ -273,34 +274,33 @@ class LambdaFilter : public Filter {
|
||||||
/// A simple filter that adds `offset` to each value it receives.
|
/// A simple filter that adds `offset` to each value it receives.
|
||||||
class OffsetFilter : public Filter {
|
class OffsetFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
explicit OffsetFilter(float offset);
|
explicit OffsetFilter(TemplatableValue<float> offset);
|
||||||
|
|
||||||
optional<float> new_value(float value) override;
|
optional<float> new_value(float value) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float offset_;
|
TemplatableValue<float> offset_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A simple filter that multiplies to each value it receives by `multiplier`.
|
/// A simple filter that multiplies to each value it receives by `multiplier`.
|
||||||
class MultiplyFilter : public Filter {
|
class MultiplyFilter : public Filter {
|
||||||
public:
|
public:
|
||||||
explicit MultiplyFilter(float multiplier);
|
explicit MultiplyFilter(TemplatableValue<float> multiplier);
|
||||||
|
|
||||||
optional<float> new_value(float value) override;
|
optional<float> new_value(float value) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float multiplier_;
|
TemplatableValue<float> multiplier_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A simple filter that only forwards the filter chain if it doesn't receive `value_to_filter_out`.
|
/// A simple filter that only forwards the filter chain if it doesn't receive `value_to_filter_out`.
|
||||||
class FilterOutValueFilter : public Filter {
|
class FilterOutValueFilter : public Filter {
|
||||||
public:
|
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;
|
optional<float> new_value(float value) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float value_to_filter_out_;
|
std::vector<TemplatableValue<float>> values_to_filter_out_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThrottleFilter : public Filter {
|
class ThrottleFilter : public Filter {
|
||||||
|
@ -316,8 +316,7 @@ class ThrottleFilter : public Filter {
|
||||||
|
|
||||||
class TimeoutFilter : public Filter, public Component {
|
class TimeoutFilter : public Filter, public Component {
|
||||||
public:
|
public:
|
||||||
explicit TimeoutFilter(uint32_t time_period, float new_value);
|
explicit TimeoutFilter(uint32_t time_period, TemplatableValue<float> new_value);
|
||||||
void set_value(float new_value) { this->value_ = new_value; }
|
|
||||||
|
|
||||||
optional<float> new_value(float value) override;
|
optional<float> new_value(float value) override;
|
||||||
|
|
||||||
|
@ -325,7 +324,7 @@ class TimeoutFilter : public Filter, public Component {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint32_t time_period_;
|
uint32_t time_period_;
|
||||||
float value_;
|
TemplatableValue<float> value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DebounceFilter : public Filter, public Component {
|
class DebounceFilter : public Filter, public Component {
|
||||||
|
|
|
@ -9,6 +9,25 @@ sensor:
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
update_interval: 60s
|
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:
|
esphome:
|
||||||
on_boot:
|
on_boot:
|
||||||
|
|
Loading…
Reference in a new issue