diff --git a/esphome/components/time_based/time_based_cover.cpp b/esphome/components/time_based/time_based_cover.cpp index e1936d5ee1..cb51467814 100644 --- a/esphome/components/time_based/time_based_cover.cpp +++ b/esphome/components/time_based/time_based_cover.cpp @@ -63,14 +63,18 @@ void TimeBasedCover::control(const CoverCall &call) { this->publish_state(); } if (call.get_toggle().has_value()) { + // Cover is not idle -> stop it if (this->current_operation != COVER_OPERATION_IDLE) { this->start_direction_(COVER_OPERATION_IDLE); this->publish_state(); } else { - if (this->position == COVER_CLOSED || this->last_operation_ == COVER_OPERATION_CLOSING) { + // Cover is idle, check its last direction of movement + if (this->position == COVER_CLOSED || this->last_moving_operation_ == COVER_OPERATION_CLOSING) { + // Cover was closing -> open it this->target_position_ = COVER_OPEN; this->start_direction_(COVER_OPERATION_OPENING); } else { + // Cover was opening -> close it this->target_position_ = COVER_CLOSED; this->start_direction_(COVER_OPERATION_CLOSING); } @@ -126,17 +130,20 @@ void TimeBasedCover::start_direction_(CoverOperation dir) { return; this->recompute_position_(); + // Keep track of the previous operation the cover was in + this->last_operation_ = current_operation; + Trigger<> *trig; switch (dir) { case COVER_OPERATION_IDLE: trig = this->stop_trigger_; break; case COVER_OPERATION_OPENING: - this->last_operation_ = dir; + this->last_moving_operation_ = dir; trig = this->open_trigger_; break; case COVER_OPERATION_CLOSING: - this->last_operation_ = dir; + this->last_moving_operation_ = dir; trig = this->close_trigger_; break; default: diff --git a/esphome/components/time_based/time_based_cover.h b/esphome/components/time_based/time_based_cover.h index 42cf66c2ab..f5d179aca7 100644 --- a/esphome/components/time_based/time_based_cover.h +++ b/esphome/components/time_based/time_based_cover.h @@ -23,7 +23,10 @@ class TimeBasedCover : public cover::Cover, public Component { void set_has_built_in_endstop(bool value) { this->has_built_in_endstop_ = value; } void set_manual_control(bool value) { this->manual_control_ = value; } void set_assumed_state(bool value) { this->assumed_state_ = value; } + // Return the previous operation the cover was executing. cover::CoverOperation get_last_operation() const { return this->last_operation_; } + // Return the previous direction of travel of the cover (either OPENING or CLOSING) + cover::CoverOperation get_last_moving_operation() const { return this->last_moving_operation_; } protected: void control(const cover::CoverCall &call) override; @@ -48,7 +51,12 @@ class TimeBasedCover : public cover::Cover, public Component { bool has_built_in_endstop_{false}; bool manual_control_{false}; bool assumed_state_{false}; - cover::CoverOperation last_operation_{cover::COVER_OPERATION_OPENING}; + // Keep track of the previous operation the cover was in. + // Useful for instance to decide how to issue a command on the basis on the last received command. + cover::CoverOperation last_operation_{cover::COVER_OPERATION_IDLE}; + // Keep track of the previous direction the cover was moving towards (either OPENING or CLOSING). + // Used by the toggle() action to know the previous direction of travel of the cover. + cover::CoverOperation last_moving_operation_{cover::COVER_OPERATION_OPENING}; }; } // namespace time_based