Handle special timeouts after power commands

This commit is contained in:
sqozz 2024-09-19 00:43:28 +02:00
parent 97c266f70f
commit b36e0aa9bf
2 changed files with 19 additions and 4 deletions

View file

@ -9,6 +9,7 @@ namespace esphome {
namespace tw7100 { namespace tw7100 {
bool waiting_for_answer = false; bool waiting_for_answer = false;
bool waiting_for_error_report = false;
unsigned long waiting_for_answer_since = 0; unsigned long waiting_for_answer_since = 0;
std::deque<std::string> cmd_queue; std::deque<std::string> cmd_queue;
unsigned long last_set_cmd_timestamp; unsigned long last_set_cmd_timestamp;
@ -139,13 +140,14 @@ void tw7100Component::loop() {
std::string response = readStringUntil(':'); std::string response = readStringUntil(':');
if (response == "") { // no response on bus, we can use our time to do something else if (response == "") { // no response on bus, we can use our time to do something else
if (!cmd_queue.empty() && !waiting_for_answer && (millis() - last_set_cmd_timestamp > _timeout_after_cmd)) { if (!cmd_queue.empty() && !waiting_for_answer && (millis() - last_set_cmd_timestamp > std::max(_timeout_after_cmd, _specialTimeoutMillis))) {
std::string cmd = cmd_queue.front(); std::string cmd = cmd_queue.front();
cmd_queue.pop_front(); cmd_queue.pop_front();
ESP_LOGV(TAG, "sending out command: %s", cmd.c_str()); ESP_LOGV(TAG, "sending out command: %s", cmd.c_str());
write_str((cmd + "\r\n").c_str()); write_str((cmd + "\r\n").c_str());
flush(); flush();
if (cmd.find("?") != std::string::npos) { // only wait for response on CMD? requests if (cmd.find("?") != std::string::npos) { // only wait for response on CMD? requests
_specialTimeoutMillis = 0;
waiting_for_answer = true; waiting_for_answer = true;
waiting_for_answer_since = millis(); waiting_for_answer_since = millis();
} else { } else {
@ -160,13 +162,15 @@ void tw7100Component::loop() {
ESP_LOGV(TAG, "buffer content: %s", response.c_str()); ESP_LOGV(TAG, "buffer content: %s", response.c_str());
std::pair<std::string, std::string> parsed_response = parse_response(response); std::pair<std::string, std::string> parsed_response = parse_response(response);
if (parsed_response.first == "ERR" && parsed_response.second == "ERR") { if (parsed_response.first == "ERR" && parsed_response.second == "ERR") {
if (powered_->state) {; if (powered_->state && !waiting_for_error_report) {
ESP_LOGW(TAG, "found ERR response, pushing request to fetch full error"); ESP_LOGW(TAG, "found ERR response, pushing request to fetch full error");
cmd_queue.push_front("ERR?"); // TODO: produces a ERR? loop on bootup if projector is turned off waiting_for_error_report = true;
cmd_queue.push_front("ERR?");
} else { } else {
ESP_LOGE(TAG, "got ERR while projector is off, check if PWR+LAMP is too much?"); ESP_LOGW(TAG, "got ERR while projector is off or waiting for a previous error report");
} }
} else if (parsed_response.first == "ERR") { } else if (parsed_response.first == "ERR") {
waiting_for_error_report = false;
ESP_LOGE(TAG, "found ERR report, reason is: %s", parsed_response.second.c_str()); ESP_LOGE(TAG, "found ERR report, reason is: %s", parsed_response.second.c_str());
// TODO: Handle error // TODO: Handle error
} else { } else {
@ -188,10 +192,20 @@ void tw7100Component::dump_config() {
void tw7100Component::push_cmd(std::string cmd, std::string param) { void tw7100Component::push_cmd(std::string cmd, std::string param) {
static const char *const TAG = "push_cmd()"; static const char *const TAG = "push_cmd()";
if (powered_->state) { if (powered_->state) {
if (cmd == "PWR" && param == "OFF") {
_specialTimeoutMillis = 5000; // time to wait after PWR OFF until projector responds again
cmd_queue.clear(); // clear eventual existing query commands to avoid errors
}
if ((cmd == "SOURCE")||(cmd == "MUTE")) {
_specialTimeoutMillis = 4000; // time to wait after source change or AV mute
}
ESP_LOGV(TAG, "pushing priority cmd (%s) from external component", cmd.c_str()); ESP_LOGV(TAG, "pushing priority cmd (%s) from external component", cmd.c_str());
cmd_queue.push_front(cmd + "?"); cmd_queue.push_front(cmd + "?");
cmd_queue.push_front(cmd + " " + param); cmd_queue.push_front(cmd + " " + param);
} else if (cmd == "PWR" && param == "ON") { } else if (cmd == "PWR" && param == "ON") {
_specialTimeoutMillis = 30000; // time to wait after PWR ON until projector responds again
cmd_queue.clear(); // clear eventual existing query commands to avoid errors
cmd_queue.push_front(cmd + "?");
cmd_queue.push_front(cmd + " " + param); cmd_queue.push_front(cmd + " " + param);
} }
} }

View file

@ -20,6 +20,7 @@ class tw7100Component : public PollingComponent, public uart::UARTDevice {
unsigned long _max_loop_time = 30; unsigned long _max_loop_time = 30;
unsigned long _readStringUntil_timeout = _max_loop_time/5; // number of milliseconds to wait for the next char before aborting timed read unsigned long _readStringUntil_timeout = _max_loop_time/5; // number of milliseconds to wait for the next char before aborting timed read
unsigned long _timeout_after_cmd = 1000; unsigned long _timeout_after_cmd = 1000;
unsigned long _specialTimeoutMillis = 0;
public: public:
tw7100Component() = default; tw7100Component() = default;