mirror of
https://github.com/esphome/esphome.git
synced 2024-12-23 14:04:53 +01:00
Retry Tuya init commands (#3482)
Co-authored-by: Samuel Sieb <samuel@sieb.net>
This commit is contained in:
parent
17b8bd8316
commit
6f49f5465b
2 changed files with 26 additions and 6 deletions
|
@ -1,7 +1,7 @@
|
||||||
#include "tuya.h"
|
#include "tuya.h"
|
||||||
#include "esphome/core/log.h"
|
|
||||||
#include "esphome/components/network/util.h"
|
#include "esphome/components/network/util.h"
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
#include "esphome/core/util.h"
|
#include "esphome/core/util.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
|
@ -10,6 +10,7 @@ namespace tuya {
|
||||||
static const char *const TAG = "tuya";
|
static const char *const TAG = "tuya";
|
||||||
static const int COMMAND_DELAY = 10;
|
static const int COMMAND_DELAY = 10;
|
||||||
static const int RECEIVE_TIMEOUT = 300;
|
static const int RECEIVE_TIMEOUT = 300;
|
||||||
|
static const int MAX_RETRIES = 5;
|
||||||
|
|
||||||
void Tuya::setup() {
|
void Tuya::setup() {
|
||||||
this->set_interval("heartbeat", 15000, [this] { this->send_empty_command_(TuyaCommandType::HEARTBEAT); });
|
this->set_interval("heartbeat", 15000, [this] { this->send_empty_command_(TuyaCommandType::HEARTBEAT); });
|
||||||
|
@ -27,8 +28,12 @@ void Tuya::loop() {
|
||||||
void Tuya::dump_config() {
|
void Tuya::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "Tuya:");
|
ESP_LOGCONFIG(TAG, "Tuya:");
|
||||||
if (this->init_state_ != TuyaInitState::INIT_DONE) {
|
if (this->init_state_ != TuyaInitState::INIT_DONE) {
|
||||||
|
if (this->init_failed_) {
|
||||||
|
ESP_LOGCONFIG(TAG, " Initialization failed. Current init_state: %u", static_cast<uint8_t>(this->init_state_));
|
||||||
|
} else {
|
||||||
ESP_LOGCONFIG(TAG, " Configuration will be reported when setup is complete. Current init_state: %u",
|
ESP_LOGCONFIG(TAG, " Configuration will be reported when setup is complete. Current init_state: %u",
|
||||||
static_cast<uint8_t>(this->init_state_));
|
static_cast<uint8_t>(this->init_state_));
|
||||||
|
}
|
||||||
ESP_LOGCONFIG(TAG, " If no further output is received, confirm that this is a supported Tuya device.");
|
ESP_LOGCONFIG(TAG, " If no further output is received, confirm that this is a supported Tuya device.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -127,6 +132,8 @@ void Tuya::handle_command_(uint8_t command, uint8_t version, const uint8_t *buff
|
||||||
|
|
||||||
if (this->expected_response_.has_value() && this->expected_response_ == command_type) {
|
if (this->expected_response_.has_value() && this->expected_response_ == command_type) {
|
||||||
this->expected_response_.reset();
|
this->expected_response_.reset();
|
||||||
|
this->command_queue_.erase(command_queue_.begin());
|
||||||
|
this->init_retries_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (command_type) {
|
switch (command_type) {
|
||||||
|
@ -332,8 +339,8 @@ void Tuya::handle_datapoints_(const uint8_t *buffer, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tuya::send_raw_command_(TuyaCommand command) {
|
void Tuya::send_raw_command_(TuyaCommand command) {
|
||||||
uint8_t len_hi = (uint8_t)(command.payload.size() >> 8);
|
uint8_t len_hi = (uint8_t) (command.payload.size() >> 8);
|
||||||
uint8_t len_lo = (uint8_t)(command.payload.size() & 0xFF);
|
uint8_t len_lo = (uint8_t) (command.payload.size() & 0xFF);
|
||||||
uint8_t version = 0;
|
uint8_t version = 0;
|
||||||
|
|
||||||
this->last_command_timestamp_ = millis();
|
this->last_command_timestamp_ = millis();
|
||||||
|
@ -378,12 +385,23 @@ void Tuya::process_command_queue_() {
|
||||||
|
|
||||||
if (this->expected_response_.has_value() && delay > RECEIVE_TIMEOUT) {
|
if (this->expected_response_.has_value() && delay > RECEIVE_TIMEOUT) {
|
||||||
this->expected_response_.reset();
|
this->expected_response_.reset();
|
||||||
|
if (init_state_ != TuyaInitState::INIT_DONE) {
|
||||||
|
if (++this->init_retries_ >= MAX_RETRIES) {
|
||||||
|
this->init_failed_ = true;
|
||||||
|
ESP_LOGE(TAG, "Initialization failed at init_state %u", static_cast<uint8_t>(this->init_state_));
|
||||||
|
this->command_queue_.erase(command_queue_.begin());
|
||||||
|
this->init_retries_ = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this->command_queue_.erase(command_queue_.begin());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Left check of delay since last command in case there's ever a command sent by calling send_raw_command_ directly
|
// Left check of delay since last command in case there's ever a command sent by calling send_raw_command_ directly
|
||||||
if (delay > COMMAND_DELAY && !this->command_queue_.empty() && this->rx_message_.empty() &&
|
if (delay > COMMAND_DELAY && !this->command_queue_.empty() && this->rx_message_.empty() &&
|
||||||
!this->expected_response_.has_value()) {
|
!this->expected_response_.has_value()) {
|
||||||
this->send_raw_command_(command_queue_.front());
|
this->send_raw_command_(command_queue_.front());
|
||||||
|
if (!this->expected_response_.has_value())
|
||||||
this->command_queue_.erase(command_queue_.begin());
|
this->command_queue_.erase(command_queue_.begin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,8 @@ class Tuya : public Component, public uart::UARTDevice {
|
||||||
optional<time::RealTimeClock *> time_id_{};
|
optional<time::RealTimeClock *> time_id_{};
|
||||||
#endif
|
#endif
|
||||||
TuyaInitState init_state_ = TuyaInitState::INIT_HEARTBEAT;
|
TuyaInitState init_state_ = TuyaInitState::INIT_HEARTBEAT;
|
||||||
|
bool init_failed_{false};
|
||||||
|
int init_retries_{0};
|
||||||
uint8_t protocol_version_ = -1;
|
uint8_t protocol_version_ = -1;
|
||||||
int gpio_status_ = -1;
|
int gpio_status_ = -1;
|
||||||
int gpio_reset_ = -1;
|
int gpio_reset_ = -1;
|
||||||
|
|
Loading…
Reference in a new issue