Почистил код, убрал лишнее, отключил лишние логи, изменил описание. Кто молодец? Я, конечно!

This commit is contained in:
I-am-nightingale
2024-04-13 05:26:39 +03:00
parent 3ebc4f07fc
commit b53db6253b
6 changed files with 125 additions and 70 deletions

View File

@@ -1,10 +1,94 @@
Подключение к системе умного дома Home Assistant, используя внешний компонент ESPHome, кондиционеров типа:
- TCL TAC-07CHSA/TPG / TAC-09CHSA/TPG / TAC-12CHSA/TPG
Внешний компонент кондиционеров TCL и аналогов для Home Assistant, используя ESPHome.
Поддерживаются кондиционеры типа TAC-07CHSA и подобные. Увы, предположить точно получится подключить кондиционер или нет практически
невозможно из-за огромного разбега в комплектациях: даже одна и та же модель, буквально буква-в-букву может, например, не иметь
родного модуля WiFI, не иметь провода с USB разъемом или вовсе на плате управления может не быть впаян разъем UART.
Однако, в целом, с пайкой или без, проверены следующие кондиционеры:
- TCL TAC-07CHSA/TPG-W
- TCL TAC-09CHSA/TPG
- TCL TAC-12CHSA/TPG
- TCL TAC-09CHSA/DSEI-W
- Daichi AIR20AVQ1/AIR20FV1
____
Пост по проекту находится [в моем канале на Дзене](https://dzen.ru/b/Zgnvt3VNQhfUZ99X)
Пост по проекту находится [в моем канале на Дзене](https://dzen.ru/b/Zhmd3bLEd3GbU8mD)
Это хоть и не готовый вариант, но вполне себе образец для бета-тестирования, есть уже почти все, что хотелось добавить и это все
вполне неплохо и довольно корректно работает. А вот на сколько неплохо и корректно- это и предстоит выяснить.
Используя компонент прфямо сейчас Вы уже не рискуете душевным здоровьем, но внезапные глюки вполне могут напасть. Если вдруг такое
случиться именно с Вами- прошу сообщить мне на Дзене, приму меры.
Я все еще не оставляю подробного описания, уповая на то, что проверять компонент и проводить эксперименты будут сколь-нибудь
подкованные в этом деле люди, не боящиеся наброситься с палкой на багованного медведя. МОжно ли этим пользоваться "на повседневку"?
Можно. Но лучше подождать окончательного варианта- оно ведь так надежнее.
____
Это все здесь, я даже не знаю, пре-альфа, потому как функционал я просто и без затей пилил по ходу вникания в суть происходящего.
Используя этот кусок кода Вы рискуете своим душевным здоровьем.
Если Вам надо- разберетесь, если не разберетесь- это Вам не надо, дождитесь нормального результата работы.
Образец для конфигурации ESPHome в файле TCL-Conditioner.yaml
Образец для конфигурации ESPHome в файле TCL-Conditioner.yaml. Скачайте к себе и используйте в ESPHome, или просто скопируйте из него
всю конфигурацию и вставьте вместо своей, однако, не забыв отредактировать все поля. в файле есть подсказки по каждому полю.
Вопрос может возникнуть с 2 моментами: платформа (чип или модуль) и подгружаемые файлы. Попробую объяснить.
## Настройка платформы
Платформа настраивается точно так же, как ей и полагается настраиваться в ESPHome. Например, так выглядит кусок кода для ESP-01S:
```yaml
esp8266:
board: esp01_1m
```
А вот так выглядит кусок кода для модуля Hommyn HDN/WFN-02-01 из первой статьи про кондиционер:
```yaml
esp32:
board: esp32-c3-devkitm-1
framework:
type: arduino
```
Можно подключать платформу и через основной конфиг, вот предложенный подписчиком пример для Esp32 WROOM32:
```yaml
esphome:
platform: ESP32
board: nodemcu-32s
```
В общем- все то же самое, как и обычно, вариант под свою платформу легко ищется в интернете.
**Важно не забыть закомментировать или удалить строки других платформ!**
## Настройка подгружаемых файлов
Для добавления или удаления определенных частей конфига я решил использовать подгружаемые файлы- они загружаются ESPHome автоматически,
если у сервера с Home Assistant есть доступ в интернет. Такой подход позволяет редактировать и обновлять не весь конфиг куском,
а частями, не трогая то, что работает.
Еще один плюс- не нужно километровые куски кода комментировать или раскомментировать, не нужно зжнать разметку, чтобы не считать
проклятые пробелы и прочее. Все делается добавлением или удалением ссылок на файлы. Итак, вот так выглядит блок подгружаемых файлов:
```yaml
packages:
remote_package:
url: https://github.com/I-am-nightingale/tclac.git
ref: master
files:
# v - равнение строк с опциями вот по этой позиции, иначе глючить будет
- packages/core.yaml # Ядро всего сущего
# - packages/leds.yaml
refresh: 30s
```
Все подгружаемые файлы указываются в секции **files:**. Для работы необходимо, чтобы был хотя-бы
```yaml
- packages/core.yaml # Ядро всего сущего
```
Все остальные модули по желанию(их описание в том же файле чуть выше). **Важно**, чтобы все строки с файлами были выровнены по
импровизированной метке, которую я специально указал, иначе у ESPHome возникнет много вопросов к Вам. Например, **должно быть так:**
```yaml
packages:
remote_package:
url: https://github.com/I-am-nightingale/tclac.git
ref: master
files:
# v - равнение строк с опциями вот по этой позиции, иначе глючить будет
- packages/core.yaml # Ядро всего сущего
- packages/leds.yaml
refresh: 30s
```
А вот так уже **не правильно:**
```yaml
packages:
remote_package:
url: https://github.com/I-am-nightingale/tclac.git
ref: master
files:
# v - равнение строк с опциями вот по этой позиции, иначе глючить будет
- packages/core.yaml # Ядро всего сущего
- packages/leds.yaml
refresh: 30s
```

View File

@@ -20,18 +20,23 @@ substitutions:
# Выводы модуля, к которым подключен UART:
uart_rx: GPIO3
uart_tx: GPIO1
# Выводы модуля для подключения сигнальных светодиодов, для работы надо раскомментировать "leds" в packages
# Выводы модуля для подключения сигнальных светодиодов, для работы надо раскомментировать "leds" в "packages"
# иначе работать не будет совсем и можно писать сюда вообще что угодною. Для тех, кто просил их удалить.
receive_led: GPIO6
transmit_led: GPIO4
# Подгружаемые файлы- загружаются и обновляются автоматически из интернета, раскомментировать нужные
# Описание опций:
# - packages/leds.yaml - светодиоды для индикации приема/передачи, пины указываются в receive_led / transmit_led
#
# Выравнивать раскомментированные строки обязательно по указанной позиции!
packages:
remote_package:
url: https://github.com/I-am-nightingale/tclac.git
ref: master
files:
# v - равнение строк с опциями вот по этой позиции, иначе глючить будет
- packages/core.yaml # Ядро всего сущего
# Подключение дополнительных опций:
# - packages/leds.yaml
refresh: 30s

View File

@@ -25,7 +25,7 @@ from esphome.components.climate import (
)
AUTO_LOAD = ["climate"]
CODEOWNERS = ["@I-am-nightingale"]
CODEOWNERS = ["@I-am-nightingale", "@xaxexa", "@junkfix"]
DEPENDENCIES = ["climate", "uart"]
TCLAC_MIN_TEMPERATURE = 16.0

View File

@@ -1,3 +1,9 @@
/**
* Create by Miguel Ángel López on 20/07/19
* and modify by xaxexa
* Refactoring & component making:
* Соловей с паяльником 15.03.2024
**/
#include "esphome.h"
#include "esphome/core/defines.h"
#include "tclac.h"
@@ -18,15 +24,11 @@ ClimateTraits tclacClimate::traits() {
traits.set_supported_fan_modes(this->supported_fan_modes_);
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_preset(ClimatePreset::CLIMATE_PRESET_NONE); // На всякий случай без предустановок
traits.add_supported_swing_mode(climate::CLIMATE_SWING_OFF);// Выключенный режим качания заслонок доступен всегда
// traits.set_visual_temperature_step(STEP_TEMPERATURE);
// traits.set_visual_min_temperature(MIN_SET_TEMPERATURE);
// traits.set_visual_max_temperature(MAX_SET_TEMPERATURE);
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);// На всякий случай без предустановок
return traits;
}
@@ -84,7 +86,7 @@ void tclacClimate::loop() {
tclacClimate::dataShow(0,0);
return;
} else {
ESP_LOGD("TCL", "checksum OK %x", check);
//ESP_LOGD("TCL", "checksum OK %x", check);
}
tclacClimate::dataShow(0,0);
// Прочитав все из буфера приступаем к разбору данных
@@ -96,7 +98,7 @@ void tclacClimate::update() {
tclacClimate::dataShow(1,1);
this->esphome::uart::UARTDevice::write_array(poll, sizeof(poll));
auto raw = tclacClimate::getHex(poll, sizeof(poll));
ESP_LOGD("TCL", "chek status sended");
//ESP_LOGD("TCL", "chek status sended");
tclacClimate::dataShow(1,0);
}
@@ -105,7 +107,7 @@ void tclacClimate::readData() {
current_temperature = float((( (dataRX[17] << 8) | dataRX[18] ) / 374 - 32)/1.8);
target_temperature = (dataRX[FAN_SPEED_POS] & SET_TEMP_MASK) + 16;
ESP_LOGD("TCL", "TEMP: %f ", current_temperature);
//ESP_LOGD("TCL", "TEMP: %f ", current_temperature);
if (dataRX[MODE_POS] & ( 1 << 4)) {
// Если кондиционер включен, то разбираем данные для отображения
@@ -208,7 +210,6 @@ void tclacClimate::control(const ClimateCall &call) {
switch_climate_mode = mode;
}
// Запрашиваем данные из переключателя предустановок кондиционера
if (call.get_preset().has_value()){
switch_preset = call.get_preset().value();
@@ -245,11 +246,10 @@ void tclacClimate::control(const ClimateCall &call) {
void tclacClimate::takeControl() {
dataTX[7] = 0b00000000;//eco,display,beep,ontimerenable, offtimerenable,power,0,0
dataTX[8] = 0b00000000;//mute,0,turbo,health,mode(4) 0=cool 1=fan 2=dry 3=heat 4=auto
dataTX[9] = 0b00000000;//[9] = 0,0,0,0,temp(4) 31 - value
dataTX[10] = 0b00000000;//[10] = 0,timerindicator,swingv(3),fan(3) 0=auto 1=low 2=med 3=high
// {0,2,3,5,0};
dataTX[7] = 0b00000000;
dataTX[8] = 0b00000000;
dataTX[9] = 0b00000000;
dataTX[10] = 0b00000000;
dataTX[11] = 0b00000000;
dataTX[19] = 0b00000000;
dataTX[32] = 0b00000000;
@@ -622,12 +622,10 @@ void tclacClimate::set_display_state(bool state) {
}
}
}
// Получение состояния режима принудительного применения настроек
void tclacClimate::set_force_mode_state(bool state) {
this->force_mode_status_ = state;
}
// Получение пина светодиода приема данных
#ifdef CONF_RX_LED
void tclacClimate::set_rx_led_pin(GPIOPin *rx_led_pin) {
@@ -692,23 +690,10 @@ void tclacClimate::set_supported_fan_modes(const std::set<climate::ClimateFanMod
void tclacClimate::set_supported_swing_modes(const std::set<climate::ClimateSwingMode> &modes) {
this->supported_swing_modes_ = modes;
}
// Получение доступных предустановок
void tclacClimate::set_supported_presets(const std::set<climate::ClimatePreset> &presets) {
this->supported_presets_ = presets;
}
// Заготовки функций запроса состояния, может пригодиться в будущем, если делать обратную связь. Очень не хочется, будет очень костыльно.
//bool tclacClimate::get_beeper_state() const { return this->beeper_status_; }
//bool tclacClimate::get_display_state() const { return this->display_status_; }
//bool tclacClimate::get_module_display_state() const { return this->module_display_status_; }
//AirflowVerticalDirection tclacClimate::get_vertical_airflow() const { return this->vertical_direction_; };
//AirflowHorizontalDirection tclacClimate::get_horizontal_airflow() const { return this->horizontal_direction_; }
//VerticalSwingDirection tclacClimate::get_vertical_swing_direction() const { return this->vertical_swing_direction_; }
//HorizontalSwingDirection tclacClimate::get_horizontal_swing_direction() const { return this->horizontal_swing_direction_; }
}
}

View File

@@ -30,7 +30,6 @@ namespace tclac {
#define FAN_SPEED_POS 8
#define FAN_QUIET_POS 33
#define FAN_AUTO 0b10000000 //auto
#define FAN_QUIET 0x80 //silent
#define FAN_LOW 0b10010000 // |
@@ -41,7 +40,6 @@ namespace tclac {
#define FAN_DIFFUSE 0b10000000 // POWER [7]
#define FAN_SPEED_MASK 0b11110000 //FAN SPEED MASK
#define SWING_POS 10
#define SWING_OFF 0b00000000
#define SWING_HORIZONTAL 0b00100000
@@ -49,10 +47,6 @@ namespace tclac {
#define SWING_BOTH 0b01100000
#define SWING_MODE_MASK 0b01100000
#define STEP_TEMPERATURE 1
#define MIN_SET_TEMPERATURE 16
#define MAX_SET_TEMPERATURE 31
using climate::ClimateCall;
using climate::ClimateMode;
using climate::ClimatePreset;
@@ -122,28 +116,17 @@ class tclacClimate : public climate::Climate, public esphome::uart::UARTDevice,
void loop() override;
void setup() override;
void update() override;
void dataShow(bool flow, bool shine);
void sendData(byte * message, byte size);
static String getHex(byte *message, byte size);
static byte getChecksum(const byte * message, size_t size);
void control(const ClimateCall &call) override; // Climate control
// Заготовки функций запроса состояния, может пригодиться в будущем, если делать обратную связь. Очень не хочется, будет очень костыльно.
//bool get_beeper_state() const;
//bool get_display_state() const;
//bool tclacClimate::get_module_display_state() const;
//AirflowVerticalDirection get_vertical_airflow() const;
//AirflowHorizontalDirection get_horizontal_airflow() const;
//VerticalSwingDirection tclacClimate::get_vertical_swing_direction() const;
//HorizontalSwingDirection tclacClimate::get_horizontal_swing_direction() const;
void set_beeper_state(bool state);
void set_display_state(bool state);
void dataShow(bool flow, bool shine);
void set_force_mode_state(bool state);
void set_rx_led_pin(GPIOPin *rx_led_pin);
void set_tx_led_pin(GPIOPin *tx_led_pin);
void sendData(byte * message, byte size);
void set_module_display_state(bool state);
static String getHex(byte *message, byte size);
void control(const ClimateCall &call) override;
static byte getChecksum(const byte * message, size_t size);
void set_vertical_airflow(AirflowVerticalDirection direction);
void set_horizontal_airflow(AirflowHorizontalDirection direction);
void set_vertical_swing_direction(VerticalSwingDirection direction);
@@ -165,10 +148,8 @@ class tclacClimate : public climate::Climate, public esphome::uart::UARTDevice,
VerticalSwingDirection vertical_swing_direction_;
std::set<ClimateSwingMode> supported_swing_modes_{};
HorizontalSwingDirection horizontal_swing_direction_;
};
}
}
#endif //TCL_ESP_TCL_H
#endif //TCL_ESP_TCL_H

View File

@@ -158,7 +158,7 @@ switch:
id(${device_name}climate).set_display_state(false);
# Светодиодная индикация обмена данными с кондиционером, по умолчанию выключена
- name: Module display
- name: Display on module
platform: template
device_class: switch
id: ledflash_mode