mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Add GPIO Switch interlock wait time (#777)
* Add interlock wait time to gpio switch Fixes https://github.com/esphome/issues/issues/753 * Format * Fix
This commit is contained in:
		| @@ -15,12 +15,14 @@ RESTORE_MODES = { | |||||||
|     'ALWAYS_ON': GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_ON, |     'ALWAYS_ON': GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_ON, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | CONF_INTERLOCK_WAIT_TIME = 'interlock_wait_time' | ||||||
| CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend({ | CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend({ | ||||||
|     cv.GenerateID(): cv.declare_id(GPIOSwitch), |     cv.GenerateID(): cv.declare_id(GPIOSwitch), | ||||||
|     cv.Required(CONF_PIN): pins.gpio_output_pin_schema, |     cv.Required(CONF_PIN): pins.gpio_output_pin_schema, | ||||||
|     cv.Optional(CONF_RESTORE_MODE, default='RESTORE_DEFAULT_OFF'): |     cv.Optional(CONF_RESTORE_MODE, default='RESTORE_DEFAULT_OFF'): | ||||||
|         cv.enum(RESTORE_MODES, upper=True, space='_'), |         cv.enum(RESTORE_MODES, upper=True, space='_'), | ||||||
|     cv.Optional(CONF_INTERLOCK): cv.ensure_list(cv.use_id(switch.Switch)), |     cv.Optional(CONF_INTERLOCK): cv.ensure_list(cv.use_id(switch.Switch)), | ||||||
|  |     cv.Optional(CONF_INTERLOCK_WAIT_TIME, default='0ms'): cv.positive_time_period_milliseconds, | ||||||
| }).extend(cv.COMPONENT_SCHEMA) | }).extend(cv.COMPONENT_SCHEMA) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -40,3 +42,4 @@ def to_code(config): | |||||||
|             lock = yield cg.get_variable(it) |             lock = yield cg.get_variable(it) | ||||||
|             interlock.append(lock) |             interlock.append(lock) | ||||||
|         cg.add(var.set_interlock(interlock)) |         cg.add(var.set_interlock(interlock)) | ||||||
|  |         cg.add(var.set_interlock_wait_time(config[CONF_INTERLOCK_WAIT_TIME])) | ||||||
|   | |||||||
| @@ -69,14 +69,30 @@ void GPIOSwitch::dump_config() { | |||||||
| void GPIOSwitch::write_state(bool state) { | void GPIOSwitch::write_state(bool state) { | ||||||
|   if (state != this->inverted_) { |   if (state != this->inverted_) { | ||||||
|     // Turning ON, check interlocking |     // Turning ON, check interlocking | ||||||
|  |  | ||||||
|  |     bool found = false; | ||||||
|     for (auto *lock : this->interlock_) { |     for (auto *lock : this->interlock_) { | ||||||
|       if (lock == this) |       if (lock == this) | ||||||
|         continue; |         continue; | ||||||
|  |  | ||||||
|       if (lock->state) |       if (lock->state) { | ||||||
|         lock->turn_off(); |         lock->turn_off(); | ||||||
|  |         found = true; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |     if (found && this->interlock_wait_time_ != 0) { | ||||||
|  |       this->set_timeout("interlock", this->interlock_wait_time_, [this, state] { | ||||||
|  |         // Don't write directly, call the function again | ||||||
|  |         // (some other switch may have changed state while we were waiting) | ||||||
|  |         this->write_state(state); | ||||||
|  |       }); | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |   } else if (this->interlock_wait_time_ != 0) { | ||||||
|  |     // If we are switched off during the interlock wait time, cancel any pending | ||||||
|  |     // re-activations | ||||||
|  |     this->cancel_timeout("interlock"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   this->pin_->digital_write(state); |   this->pin_->digital_write(state); | ||||||
|   this->publish_state(state); |   this->publish_state(state); | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ class GPIOSwitch : public switch_::Switch, public Component { | |||||||
|   void setup() override; |   void setup() override; | ||||||
|   void dump_config() override; |   void dump_config() override; | ||||||
|   void set_interlock(const std::vector<Switch *> &interlock); |   void set_interlock(const std::vector<Switch *> &interlock); | ||||||
|  |   void set_interlock_wait_time(uint32_t interlock_wait_time) { interlock_wait_time_ = interlock_wait_time; } | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   void write_state(bool state) override; |   void write_state(bool state) override; | ||||||
| @@ -33,6 +34,7 @@ class GPIOSwitch : public switch_::Switch, public Component { | |||||||
|   GPIOPin *pin_; |   GPIOPin *pin_; | ||||||
|   GPIOSwitchRestoreMode restore_mode_{GPIO_SWITCH_RESTORE_DEFAULT_OFF}; |   GPIOSwitchRestoreMode restore_mode_{GPIO_SWITCH_RESTORE_DEFAULT_OFF}; | ||||||
|   std::vector<Switch *> interlock_; |   std::vector<Switch *> interlock_; | ||||||
|  |   uint32_t interlock_wait_time_{0}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace gpio | }  // namespace gpio | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user