mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01:00
Update the delta filter to take a percentage value as well as an absolute value (#4391)
This commit is contained in:
parent
1b8b8cdd11
commit
25fb288016
5 changed files with 29 additions and 10 deletions
|
@ -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 (fabsf(value - this->last_value_) >= this->min_delta_) {
|
||||
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_);
|
||||
}
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue