diff --git a/tw7100.cpp b/tw7100.cpp index b91d33e..dbc03d4 100644 --- a/tw7100.cpp +++ b/tw7100.cpp @@ -9,6 +9,7 @@ namespace esphome { namespace tw7100 { bool waiting_for_answer = false; +bool waiting_for_error_report = false; unsigned long waiting_for_answer_since = 0; std::deque cmd_queue; unsigned long last_set_cmd_timestamp; @@ -139,13 +140,14 @@ void tw7100Component::loop() { std::string response = readStringUntil(':'); 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(); cmd_queue.pop_front(); ESP_LOGV(TAG, "sending out command: %s", cmd.c_str()); write_str((cmd + "\r\n").c_str()); flush(); if (cmd.find("?") != std::string::npos) { // only wait for response on CMD? requests + _specialTimeoutMillis = 0; waiting_for_answer = true; waiting_for_answer_since = millis(); } else { @@ -160,13 +162,15 @@ void tw7100Component::loop() { ESP_LOGV(TAG, "buffer content: %s", response.c_str()); std::pair parsed_response = parse_response(response); 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"); - 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 { - 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") { + waiting_for_error_report = false; ESP_LOGE(TAG, "found ERR report, reason is: %s", parsed_response.second.c_str()); // TODO: Handle error } else { @@ -188,10 +192,20 @@ void tw7100Component::dump_config() { void tw7100Component::push_cmd(std::string cmd, std::string param) { static const char *const TAG = "push_cmd()"; 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()); cmd_queue.push_front(cmd + "?"); cmd_queue.push_front(cmd + " " + param); } 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); } } diff --git a/tw7100.h b/tw7100.h index e4eaae3..7c35d64 100644 --- a/tw7100.h +++ b/tw7100.h @@ -20,6 +20,7 @@ class tw7100Component : public PollingComponent, public uart::UARTDevice { 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 _timeout_after_cmd = 1000; + unsigned long _specialTimeoutMillis = 0; public: tw7100Component() = default;