Почистил код, убрал лишнее, отключил лишние логи, изменил описание. Кто молодец? Я, конечно!
This commit is contained in:
98
README.md
98
README.md
@@ -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
|
||||
```
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -21,12 +27,8 @@ ClimateTraits tclacClimate::traits() {
|
||||
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_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_; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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,9 +148,7 @@ class tclacClimate : public climate::Climate, public esphome::uart::UARTDevice,
|
||||
VerticalSwingDirection vertical_swing_direction_;
|
||||
std::set<ClimateSwingMode> supported_swing_modes_{};
|
||||
HorizontalSwingDirection horizontal_swing_direction_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user