diff --git a/components/hauslane/hauslane.cpp b/components/hauslane/hauslane.cpp index b66a837..0364e92 100644 --- a/components/hauslane/hauslane.cpp +++ b/components/hauslane/hauslane.cpp @@ -5,7 +5,6 @@ namespace esphome { namespace hauslane { static const char *TAG = "hauslane"; -static const int DELAY=250; // how long to press/release buttons in ms void Hauslane::setup() { // initialize the input pins @@ -65,6 +64,52 @@ void Hauslane::loop() { pos = 0; } } + + // execute new button press every DELAY ms if needed to adjust state + if (millis() - this->last_press > DELAY) { + if (this->last_button) { + // button already pressed, so de-activate button + button_press(this->last_button, false); + } else if (this->meet_target) { + // adjustment of speed/light requested, so press buttons until + // reaching speed_target and light_target + if (this->speed != this->speed_target) { + // adjust speed as necessary + if (this->speed_target==0 && !this->light_cur) { + // request fan turn off and light is off, so simply hit power button + button_press(pin_power, true); + } else if (this->speed == 0 && !this->light_cur) { + if (this->power) { + // power already on, so activate fan by pressing down button + button_press(pin_down, true); + } else { + // first activate by pressing power button + button_press(pin_power, true); + } + } else if (this->speed < this->speed_target) { + // increase speed + button_press(pin_up, true) + } else if (this->speed > this->speed_target) { + // decrease speed + button_press(pin_down, true) + } + } else if (this->light_cur != this->light_target) { + if (this->power) { + // press light button + button_press(pin_light, true) + } else { + // power on hood first + button_press(pin_power, true); + } + } else { + // target already met, so rest flag + this->meet_target=false; + } + } else if (this->speed==0 && !this->light_cur) { + // reset power flag + this->power=false; + } + } } } @@ -78,44 +123,17 @@ void Hauslane::dump_config() { // turns the light on/off void Hauslane::set_light(bool binary) { - if (this->light_cur != binary) { - if (speed==0) { - // fan is not on, so need to power system on before pressing light button - button_press(pin_power); - if (binary) { - button_press(pin_light); - } - } else { - // fan is on, so only need to press light button - button_press(pin_light); - } + if (this->light_target != binary) { + this->light_target = binary; + this->meet_target = true; } } // set the speed of the fan 0=off, 6=full void Hauslane::set_speed(int new_speed) { - if (new_speed==0 && !this->light_cur) { - // request fan turn off and light is off, so simply hit the power button - button_press(pin_power); - } else if (this->speed == 0) { - // requesting speed from 1-6 - if (!this->light_cur) { - // light is off, so activate hood with power button first - button_press(pin_power); - } - // turn on the fan to previously used speed by pressing down button - button_press(pin_down); - } else { - // adjust speed pressing up/down appropriate number of times - while (this->speed != new_speed) { - if (this->speed < new_speed) { - this->speed++; - button_press(pin_up); - } else if (this->speed > new_speed) { - this->speed--; - button_press(pin_down); - } - } + if (this->speed_target != new_speed) { + this->speed_target = new_speed; + this->meet_target = true; } } @@ -211,7 +229,7 @@ void Hauslane::set_state(bool set_light, uint8_t set_speed) { } if (speed != set_speed) { // save current state of fan in memory - ESP_LOGD(TAG, "Received fan peed: %d", set_speed); + ESP_LOGD(TAG, "Received fan speed: %d", set_speed); this->speed = set_speed; // send fan state to API if it is active if (this->send_fan_speed) { @@ -225,27 +243,34 @@ void Hauslane::set_state(bool set_light, uint8_t set_speed) { // simulates a button press for the specified button on front panel via GPIO void Hauslane::command(std::string command) { if (command == "timer" && pin_timer) { - button_press(pin_timer); + button_press(pin_timer, true); } else if (command == "up" && pin_up) { - button_press(pin_up); + button_press(pin_up, true); } else if (command =="down" && pin_down) { - button_press(pin_down); + button_press(pin_down, true); } else if (command == "light" && pin_light) { - button_press(pin_light); + button_press(pin_light, true); } else if (command == "power" && pin_power) { - button_press(pin_power); + button_press(pin_power, true); } else { ESP_LOGD(TAG, "Invalid button name: %s", command.c_str()); } } // simulate a button press by activating the GPIO then releasing -void Hauslane::button_press(GPIOPin *pin) { - ESP_LOGD(TAG, "Press button: %d", pin); - pin->digital_write(true); - delay(DELAY); - pin->digital_write(false); - delay(DELAY); +void Hauslane::button_press(GPIOPin *pin, val) { + if (val) { + ESP_LOGD(TAG, "Press button: %d", pin); + this->last_button=pin; + } else { + ESP_LOGD(TAG, "Release button: %d", pin); + if (this->last_button=this->power_pin) { + this->power= !this->power; + } + this->last_button=NULL; + } + pin->digital_write(val); + last_press=millis(); } // ESPHome light component diff --git a/components/hauslane/hauslane.h b/components/hauslane/hauslane.h index a797594..766fb57 100644 --- a/components/hauslane/hauslane.h +++ b/components/hauslane/hauslane.h @@ -17,6 +17,7 @@ static const unsigned char MSG_START[] = {0x08, 0x08, 0x08, 0xfe, 0xc0}; static const unsigned char MSG_END[] = {0xc0, 0xce, 0xce, 0xce}; static const uint8_t START_LEN=5; static const uint8_t END_LEN=4; +static const int DELAY=250; // how long to press/release buttons in ms class Hauslane : public Component, public uart::UARTDevice, public api::CustomAPIDevice { public: @@ -40,14 +41,20 @@ class Hauslane : public Component, public uart::UARTDevice, public api::CustomAP void parse_state(); void set_state(bool set_light, uint8_t set_speed); bool light_cur=false; + bool light_target=false; uint8_t speed=0; + uint8_t speed_target=0; + bool meet_target=false; + bool power=false; + unsigned long last_press=0; GPIOPin *pin_timer; GPIOPin *pin_up; GPIOPin *pin_down; GPIOPin *pin_light; GPIOPin *pin_power; + GPIOPin *last_button; void command(std::string command); - void button_press(GPIOPin *pin); + void button_press(GPIOPin *pin, bool val); std::function send_light_state; std::function send_fan_speed; };