Rewrite button presses in loop to prevent blocking
This commit is contained in:
@@ -5,7 +5,6 @@ namespace esphome {
|
|||||||
namespace hauslane {
|
namespace hauslane {
|
||||||
|
|
||||||
static const char *TAG = "hauslane";
|
static const char *TAG = "hauslane";
|
||||||
static const int DELAY=250; // how long to press/release buttons in ms
|
|
||||||
|
|
||||||
void Hauslane::setup() {
|
void Hauslane::setup() {
|
||||||
// initialize the input pins
|
// initialize the input pins
|
||||||
@@ -65,6 +64,52 @@ void Hauslane::loop() {
|
|||||||
pos = 0;
|
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
|
// turns the light on/off
|
||||||
void Hauslane::set_light(bool binary) {
|
void Hauslane::set_light(bool binary) {
|
||||||
if (this->light_cur != binary) {
|
if (this->light_target != binary) {
|
||||||
if (speed==0) {
|
this->light_target = binary;
|
||||||
// fan is not on, so need to power system on before pressing light button
|
this->meet_target = true;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the speed of the fan 0=off, 6=full
|
// set the speed of the fan 0=off, 6=full
|
||||||
void Hauslane::set_speed(int new_speed) {
|
void Hauslane::set_speed(int new_speed) {
|
||||||
if (new_speed==0 && !this->light_cur) {
|
if (this->speed_target != new_speed) {
|
||||||
// request fan turn off and light is off, so simply hit the power button
|
this->speed_target = new_speed;
|
||||||
button_press(pin_power);
|
this->meet_target = true;
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +229,7 @@ void Hauslane::set_state(bool set_light, uint8_t set_speed) {
|
|||||||
}
|
}
|
||||||
if (speed != set_speed) {
|
if (speed != set_speed) {
|
||||||
// save current state of fan in memory
|
// 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;
|
this->speed = set_speed;
|
||||||
// send fan state to API if it is active
|
// send fan state to API if it is active
|
||||||
if (this->send_fan_speed) {
|
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
|
// simulates a button press for the specified button on front panel via GPIO
|
||||||
void Hauslane::command(std::string command) {
|
void Hauslane::command(std::string command) {
|
||||||
if (command == "timer" && pin_timer) {
|
if (command == "timer" && pin_timer) {
|
||||||
button_press(pin_timer);
|
button_press(pin_timer, true);
|
||||||
} else if (command == "up" && pin_up) {
|
} else if (command == "up" && pin_up) {
|
||||||
button_press(pin_up);
|
button_press(pin_up, true);
|
||||||
} else if (command =="down" && pin_down) {
|
} else if (command =="down" && pin_down) {
|
||||||
button_press(pin_down);
|
button_press(pin_down, true);
|
||||||
} else if (command == "light" && pin_light) {
|
} else if (command == "light" && pin_light) {
|
||||||
button_press(pin_light);
|
button_press(pin_light, true);
|
||||||
} else if (command == "power" && pin_power) {
|
} else if (command == "power" && pin_power) {
|
||||||
button_press(pin_power);
|
button_press(pin_power, true);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGD(TAG, "Invalid button name: %s", command.c_str());
|
ESP_LOGD(TAG, "Invalid button name: %s", command.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulate a button press by activating the GPIO then releasing
|
// simulate a button press by activating the GPIO then releasing
|
||||||
void Hauslane::button_press(GPIOPin *pin) {
|
void Hauslane::button_press(GPIOPin *pin, val) {
|
||||||
|
if (val) {
|
||||||
ESP_LOGD(TAG, "Press button: %d", pin);
|
ESP_LOGD(TAG, "Press button: %d", pin);
|
||||||
pin->digital_write(true);
|
this->last_button=pin;
|
||||||
delay(DELAY);
|
} else {
|
||||||
pin->digital_write(false);
|
ESP_LOGD(TAG, "Release button: %d", pin);
|
||||||
delay(DELAY);
|
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
|
// 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 unsigned char MSG_END[] = {0xc0, 0xce, 0xce, 0xce};
|
||||||
static const uint8_t START_LEN=5;
|
static const uint8_t START_LEN=5;
|
||||||
static const uint8_t END_LEN=4;
|
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 {
|
class Hauslane : public Component, public uart::UARTDevice, public api::CustomAPIDevice {
|
||||||
public:
|
public:
|
||||||
@@ -40,14 +41,20 @@ class Hauslane : public Component, public uart::UARTDevice, public api::CustomAP
|
|||||||
void parse_state();
|
void parse_state();
|
||||||
void set_state(bool set_light, uint8_t set_speed);
|
void set_state(bool set_light, uint8_t set_speed);
|
||||||
bool light_cur=false;
|
bool light_cur=false;
|
||||||
|
bool light_target=false;
|
||||||
uint8_t speed=0;
|
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_timer;
|
||||||
GPIOPin *pin_up;
|
GPIOPin *pin_up;
|
||||||
GPIOPin *pin_down;
|
GPIOPin *pin_down;
|
||||||
GPIOPin *pin_light;
|
GPIOPin *pin_light;
|
||||||
GPIOPin *pin_power;
|
GPIOPin *pin_power;
|
||||||
|
GPIOPin *last_button;
|
||||||
void command(std::string command);
|
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(bool)> send_light_state;
|
||||||
std::function<void(int)> send_fan_speed;
|
std::function<void(int)> send_fan_speed;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user