mirror of
https://github.com/esphome/esphome.git
synced 2024-11-29 18:24:13 +01:00
add time based cover, has built in endstop (#665)
* add has built in endstop * rewrite as proposed * Update esphome/components/time_based/time_based_cover.h Co-Authored-By: Otto Winter <otto@otto-winter.com> * lint * Re trigger stop_operation if stop called * allow se triggering open/close command if safe * using COVER_OPEN/CLOSE constants
This commit is contained in:
parent
d27291b997
commit
83a92f03fc
3 changed files with 23 additions and 4 deletions
|
@ -8,6 +8,8 @@ from esphome.const import CONF_CLOSE_ACTION, CONF_CLOSE_DURATION, CONF_ID, CONF_
|
||||||
time_based_ns = cg.esphome_ns.namespace('time_based')
|
time_based_ns = cg.esphome_ns.namespace('time_based')
|
||||||
TimeBasedCover = time_based_ns.class_('TimeBasedCover', cover.Cover, cg.Component)
|
TimeBasedCover = time_based_ns.class_('TimeBasedCover', cover.Cover, cg.Component)
|
||||||
|
|
||||||
|
CONF_HAS_BUILT_IN_ENDSTOP = 'has_built_in_endstop'
|
||||||
|
|
||||||
CONFIG_SCHEMA = cover.COVER_SCHEMA.extend({
|
CONFIG_SCHEMA = cover.COVER_SCHEMA.extend({
|
||||||
cv.GenerateID(): cv.declare_id(TimeBasedCover),
|
cv.GenerateID(): cv.declare_id(TimeBasedCover),
|
||||||
cv.Required(CONF_STOP_ACTION): automation.validate_automation(single=True),
|
cv.Required(CONF_STOP_ACTION): automation.validate_automation(single=True),
|
||||||
|
@ -17,6 +19,8 @@ CONFIG_SCHEMA = cover.COVER_SCHEMA.extend({
|
||||||
|
|
||||||
cv.Required(CONF_CLOSE_ACTION): automation.validate_automation(single=True),
|
cv.Required(CONF_CLOSE_ACTION): automation.validate_automation(single=True),
|
||||||
cv.Required(CONF_CLOSE_DURATION): cv.positive_time_period_milliseconds,
|
cv.Required(CONF_CLOSE_DURATION): cv.positive_time_period_milliseconds,
|
||||||
|
|
||||||
|
cv.Optional(CONF_HAS_BUILT_IN_ENDSTOP, default=False): cv.boolean,
|
||||||
}).extend(cv.COMPONENT_SCHEMA)
|
}).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,3 +36,5 @@ def to_code(config):
|
||||||
|
|
||||||
cg.add(var.set_close_duration(config[CONF_CLOSE_DURATION]))
|
cg.add(var.set_close_duration(config[CONF_CLOSE_DURATION]))
|
||||||
yield automation.build_automation(var.get_close_trigger(), [], config[CONF_CLOSE_ACTION])
|
yield automation.build_automation(var.get_close_trigger(), [], config[CONF_CLOSE_ACTION])
|
||||||
|
|
||||||
|
cg.add(var.set_has_built_in_endstop(config[CONF_HAS_BUILT_IN_ENDSTOP]))
|
||||||
|
|
|
@ -30,13 +30,18 @@ void TimeBasedCover::loop() {
|
||||||
// Recompute position every loop cycle
|
// Recompute position every loop cycle
|
||||||
this->recompute_position_();
|
this->recompute_position_();
|
||||||
|
|
||||||
if (this->current_operation != COVER_OPERATION_IDLE && this->is_at_target_()) {
|
if (this->is_at_target_()) {
|
||||||
|
if (this->has_built_in_endstop_ && (this->target_position_ == COVER_OPEN || this->target_position_ == COVER_CLOSED)) {
|
||||||
|
// Don't trigger stop, let the cover stop by itself.
|
||||||
|
this->current_operation = COVER_OPERATION_IDLE;
|
||||||
|
} else {
|
||||||
this->start_direction_(COVER_OPERATION_IDLE);
|
this->start_direction_(COVER_OPERATION_IDLE);
|
||||||
|
}
|
||||||
this->publish_state();
|
this->publish_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send current position every second
|
// Send current position every second
|
||||||
if (this->current_operation != COVER_OPERATION_IDLE && now - this->last_publish_time_ > 1000) {
|
if (now - this->last_publish_time_ > 1000) {
|
||||||
this->publish_state(false);
|
this->publish_state(false);
|
||||||
this->last_publish_time_ = now;
|
this->last_publish_time_ = now;
|
||||||
}
|
}
|
||||||
|
@ -57,6 +62,12 @@ void TimeBasedCover::control(const CoverCall &call) {
|
||||||
auto pos = *call.get_position();
|
auto pos = *call.get_position();
|
||||||
if (pos == this->position) {
|
if (pos == this->position) {
|
||||||
// already at target
|
// already at target
|
||||||
|
// for covers with built in end stop, we should send the command again
|
||||||
|
if (this->has_built_in_endstop_ && (pos == COVER_OPEN || pos == COVER_CLOSED)) {
|
||||||
|
auto op = pos == COVER_CLOSED ? COVER_OPERATION_CLOSING : COVER_OPERATION_OPENING;
|
||||||
|
this->target_position_ = pos;
|
||||||
|
this->start_direction_(op);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
auto op = pos < this->position ? COVER_OPERATION_CLOSING : COVER_OPERATION_OPENING;
|
auto op = pos < this->position ? COVER_OPERATION_CLOSING : COVER_OPERATION_OPENING;
|
||||||
this->target_position_ = pos;
|
this->target_position_ = pos;
|
||||||
|
@ -82,7 +93,7 @@ bool TimeBasedCover::is_at_target_() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void TimeBasedCover::start_direction_(CoverOperation dir) {
|
void TimeBasedCover::start_direction_(CoverOperation dir) {
|
||||||
if (dir == this->current_operation)
|
if (dir == this->current_operation && dir != COVER_OPERATION_IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this->recompute_position_();
|
this->recompute_position_();
|
||||||
|
|
|
@ -20,6 +20,7 @@ class TimeBasedCover : public cover::Cover, public Component {
|
||||||
void set_open_duration(uint32_t open_duration) { this->open_duration_ = open_duration; }
|
void set_open_duration(uint32_t open_duration) { this->open_duration_ = open_duration; }
|
||||||
void set_close_duration(uint32_t close_duration) { this->close_duration_ = close_duration; }
|
void set_close_duration(uint32_t close_duration) { this->close_duration_ = close_duration; }
|
||||||
cover::CoverTraits get_traits() override;
|
cover::CoverTraits get_traits() override;
|
||||||
|
void set_has_built_in_endstop(bool value) { this->has_built_in_endstop_ = value; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void control(const cover::CoverCall &call) override;
|
void control(const cover::CoverCall &call) override;
|
||||||
|
@ -41,6 +42,7 @@ class TimeBasedCover : public cover::Cover, public Component {
|
||||||
uint32_t start_dir_time_{0};
|
uint32_t start_dir_time_{0};
|
||||||
uint32_t last_publish_time_{0};
|
uint32_t last_publish_time_{0};
|
||||||
float target_position_{0};
|
float target_position_{0};
|
||||||
|
bool has_built_in_endstop_{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace time_based
|
} // namespace time_based
|
||||||
|
|
Loading…
Reference in a new issue