mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00: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:
		
				
					committed by
					
						 Otto Winter
						Otto Winter
					
				
			
			
				
	
			
			
			
						parent
						
							d27291b997
						
					
				
				
					commit
					83a92f03fc
				
			| @@ -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_()) { | ||||||
|     this->start_direction_(COVER_OPERATION_IDLE); |     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->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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user