#include "hbridge_switch.h" #include "esphome/core/log.h" #include namespace esphome { namespace hbridge { static const char *const TAG = "switch.hbridge"; float HBridgeSwitch::get_setup_priority() const { return setup_priority::HARDWARE; } void HBridgeSwitch::setup() { ESP_LOGCONFIG(TAG, "Running setup for '%s'", this->name_.c_str()); optional initial_state = this->get_initial_state_with_restore_mode(); // Like GPIOSwitch does, set the pin state both before and after pin setup() this->on_pin_->digital_write(false); this->on_pin_->setup(); this->on_pin_->digital_write(false); this->off_pin_->digital_write(false); this->off_pin_->setup(); this->off_pin_->digital_write(false); if (initial_state.has_value()) this->write_state(initial_state.value()); } void HBridgeSwitch::dump_config() { LOG_SWITCH("", "H-Bridge Switch", this); LOG_PIN(" On Pin: ", this->on_pin_); LOG_PIN(" Off Pin: ", this->off_pin_); ESP_LOGCONFIG(TAG, " Pulse length: %" PRId32 " ms", this->pulse_length_); if (this->wait_time_) ESP_LOGCONFIG(TAG, " Wait time %" PRId32 " ms", this->wait_time_); } void HBridgeSwitch::write_state(bool state) { this->desired_state_ = state; if (!this->timer_running_) this->timer_fn_(); } void HBridgeSwitch::timer_fn_() { uint32_t next_timeout = 0; while ((uint8_t) this->desired_state_ != this->relay_state_) { switch (this->relay_state_) { case RELAY_STATE_ON: case RELAY_STATE_OFF: case RELAY_STATE_UNKNOWN: if (this->desired_state_) { this->on_pin_->digital_write(true); this->relay_state_ = RELAY_STATE_SWITCHING_ON; } else { this->off_pin_->digital_write(true); this->relay_state_ = RELAY_STATE_SWITCHING_OFF; } next_timeout = this->pulse_length_; if (!this->optimistic_) this->publish_state(this->desired_state_); break; case RELAY_STATE_SWITCHING_ON: this->on_pin_->digital_write(false); this->relay_state_ = RELAY_STATE_ON; if (this->optimistic_) this->publish_state(true); next_timeout = this->wait_time_; break; case RELAY_STATE_SWITCHING_OFF: this->off_pin_->digital_write(false); this->relay_state_ = RELAY_STATE_OFF; if (this->optimistic_) this->publish_state(false); next_timeout = this->wait_time_; break; } if (next_timeout) { this->timer_running_ = true; this->set_timeout(next_timeout, [this]() { this->timer_fn_(); }); return; } // In the case where ON/OFF state has been reached but we need to // immediately change back again to reach desired_state_, we loop. } this->timer_running_ = false; } } // namespace hbridge } // namespace esphome