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') | ||||
| 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({ | ||||
|     cv.GenerateID(): cv.declare_id(TimeBasedCover), | ||||
|     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_DURATION): cv.positive_time_period_milliseconds, | ||||
|  | ||||
|     cv.Optional(CONF_HAS_BUILT_IN_ENDSTOP, default=False): cv.boolean, | ||||
| }).extend(cv.COMPONENT_SCHEMA) | ||||
|  | ||||
|  | ||||
| @@ -32,3 +36,5 @@ def to_code(config): | ||||
|  | ||||
|     cg.add(var.set_close_duration(config[CONF_CLOSE_DURATION])) | ||||
|     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 | ||||
|   this->recompute_position_(); | ||||
|  | ||||
|   if (this->current_operation != COVER_OPERATION_IDLE && this->is_at_target_()) { | ||||
|     this->start_direction_(COVER_OPERATION_IDLE); | ||||
|   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->publish_state(); | ||||
|   } | ||||
|  | ||||
|   // 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->last_publish_time_ = now; | ||||
|   } | ||||
| @@ -57,6 +62,12 @@ void TimeBasedCover::control(const CoverCall &call) { | ||||
|     auto pos = *call.get_position(); | ||||
|     if (pos == this->position) { | ||||
|       // 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 { | ||||
|       auto op = pos < this->position ? COVER_OPERATION_CLOSING : COVER_OPERATION_OPENING; | ||||
|       this->target_position_ = pos; | ||||
| @@ -82,7 +93,7 @@ bool TimeBasedCover::is_at_target_() const { | ||||
|   } | ||||
| } | ||||
| void TimeBasedCover::start_direction_(CoverOperation dir) { | ||||
|   if (dir == this->current_operation) | ||||
|   if (dir == this->current_operation && dir != COVER_OPERATION_IDLE) | ||||
|     return; | ||||
|  | ||||
|   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_close_duration(uint32_t close_duration) { this->close_duration_ = close_duration; } | ||||
|   cover::CoverTraits get_traits() override; | ||||
|   void set_has_built_in_endstop(bool value) { this->has_built_in_endstop_ = value; } | ||||
|  | ||||
|  protected: | ||||
|   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 last_publish_time_{0}; | ||||
|   float target_position_{0}; | ||||
|   bool has_built_in_endstop_{false}; | ||||
| }; | ||||
|  | ||||
| }  // namespace time_based | ||||
|   | ||||
		Reference in New Issue
	
	Block a user