esphome/esphome/components/number/number_call.cpp
Maurice Makaay d9caab4108
Number enhancement (#3429)
Co-authored-by: Maurice Makaay <mmakaay1@xs4all.net>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
2022-05-10 16:58:56 +12:00

119 lines
3.8 KiB
C++

#include "number_call.h"
#include "number.h"
#include "esphome/core/log.h"
namespace esphome {
namespace number {
static const char *const TAG = "number";
NumberCall &NumberCall::set_value(float value) { return this->with_operation(NUMBER_OP_SET).with_value(value); }
NumberCall &NumberCall::number_increment(bool cycle) {
return this->with_operation(NUMBER_OP_INCREMENT).with_cycle(cycle);
}
NumberCall &NumberCall::number_decrement(bool cycle) {
return this->with_operation(NUMBER_OP_DECREMENT).with_cycle(cycle);
}
NumberCall &NumberCall::number_to_min() { return this->with_operation(NUMBER_OP_TO_MIN); }
NumberCall &NumberCall::number_to_max() { return this->with_operation(NUMBER_OP_TO_MAX); }
NumberCall &NumberCall::with_operation(NumberOperation operation) {
this->operation_ = operation;
return *this;
}
NumberCall &NumberCall::with_value(float value) {
this->value_ = value;
return *this;
}
NumberCall &NumberCall::with_cycle(bool cycle) {
this->cycle_ = cycle;
return *this;
}
void NumberCall::perform() {
auto *parent = this->parent_;
const auto *name = parent->get_name().c_str();
const auto &traits = parent->traits;
if (this->operation_ == NUMBER_OP_NONE) {
ESP_LOGW(TAG, "'%s' - NumberCall performed without selecting an operation", name);
return;
}
float target_value = NAN;
float min_value = traits.get_min_value();
float max_value = traits.get_max_value();
if (this->operation_ == NUMBER_OP_SET) {
ESP_LOGD(TAG, "'%s' - Setting number value", name);
if (!this->value_.has_value() || std::isnan(*this->value_)) {
ESP_LOGW(TAG, "'%s' - No value set for NumberCall", name);
return;
}
target_value = this->value_.value();
} else if (this->operation_ == NUMBER_OP_TO_MIN) {
if (std::isnan(min_value)) {
ESP_LOGW(TAG, "'%s' - Can't set to min value through NumberCall: no min_value defined", name);
} else {
target_value = min_value;
}
} else if (this->operation_ == NUMBER_OP_TO_MAX) {
if (std::isnan(max_value)) {
ESP_LOGW(TAG, "'%s' - Can't set to max value through NumberCall: no max_value defined", name);
} else {
target_value = max_value;
}
} else if (this->operation_ == NUMBER_OP_INCREMENT) {
ESP_LOGD(TAG, "'%s' - Increment number, with%s cycling", name, this->cycle_ ? "" : "out");
if (!parent->has_state()) {
ESP_LOGW(TAG, "'%s' - Can't increment number through NumberCall: no active state to modify", name);
return;
}
auto step = traits.get_step();
target_value = parent->state + (std::isnan(step) ? 1 : step);
if (target_value > max_value) {
if (this->cycle_ && !std::isnan(min_value)) {
target_value = min_value;
} else {
target_value = max_value;
}
}
} else if (this->operation_ == NUMBER_OP_DECREMENT) {
ESP_LOGD(TAG, "'%s' - Decrement number, with%s cycling", name, this->cycle_ ? "" : "out");
if (!parent->has_state()) {
ESP_LOGW(TAG, "'%s' - Can't decrement number through NumberCall: no active state to modify", name);
return;
}
auto step = traits.get_step();
target_value = parent->state - (std::isnan(step) ? 1 : step);
if (target_value < min_value) {
if (this->cycle_ && !std::isnan(max_value)) {
target_value = max_value;
} else {
target_value = min_value;
}
}
}
if (target_value < min_value) {
ESP_LOGW(TAG, "'%s' - Value %f must not be less than minimum %f", name, target_value, min_value);
return;
}
if (target_value > max_value) {
ESP_LOGW(TAG, "'%s' - Value %f must not be greater than maximum %f", name, target_value, max_value);
return;
}
ESP_LOGD(TAG, " New number value: %f", target_value);
this->parent_->control(target_value);
}
} // namespace number
} // namespace esphome