Fix status parsing and power flag handling
This commit is contained in:
@@ -14,6 +14,8 @@
|
|||||||
namespace esphome{
|
namespace esphome{
|
||||||
namespace tclac{
|
namespace tclac{
|
||||||
|
|
||||||
|
constexpr uint8_t TCL_FRAME_TYPE_STATUS = 0x04;
|
||||||
|
constexpr size_t TCL_STATUS_FRAME_MIN_SIZE = 40;
|
||||||
|
|
||||||
ClimateTraits tclacClimate::traits() {
|
ClimateTraits tclacClimate::traits() {
|
||||||
auto traits = climate::ClimateTraits();
|
auto traits = climate::ClimateTraits();
|
||||||
@@ -51,17 +53,27 @@ void tclacClimate::setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void tclacClimate::loop() {
|
void tclacClimate::loop() {
|
||||||
// Если в буфере UART что-то есть, то читаем это что-то
|
|
||||||
if (esphome::uart::UARTDevice::available() > 0) {
|
if (esphome::uart::UARTDevice::available() > 0) {
|
||||||
dataShow(0, true);
|
dataShow(0, true);
|
||||||
dataRX[0] = esphome::uart::UARTDevice::read();
|
size_t skipped = 0;
|
||||||
// Если принятый байт- не заголовок (0xBB), то просто покидаем цикл
|
bool header_found = false;
|
||||||
if (dataRX[0] != 0xBB) {
|
while (esphome::uart::UARTDevice::available() > 0) {
|
||||||
ESP_LOGD("TCL", "Wrong byte");
|
uint8_t byte = esphome::uart::UARTDevice::read();
|
||||||
|
if (byte == 0xBB) {
|
||||||
|
dataRX[0] = byte;
|
||||||
|
header_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skipped += 1;
|
||||||
|
}
|
||||||
|
if (!header_found) {
|
||||||
|
if (skipped > 0)
|
||||||
|
ESP_LOGV("TCL", "Skipped %u byte(s) waiting for header", (unsigned) skipped);
|
||||||
dataShow(0,0);
|
dataShow(0,0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// А вот если совпал заголовок (0xBB), то начинаем чтение по цепочке еще 4 байт
|
if (skipped > 0)
|
||||||
|
ESP_LOGV("TCL", "Resynced after skipping %u byte(s)", (unsigned) skipped);
|
||||||
delay(5);
|
delay(5);
|
||||||
dataRX[1] = esphome::uart::UARTDevice::read();
|
dataRX[1] = esphome::uart::UARTDevice::read();
|
||||||
delay(5);
|
delay(5);
|
||||||
@@ -70,32 +82,30 @@ void tclacClimate::loop() {
|
|||||||
dataRX[3] = esphome::uart::UARTDevice::read();
|
dataRX[3] = esphome::uart::UARTDevice::read();
|
||||||
delay(5);
|
delay(5);
|
||||||
dataRX[4] = esphome::uart::UARTDevice::read();
|
dataRX[4] = esphome::uart::UARTDevice::read();
|
||||||
|
size_t payload_with_checksum = static_cast<size_t>(dataRX[4]) + 1;
|
||||||
//auto raw = getHex(dataRX, 5);
|
size_t frame_size = payload_with_checksum + 5;
|
||||||
|
if (frame_size > sizeof(dataRX)) {
|
||||||
//ESP_LOGD("TCL", "first 5 byte : %s ", raw.c_str());
|
ESP_LOGW("TCL", "Frame size %u exceeds buffer", (unsigned) frame_size);
|
||||||
|
tclacClimate::dataShow(0,0);
|
||||||
// Из первы<D0B2>
|
return;
|
||||||
5 байт нам нужен пятый- он содержит длину сообщения
|
}
|
||||||
esphome::uart::UARTDevice::read_array(dataRX+5, dataRX[4]+1);
|
esphome::uart::UARTDevice::read_array(dataRX + 5, payload_with_checksum);
|
||||||
|
uint8_t check = getChecksum(dataRX, frame_size);
|
||||||
uint8_t check = getChecksum(dataRX, sizeof(dataRX));
|
if (check != dataRX[frame_size - 1]) {
|
||||||
|
|
||||||
//raw = getHex(dataRX, sizeof(dataRX));
|
|
||||||
|
|
||||||
//ESP_LOGD("TCL", "RX full : %s ", raw.c_str());
|
|
||||||
|
|
||||||
// Проверяем контрольную сумму
|
|
||||||
if (check != dataRX[60]) {
|
|
||||||
ESP_LOGD("TCL", "Invalid checksum %x", check);
|
ESP_LOGD("TCL", "Invalid checksum %x", check);
|
||||||
tclacClimate::dataShow(0,0);
|
tclacClimate::dataShow(0,0);
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
//ESP_LOGD("TCL", "checksum OK %x", check);
|
|
||||||
}
|
}
|
||||||
tclacClimate::dataShow(0,0);
|
tclacClimate::dataShow(0,0);
|
||||||
// Прочитав все из буфера приступаем к разбору данны<D0BD>
|
uint8_t frame_type = dataRX[3];
|
||||||
|
if (frame_type != TCL_FRAME_TYPE_STATUS) {
|
||||||
|
ESP_LOGV("TCL", "Ignoring frame type 0x%02X", frame_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (frame_size < TCL_STATUS_FRAME_MIN_SIZE) {
|
||||||
|
ESP_LOGV("TCL", "Ignoring short status frame (%u bytes)", (unsigned) frame_size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
tclacClimate::readData();
|
tclacClimate::readData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,7 +125,8 @@ void tclacClimate::readData() {
|
|||||||
|
|
||||||
//ESP_LOGD("TCL", "TEMP: %f ", current_temperature);
|
//ESP_LOGD("TCL", "TEMP: %f ", current_temperature);
|
||||||
|
|
||||||
if (dataRX[MODE_POS] & ( 1 << 4)) {
|
bool device_is_on = (dataRX[MODE_POS] & MODE_STATUS_POWER_FLAG) != 0;
|
||||||
|
if (device_is_on) {
|
||||||
// Если кондиционер включен, то разбираем данные для отображения
|
// Если кондиционер включен, то разбираем данные для отображения
|
||||||
// ESP_LOGD("TCL", "AC is on");
|
// ESP_LOGD("TCL", "AC is on");
|
||||||
uint8_t modeswitch = MODE_MASK & dataRX[MODE_POS];
|
uint8_t modeswitch = MODE_MASK & dataRX[MODE_POS];
|
||||||
@@ -308,23 +319,23 @@ void tclacClimate::takeControl() {
|
|||||||
dataTX[8] += 0b00000000;
|
dataTX[8] += 0b00000000;
|
||||||
break;
|
break;
|
||||||
case climate::CLIMATE_MODE_AUTO:
|
case climate::CLIMATE_MODE_AUTO:
|
||||||
dataTX[7] += 0b00000100;
|
dataTX[7] += MODE_COMMAND_POWER_FLAG;
|
||||||
dataTX[8] += 0b00001000;
|
dataTX[8] += 0b00001000;
|
||||||
break;
|
break;
|
||||||
case climate::CLIMATE_MODE_COOL:
|
case climate::CLIMATE_MODE_COOL:
|
||||||
dataTX[7] += 0b00000100;
|
dataTX[7] += MODE_COMMAND_POWER_FLAG;
|
||||||
dataTX[8] += 0b00000011;
|
dataTX[8] += 0b00000011;
|
||||||
break;
|
break;
|
||||||
case climate::CLIMATE_MODE_DRY:
|
case climate::CLIMATE_MODE_DRY:
|
||||||
dataTX[7] += 0b00000100;
|
dataTX[7] += MODE_COMMAND_POWER_FLAG;
|
||||||
dataTX[8] += 0b00000010;
|
dataTX[8] += 0b00000010;
|
||||||
break;
|
break;
|
||||||
case climate::CLIMATE_MODE_FAN_ONLY:
|
case climate::CLIMATE_MODE_FAN_ONLY:
|
||||||
dataTX[7] += 0b00000100;
|
dataTX[7] += MODE_COMMAND_POWER_FLAG;
|
||||||
dataTX[8] += 0b00000111;
|
dataTX[8] += 0b00000111;
|
||||||
break;
|
break;
|
||||||
case climate::CLIMATE_MODE_HEAT:
|
case climate::CLIMATE_MODE_HEAT:
|
||||||
dataTX[7] += 0b00000100;
|
dataTX[7] += MODE_COMMAND_POWER_FLAG;
|
||||||
dataTX[8] += 0b00000001;
|
dataTX[8] += 0b00000001;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ using byte = uint8_t;
|
|||||||
|
|
||||||
#define MODE_POS 7
|
#define MODE_POS 7
|
||||||
#define MODE_MASK 0b00111111
|
#define MODE_MASK 0b00111111
|
||||||
|
#define MODE_STATUS_POWER_FLAG 0b00010000
|
||||||
|
#define MODE_COMMAND_POWER_FLAG 0b00000100
|
||||||
|
|
||||||
#define MODE_AUTO 0b00110101
|
#define MODE_AUTO 0b00110101
|
||||||
#define MODE_COOL 0b00110001
|
#define MODE_COOL 0b00110001
|
||||||
|
|||||||
Reference in New Issue
Block a user