Rewrite button presses in loop to prevent blocking
This commit is contained in:
@@ -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,55 @@ 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 != NULL) {
|
||||
// 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 reset flag
|
||||
this->meet_target=false;
|
||||
}
|
||||
} else if (this->speed==0 && !this->light_cur) {
|
||||
// reset power flag
|
||||
if(this->power) {
|
||||
this->power=false;
|
||||
ESP_LOGD(TAG, "Hood power: %d", this->power);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,44 +126,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,9 +230,9 @@ void Hauslane::set_state(bool set_light, uint8_t set_speed) {
|
||||
this->send_light_state(set_light);
|
||||
}
|
||||
}
|
||||
if (speed != set_speed) {
|
||||
if (this->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 +246,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) {
|
||||
void Hauslane::button_press(GPIOPin *pin, bool val) {
|
||||
if (val) {
|
||||
ESP_LOGD(TAG, "Press button: %d", pin);
|
||||
pin->digital_write(true);
|
||||
delay(DELAY);
|
||||
pin->digital_write(false);
|
||||
delay(DELAY);
|
||||
this->last_button=pin;
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Release button: %d", pin);
|
||||
if (this->last_button==this->pin_power) {
|
||||
this->power= !this->power;
|
||||
}
|
||||
this->last_button=NULL;
|
||||
}
|
||||
pin->digital_write(val);
|
||||
last_press=millis();
|
||||
}
|
||||
|
||||
// ESPHome light component
|
||||
|
||||
@@ -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<void(bool)> send_light_state;
|
||||
std::function<void(int)> send_fan_speed;
|
||||
};
|
||||
|
||||
@@ -38,6 +38,11 @@ captive_portal:
|
||||
uart:
|
||||
baud_rate: 3600
|
||||
rx_pin: 6
|
||||
# uncomment below to get the raw UART messages
|
||||
#debug:
|
||||
# direction: RX
|
||||
# sequence:
|
||||
# - lambda: UARTDebug::log_string(direction, bytes);
|
||||
|
||||
hauslane:
|
||||
id: hauslane_id
|
||||
|
||||
Reference in New Issue
Block a user