mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 09:18:00 +01:00
feedback component: Support for overshoot_duration
Allows the cover to overshoot max open-closed positions by some specific duration
This commit is contained in:
parent
1829e68730
commit
d99347404c
3 changed files with 34 additions and 7 deletions
|
@ -1,18 +1,18 @@
|
||||||
import esphome.codegen as cg
|
|
||||||
import esphome.config_validation as cv
|
|
||||||
from esphome import automation
|
from esphome import automation
|
||||||
|
import esphome.codegen as cg
|
||||||
from esphome.components import binary_sensor, cover
|
from esphome.components import binary_sensor, cover
|
||||||
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ASSUMED_STATE,
|
CONF_ASSUMED_STATE,
|
||||||
CONF_CLOSE_ACTION,
|
CONF_CLOSE_ACTION,
|
||||||
CONF_CLOSE_DURATION,
|
CONF_CLOSE_DURATION,
|
||||||
CONF_CLOSE_ENDSTOP,
|
CONF_CLOSE_ENDSTOP,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
|
CONF_MAX_DURATION,
|
||||||
CONF_OPEN_ACTION,
|
CONF_OPEN_ACTION,
|
||||||
CONF_OPEN_DURATION,
|
CONF_OPEN_DURATION,
|
||||||
CONF_OPEN_ENDSTOP,
|
CONF_OPEN_ENDSTOP,
|
||||||
CONF_STOP_ACTION,
|
CONF_STOP_ACTION,
|
||||||
CONF_MAX_DURATION,
|
|
||||||
CONF_UPDATE_INTERVAL,
|
CONF_UPDATE_INTERVAL,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ CONF_HAS_BUILT_IN_ENDSTOP = "has_built_in_endstop"
|
||||||
CONF_INFER_ENDSTOP_FROM_MOVEMENT = "infer_endstop_from_movement"
|
CONF_INFER_ENDSTOP_FROM_MOVEMENT = "infer_endstop_from_movement"
|
||||||
CONF_DIRECTION_CHANGE_WAIT_TIME = "direction_change_wait_time"
|
CONF_DIRECTION_CHANGE_WAIT_TIME = "direction_change_wait_time"
|
||||||
CONF_ACCELERATION_WAIT_TIME = "acceleration_wait_time"
|
CONF_ACCELERATION_WAIT_TIME = "acceleration_wait_time"
|
||||||
|
CONF_OVERSHOOT_DURATION = "overshoot_duration"
|
||||||
CONF_OBSTACLE_ROLLBACK = "obstacle_rollback"
|
CONF_OBSTACLE_ROLLBACK = "obstacle_rollback"
|
||||||
|
|
||||||
endstop_ns = cg.esphome_ns.namespace("feedback")
|
endstop_ns = cg.esphome_ns.namespace("feedback")
|
||||||
|
@ -77,6 +78,9 @@ CONFIG_FEEDBACK_COVER_BASE_SCHEMA = cover.COVER_SCHEMA.extend(
|
||||||
cv.Optional(
|
cv.Optional(
|
||||||
CONF_ACCELERATION_WAIT_TIME, "0s"
|
CONF_ACCELERATION_WAIT_TIME, "0s"
|
||||||
): cv.positive_time_period_milliseconds,
|
): cv.positive_time_period_milliseconds,
|
||||||
|
cv.Optional(
|
||||||
|
CONF_OVERSHOOT_DURATION, "0s"
|
||||||
|
): cv.positive_time_period_milliseconds,
|
||||||
cv.Optional(CONF_OBSTACLE_ROLLBACK, default="10%"): cv.percentage,
|
cv.Optional(CONF_OBSTACLE_ROLLBACK, default="10%"): cv.percentage,
|
||||||
},
|
},
|
||||||
).extend(cv.COMPONENT_SCHEMA)
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
@ -154,4 +158,5 @@ async def to_code(config):
|
||||||
var.set_direction_change_waittime(config[CONF_DIRECTION_CHANGE_WAIT_TIME])
|
var.set_direction_change_waittime(config[CONF_DIRECTION_CHANGE_WAIT_TIME])
|
||||||
)
|
)
|
||||||
cg.add(var.set_acceleration_wait_time(config[CONF_ACCELERATION_WAIT_TIME]))
|
cg.add(var.set_acceleration_wait_time(config[CONF_ACCELERATION_WAIT_TIME]))
|
||||||
|
cg.add(var.set_overshoot_duration(config[CONF_OVERSHOOT_DURATION]))
|
||||||
cg.add(var.set_obstacle_rollback(config[CONF_OBSTACLE_ROLLBACK]))
|
cg.add(var.set_obstacle_rollback(config[CONF_OBSTACLE_ROLLBACK]))
|
||||||
|
|
|
@ -77,6 +77,9 @@ void FeedbackCover::dump_config() {
|
||||||
if (this->acceleration_wait_time_) {
|
if (this->acceleration_wait_time_) {
|
||||||
ESP_LOGCONFIG(TAG, " Acceleration wait time: %.1fs", this->acceleration_wait_time_ / 1e3f);
|
ESP_LOGCONFIG(TAG, " Acceleration wait time: %.1fs", this->acceleration_wait_time_ / 1e3f);
|
||||||
}
|
}
|
||||||
|
if (this->overshoot_duration_) {
|
||||||
|
ESP_LOGCONFIG(TAG, " Overshoot duration: %.1fs", this->overshoot_duration_ / 1e3f);
|
||||||
|
}
|
||||||
#ifdef USE_BINARY_SENSOR
|
#ifdef USE_BINARY_SENSOR
|
||||||
if (this->obstacle_rollback_ && (this->open_obstacle_ != nullptr || this->close_obstacle_ != nullptr)) {
|
if (this->obstacle_rollback_ && (this->open_obstacle_ != nullptr || this->close_obstacle_ != nullptr)) {
|
||||||
ESP_LOGCONFIG(TAG, " Obstacle rollback: %.1f%%", this->obstacle_rollback_ * 100);
|
ESP_LOGCONFIG(TAG, " Obstacle rollback: %.1f%%", this->obstacle_rollback_ * 100);
|
||||||
|
@ -229,11 +232,26 @@ void FeedbackCover::loop() {
|
||||||
// (stoping from endstop sensor is handled in callback)
|
// (stoping from endstop sensor is handled in callback)
|
||||||
if (this->current_trigger_operation_ != COVER_OPERATION_IDLE) {
|
if (this->current_trigger_operation_ != COVER_OPERATION_IDLE) {
|
||||||
if (this->is_at_target_()) {
|
if (this->is_at_target_()) {
|
||||||
if (this->has_built_in_endstop_ &&
|
if (this->target_position_ == COVER_OPEN || this->target_position_ == COVER_CLOSED) {
|
||||||
(this->target_position_ == COVER_OPEN || this->target_position_ == COVER_CLOSED)) {
|
if (this->has_built_in_endstop_) {
|
||||||
// Don't trigger stop, let the cover stop by itself.
|
// Don't trigger stop, let the cover stop by itself.
|
||||||
this->set_current_operation_(COVER_OPERATION_IDLE, true);
|
this->set_current_operation_(COVER_OPERATION_IDLE, true);
|
||||||
|
} else if (this->overshoot_duration_) {
|
||||||
|
// We want to overshoot a bit on cover being totaly open or closed, in order to make sure cover is synced
|
||||||
|
if (!this->start_overshoot_time_) {
|
||||||
|
// We just started overshooting, save time for comparison
|
||||||
|
this->start_overshoot_time_ = now;
|
||||||
|
} else if (now - this->start_overshoot_time_ > this->overshoot_duration_) {
|
||||||
|
// We overshot enough, stop the cover
|
||||||
|
ESP_LOGD(TAG, "'%s' - Overshoot duration reached. Stopping cover.", this->name_.c_str());
|
||||||
|
this->start_direction_(COVER_OPERATION_IDLE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No overshoot_duration, stop immediately at open-close
|
||||||
|
this->start_direction_(COVER_OPERATION_IDLE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Not on open-close position, stop immediately
|
||||||
this->start_direction_(COVER_OPERATION_IDLE);
|
this->start_direction_(COVER_OPERATION_IDLE);
|
||||||
}
|
}
|
||||||
} else if (now - this->start_dir_time_ > this->max_duration_) {
|
} else if (now - this->start_dir_time_ > this->max_duration_) {
|
||||||
|
@ -335,6 +353,7 @@ void FeedbackCover::start_direction_(CoverOperation dir) {
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
case COVER_OPERATION_IDLE:
|
case COVER_OPERATION_IDLE:
|
||||||
trig = this->stop_trigger_;
|
trig = this->stop_trigger_;
|
||||||
|
this->start_overshoot_time_ = 0;
|
||||||
break;
|
break;
|
||||||
case COVER_OPERATION_OPENING:
|
case COVER_OPERATION_OPENING:
|
||||||
this->last_operation_ = dir;
|
this->last_operation_ = dir;
|
||||||
|
|
|
@ -35,6 +35,7 @@ class FeedbackCover : public cover::Cover, public Component {
|
||||||
void set_has_built_in_endstop(bool value) { this->has_built_in_endstop_ = value; }
|
void set_has_built_in_endstop(bool value) { this->has_built_in_endstop_ = value; }
|
||||||
void set_assumed_state(bool value) { this->assumed_state_ = value; }
|
void set_assumed_state(bool value) { this->assumed_state_ = value; }
|
||||||
void set_max_duration(uint32_t max_duration) { this->max_duration_ = max_duration; }
|
void set_max_duration(uint32_t max_duration) { this->max_duration_ = max_duration; }
|
||||||
|
void set_overshoot_duration(uint32_t overshoot_duration) { this->overshoot_duration_ = overshoot_duration; }
|
||||||
void set_obstacle_rollback(float obstacle_rollback) { this->obstacle_rollback_ = obstacle_rollback; }
|
void set_obstacle_rollback(float obstacle_rollback) { this->obstacle_rollback_ = obstacle_rollback; }
|
||||||
void set_update_interval(uint32_t interval) { this->update_interval_ = interval; }
|
void set_update_interval(uint32_t interval) { this->update_interval_ = interval; }
|
||||||
void set_infer_endstop(bool infer_endstop) { this->infer_endstop_ = infer_endstop; }
|
void set_infer_endstop(bool infer_endstop) { this->infer_endstop_ = infer_endstop; }
|
||||||
|
@ -69,6 +70,7 @@ class FeedbackCover : public cover::Cover, public Component {
|
||||||
uint32_t open_duration_{0};
|
uint32_t open_duration_{0};
|
||||||
uint32_t close_duration_{0};
|
uint32_t close_duration_{0};
|
||||||
uint32_t max_duration_{UINT32_MAX};
|
uint32_t max_duration_{UINT32_MAX};
|
||||||
|
uint32_t overshoot_duration_{0};
|
||||||
optional<uint32_t> direction_change_waittime_{};
|
optional<uint32_t> direction_change_waittime_{};
|
||||||
uint32_t acceleration_wait_time_{0};
|
uint32_t acceleration_wait_time_{0};
|
||||||
bool has_built_in_endstop_{false};
|
bool has_built_in_endstop_{false};
|
||||||
|
@ -82,6 +84,7 @@ class FeedbackCover : public cover::Cover, public Component {
|
||||||
uint32_t last_recompute_time_{0};
|
uint32_t last_recompute_time_{0};
|
||||||
uint32_t start_dir_time_{0};
|
uint32_t start_dir_time_{0};
|
||||||
uint32_t last_publish_time_{0};
|
uint32_t last_publish_time_{0};
|
||||||
|
uint32_t start_overshoot_time_{0};
|
||||||
float target_position_{0};
|
float target_position_{0};
|
||||||
uint32_t update_interval_{1000};
|
uint32_t update_interval_{1000};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue