From ab6c3fe3e9b0258898cd361c0f9257214fe14804 Mon Sep 17 00:00:00 2001 From: christoph Date: Wed, 17 Dec 2025 16:26:59 +0100 Subject: [PATCH] Translate TCL AC comments to English --- esphome_components/components/tclac/tclac.cpp | 204 ++++++++---------- esphome_components/components/tclac/tclac.h | 17 +- 2 files changed, 100 insertions(+), 121 deletions(-) diff --git a/esphome_components/components/tclac/tclac.cpp b/esphome_components/components/tclac/tclac.cpp index 8340419..f51c2c1 100644 --- a/esphome_components/components/tclac/tclac.cpp +++ b/esphome_components/components/tclac/tclac.cpp @@ -1,9 +1,8 @@ /** -* Create by Miguel Ángel López on 20/07/19 -* and modify by xaxexa -* Refactoring & component making: -* Соловей с паяльником 15.03.2024 -**/ + * Created by Miguel Angel Lopez on 20/07/19 + * Modified by xaxexa + * ESPHome component refactor completed on 15.03.2024 + */ #include "esphome.h" #include "esphome/core/defines.h" #include "tclac.h" @@ -30,11 +29,11 @@ ClimateTraits tclacClimate::traits() { if (!this->supported_swing_modes_.empty()) traits.set_supported_swing_modes(this->supported_swing_modes_); - traits.add_supported_mode(climate::CLIMATE_MODE_OFF); // Выключенный режим кондиционера доступен всегда - traits.add_supported_mode(climate::CLIMATE_MODE_AUTO); // Автоматический режим кондиционера тоже - traits.add_supported_fan_mode(climate::CLIMATE_FAN_AUTO); // Автоматический режим вентилятора доступен всегда - traits.add_supported_swing_mode(climate::CLIMATE_SWING_OFF); // Выключенный режим качания заслонок доступен всегда - traits.add_supported_preset(ClimatePreset::CLIMATE_PRESET_NONE);// На всякий случай без предустановок + traits.add_supported_mode(climate::CLIMATE_MODE_OFF); // Always expose the OFF mode. + traits.add_supported_mode(climate::CLIMATE_MODE_AUTO); // Always expose the AUTO mode as well. + traits.add_supported_fan_mode(climate::CLIMATE_FAN_AUTO); // Fan AUTO mode is always available. + traits.add_supported_swing_mode(climate::CLIMATE_SWING_OFF); // Always expose the Swing OFF mode. + traits.add_supported_preset(ClimatePreset::CLIMATE_PRESET_NONE);// Expose the NONE preset even when presets are not configured. return traits; } @@ -127,7 +126,7 @@ void tclacClimate::readData() { bool device_is_on = (dataRX[MODE_POS] & MODE_STATUS_POWER_FLAG) != 0; if (device_is_on) { - // Если кондиционер включен, то разбираем данные для отображения + // When the AC is running, parse the state so we can show it. // ESP_LOGD("TCL", "AC is on"); uint8_t modeswitch = MODE_MASK & dataRX[MODE_POS]; uint8_t fanspeedswitch = FAN_SPEED_MASK & dataRX[FAN_SPEED_POS]; @@ -197,8 +196,7 @@ void tclacClimate::readData() { break; } - // Обработка данны - о пресете + // Handle preset information received from the unit. preset = ClimatePreset::CLIMATE_PRESET_NONE; if (dataRX[7] & (1 << 6)){ preset = ClimatePreset::CLIMATE_PRESET_ECO; @@ -209,20 +207,20 @@ void tclacClimate::readData() { } } else { - // Если кондиционер выключен, то все режимы показываются, как выключенные + // If the AC is off, pretend every mode is OFF. mode = climate::CLIMATE_MODE_OFF; //fan_mode = climate::CLIMATE_FAN_OFF; swing_mode = climate::CLIMATE_SWING_OFF; preset = ClimatePreset::CLIMATE_PRESET_NONE; } - // Публикуем данные + // Publish the freshly parsed climate state. this->publish_state(); allow_take_control = true; } // Climate control void tclacClimate::control(const ClimateCall &call) { - // Запрашиваем данные из переключателя режимов работы кондиционера + // Figure out which climate mode should be sent (call override or current). if (call.get_mode().has_value()){ switch_climate_mode = call.get_mode().value(); ESP_LOGD("TCL", "Get MODE from call"); @@ -231,29 +229,29 @@ void tclacClimate::control(const ClimateCall &call) { ESP_LOGD("TCL", "Get MODE from AC"); } - // Запрашиваем данные из переключателя предустановок кондиционера + // Figure out which preset should be sent. if (call.get_preset().has_value()){ switch_preset = call.get_preset().value(); } else { switch_preset = preset.value(); } - // Запрашиваем данные из переключателя режимов вентилятора + // Figure out which fan mode should be sent. if (call.get_fan_mode().has_value()){ switch_fan_mode = call.get_fan_mode().value(); } else { switch_fan_mode = fan_mode.value(); } - // Запрашиваем данные из переключателя режимов качания заслонок + // Figure out which swing mode should be sent. if (call.get_swing_mode().has_value()){ switch_swing_mode = call.get_swing_mode().value(); } else { - // А если в переключателе пусто- заполняем значением из последнего опроса состояния. Типа, ничего не поменялось. + // If nothing was provided, reuse the last known value so behavior stays unchanged. switch_swing_mode = swing_mode; } - // Расчет температуры + // Encode the requested target temperature (AC expects 31 - value). if (call.get_target_temperature().has_value()) { target_temperature_set = 31-(int)call.get_target_temperature().value(); } else { @@ -286,7 +284,7 @@ void tclacClimate::takeControl() { target_temperature_set = 31-(int)target_temperature; } - // Включаем или отключаем пищалку в зависимости от переключателя в настройка + // Toggle the beeper according to the configuration flag. if (beeper_status_){ ESP_LOGD("TCL", "Beep mode ON"); @@ -296,13 +294,11 @@ void tclacClimate::takeControl() { dataTX[7] += 0b00000000; } - // Включаем или отключаем дисплей на кондиционере в зависимости от переключателя в настройка + // Toggle the AC display according to the configuration flag. - // Включаем дисплей только если кондиционер в одном из рабочи - режимов + // Only enable the display while the AC runs in an active mode. - // ВНИМАНИЕ! При выключении дисплея кондиционер сам принудительно пере -одит в автоматический режим! + // WARNING: turning the display off forces the AC into AUTO mode! if ((display_status_) && (switch_climate_mode != climate::CLIMATE_MODE_OFF)){ ESP_LOGD("TCL", "Dispaly turn ON"); @@ -312,7 +308,7 @@ void tclacClimate::takeControl() { dataTX[7] += 0b00000000; } - // Настраиваем режим работы кондиционера + // Encode the selected climate mode into the control frame. switch (switch_climate_mode) { case climate::CLIMATE_MODE_OFF: dataTX[7] += 0b00000000; @@ -340,7 +336,7 @@ void tclacClimate::takeControl() { break; } - // Настраиваем режим вентилятора + // Encode the selected fan mode into the control frame. switch(switch_fan_mode) { case climate::CLIMATE_FAN_AUTO: dataTX[8] += 0b00000000; @@ -376,7 +372,7 @@ void tclacClimate::takeControl() { break; } - // Устанавливаем режим качания заслонок + // Encode the requested swing mode bits. switch(switch_swing_mode) { case climate::CLIMATE_SWING_OFF: dataTX[10] += 0b00000000; @@ -396,7 +392,7 @@ void tclacClimate::takeControl() { break; } - // Устанавливаем предустановки кондиционера + // Encode the requested preset bits. switch(switch_preset) { case ClimatePreset::CLIMATE_PRESET_NONE: break; @@ -411,48 +407,41 @@ void tclacClimate::takeControl() { break; } - //Режим заслонок - // Вертикальная заслонка - // Качание вертикальной заслонки [10 байт, маска 00111000]: - // 000 - Качание отключено, заслонка в последней позиции или в фиксации - // 111 - Качание включено в выбранном режиме - // Режим качания вертикальной заслонки (режим фиксации заслонки роли не играет, если качание включено) [32 байт, маска 00011000]: - // 01 - качание свер -у вниз, ПО УМОЛЧАНИЮ - // 10 - качание в вер -ней половине - // 11 - качание в нижней половине - // Режим фиксации заслонки (режим качания заслонки роли не играет, если качание выключено) [32 байт, маска 00000111]: - // 000 - нет фиксации, ПО УМОЛЧАНИЮ - // 001 - фиксация ввер -у - // 010 - фиксация между вер -ом и серединой - // 011 - фиксация в середине - // 100 - фиксация между серединой и низом - // 101 - фиксация внизу - // Горизонтальные заслонки - // Качание горизонтальны - заслонок [11 байт, маска 00001000]: - // 0 - Качание отключено, заслонки в последней позиции или в фиксации - // 1 - Качание включено в выбранном режиме - // Режим качания горизонтальны - заслонок (режим фиксации заслонок роли не играет, если качание включено) [33 байт, маска 00111000]: - // 001 - качание слева направо, ПО УМОЛЧАНИЮ - // 010 - качание слева - // 011 - качание по середине - // 100 - качание справа - // Режим фиксации горизонтальны - заслонок (режим качания заслонок роли не играет, если качание выключено) [33 байт, маска 00000111]: - // 000 - нет фиксации, ПО УМОЛЧАНИЮ - // 001 - фиксация слева - // 010 - фиксация между левой стороной и серединой - // 011 - фиксация в середине - // 100 - фиксация между серединой и правой стороной - // 101 - фиксация справа + // Louver control helper information. + // Vertical louver handling. + // Vertical swing bits [byte 10, mask 0b00111000]: + // 000 - swing off, louver stays in its last/fixed position. + // 111 - swing enabled per the requested pattern. + // Vertical swing macro mode (fixation ignored when swing runs) [byte 32, mask 0b00011000]: + // 01 - sweep from top to bottom (default). + // 10 - sweep only in the upper half. + // 11 - sweep only in the lower half. + // Vertical fixation position when swing is disabled [byte 32, mask 0b00000111]: + // 000 - no fixation (default). + // 001 - fix at the top. + // 010 - fix between top and center. + // 011 - fix at the center. + // 100 - fix between center and bottom. + // 101 - fix at the bottom. + // Horizontal louver handling. + // Horizontal swing bit [byte 11, mask 0b00001000]: + // 0 - swing off, louvers stay where they were. + // 1 - swing enabled. + // Horizontal swing macro mode (fixation ignored while swinging) [byte 33, mask 0b00111000]: + // 001 - sweep from left to right (default). + // 010 - sweep primarily on the left side. + // 011 - sweep around the center. + // 100 - sweep primarily on the right side. + // Horizontal fixation position when swing is disabled [byte 33, mask 0b00000111]: + // 000 - no fixation (default). + // 001 - fix to the far left. + // 010 - fix between the left edge and center. + // 011 - fix at the center. + // 100 - fix between the center and right edge. + // 101 - fix to the far right. - // Устанавливаем режим для качания вертикальной заслонки + // Apply the requested vertical swing direction. switch(vertical_swing_direction_) { case VerticalSwingDirection::UP_DOWN: dataTX[32] += 0b00001000; @@ -467,8 +456,7 @@ void tclacClimate::takeControl() { ESP_LOGD("TCL", "Vertical swing: downer"); break; } - // Устанавливаем режим для качания горизонтальны - заслонок + // Apply the requested horizontal swing direction. switch(horizontal_swing_direction_) { case HorizontalSwingDirection::LEFT_RIGHT: dataTX[33] += 0b00001000; @@ -487,7 +475,7 @@ void tclacClimate::takeControl() { ESP_LOGD("TCL", "Horizontal swing: righter"); break; } - // Устанавливаем положение фиксации вертикальной заслонки + // Apply the requested vertical fixation position. switch(vertical_direction_) { case AirflowVerticalDirection::LAST: dataTX[32] += 0b00000000; @@ -514,8 +502,7 @@ void tclacClimate::takeControl() { ESP_LOGD("TCL", "Vertical fix: down"); break; } - // Устанавливаем положение фиксации горизонтальны - заслонок + // Apply the requested horizontal fixation position. switch(horizontal_direction_) { case AirflowHorizontalDirection::LAST: dataTX[33] += 0b00000000; @@ -543,15 +530,15 @@ void tclacClimate::takeControl() { break; } - // Установка температуры + // Set the encoded temperature byte. dataTX[9] = target_temperature_set; - // Собираем массив байт для отправки в кондиционер - dataTX[0] = 0xBB; //стартовый байт заголовка - dataTX[1] = 0x00; //стартовый байт заголовка - dataTX[2] = 0x01; //стартовый байт заголовка - dataTX[3] = 0x03; //0x03 - управление, 0x04 - опрос - dataTX[4] = 0x20; //0x20 - управление, 0x19 - опрос + // Assemble the outbound control frame. + dataTX[0] = 0xBB; // Frame header byte. + dataTX[1] = 0x00; // Frame header byte. + dataTX[2] = 0x01; // Frame header byte. + dataTX[3] = 0x03; // 0x03 = control frame, 0x04 = status frame. + dataTX[4] = 0x20; // 0x20 is the control payload length, 0x19 is the status payload length. dataTX[5] = 0x03; //?? dataTX[6] = 0x01; //?? //dataTX[7] = 0x64; //eco,display,beep,ontimerenable, offtimerenable,power,0,0 @@ -578,12 +565,12 @@ void tclacClimate::takeControl() { dataTX[28] = 0x00; //?? dataTX[30] = 0x00; //?? dataTX[31] = 0x00; //?? - //dataTX[32] = 0x00; //0,0,0,режим вертикального качания(2),режим вертикальной фиксации(3) - //dataTX[33] = 0x00; //0,0,режим горизонтального качания(3),режим горизонтальной фиксации(3) + // 0,0,0, vertical swing bits (2), vertical fixation bits (3). + // 0,0, horizontal swing bits (3), horizontal fixation bits (3). dataTX[34] = 0x00; //?? dataTX[35] = 0x00; //?? dataTX[36] = 0x00; //?? - dataTX[37] = 0xFF; //Контрольная сумма + dataTX[37] = 0xFF; // Checksum byte. dataTX[37] = tclacClimate::getChecksum(dataTX, sizeof(dataTX)); tclacClimate::sendData(dataTX, sizeof(dataTX)); @@ -591,8 +578,7 @@ void tclacClimate::takeControl() { is_call_control = false; } -// Отправка данны - в кондиционер +// Send the prepared frame to the AC. void tclacClimate::sendData(uint8_t * message, uint8_t size) { tclacClimate::dataShow(1,1); //Serial.write(message, size); @@ -602,7 +588,7 @@ void tclacClimate::sendData(uint8_t * message, uint8_t size) { tclacClimate::dataShow(1,0); } -// Преобразование байта в читабельный формат +// Convert a byte array into a readable hex string. std::string tclacClimate::getHex(const byte *message, size_t size) { std::ostringstream oss; for (size_t i = 0; i < size; ++i) { @@ -619,7 +605,7 @@ std::string tclacClimate::getHex(const byte *message, size_t size) { return s; } -// Вычисление контрольной суммы +// Calculate the XOR checksum for a frame. uint8_t tclacClimate::getChecksum(const byte * message, size_t size) { uint8_t position = size - 1; uint8_t crc = 0; @@ -628,7 +614,7 @@ uint8_t tclacClimate::getChecksum(const byte * message, size_t size) { return crc; } -// Мигаем светодиодами +// Blink LEDs to indicate RX/TX activity. void tclacClimate::dataShow(bool flow, bool shine) { if (module_display_status_){ if (flow == 0){ @@ -656,9 +642,9 @@ void tclacClimate::dataShow(bool flow, bool shine) { } } -// Действия с данными из конфига +// Helpers for manipulating configuration-backed state. -// Получение состояния пищалки +// Update the stored beeper state. void tclacClimate::set_beeper_state(bool state) { this->beeper_status_ = state; if (force_mode_status_){ @@ -667,7 +653,7 @@ void tclacClimate::set_beeper_state(bool state) { } } } -// Получение состояния дисплея кондиционера +// Update the stored AC display state. void tclacClimate::set_display_state(bool state) { this->display_status_ = state; if (force_mode_status_){ @@ -676,29 +662,29 @@ void tclacClimate::set_display_state(bool state) { } } } -// Получение состояния режима принудительного применения настроек +// Update whether forced control is currently enabled. void tclacClimate::set_force_mode_state(bool state) { this->force_mode_status_ = state; } -// Получение пина светодиода приема данны +// Assign the RX LED pin. #ifdef CONF_RX_LED void tclacClimate::set_rx_led_pin(GPIOPin *rx_led_pin) { this->rx_led_pin_ = rx_led_pin; } #endif -// Получение пина светодиода передачи данны +// Assign the TX LED pin. #ifdef CONF_TX_LED void tclacClimate::set_tx_led_pin(GPIOPin *tx_led_pin) { this->tx_led_pin_ = tx_led_pin; } #endif -// Получение состояния светодиодов связи модуля +// Update the module display flag. void tclacClimate::set_module_display_state(bool state) { this->module_display_status_ = state; } -// Получение режима фиксации вертикальной заслонки +// Update the stored vertical airflow fixation target. void tclacClimate::set_vertical_airflow(AirflowVerticalDirection direction) { this->vertical_direction_ = direction; if (force_mode_status_){ @@ -707,8 +693,7 @@ void tclacClimate::set_vertical_airflow(AirflowVerticalDirection direction) { } } } -// Получение режима фиксации горизонтальны - заслонок +// Update the stored horizontal airflow fixation target. void tclacClimate::set_horizontal_airflow(AirflowHorizontalDirection direction) { this->horizontal_direction_ = direction; if (force_mode_status_){ @@ -717,7 +702,7 @@ void tclacClimate::set_horizontal_airflow(AirflowHorizontalDirection direction) } } } -// Получение режима качания вертикальной заслонки +// Update the stored vertical swing direction. void tclacClimate::set_vertical_swing_direction(VerticalSwingDirection direction) { this->vertical_swing_direction_ = direction; if (force_mode_status_){ @@ -726,13 +711,11 @@ void tclacClimate::set_vertical_swing_direction(VerticalSwingDirection direction } } } -// Получение доступны - режимов работы кондиционера +// Register supported climate modes. void tclacClimate::set_supported_modes(const std::set &modes) { this->supported_modes_ = modes; } -// Получение режима качания горизонтальны - заслонок +// Update the stored horizontal swing direction. void tclacClimate::set_horizontal_swing_direction(HorizontalSwingDirection direction) { horizontal_swing_direction_ = direction; if (force_mode_status_){ @@ -741,18 +724,15 @@ void tclacClimate::set_horizontal_swing_direction(HorizontalSwingDirection direc } } } -// Получение доступны - скоростей вентилятора +// Register supported fan modes. void tclacClimate::set_supported_fan_modes(const std::set &modes){ this->supported_fan_modes_ = modes; } -// Получение доступны - режимов качания заслонок +// Register supported swing modes. void tclacClimate::set_supported_swing_modes(const std::set &modes) { this->supported_swing_modes_ = modes; } -// Получение доступны - предустановок +// Register supported presets. void tclacClimate::set_supported_presets(const std::set &presets) { this->supported_presets_ = presets; } diff --git a/esphome_components/components/tclac/tclac.h b/esphome_components/components/tclac/tclac.h index 4a816a1..5afdd40 100644 --- a/esphome_components/components/tclac/tclac.h +++ b/esphome_components/components/tclac/tclac.h @@ -1,9 +1,8 @@ /** -* Create by Miguel Ángel López on 20/07/19 -* and modify by xaxexa -* Refactoring & component making: -* Соловей с паяльником 15.03.2024 -**/ + * Created by Miguel Angel Lopez on 20/07/19 + * Modified by xaxexa + * ESPHome component refactor completed on 15.03.2024 + */ #ifndef TCL_ESP_TCL_H #define TCL_ESP_TCL_H @@ -96,13 +95,13 @@ class tclacClimate : public climate::Climate, public esphome::uart::UARTDevice, private: uint8_t checksum; - // dataTX с управлением состоит из 38 байт + // dataTX holds the 38-byte control frame payload uint8_t dataTX[38]; - // А dataRX по прежнему из 61 байта + // dataRX still contains the 61-byte status frame payload uint8_t dataRX[61]; - // Команда запроса состояния + // Command frame that requests the current AC state uint8_t poll_message_[8] = {0xBB,0x00,0x01,0x04,0x02,0x01,0x00,0xBD}; - // Инициализация и начальное наполнение переменных состоянй переключателей + // Initialize and seed the state-tracking fields bool beeper_status_; bool display_status_; bool force_mode_status_;