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:
Otto Winter 2019-10-20 18:10:14 +02:00
parent b70a0325c5
commit 644aec791e
No known key found for this signature in database
GPG key ID: DB66C0BE6013F97E
3 changed files with 22 additions and 1 deletions

View file

@ -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]))

View file

@ -69,13 +69,29 @@ 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);

View file

@ -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