mirror of
https://github.com/GrKoR/esphome_aux_ac_component.git
synced 2025-12-06 11:36:55 +03:00
Compare commits
108 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
577eac89c8 | ||
|
|
fa3bdf21db | ||
|
|
c959d7be7e | ||
|
|
60d6f56fcf | ||
|
|
a8eba8882e | ||
|
|
96455e5882 | ||
|
|
89db23434b | ||
|
|
945d2603f1 | ||
|
|
6291828cec | ||
|
|
8dc9f0f478 | ||
|
|
03e0ee0d9a | ||
|
|
848fd8f6c1 | ||
|
|
e77d49c52a | ||
|
|
42fd8d5ba1 | ||
|
|
00aa426bfc | ||
|
|
029d92be96 | ||
|
|
d1e64af8a4 | ||
|
|
d238c8b661 | ||
|
|
140447ceab | ||
|
|
6920102969 | ||
|
|
f20f89cb93 | ||
|
|
6a98c47ada | ||
|
|
b5e88f7abc | ||
|
|
a166d18ede | ||
|
|
7de56fb656 | ||
|
|
cf5c88662d | ||
|
|
a7d2a73802 | ||
|
|
078a6b20cf | ||
|
|
69eebdb8c8 | ||
|
|
fe00198764 | ||
|
|
da5fcd5848 | ||
|
|
9d4930d290 | ||
|
|
26ae9c248c | ||
|
|
e67898997d | ||
|
|
e158586268 | ||
|
|
2d446f88e4 | ||
|
|
5591b91f7b | ||
|
|
551c476549 | ||
|
|
bdbd1478b7 | ||
|
|
9c2daf0615 | ||
|
|
3ca873450d | ||
|
|
5e1b78df9f | ||
|
|
7a252e5955 | ||
|
|
79f23c341d | ||
|
|
360d274088 | ||
|
|
973f961e5f | ||
|
|
cf990eb467 | ||
|
|
1c6575a264 | ||
|
|
7f68f3fdac | ||
|
|
e7bca33f35 | ||
|
|
f859e656a4 | ||
|
|
5b229da380 | ||
|
|
656344dda6 | ||
|
|
b10a2f5dab | ||
|
|
b80f4972f0 | ||
|
|
2a38208628 | ||
|
|
07a98e5789 | ||
|
|
fe323a6f65 | ||
|
|
584ef0d57a | ||
|
|
d15272f437 | ||
|
|
23584bf53a | ||
|
|
1b3bcdfa0f | ||
|
|
558922047e | ||
|
|
9f362f475b | ||
|
|
dad7025632 | ||
|
|
16824c10cc | ||
|
|
f31cfb3c16 | ||
|
|
35d0364655 | ||
|
|
25ab6feb4f | ||
|
|
3f1b31bb52 | ||
|
|
06388ebb2c | ||
|
|
1f11db4ae0 | ||
|
|
87f686564e | ||
|
|
37c261700b | ||
|
|
789053e4be | ||
|
|
f8d3714871 | ||
|
|
e5704ba869 | ||
|
|
e3e60e4f4f | ||
|
|
e98c67e75e | ||
|
|
3f1e928a09 | ||
|
|
507fc06813 | ||
|
|
a48ec376b1 | ||
|
|
c2dfbefbcf | ||
|
|
f324cd1a0e | ||
|
|
4bd5c4509d | ||
|
|
8228ee0777 | ||
|
|
453f697c48 | ||
|
|
82a17f0247 | ||
|
|
d14ed9650d | ||
|
|
e7377604ba | ||
|
|
2f0f514ea6 | ||
|
|
394e64e1f8 | ||
|
|
fcbc853835 | ||
|
|
c8d661377f | ||
|
|
9c6faeecb8 | ||
|
|
8afa70a999 | ||
|
|
ca9a76124c | ||
|
|
dacd435177 | ||
|
|
bf8ab77c02 | ||
|
|
61cad07acc | ||
|
|
3110c482c9 | ||
|
|
53a886f818 | ||
|
|
2d4162323a | ||
|
|
74d555b5e1 | ||
|
|
7df8ab3cc2 | ||
|
|
90d9a5cfa7 | ||
|
|
864ad07699 | ||
|
|
e595a4acf9 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -3,6 +3,7 @@
|
||||
# You can modify this file to suit your needs.
|
||||
**/.vscode/
|
||||
**/.esphome/
|
||||
**/esphome/
|
||||
**/.pioenvs/
|
||||
**/.piolibdeps/
|
||||
**/lib/
|
||||
@@ -12,6 +13,6 @@
|
||||
**/livingroom_ac/
|
||||
**/kitchen_ac/
|
||||
/examples/*/*.h
|
||||
**/tests/test_*
|
||||
**/__pycache__
|
||||
**/private/
|
||||
**/private/
|
||||
**/tests
|
||||
10
README-EN.md
10
README-EN.md
@@ -36,7 +36,7 @@ The best way to report about your test results is writing a message in the [tele
|
||||
For correct component operation, you need hardware and firmware. The hardware description is located [in a separate file](docs/HARDWARE-EN.md).
|
||||
|
||||
### Firmware: Integration aux_ac to your configuration ###
|
||||
You need [ESPHome](https://esphome.io) v.1.18.0 or above. `External_components` have appeared in this version. But it is better to use ESPHome v.1.20.4 or above, cause there were a lot of `external_components` errors corrected before this version.
|
||||
You need [ESPHome](https://esphome.io) v.2025.2.0 or above. You can try esphome before 2025.2.0 but I can't guarantee error-free compilation of the examples.
|
||||
|
||||
## Installing ##
|
||||
1. Declare external component. Read [the manual](https://esphome.io/components/external_components.html?highlight=external) for details.
|
||||
@@ -46,6 +46,14 @@ external_components:
|
||||
type: git
|
||||
url: https://github.com/GrKoR/esphome_aux_ac_component
|
||||
```
|
||||
In case you need a specific version of the component, you can use the component declaration from the example below. The example uses version 0.2.14 of the component. You can find a list of available versions [on the GitHub tags page](https://github.com/GrKoR/esphome_aux_ac_component/tags).
|
||||
```yaml
|
||||
external_components:
|
||||
- source:
|
||||
type: git
|
||||
url: https://github.com/GrKoR/esphome_aux_ac_component
|
||||
ref: v.0.2.14
|
||||
```
|
||||
2. Configure UART to communicate with air conditioner:
|
||||
```yaml
|
||||
uart:
|
||||
|
||||
10
README.md
10
README.md
@@ -43,7 +43,7 @@ AUX - это один из нескольких OEM-производителей
|
||||
Для работы с кондиционером понадобится "железо" и прошивка. Описание электроники вынесено [в отдельный файл](docs/HARDWARE.md).
|
||||
|
||||
### Прошивка: интеграция aux_ac в вашу конфигурацию ESPHome ###
|
||||
Для использования требуется [ESPHome](https://esphome.io) версией не ниже 1.18.0. Именно в этой версии появились `external_components`. Но лучше использовать версию 1.20.4 или старше, так как до этой версии массированно исправлялись ошибки в механизме подключения внешних компонентов.<br />
|
||||
Для использования требуется [ESPHome](https://esphome.io) версией не ниже 2025.2.0. Работа с более ранними версиями возможна, но не гарантируется.<br />
|
||||
|
||||
## Установка ##
|
||||
1. Подключите компонент.
|
||||
@@ -54,6 +54,14 @@ external_components:
|
||||
type: git
|
||||
url: https://github.com/GrKoR/esphome_aux_ac_component
|
||||
```
|
||||
Если требуется прошить определенную версию компонента, используйте синтаксис из примера ниже. Здесь прошивается версия 0.2.14. Список версий смотрите [в тегах на гитхаб](https://github.com/GrKoR/esphome_aux_ac_component/tags).
|
||||
```yaml
|
||||
external_components:
|
||||
- source:
|
||||
type: git
|
||||
url: https://github.com/GrKoR/esphome_aux_ac_component
|
||||
ref: v.0.2.14
|
||||
```
|
||||
2. Настройте UART для коммуникации с вашим кондиционером:
|
||||
```yaml
|
||||
uart:
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "aux_ac.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace aux_ac {
|
||||
|
||||
// **************************************** DISPLAY ACTIONS ****************************************
|
||||
template <typename... Ts>
|
||||
class AirConDisplayOffAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit AirConDisplayOffAction(AirCon *ac) : ac_(ac) {}
|
||||
|
||||
void play(Ts... x) override { this->ac_->displayOffSequence(); }
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
class AirConDisplayOnAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit AirConDisplayOnAction(AirCon *ac) : ac_(ac) {}
|
||||
|
||||
void play(Ts... x) override { this->ac_->displayOnSequence(); }
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
};
|
||||
|
||||
// **************************************** VERTICAL LOUVER ACTIONS ****************************************
|
||||
template <typename... Ts>
|
||||
class AirConVLouverSwingAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit AirConVLouverSwingAction(AirCon *ac) : ac_(ac) {}
|
||||
|
||||
void play(Ts... x) override { this->ac_->setVLouverSwingSequence(); }
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
class AirConVLouverStopAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit AirConVLouverStopAction(AirCon *ac) : ac_(ac) {}
|
||||
|
||||
void play(Ts... x) override { this->ac_->setVLouverStopSequence(); }
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
class AirConVLouverTopAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit AirConVLouverTopAction(AirCon *ac) : ac_(ac) {}
|
||||
|
||||
void play(Ts... x) override { this->ac_->setVLouverTopSequence(); }
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
class AirConVLouverMiddleAboveAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit AirConVLouverMiddleAboveAction(AirCon *ac) : ac_(ac) {}
|
||||
|
||||
void play(Ts... x) override { this->ac_->setVLouverMiddleAboveSequence(); }
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
class AirConVLouverMiddleAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit AirConVLouverMiddleAction(AirCon *ac) : ac_(ac) {}
|
||||
|
||||
void play(Ts... x) override { this->ac_->setVLouverMiddleSequence(); }
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
class AirConVLouverMiddleBelowAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit AirConVLouverMiddleBelowAction(AirCon *ac) : ac_(ac) {}
|
||||
|
||||
void play(Ts... x) override { this->ac_->setVLouverMiddleBelowSequence(); }
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
class AirConVLouverBottomAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit AirConVLouverBottomAction(AirCon *ac) : ac_(ac) {}
|
||||
|
||||
void play(Ts... x) override { this->ac_->setVLouverBottomSequence(); }
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
class AirConVLouverSetAction : public Action<Ts...> {
|
||||
public:
|
||||
AirConVLouverSetAction(AirCon *ac) : ac_(ac) {}
|
||||
TEMPLATABLE_VALUE(uint8_t, value);
|
||||
|
||||
void play(Ts... x) {
|
||||
vlpos_ = this->value_.value(x...);
|
||||
this->ac_->setVLouverFrontendSequence((ac_vlouver_frontend)vlpos_);
|
||||
}
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
uint8_t vlpos_;
|
||||
};
|
||||
|
||||
// **************************************** SEND TEST PACKET ACTION ****************************************
|
||||
template <typename... Ts>
|
||||
class AirConSendTestPacketAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit AirConSendTestPacketAction(AirCon *ac) : ac_(ac) {}
|
||||
void set_data_template(std::function<std::vector<uint8_t>(Ts...)> func) {
|
||||
this->data_func_ = func;
|
||||
this->static_ = false;
|
||||
}
|
||||
void set_data_static(const std::vector<uint8_t> &data) {
|
||||
this->data_static_ = data;
|
||||
this->static_ = true;
|
||||
}
|
||||
|
||||
void play(Ts... x) override {
|
||||
if (this->static_) {
|
||||
this->ac_->sendTestPacket(this->data_static_);
|
||||
} else {
|
||||
auto val = this->data_func_(x...);
|
||||
this->ac_->sendTestPacket(val);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
bool static_{false};
|
||||
std::function<std::vector<uint8_t>(Ts...)> data_func_{};
|
||||
std::vector<uint8_t> data_static_{};
|
||||
};
|
||||
|
||||
// **************************************** POWER LIMITATION ACTIONS ****************************************
|
||||
template <typename... Ts>
|
||||
class AirConPowerLimitationOffAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit AirConPowerLimitationOffAction(AirCon *ac) : ac_(ac) {}
|
||||
|
||||
void play(Ts... x) override { this->ac_->powerLimitationOffSequence(); }
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
class AirConPowerLimitationOnAction : public Action<Ts...> {
|
||||
public:
|
||||
AirConPowerLimitationOnAction(AirCon *ac) : ac_(ac) {}
|
||||
TEMPLATABLE_VALUE(uint8_t, value);
|
||||
|
||||
void play(Ts... x) {
|
||||
this->pwr_lim_ = this->value_.value(x...);
|
||||
this->ac_->powerLimitationOnSequence(this->pwr_lim_);
|
||||
}
|
||||
|
||||
protected:
|
||||
AirCon *ac_;
|
||||
uint8_t pwr_lim_;
|
||||
};
|
||||
|
||||
} // namespace aux_ac
|
||||
} // namespace esphome
|
||||
File diff suppressed because it is too large
Load Diff
148
components/aux_ac/aux_frame.h
Normal file
148
components/aux_ac/aux_frame.h
Normal file
@@ -0,0 +1,148 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h> // for memcpy and memset, move to .cpp later if needed
|
||||
|
||||
namespace esphome
|
||||
{
|
||||
namespace aux_ac
|
||||
{
|
||||
|
||||
class AuxFrame
|
||||
{
|
||||
private:
|
||||
// CRC of the AUX frame
|
||||
// https://github.com/GrKoR/AUX_HVAC_Protocol#packet_crc
|
||||
union frame_crc_t
|
||||
{
|
||||
uint16_t crc16;
|
||||
uint8_t crc[2];
|
||||
};
|
||||
|
||||
// frame header
|
||||
// https://github.com/GrKoR/AUX_HVAC_Protocol#packet_header
|
||||
struct frame_header_t
|
||||
{
|
||||
uint8_t startByte;
|
||||
uint8_t _unknown1;
|
||||
uint8_t frameType;
|
||||
uint8_t wifi;
|
||||
uint8_t pingAnswer;
|
||||
uint8_t _unknown2;
|
||||
uint8_t bodyLength;
|
||||
uint8_t _unknown3;
|
||||
};
|
||||
|
||||
uint8_t *_rawData = nullptr;
|
||||
frame_header_t *_header = nullptr;
|
||||
uint8_t *_body = nullptr;
|
||||
frame_crc_t *_crc = nullptr;
|
||||
|
||||
bool _isValid = false;
|
||||
|
||||
uint8_t const AC_PACKET_START_BYTE = 0xBB;
|
||||
uint8_t const AC_HEADER_SIZE = 8;
|
||||
uint8_t const AC_BODY_LENGTH_OFFSET = 6;
|
||||
|
||||
uint8_t const AC_BUFFER_SIZE = 35; // TODO: integrate it with aux_uart.h
|
||||
|
||||
uint16_t _CRC16(uint8_t *data, uint8_t len)
|
||||
{
|
||||
uint32_t crc = 0;
|
||||
|
||||
uint8_t _crcBuffer[AC_BUFFER_SIZE];
|
||||
memset(_crcBuffer, 0, AC_BUFFER_SIZE);
|
||||
memcpy(_crcBuffer, data, len);
|
||||
|
||||
if ((len % 2) == 1)
|
||||
len++;
|
||||
|
||||
uint32_t word = 0;
|
||||
for (uint8_t i = 0; i < len; i += 2)
|
||||
{
|
||||
word = (_crcBuffer[i] << 8) + _crcBuffer[i + 1];
|
||||
crc += word;
|
||||
}
|
||||
crc = (crc >> 16) + (crc & 0xFFFF);
|
||||
crc = ~crc;
|
||||
|
||||
return crc & 0xFFFF;
|
||||
}
|
||||
|
||||
bool _checkCRC()
|
||||
{
|
||||
frame_crc_t crc;
|
||||
crc.crc16 = _CRC16(this->_rawData, AC_HEADER_SIZE + this->_rawData[AC_BODY_LENGTH_OFFSET]);
|
||||
|
||||
return ((this->_crc->crc[0] == crc.crc[1]) && (this->_crc->crc[1] == crc.crc[0]));
|
||||
}
|
||||
|
||||
void _checkFrame()
|
||||
{
|
||||
this->_isValid = false;
|
||||
if (this->_rawData == nullptr)
|
||||
return;
|
||||
|
||||
if (this->_header->startByte != AC_PACKET_START_BYTE)
|
||||
return;
|
||||
|
||||
if (!this->_checkCRC())
|
||||
return;
|
||||
|
||||
this->_isValid = true;
|
||||
}
|
||||
|
||||
public:
|
||||
AuxFrame() = default;
|
||||
~AuxFrame() {};
|
||||
|
||||
void set_data(uint8_t *data)
|
||||
{
|
||||
clearData();
|
||||
if (data == nullptr)
|
||||
return;
|
||||
|
||||
this->_rawData = data;
|
||||
this->_header = (frame_header_t *)this->_rawData;
|
||||
this->_crc = (frame_crc_t *)(this->_rawData + AC_HEADER_SIZE + this->_header->bodyLength);
|
||||
if (this->_header->bodyLength > 0)
|
||||
this->_body = this->_rawData + AC_HEADER_SIZE;
|
||||
else
|
||||
this->_body = nullptr;
|
||||
this->_checkFrame();
|
||||
}
|
||||
|
||||
void clearData()
|
||||
{
|
||||
this->_rawData = nullptr;
|
||||
this->_header = nullptr;
|
||||
this->_crc = nullptr;
|
||||
this->_body = nullptr;
|
||||
this->_isValid = false;
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return this->_isValid;
|
||||
};
|
||||
|
||||
uint8_t frameSize() const
|
||||
{
|
||||
if (!this->isValid())
|
||||
return 0;
|
||||
|
||||
return AC_HEADER_SIZE + this->_header->bodyLength + 2;
|
||||
}
|
||||
|
||||
uint8_t bodyLength() const
|
||||
{
|
||||
if (!this->isValid())
|
||||
return 0;
|
||||
|
||||
return this->_header->bodyLength;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux_ac
|
||||
|
||||
} // namespace esphome
|
||||
100
components/aux_ac/aux_logger.cpp
Normal file
100
components/aux_ac/aux_logger.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "aux_logger.h"
|
||||
|
||||
namespace esphome
|
||||
{
|
||||
namespace aux_ac
|
||||
{
|
||||
static const char *const TAG = "AirCon"; // TODO: verify if this tag is appropriate
|
||||
|
||||
/** вывод отладочной информации в лог
|
||||
*
|
||||
* dbgLevel - уровень сообщения, определен в ESPHome. За счет его использования можно из ESPHome управлять полнотой сведений в логе.
|
||||
* msg - сообщение, выводимое в лог
|
||||
* line - строка, на которой произошел вызов (удобно при отладке)
|
||||
*/
|
||||
void debugMsg(const /*String &*/ char *msg, uint8_t dbgLevel, unsigned int line, ...)
|
||||
{
|
||||
if (dbgLevel < ESPHOME_LOG_LEVEL_NONE)
|
||||
dbgLevel = ESPHOME_LOG_LEVEL_NONE;
|
||||
if (dbgLevel > ESPHOME_LOG_LEVEL_VERY_VERBOSE)
|
||||
dbgLevel = ESPHOME_LOG_LEVEL_VERY_VERBOSE;
|
||||
|
||||
if (line == 0)
|
||||
line = __LINE__; // если строка не передана, берем текущую строку
|
||||
|
||||
va_list vl;
|
||||
va_start(vl, line);
|
||||
esp_log_vprintf_(dbgLevel, TAG, line, msg, vl);
|
||||
va_end(vl);
|
||||
};
|
||||
|
||||
/** выводим данные пакета в лог для отладки
|
||||
*
|
||||
* dbgLevel - уровень сообщения, определен в ESPHome. За счет его использования можно из ESPHome управлять полнотой сведений в логе.
|
||||
* packet - указатель на пакет для вывода;
|
||||
* если указатель на crc равен nullptr или первый байт в буфере не AC_PACKET_START_BYTE, то считаем, что передан битый пакет
|
||||
* или не пакет вовсе. Для такого выводим только массив байт.
|
||||
* Для нормального пакета данные выводятся с форматированием.
|
||||
* line - строка, на которой произошел вызов (удобно при отладке)
|
||||
**/
|
||||
void debugPrintPacket(packet_t *packet, uint8_t dbgLevel, unsigned int line)
|
||||
{
|
||||
// определяем, полноценный ли пакет нам передан
|
||||
bool notAPacket = false;
|
||||
/*
|
||||
// указатель заголовка всегда установден на начало буфера
|
||||
notAPacket = notAPacket || (packet->crc == nullptr);
|
||||
notAPacket = notAPacket || (packet->data[0] != AC_PACKET_START_BYTE);
|
||||
|
||||
String st = "";
|
||||
char textBuf[11];
|
||||
|
||||
// заполняем время получения пакета
|
||||
memset(textBuf, 0, 11);
|
||||
sprintf(textBuf, "%010" PRIu32, packet->msec);
|
||||
st = st + textBuf + ": ";
|
||||
|
||||
// формируем преамбулы
|
||||
if (packet == &_inPacket)
|
||||
{
|
||||
st += "[<=] "; // преамбула входящего пакета
|
||||
}
|
||||
else if (packet == &_outPacket)
|
||||
{
|
||||
st += "[=>] "; // преамбула исходящего пакета
|
||||
}
|
||||
else
|
||||
{
|
||||
st += "[--] "; // преамбула для "непакета"
|
||||
}
|
||||
|
||||
// формируем данные
|
||||
for (int i = 0; i < packet->bytesLoaded; i++)
|
||||
{
|
||||
// для заголовков нормальных пакетов надо отработать скобки (если они есть)
|
||||
if ((!notAPacket) && (i == 0))
|
||||
st += HOLMES_HEADER_BRACKET_OPEN;
|
||||
// для CRC нормальных пакетов надо отработать скобки (если они есть)
|
||||
if ((!notAPacket) && (i == packet->header->body_length + AC_HEADER_SIZE))
|
||||
st += HOLMES_CRC_BRACKET_OPEN;
|
||||
|
||||
memset(textBuf, 0, 11);
|
||||
sprintf(textBuf, HOLMES_BYTE_FORMAT, packet->data[i]);
|
||||
st += textBuf;
|
||||
|
||||
// для заголовков нормальных пакетов надо отработать скобки (если они есть)
|
||||
if ((!notAPacket) && (i == AC_HEADER_SIZE - 1))
|
||||
st += HOLMES_HEADER_BRACKET_CLOSE;
|
||||
// для CRC нормальных пакетов надо отработать скобки (если они есть)
|
||||
if ((!notAPacket) && (i == packet->header->body_length + AC_HEADER_SIZE + 2 - 1))
|
||||
st += HOLMES_CRC_BRACKET_CLOSE;
|
||||
|
||||
st += HOLMES_DELIMITER;
|
||||
}
|
||||
|
||||
_debugMsg(st, dbgLevel, line);
|
||||
*/
|
||||
}
|
||||
|
||||
} // namespace aux_ac
|
||||
} // namespace esphome
|
||||
15
components/aux_ac/aux_logger.h
Normal file
15
components/aux_ac/aux_logger.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome
|
||||
{
|
||||
namespace aux_ac
|
||||
{
|
||||
using packet_t = uint8_t; // TODO: Replace with actual packet_t definition
|
||||
|
||||
void debugMsg(const char *msg, uint8_t dbgLevel, unsigned int line = 0, ...);
|
||||
void debugPrintPacket(packet_t *packet, uint8_t dbgLevel = ESPHOME_LOG_LEVEL_DEBUG, unsigned int line = __LINE__);
|
||||
} // namespace aux_ac
|
||||
} // namespace esphome
|
||||
68
components/aux_ac/aux_uart.cpp
Normal file
68
components/aux_ac/aux_uart.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "aux_uart.h"
|
||||
|
||||
namespace esphome
|
||||
{
|
||||
namespace aux_ac
|
||||
{
|
||||
void AuxUart::send_frame(const std::vector<uint8_t> &frame)
|
||||
{
|
||||
this->write_array(frame);
|
||||
}
|
||||
|
||||
bool AuxUart::read_frame(std::vector<uint8_t> &frame)
|
||||
{
|
||||
// Check if enough data is available
|
||||
if (this->available() < 3)
|
||||
return false;
|
||||
|
||||
// Peek at the first 3 bytes to determine the frame length
|
||||
uint8_t header[3];
|
||||
if (!this->peek_array(header, 3))
|
||||
return false;
|
||||
|
||||
// Validate start byte
|
||||
if (header[0] != 0xAA)
|
||||
{
|
||||
// Invalid start byte, discard one byte and return false
|
||||
uint8_t discard;
|
||||
this->read_byte(&discard);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Determine frame length from the second byte
|
||||
size_t frame_length = header[1];
|
||||
if (frame_length < 3 || frame_length > AC_BUFFER_SIZE)
|
||||
{
|
||||
// Invalid length, discard one byte and return false
|
||||
uint8_t discard;
|
||||
this->read_byte(&discard);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the full frame is available
|
||||
if (this->available() < frame_length)
|
||||
return false;
|
||||
|
||||
// Read the full frame into the internal buffer
|
||||
if (!this->read_array(this->_data, frame_length))
|
||||
return false;
|
||||
|
||||
// Validate checksum
|
||||
uint8_t checksum = 0;
|
||||
for (size_t i = 0; i < frame_length - 1; i++)
|
||||
{
|
||||
checksum += this->_data[i];
|
||||
}
|
||||
if (checksum != this->_data[frame_length - 1])
|
||||
{
|
||||
// Invalid checksum, discard the frame and return false
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy the valid frame to the output vector
|
||||
frame.assign(this->_data, this->_data + frame_length);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace aux_ac
|
||||
} // namespace esphome
|
||||
30
components/aux_ac/aux_uart.h
Normal file
30
components/aux_ac/aux_uart.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/uart/uart.h"
|
||||
|
||||
#define AC_BUFFER_SIZE 35
|
||||
|
||||
using namespace esphome::uart;
|
||||
|
||||
namespace esphome
|
||||
{
|
||||
namespace aux_ac
|
||||
{
|
||||
class AuxUart : public UARTDevice
|
||||
{
|
||||
public:
|
||||
AuxUart() = delete;
|
||||
explicit AuxUart(UARTComponent *parent) : UARTDevice(parent) {}
|
||||
~AuxUart() = default;
|
||||
|
||||
void send_frame(const std::vector<uint8_t> &frame);
|
||||
bool read_frame(std::vector<uint8_t> &frame);
|
||||
|
||||
protected:
|
||||
// Internal buffer for incoming data
|
||||
uint8_t _data[AC_BUFFER_SIZE];
|
||||
};
|
||||
|
||||
} // namespace aux_ac
|
||||
} // namespace esphome
|
||||
@@ -1,338 +1,46 @@
|
||||
import logging
|
||||
from esphome.core import CORE, Define
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import climate, uart, sensor, binary_sensor, text_sensor
|
||||
from esphome import automation
|
||||
from esphome.automation import maybe_simple_id
|
||||
from esphome.components import uart, climate
|
||||
|
||||
from esphome.const import (
|
||||
CONF_CUSTOM_FAN_MODES,
|
||||
CONF_CUSTOM_PRESETS,
|
||||
CONF_DATA,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_OPTIMISTIC,
|
||||
CONF_PERIOD,
|
||||
CONF_POSITION,
|
||||
CONF_SUPPORTED_MODES,
|
||||
CONF_SUPPORTED_SWING_MODES,
|
||||
CONF_SUPPORTED_PRESETS,
|
||||
CONF_TIMEOUT,
|
||||
CONF_UART_ID,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_PERCENT,
|
||||
ICON_POWER,
|
||||
ICON_THERMOMETER,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
DEVICE_CLASS_POWER_FACTOR,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
)
|
||||
from esphome.components.climate import (
|
||||
ClimateMode,
|
||||
ClimatePreset,
|
||||
ClimateSwingMode,
|
||||
)
|
||||
|
||||
AUX_AC_FIRMWARE_VERSION = '0.2.17'
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CODEOWNERS = ["@GrKoR"]
|
||||
DEPENDENCIES = ["climate", "uart"]
|
||||
AUTO_LOAD = ["sensor", "binary_sensor", "text_sensor"]
|
||||
|
||||
CONF_SHOW_ACTION = "show_action"
|
||||
|
||||
CONF_INDOOR_TEMPERATURE = "indoor_temperature"
|
||||
CONF_OUTDOOR_TEMPERATURE = "outdoor_temperature"
|
||||
ICON_OUTDOOR_TEMPERATURE = "mdi:home-thermometer-outline"
|
||||
|
||||
CONF_INBOUND_TEMPERATURE = "inbound_temperature"
|
||||
ICON_INBOUND_TEMPERATURE = "mdi:thermometer-plus"
|
||||
|
||||
CONF_OUTBOUND_TEMPERATURE = "outbound_temperature"
|
||||
ICON_OUTBOUND_TEMPERATURE = "mdi:thermometer-minus"
|
||||
|
||||
CONF_COMPRESSOR_TEMPERATURE = "compressor_temperature"
|
||||
ICON_COMPRESSOR_TEMPERATURE = "mdi:thermometer-lines"
|
||||
|
||||
CONF_DISPLAY_STATE = "display_state"
|
||||
CONF_INVERTER_POWER = "inverter_power"
|
||||
CONF_INVERTER_POWER_DEPRICATED = "invertor_power"
|
||||
|
||||
CONF_DEFROST_STATE = "defrost_state"
|
||||
ICON_DEFROST = "mdi:snowflake-melt"
|
||||
|
||||
CONF_DISPLAY_INVERTED = "display_inverted"
|
||||
ICON_DISPLAY = "mdi:clock-digital"
|
||||
|
||||
CONF_PRESET_REPORTER = "preset_reporter"
|
||||
ICON_PRESET_REPORTER = "mdi:format-list-group"
|
||||
|
||||
CONF_VLOUVER_STATE = "vlouver_state"
|
||||
ICON_VLOUVER_STATE = "mdi:compare-vertical"
|
||||
|
||||
CONF_LIMIT = "limit"
|
||||
CONF_INVERTER_POWER_LIMIT_VALUE = "inverter_power_limit_value"
|
||||
ICON_INVERTER_POWER_LIMIT_VALUE = "mdi:meter-electric-outline"
|
||||
CONF_INVERTER_POWER_LIMIT_STATE = "inverter_power_limit_state"
|
||||
ICON_INVERTER_POWER_LIMIT_STATE = "mdi:meter-electric-outline"
|
||||
|
||||
DEPENDENCIES = ["uart"]
|
||||
|
||||
aux_ac_ns = cg.esphome_ns.namespace("aux_ac")
|
||||
AirCon = aux_ac_ns.class_("AirCon", climate.Climate, cg.Component)
|
||||
Capabilities = aux_ac_ns.namespace("Constants")
|
||||
|
||||
# Display actions
|
||||
AirConDisplayOffAction = aux_ac_ns.class_("AirConDisplayOffAction", automation.Action)
|
||||
AirConDisplayOnAction = aux_ac_ns.class_("AirConDisplayOnAction", automation.Action)
|
||||
|
||||
# test packet action
|
||||
AirConSendTestPacketAction = aux_ac_ns.class_(
|
||||
"AirConSendTestPacketAction", automation.Action
|
||||
)
|
||||
|
||||
# vertical louvers actions
|
||||
AirConVLouverSwingAction = aux_ac_ns.class_(
|
||||
"AirConVLouverSwingAction", automation.Action
|
||||
)
|
||||
AirConVLouverStopAction = aux_ac_ns.class_("AirConVLouverStopAction", automation.Action)
|
||||
AirConVLouverTopAction = aux_ac_ns.class_("AirConVLouverTopAction", automation.Action)
|
||||
AirConVLouverMiddleAboveAction = aux_ac_ns.class_(
|
||||
"AirConVLouverMiddleAboveAction", automation.Action
|
||||
)
|
||||
AirConVLouverMiddleAction = aux_ac_ns.class_(
|
||||
"AirConVLouverMiddleAction", automation.Action
|
||||
)
|
||||
AirConVLouverMiddleBelowAction = aux_ac_ns.class_(
|
||||
"AirConVLouverMiddleBelowAction", automation.Action
|
||||
)
|
||||
AirConVLouverBottomAction = aux_ac_ns.class_(
|
||||
"AirConVLouverBottomAction", automation.Action
|
||||
)
|
||||
AirConVLouverSetAction = aux_ac_ns.class_(
|
||||
"AirConVLouverSetAction", automation.Action
|
||||
)
|
||||
|
||||
# power limitation actions
|
||||
AirConPowerLimitationOffAction = aux_ac_ns.class_(
|
||||
"AirConPowerLimitationOffAction", automation.Action
|
||||
)
|
||||
AirConPowerLimitationOnAction = aux_ac_ns.class_(
|
||||
"AirConPowerLimitationOnAction", automation.Action
|
||||
)
|
||||
|
||||
|
||||
AC_PACKET_TIMEOUT_MIN = 150
|
||||
AC_PACKET_TIMEOUT_MAX = 600
|
||||
def validate_packet_timeout(value):
|
||||
minV = AC_PACKET_TIMEOUT_MIN
|
||||
maxV = AC_PACKET_TIMEOUT_MAX
|
||||
if value in range(minV, maxV+1):
|
||||
return cv.Schema(cv.uint32_t)(value)
|
||||
raise cv.Invalid(f"Timeout should be in range: {minV}..{maxV}.")
|
||||
|
||||
|
||||
AC_POWER_LIMIT_MIN = 30
|
||||
AC_POWER_LIMIT_MAX = 100
|
||||
def validate_power_limit_range(value):
|
||||
minV = AC_POWER_LIMIT_MIN
|
||||
maxV = AC_POWER_LIMIT_MAX
|
||||
if value in range(minV, maxV+1):
|
||||
return cv.Schema(cv.uint32_t)(value)
|
||||
raise cv.Invalid(f"Power limit should be in range: {minV}..{maxV}")
|
||||
|
||||
|
||||
ALLOWED_CLIMATE_MODES = {
|
||||
"HEAT_COOL": ClimateMode.CLIMATE_MODE_HEAT_COOL,
|
||||
"COOL": ClimateMode.CLIMATE_MODE_COOL,
|
||||
"HEAT": ClimateMode.CLIMATE_MODE_HEAT,
|
||||
"DRY": ClimateMode.CLIMATE_MODE_DRY,
|
||||
"FAN_ONLY": ClimateMode.CLIMATE_MODE_FAN_ONLY,
|
||||
}
|
||||
validate_modes = cv.enum(ALLOWED_CLIMATE_MODES, upper=True)
|
||||
|
||||
ALLOWED_CLIMATE_PRESETS = {
|
||||
"SLEEP": ClimatePreset.CLIMATE_PRESET_SLEEP,
|
||||
}
|
||||
validate_presets = cv.enum(ALLOWED_CLIMATE_PRESETS, upper=True)
|
||||
|
||||
ALLOWED_CLIMATE_SWING_MODES = {
|
||||
"BOTH": ClimateSwingMode.CLIMATE_SWING_BOTH,
|
||||
"VERTICAL": ClimateSwingMode.CLIMATE_SWING_VERTICAL,
|
||||
"HORIZONTAL": ClimateSwingMode.CLIMATE_SWING_HORIZONTAL,
|
||||
}
|
||||
validate_swing_modes = cv.enum(ALLOWED_CLIMATE_SWING_MODES, upper=True)
|
||||
|
||||
CUSTOM_FAN_MODES = {
|
||||
"MUTE": Capabilities.MUTE,
|
||||
"TURBO": Capabilities.TURBO,
|
||||
}
|
||||
validate_custom_fan_modes = cv.enum(CUSTOM_FAN_MODES, upper=True)
|
||||
|
||||
CUSTOM_PRESETS = {
|
||||
"CLEAN": Capabilities.CLEAN,
|
||||
"HEALTH": Capabilities.HEALTH,
|
||||
"ANTIFUNGUS": Capabilities.ANTIFUNGUS,
|
||||
}
|
||||
validate_custom_presets = cv.enum(CUSTOM_PRESETS, upper=True)
|
||||
|
||||
|
||||
def validate_raw_data(value):
|
||||
if isinstance(value, list):
|
||||
return cv.Schema([cv.hex_uint8_t])(value)
|
||||
raise cv.Invalid("data must be a list of bytes")
|
||||
|
||||
AuxUart = aux_ac_ns.class_("AuxUart", uart.UARTDevice)
|
||||
|
||||
def output_info(config):
|
||||
"""_LOGGER.info(config.items())"""
|
||||
_LOGGER.info("AUX_AC firmware version: %s", AUX_AC_FIRMWARE_VERSION)
|
||||
return config
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
climate.CLIMATE_SCHEMA.extend(
|
||||
uart.UART_DEVICE_SCHEMA
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(AirCon),
|
||||
cv.Optional(CONF_PERIOD, default="7s"): cv.time_period,
|
||||
cv.Optional(CONF_SHOW_ACTION, default="true"): cv.boolean,
|
||||
cv.Optional(CONF_DISPLAY_INVERTED, default="false"): cv.boolean,
|
||||
cv.Optional(CONF_TIMEOUT, default=AC_PACKET_TIMEOUT_MIN): validate_packet_timeout,
|
||||
cv.Optional(CONF_OPTIMISTIC, default="true"): cv.boolean,
|
||||
cv.Optional(CONF_INVERTER_POWER_DEPRICATED): cv.invalid(
|
||||
"The name of sensor was changed in v.0.2.9 from 'invertor_power' to 'inverter_power'. Update your config please."
|
||||
),
|
||||
cv.Optional(CONF_INVERTER_POWER): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_PERCENT,
|
||||
icon=ICON_POWER,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_POWER_FACTOR,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
|
||||
cv.Optional(CONF_INDOOR_TEMPERATURE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
icon=ICON_THERMOMETER,
|
||||
accuracy_decimals=1,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_OUTDOOR_TEMPERATURE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
icon=ICON_OUTDOOR_TEMPERATURE,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_INBOUND_TEMPERATURE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
icon=ICON_INBOUND_TEMPERATURE,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_OUTBOUND_TEMPERATURE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
icon=ICON_OUTBOUND_TEMPERATURE,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_COMPRESSOR_TEMPERATURE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
icon=ICON_COMPRESSOR_TEMPERATURE,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_VLOUVER_STATE): sensor.sensor_schema(
|
||||
icon=ICON_VLOUVER_STATE,
|
||||
accuracy_decimals=0,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_DISPLAY_STATE): binary_sensor.binary_sensor_schema(
|
||||
icon=ICON_DISPLAY,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_DEFROST_STATE): binary_sensor.binary_sensor_schema(
|
||||
icon=ICON_DEFROST,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_PRESET_REPORTER): text_sensor.text_sensor_schema(
|
||||
icon=ICON_PRESET_REPORTER,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_INVERTER_POWER_LIMIT_VALUE): sensor.sensor_schema(
|
||||
unit_of_measurement=UNIT_PERCENT,
|
||||
icon=ICON_INVERTER_POWER_LIMIT_VALUE,
|
||||
accuracy_decimals=0,
|
||||
device_class=DEVICE_CLASS_POWER_FACTOR,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_INVERTER_POWER_LIMIT_STATE): binary_sensor.binary_sensor_schema(
|
||||
icon=ICON_INVERTER_POWER_LIMIT_STATE,
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_INTERNAL, default="true"): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_SUPPORTED_MODES): cv.ensure_list(validate_modes),
|
||||
cv.Optional(CONF_SUPPORTED_SWING_MODES): cv.ensure_list(
|
||||
validate_swing_modes
|
||||
),
|
||||
cv.Optional(CONF_SUPPORTED_PRESETS): cv.ensure_list(validate_presets),
|
||||
cv.Optional(CONF_CUSTOM_PRESETS): cv.ensure_list(validate_custom_presets),
|
||||
cv.Optional(CONF_CUSTOM_FAN_MODES): cv.ensure_list(
|
||||
validate_custom_fan_modes
|
||||
),
|
||||
cv.GenerateID(): cv.declare_id(AuxUart),
|
||||
}
|
||||
)
|
||||
.extend(uart.UART_DEVICE_SCHEMA)
|
||||
.extend(cv.COMPONENT_SCHEMA),
|
||||
),
|
||||
output_info,
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
CORE.add_define(
|
||||
Define("AUX_AC_FIRMWARE_VERSION", '"'+AUX_AC_FIRMWARE_VERSION+'"')
|
||||
)
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await climate.register_climate(var, config)
|
||||
# await cg.register_component(var, config)
|
||||
|
||||
parent = await cg.get_variable(config[CONF_UART_ID])
|
||||
cg.add(var.initAC(parent))
|
||||
@@ -386,7 +94,7 @@ async def to_code(config):
|
||||
conf = config[CONF_PRESET_REPORTER]
|
||||
sens = await text_sensor.new_text_sensor(conf)
|
||||
cg.add(var.set_preset_reporter_sensor(sens))
|
||||
|
||||
|
||||
if CONF_INVERTER_POWER_LIMIT_VALUE in config:
|
||||
conf = config[CONF_INVERTER_POWER_LIMIT_VALUE]
|
||||
sens = await sensor.new_sensor(conf)
|
||||
@@ -412,170 +120,3 @@ async def to_code(config):
|
||||
cg.add(var.set_custom_presets(config[CONF_CUSTOM_PRESETS]))
|
||||
if CONF_CUSTOM_FAN_MODES in config:
|
||||
cg.add(var.set_custom_fan_modes(config[CONF_CUSTOM_FAN_MODES]))
|
||||
|
||||
|
||||
|
||||
DISPLAY_ACTION_SCHEMA = maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(AirCon),
|
||||
}
|
||||
)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.display_off", AirConDisplayOffAction, DISPLAY_ACTION_SCHEMA
|
||||
)
|
||||
async def display_off_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.display_on", AirConDisplayOnAction, DISPLAY_ACTION_SCHEMA
|
||||
)
|
||||
async def display_on_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
|
||||
VLOUVER_ACTION_SCHEMA = maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(AirCon),
|
||||
}
|
||||
)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.vlouver_stop", AirConVLouverStopAction, VLOUVER_ACTION_SCHEMA
|
||||
)
|
||||
async def vlouver_stop_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.vlouver_swing", AirConVLouverSwingAction, VLOUVER_ACTION_SCHEMA
|
||||
)
|
||||
async def vlouver_swing_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.vlouver_top", AirConVLouverTopAction, VLOUVER_ACTION_SCHEMA
|
||||
)
|
||||
async def vlouver_top_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.vlouver_middle_above", AirConVLouverMiddleAboveAction, VLOUVER_ACTION_SCHEMA
|
||||
)
|
||||
async def vlouver_middle_above_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.vlouver_middle", AirConVLouverMiddleAction, VLOUVER_ACTION_SCHEMA
|
||||
)
|
||||
async def vlouver_middle_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.vlouver_middle_below", AirConVLouverMiddleBelowAction, VLOUVER_ACTION_SCHEMA
|
||||
)
|
||||
async def vlouver_middle_below_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.vlouver_bottom", AirConVLouverBottomAction, VLOUVER_ACTION_SCHEMA
|
||||
)
|
||||
async def vlouver_bottom_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
|
||||
VLOUVER_SET_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(AirCon),
|
||||
cv.Required(CONF_POSITION): cv.templatable(cv.int_range(0, 6)),
|
||||
}
|
||||
)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.vlouver_set", AirConVLouverSetAction, VLOUVER_SET_ACTION_SCHEMA
|
||||
)
|
||||
async def vlouver_set_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
template_ = await cg.templatable(config[CONF_POSITION], args, int)
|
||||
cg.add(var.set_value(template_))
|
||||
return var
|
||||
|
||||
|
||||
|
||||
POWER_LIMITATION_OFF_ACTION_SCHEMA = maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(AirCon),
|
||||
}
|
||||
)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.power_limit_off", AirConPowerLimitationOffAction, POWER_LIMITATION_OFF_ACTION_SCHEMA
|
||||
)
|
||||
async def power_limit_off_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
return cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
|
||||
POWER_LIMITATION_ON_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(AirCon),
|
||||
cv.Optional(CONF_LIMIT, default=AC_POWER_LIMIT_MIN): validate_power_limit_range,
|
||||
}
|
||||
)
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.power_limit_on", AirConPowerLimitationOnAction, POWER_LIMITATION_ON_ACTION_SCHEMA
|
||||
)
|
||||
async def power_limit_on_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
template_ = await cg.templatable(config[CONF_LIMIT], args, int)
|
||||
cg.add(var.set_value(template_))
|
||||
return var
|
||||
|
||||
|
||||
|
||||
# *********************************************************************************************************
|
||||
# ВАЖНО! Только для инженеров!
|
||||
# Вызывайте метод aux_ac.send_packet только если понимаете, что делаете! Он не проверяет данные, а передаёт
|
||||
# кондиционеру всё как есть. Какой эффект получится от передачи кондиционеру рандомных байт, никто не знает.
|
||||
# Вы действуете на свой страх и риск.
|
||||
# *********************************************************************************************************
|
||||
SEND_TEST_PACKET_ACTION_SCHEMA = maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(AirCon),
|
||||
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"aux_ac.send_packet", AirConSendTestPacketAction, SEND_TEST_PACKET_ACTION_SCHEMA
|
||||
)
|
||||
async def send_packet_to_code(config, action_id, template_arg, args):
|
||||
paren = await cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
data = config[CONF_DATA]
|
||||
if isinstance(data, bytes):
|
||||
data = list(data)
|
||||
|
||||
if cg.is_template(data):
|
||||
templ = await cg.templatable(data, args, cg.std_vector.template(cg.uint8))
|
||||
cg.add(var.set_data_template(templ))
|
||||
else:
|
||||
cg.add(var.set_data_static(data))
|
||||
|
||||
return var
|
||||
|
||||
@@ -2,26 +2,45 @@
|
||||
`Aux_ac` has been tested and works successfully with the air conditioners from the list below.<br/>
|
||||
Кондиционеры из списка ниже протестированы и точно совместимы с `aux_ac`.
|
||||
|
||||
+ ANDE (models: AND-12/FA+, AND-AMWM-H12(JA) / AND-AM2-H18/4DR3)
|
||||
+ Argo (models: Greenstyle 9000, Greenstyle 12000, Greenstyle 18000)
|
||||
+ AUX (models: ALMD-H48/5DR2 / AL-H48/5DR2(U), AMWM-H07/4R1 multisplit, ASW-H07A4/DE-R1DI, ASW-H07A4/FP-R1DI, ASW-H09A4/FP-R1DI, ASW-H09A4/LK-700R1, ASW-H09A4/LK-700R1DI, ASW-H12B4/JD-R2DI, ASW-H12A4/FAR1, ASW-H09B4/LK-700R1, ASW-H12U3/JIR1DI-US, AUX-18QC/I / AUX-18QC/O, KFR-26GW/BpHRB+3, KFR-26GW/BpQYA2+2R3, KFR-26GW/BpQYD2+2R3, KFR-26GW/BpR3QYA1+1, KFR-26GW/BpR3QYD1+1, KFR-26GW/BpR3QYQ1+1, KFR-26GW/BpR3QYQ2+2, KFR-35GW/BpQYA1+1R3, KFR-35GW/BpQYA2+2R3, KFR-35GW/BpQYD1+1R3, KFR-35GW/BpQYD2+2R3, KFR-35GW/BpR3QYQ1+1, KFR-35GW/BpR3QYQ2+2 (see [issue #71](https://github.com/GrKoR/esphome_aux_ac_component/issues/71) for detais of `Aegean Sea`[爱琴海] AUX family AC connection)
|
||||
+ Ballu (models: BLC_CF/in-60HN1, BSUI-09HN8, BSUI-12HN8)
|
||||
+ Centek (models: CT-65A12, CT-65F09, CT-65F12, CT-65Q09, CT-65Q12, CT-65U13, CT-65Z10, CT-65Z18, CT-65V24)
|
||||
+ Arielli (models: ASW-H09B4/FGR3DI-EU)
|
||||
+ AUX (models: ALLD-H18/4R1C / AL-H18/4R1C(U), ALMD-H48/5DR2 / AL-H48/5DR2(U), ALMD-H24/4DR2A / AL-H24/4DR2A(U), AMWM-H07/4R1 multisplit, AMWM-H07/4R2(J) multisplit, AMWM-H12/4R2(J) multisplit, AMWM-H12/4R3 multisplit, ASM-H12LL, ASM-H24LD, ASW-12A3INV/SS, ASW-H07A4/DE-R1DI, ASW-H07A4/FP-R1DI, ASW-H07A4/JD-R1, ASW-H09A4/FP-R1DI, ASW-H09A4/LK-700R1, ASW-H09A4/LK-700R1DI, ASW-H09B4/LK-700R1, ASW-H09B7A4, ASW-H12A4/FAR1, ASW-H12A4/HA-R2DI, ASW-H12A4/JD-R2DI, ASW-H12B4/JD-R2DI, ASW-H12C5C4/JER3DI-B8-2, ASW-H12C5C4/JOR3DI-B8, ASW-H12U3/JIR1DI-US, ASW-H18A4/QH-R1DI / AS-H18A4/QH-R1DI, ASW-H18E3A4, AUX-07JO/I / AUX-M3-21LCLH multisplit, AUX-09CAA/I / ASW-H09A4/CAR3DI-C3, AUX-12JO/I / AUX-M3-21LCLH multisplit, AUX-12F3H, AUX-18QC/I / AUX-18QC/O, AWM-09G1V4-X, HA-18000BTU, KFR-26GW/BpHRB+3, KFR-26GW/BpQYA2+2R3, KFR-26GW/BpQYD2+2R3, KFR-26GW/BpR3QYA1+1, KFR-26GW/BpR3QYD1+1, KFR-26GW/BpR3QYQ1+1, KFR-26GW/BpR3QYQ2+2, KFR-35GW/BpQYA1+1R3, KFR-35GW/BpQYA2+2R3, KFR-35GW/BpQYD1+1R3, KFR-35GW/BpQYD2+2R3, KFR-35GW/BpR3QYQ1+1, KFR-35GW/BpR3QYQ2+2 (see [issue #71](https://github.com/GrKoR/esphome_aux_ac_component/issues/71) for detais of `Aegean Sea`[爱琴海] AUX family AC connection)
|
||||
+ Ballu (models: BLC_CF/in-60HN1 / BLC_O/out-60HN1, Orbis BPAC-08 OR/N6, BSUI/in-09HN8 / BSUI/out-09HN8, BSUI/in-12HN8 / BSUI/out-12HN8, BSUI/in-18HN8 / BSUI/out-18HN8, BSW/in-09HN1 / BSW/out-09HN1, BSW/in-12HN1 / BSW/out-12HN1, BSW/in-18HN1 / BSW/out-18HN1)
|
||||
+ Baymak (models: Elegant Plus 9, Elegant Plus 12)
|
||||
+ Centek (models: CT-65A09, CT-65A12, CT-65EDC07, CT-65F09, CT-65F12, CT-65FDC07, CT-65FDC09, CT-65J09, CT-65J12, CT-65J24, CT-65K07, CT-65Q09, CT-65Q12, CT-65RDC07, CT-65RDC09, CT-65RDC12, CT-65SDC07, CT-65SDC09, CT-65SDC18, CT-65U13, CT-65U18, CT-65V12, CT-65V24, CT-65X12, CT-65Z10, CT-65Z18)
|
||||
+ Costway (models: FP10318US-22WH, FP10524US-22WH)
|
||||
+ Dimstal (model: SMND-QC-12-J-Smart ECO)
|
||||
+ Elgin (models: HWFI09B2IA/ HWFE09B2NA)
|
||||
+ Energolux (models: SAS07L2-A, SAS07L4-A, SAS07M2-AI, SAS09B3-A, SAS09L4-A, SAS09Z4-AI, SAS12BN1-AI, SAS12CH1-AI, SAS12Z3-AI)
|
||||
+ Electrolux (models: EACS/I-07HSK/N3, EACS/I-09HIX-BLACK/N8)
|
||||
+ Elgin (models: HIFI09C2WA / HIFE09C2CA, HJFI12C2WB, HWFI09B2IA / HWFE09B2NA, HWFI30B2IA / HWFE30B2NA)
|
||||
+ Energolux (models: SAS07L2-A, SAS07L4-A, SAS07M2-AI, SAS09B3-A, SAS09L4-A, SAS09Z4-AI, SAS12BN1-AI, SAS09Z4-AI, SAS18Z4-AI)
|
||||
+ Fujico (models: ACF-I07AHRDN1)
|
||||
+ Hyundai (models: H-AR16-07H, H-AR21-07H, H-AR21-09H)
|
||||
+ iClima (models: ICI-09A/IUI-09A)
|
||||
+ Idea (models: ISR-12HR-SA7-DN1 ION)
|
||||
+ IGC (models: RAK-07NH multysplit, RAS-07AX/RAC-07AX)
|
||||
+ IGC (models: RAK-07NH multysplit, RAS-07AX/RAC-07AX, RAS-V09N2X/RAC-V09N2X, RAS-V12NQR/RAC-V12NQR)
|
||||
+ IKON (models: ASW-H12C5C4/HCR3DI-B8)
|
||||
+ Ishimatsu (models: AVK-07I, AVK-09I)
|
||||
+ Loriot (models: LAC-09AS)
|
||||
+ Mirage (models: EWC121E - CWC121E)
|
||||
+ Osaka (models: STVP-12HH3)
|
||||
+ RCool (models: GRA12B0-KSZKLM641)
|
||||
+ Roda (models: RS-AL09F)
|
||||
+ Rinnai (models: RINV25RC)
|
||||
+ Roda (models: RS-AL09F, RS-AL24F)
|
||||
+ Rovex (models: RS-07ALS1, RS-09ALS1, RS-12ALS1)
|
||||
+ Royal Clima (models: CO-D 18HNI/CO-E 18HNI, RCI-SA30HN)
|
||||
+ Royal Clima (models: CO-D 18HNI/CO-E 18HNI, CO-D 24HNI/CO-E 24HNI, RC-VNR29HN, RC-RNC28HN, RCI-SA30HN)
|
||||
+ RVX (models: RS-12ALS)
|
||||
+ Samurai (models: SMA-07HRN1 ION, SMA-09HRN1 ION)
|
||||
+ Subtropic (models: SUB-07HN1, SUB-12HN1)
|
||||
+ Scarlett (models: RRI-09-MPI)
|
||||
+ SEVRA (models: SEV-09JO)
|
||||
+ Subtropic (models: SUB/in-07HN1 / SUB/out-07HN1, SUB/in-09HN1 / SUB/out-09HN1, SUB/in-12HN1 / SUB/out-12HN1)
|
||||
+ Tesla (models: TA35FFML-12410M)
|
||||
+ Tornado (models: ISKA-INV-12 X WIFI EU)
|
||||
+ TOYOTOMI (models: SONZAI THN/THG-A35SZ)
|
||||
+ VOX (models: IVA5-12JR1, IJO09-SC4D)
|
||||
+ Vertex (models: Falcon-18A)
|
||||
+ VORTEX (models: VAI-A 1219F JMRV)
|
||||
+ VOX (models: IJO09-SC4D, IVA5-12JR1)
|
||||
+ Xigma (models: XG-SJ56RHA-IDU)
|
||||
+ Zephir (models: ZEL 12000BTU)
|
||||
+ Бирюса (models: B-07DPR/B-07DPQ, B-09FIR/B-09FIQ)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ It use [JST SM](https://www.jst-mfg.com/product/pdf/eng/eSM.pdf) connector for 5
|
||||
### Pinout ###
|
||||
1. Yellow: +12V..+14V DC. Measured +14.70V max and +13.70V min. Service manual declares up to +16V.
|
||||
2. Black: ground.
|
||||
3. White: +5V DC (max: +5.63V; min: +4.43V) I have no idea what this is for. It goes directly to the air conditioner microcontroller through resistor 1kOhm and it does not affect the operation of the module.
|
||||
3. White: +5V DC (max: +5.63V; min: +4.43V) Enable signal for the 3V3 buck regulator on the OEM module. It goes directly to the air conditioner microcontroller through resistor 1kOhm. It's non used with the EPS module.
|
||||
4. Blue: TX of air conditioner. High is +5V.
|
||||
5. Red: RX of air conditioner. High is +5V.
|
||||
|
||||
@@ -26,17 +26,21 @@ You should feed your ESP **from +12V..+14V line only**! It is prohibited to use
|
||||
## 4-wire connection (pseudo-USB)
|
||||
For 4-wire connection it is used USB-like connector. It is only physical USB but its pinout is UART with +12V..+14V power line.
|
||||
|
||||
**ATTENTION!** It is incompatible with normal USB devices! Ordinary USB device like USB flash drive will be damaged if it will be plugged in air conditioner USB connector.
|
||||
**ATTENTION!** It is incompatible with normal USB devices! Ordinary USB device like USB flash drive will be damaged if it will be plugged in air conditioner USB connector.
|
||||
|
||||
**ATTENTION #2!** Manufacturer was changed power circuit and connector pinout in 2022-2023: power rail has +8.5V DC and TX/RX pins are swapped.
|
||||
|
||||
### Pinout ###
|
||||
<img src="https://github.com/GrKoR/esphome_aux_ac_component/blob/master/images/USB-pinout.png?raw=true" width="400">
|
||||
|
||||
1. +12V..+14V DC. Service manual declares up to +16V.
|
||||
2. RX of air conditioner. High level is +5V.
|
||||
3. TX of air conditioner. High level is +5V.
|
||||
1. +12V..+14V DC before 2022-2023, possible +8.5V DC after 2022-2023. Service manual declares up to +16V.
|
||||
2. RX of the air conditioner for models manufactured before about Jul.2022, TX of the air conditioner for later modifications. High level is +5V.
|
||||
3. TX of the air conditioner for models manufactured before about Jul.2022, RX of the air conditioner for later modifications. High level is +5V.
|
||||
4. GND - ground.
|
||||
|
||||
Big thanks to [@diabl0](https://github.com/diabl0) for this pinout in [issue #70](https://github.com/GrKoR/esphome_aux_ac_component/issues/70).
|
||||
Big thanks to [@diabl0](https://github.com/diabl0) for this pinout in [issue #70](https://github.com/GrKoR/esphome_aux_ac_component/issues/70).
|
||||
|
||||
If you are not sure, on which USB-pins do you have RX and TX lines, than don't afraid to connect it randomly. Neither air conditioner nor ESP will be damaged in this situation, just `aux_ac` can't receive data from the air conditioner. Swap TX and RX and your device will probably work.
|
||||
|
||||
## Power supply
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
### Распиновка ###
|
||||
1. Желтый: +12В..+14В постоянного тока. Осциллограф показал от +13.70В до +14.70В. В сервисном мануале встречалось, что питание возможно до +16В.
|
||||
2. Черный: земля.
|
||||
3. Белый: +5В постоянного тока (измерено от +4.43В до +5.63В). Для чего нужна эта линия - не понятно. У меня нет версий. Эксперименты с родным Wi-Fi модулем сплит-системы показали, что эта линия в работе Wi-Fi не участвует. Линия идет напрямую на ножку контроллера в сплите через резистор 1 кОм.
|
||||
3. Белый: +5В постоянного тока (измерено от +4.43В до +5.63В). По информации от пользователей, это сигнальная линия, включающая по DC-DC конвертор на wifi-модуле по команде с кондиционера. Линия идет напрямую на ножку контроллера в сплите через резистор 1 кОм. Эксперименты с родным Wi-Fi модулем сплит-системы показали, что эта линия в работе Wi-Fi не участвует и имеет всегда высокий уровень. В работе компонента и самодельного wifi-модуля эта линия не используется.
|
||||
4. Синий: TX кондиционера. Высокий уровень +5В.
|
||||
5. Red: RX кондиционера. Высокий уровень +5В.
|
||||
|
||||
@@ -26,16 +26,20 @@
|
||||
|
||||
**ВНИМАНИЕ!** С устройствами c настоящим USB этот интерфейс не совместим! Если вставить в разъём обычную USB-флешку или другое устройство, скорее всего оно просто сгорит.
|
||||
|
||||
**ВНИМАНИЕ №2!** В 2022-2023 производитель поменял распиновку и схему питания. Теперь кондиционеры на USB-коннектор выдают +8.5В. А пины RX и TX поменялись местами.
|
||||
|
||||
### Распиновка ###
|
||||
<img src="https://github.com/GrKoR/esphome_aux_ac_component/blob/master/images/USB-pinout.png?raw=true" width="400">
|
||||
|
||||
1. +12В..+14В постоянного тока. Осциллограф показал от +13.70В до +14.70В. В сервисном мануале встречалось, что питание возможно до +16В.
|
||||
2. RX кондиционера. Высокий уровень +5В.
|
||||
3. TX кондиционера. Высокий уровень +5В.
|
||||
1. +12В..+14В постоянного тока для кондиционеров до 2023 года, возможно +8.5В для кондиционеров 2022-2023 годов и моложе. В сервисном мануале на кондиционеры до 2022 года встречалось, что питание возможно до +16В.
|
||||
2. RX кондиционера для моделей, произведенных примерно до 07.2022, TX кондиционера для более поздних модификаций. Высокий уровень +5В.
|
||||
3. TX кондиционера для моделей, произведенных примерно до 07.2022, RX кондиционера для более поздних модификаций. Высокий уровень +5В.
|
||||
4. земля.
|
||||
|
||||
Большое спасибо [@diabl0](https://github.com/diabl0) за эту распиновку ([issue #70](https://github.com/GrKoR/esphome_aux_ac_component/issues/70)).
|
||||
|
||||
Если вы не знаете, на каких именно пинах USB-разъема в вашем случае расположены TX и RX, то не бойтесь подключить наугад. Ни кондиционер, ни ESP не пострадают, если вы перепутаете линии TX и RX. Просто компонент не увидит кондиционер, о чем будут сообщения в логе. В таком случае просто попробуйте поменять TX и RX местами.
|
||||
|
||||
## Питание
|
||||
|
||||
Для питания ESP8266 можно использовать любой подходящий DC-DC преобразователь. Я использовал такой:
|
||||
|
||||
10
examples/advanced/.gitignore
vendored
10
examples/advanced/.gitignore
vendored
@@ -1,10 +0,0 @@
|
||||
# Gitignore settings for ESPHome
|
||||
# This is an example and may include too much for your use-case.
|
||||
# You can modify this file to suit your needs.
|
||||
/.esphome/
|
||||
**/.pioenvs/
|
||||
**/.piolibdeps/
|
||||
**/lib/
|
||||
**/src/
|
||||
**/platformio.ini
|
||||
/secrets.yaml
|
||||
@@ -1,217 +0,0 @@
|
||||
# DON'T COMPILE THIS FILE
|
||||
# This file contains common settings for all air conditioners of your house
|
||||
external_components:
|
||||
- source: github://GrKoR/esphome_aux_ac_component
|
||||
components: [ aux_ac ]
|
||||
refresh: 0s
|
||||
|
||||
esphome:
|
||||
name: $devicename
|
||||
platform: ESP8266
|
||||
board: esp12e
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_pass
|
||||
manual_ip:
|
||||
static_ip: ${wifi_ip}
|
||||
gateway: !secret wifi_gateway
|
||||
subnet: !secret wifi_subnet
|
||||
ap:
|
||||
ssid: ${upper_devicename} Hotspot
|
||||
password: !secret wifi_ap_pass
|
||||
use_address: ${wifi_ota_ip}
|
||||
|
||||
captive_portal:
|
||||
debug:
|
||||
|
||||
logger:
|
||||
level: DEBUG
|
||||
baud_rate: 0
|
||||
# set hardware_uart to UART1 and comment out baud_rate above in case of boot crashes
|
||||
# it is suitable if you need hardware loggin
|
||||
# hardware_uart: UART1
|
||||
|
||||
api:
|
||||
password: !secret api_pass
|
||||
|
||||
ota:
|
||||
password: !secret ota_pass
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
auth:
|
||||
username: !secret web_server_user
|
||||
password: !secret web_server_password
|
||||
|
||||
# UART0 configuration for AUX air conditioner communication
|
||||
uart:
|
||||
id: ac_uart_bus
|
||||
# ATTENTION! Use GPIO4 (D2) and GPIO5 (D1) as the TX and RX for NodeMCU-like boards!
|
||||
tx_pin: GPIO1
|
||||
rx_pin: GPIO3
|
||||
baud_rate: 4800
|
||||
data_bits: 8
|
||||
parity: EVEN
|
||||
stop_bits: 1
|
||||
|
||||
|
||||
|
||||
climate:
|
||||
- platform: aux_ac
|
||||
name: ${upper_devicename}
|
||||
id: aux_id
|
||||
uart_id: ac_uart_bus
|
||||
period: 7s
|
||||
show_action: true
|
||||
display_inverted: true
|
||||
optimistic: true
|
||||
indoor_temperature:
|
||||
name: ${upper_devicename} Indoor Temperature
|
||||
id: ${devicename}_indoor_temp
|
||||
internal: false
|
||||
display_state:
|
||||
name: ${upper_devicename} Display State
|
||||
id: ${devicename}_display_state
|
||||
internal: false
|
||||
outdoor_temperature:
|
||||
name: ${upper_devicename} Outdoor Temperature
|
||||
id: ${devicename}_outdoor_temp
|
||||
internal: false
|
||||
outbound_temperature:
|
||||
name: ${upper_devicename} Coolant Outbound Temperature
|
||||
id: ${devicename}_outbound_temp
|
||||
internal: false
|
||||
inbound_temperature:
|
||||
name: ${upper_devicename} Coolant Inbound Temperature
|
||||
id: ${devicename}_inbound_temp
|
||||
internal: false
|
||||
compressor_temperature:
|
||||
name: ${upper_devicename} Compressor Temperature
|
||||
id: ${devicename}_strange_temp
|
||||
internal: false
|
||||
defrost_state:
|
||||
name: ${upper_devicename} Defrost State
|
||||
id: ${devicename}_defrost_state
|
||||
internal: false
|
||||
inverter_power:
|
||||
name: ${upper_devicename} Invertor Power
|
||||
id: ${devicename}_inverter_power
|
||||
internal: false
|
||||
preset_reporter:
|
||||
name: ${upper_devicename} Preset Reporter
|
||||
id: ${devicename}_preset_reporter
|
||||
internal: false
|
||||
vlouver_state:
|
||||
name: ${upper_devicename} VLouvers State
|
||||
id: ${devicename}_vlouver_state
|
||||
internal: false
|
||||
visual:
|
||||
min_temperature: 16
|
||||
max_temperature: 32
|
||||
temperature_step: 0.5
|
||||
supported_modes:
|
||||
- HEAT_COOL
|
||||
- COOL
|
||||
- HEAT
|
||||
- DRY
|
||||
- FAN_ONLY
|
||||
custom_fan_modes:
|
||||
- MUTE
|
||||
- TURBO
|
||||
supported_presets:
|
||||
- SLEEP
|
||||
custom_presets:
|
||||
- CLEAN
|
||||
- HEALTH
|
||||
- ANTIFUNGUS
|
||||
supported_swing_modes:
|
||||
- VERTICAL
|
||||
- HORIZONTAL
|
||||
- BOTH
|
||||
|
||||
|
||||
sensor:
|
||||
# just wifi signal strength for debug purpose only
|
||||
- platform: wifi_signal
|
||||
name: ${upper_devicename} WiFi Signal
|
||||
update_interval: 30s
|
||||
unit_of_measurement: "dBa"
|
||||
accuracy_decimals: 0
|
||||
|
||||
|
||||
switch:
|
||||
- platform: template
|
||||
name: ${upper_devicename} Display
|
||||
lambda: |-
|
||||
if (id(${devicename}_display_state).state) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
turn_on_action:
|
||||
- aux_ac.display_on: aux_id
|
||||
turn_off_action:
|
||||
- aux_ac.display_off: aux_id
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Stop
|
||||
icon: "mdi:circle-small"
|
||||
on_press:
|
||||
- aux_ac.vlouver_stop: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Swing
|
||||
icon: "mdi:pan-vertical"
|
||||
on_press:
|
||||
- aux_ac.vlouver_swing: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Top
|
||||
icon: "mdi:pan-up"
|
||||
on_press:
|
||||
- aux_ac.vlouver_top: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Middle Above
|
||||
icon: "mdi:pan-top-left"
|
||||
on_press:
|
||||
- aux_ac.vlouver_middle_above: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Middle
|
||||
icon: "mdi:pan-left"
|
||||
on_press:
|
||||
- aux_ac.vlouver_middle: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Middle Below
|
||||
icon: "mdi:pan-bottom-left"
|
||||
on_press:
|
||||
- aux_ac.vlouver_middle_below: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Bottom
|
||||
icon: "mdi:pan-down"
|
||||
on_press:
|
||||
- aux_ac.vlouver_bottom: aux_id
|
||||
|
||||
|
||||
number:
|
||||
- platform: template
|
||||
name: ${upper_devicename} Vertical Louvers
|
||||
id: ${devicename}_vlouver
|
||||
icon: "mdi:circle-small"
|
||||
mode: "slider"
|
||||
min_value: 0
|
||||
max_value: 6
|
||||
step: 1
|
||||
update_interval: 2s
|
||||
lambda: |-
|
||||
return id(${devicename}_vlouver_state).state;
|
||||
set_action:
|
||||
then:
|
||||
- aux_ac.vlouver_set:
|
||||
id: aux_id
|
||||
position: !lambda "return x;"
|
||||
@@ -1,17 +0,0 @@
|
||||
# compile this file with ESPHome
|
||||
# This file contains unique settings for specific air conditioner
|
||||
|
||||
#===================================================================================
|
||||
# KITCHEN AIR CONDITIONER
|
||||
#===================================================================================
|
||||
|
||||
substitutions:
|
||||
devicename: kitchen_ac
|
||||
upper_devicename: Kitchen AC
|
||||
|
||||
# use different wifi_ip and wifi_ota_ip in case of esp ip-address change
|
||||
# if ip haven't changed wifi_ip and wifi_ota_ip should be the same
|
||||
wifi_ip: !secret wifi_ip_kitchen
|
||||
wifi_ota_ip: !secret wifi_ota_ip_kitchen
|
||||
|
||||
<<: !include ac_common.yaml
|
||||
@@ -1,17 +0,0 @@
|
||||
# compile this file with ESPHome
|
||||
# This file contains unique settings for specific air conditioner
|
||||
|
||||
#===================================================================================
|
||||
# LIVINGROOM AIR CONDITIONER
|
||||
#===================================================================================
|
||||
|
||||
substitutions:
|
||||
devicename: livingroom_ac
|
||||
upper_devicename: Livingroom AC
|
||||
|
||||
# use different wifi_ip and wifi_ota_ip in case of esp ip-address change
|
||||
# if ip haven't changed wifi_ip and wifi_ota_ip should be the same
|
||||
wifi_ip: !secret wifi_ip_livingroom
|
||||
wifi_ota_ip: !secret wifi_ota_ip_livingroom
|
||||
|
||||
<<: !include ac_common.yaml
|
||||
10
examples/simple/.gitignore
vendored
10
examples/simple/.gitignore
vendored
@@ -1,10 +0,0 @@
|
||||
# Gitignore settings for ESPHome
|
||||
# This is an example and may include too much for your use-case.
|
||||
# You can modify this file to suit your needs.
|
||||
/.esphome/
|
||||
**/.pioenvs/
|
||||
**/.piolibdeps/
|
||||
**/lib/
|
||||
**/src/
|
||||
**/platformio.ini
|
||||
/secrets.yaml
|
||||
@@ -1,47 +0,0 @@
|
||||
external_components:
|
||||
- source: github://GrKoR/esphome_aux_ac_component
|
||||
components: [ aux_ac ]
|
||||
refresh: 0s
|
||||
|
||||
esphome:
|
||||
name: aux_air_conditioner
|
||||
platform: ESP8266
|
||||
board: esp12e
|
||||
|
||||
# don't forget to set your's wifi settings!
|
||||
wifi:
|
||||
ssid: "WIFI SSID"
|
||||
password: "seCRETpassWORD"
|
||||
manual_ip:
|
||||
static_ip: 192.168.0.2
|
||||
gateway: 192.168.0.1
|
||||
subnet: 255.255.255.0
|
||||
ap:
|
||||
ssid: AUX Hotspot
|
||||
password: "seCREThotSPOTpassWORD"
|
||||
|
||||
captive_portal:
|
||||
debug:
|
||||
|
||||
logger:
|
||||
level: DEBUG
|
||||
baud_rate: 0
|
||||
|
||||
api:
|
||||
|
||||
ota:
|
||||
|
||||
# UART0 configuration for AUX air conditioner communication
|
||||
uart:
|
||||
id: ac_uart_bus
|
||||
# ATTENTION! Use GPIO4 (D2) and GPIO5 (D1) as the TX and RX for NodeMCU-like boards!
|
||||
tx_pin: GPIO1
|
||||
rx_pin: GPIO3
|
||||
baud_rate: 4800
|
||||
data_bits: 8
|
||||
parity: EVEN
|
||||
stop_bits: 1
|
||||
|
||||
climate:
|
||||
- platform: aux_ac
|
||||
name: "AC Name"
|
||||
10
tests/.gitignore
vendored
10
tests/.gitignore
vendored
@@ -1,10 +0,0 @@
|
||||
# Gitignore settings for ESPHome
|
||||
# This is an example and may include too much for your use-case.
|
||||
# You can modify this file to suit your needs.
|
||||
/.esphome/
|
||||
**/.pioenvs/
|
||||
**/.piolibdeps/
|
||||
**/lib/
|
||||
**/src/
|
||||
**/platformio.ini
|
||||
/secrets.yaml
|
||||
@@ -1,191 +0,0 @@
|
||||
import time
|
||||
import aioesphomeapi
|
||||
import asyncio
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
from aioesphomeapi.api_pb2 import (LOG_LEVEL_NONE,
|
||||
LOG_LEVEL_ERROR,
|
||||
LOG_LEVEL_WARN,
|
||||
LOG_LEVEL_INFO,
|
||||
LOG_LEVEL_DEBUG,
|
||||
LOG_LEVEL_VERBOSE,
|
||||
LOG_LEVEL_VERY_VERBOSE)
|
||||
|
||||
def createParser ():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='''This script is used for collecting logs from ac_aux ESPHome component.
|
||||
For more info, see https://github.com/GrKoR/ac_python_logger''',
|
||||
add_help = False)
|
||||
parent_group = parser.add_argument_group (title='Params')
|
||||
parent_group.add_argument ('--help', '-h', action='help', help='show this help message and exit')
|
||||
parent_group.add_argument ('-i', '--ip', nargs=1, required=True, help='IP address of the esphome device')
|
||||
parent_group.add_argument ('-p', '--pwd', nargs=1, required=True, help='native API password for the esphome device')
|
||||
return parser
|
||||
|
||||
async def main():
|
||||
"""Connect to an ESPHome device and wait for state changes."""
|
||||
api = aioesphomeapi.APIClient(namespace.ip[0], 6053, namespace.pwd[0])
|
||||
|
||||
try:
|
||||
await api.connect(login=True)
|
||||
except aioesphomeapi.InvalidAuthAPIError as e:
|
||||
return print(e)
|
||||
|
||||
print(api.api_version)
|
||||
|
||||
async def display_off():
|
||||
await api.execute_service(
|
||||
service,
|
||||
data={
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x01, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00],
|
||||
}
|
||||
)
|
||||
|
||||
async def display_on():
|
||||
await api.execute_service(
|
||||
service,
|
||||
data={
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x01, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
|
||||
}
|
||||
)
|
||||
|
||||
async def ac_enable():
|
||||
await api.execute_service(
|
||||
service,
|
||||
data={
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x00, 0x87, 0xE0, 0x2F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
|
||||
}
|
||||
)
|
||||
|
||||
async def ac_disable():
|
||||
await api.execute_service(
|
||||
service,
|
||||
data={
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x00, 0x87, 0xE0, 0x2F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
||||
}
|
||||
)
|
||||
|
||||
async def ac_get11_01():
|
||||
await api.execute_service(
|
||||
service,
|
||||
data={
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x02, 0x00, 0x11, 0x01],
|
||||
}
|
||||
)
|
||||
|
||||
async def ac_get11_00():
|
||||
await api.execute_service(
|
||||
service,
|
||||
data={
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x02, 0x00, 0x11, 0x00],
|
||||
}
|
||||
)
|
||||
|
||||
async def ac_set_vlouver(lvr):
|
||||
await api.execute_service(
|
||||
service,
|
||||
data={
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, lvr, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
|
||||
}
|
||||
)
|
||||
|
||||
async def ac_set_hlouver(lvr):
|
||||
await api.execute_service(
|
||||
service,
|
||||
data={
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, lvr, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
|
||||
}
|
||||
)
|
||||
|
||||
# key надо искать в выводе list_entities_services
|
||||
service = aioesphomeapi.UserService(
|
||||
name="send_data",
|
||||
key=311254518,
|
||||
args=[
|
||||
aioesphomeapi.UserServiceArg(name="data_buf", type=aioesphomeapi.UserServiceArgType.INT_ARRAY),
|
||||
],
|
||||
)
|
||||
|
||||
time.sleep(7)
|
||||
await ac_get11_00()
|
||||
time.sleep(7)
|
||||
await ac_get11_01()
|
||||
|
||||
#await ac_set_vlouver( 0b10010000 ) # swing on
|
||||
#await ac_set_vlouver( 0b10010111 ) # swing off
|
||||
#await ac_set_vlouver( 0b10010001 ) # 1
|
||||
#await ac_set_vlouver( 0b10010010 ) # 2
|
||||
#await ac_set_vlouver( 0b10010011 ) # 3
|
||||
#await ac_set_vlouver( 0b10010100 ) # 4
|
||||
#await ac_set_vlouver( 0b10010101 ) # 5
|
||||
#await ac_set_vlouver( 0b10010110 ) # не работает, сбрасывает на swing on
|
||||
#time.sleep(5)
|
||||
|
||||
#await ac_set_hlouver( 0b00000000 ) # swing on
|
||||
#await ac_set_hlouver( 0b11100000 ) # swing off
|
||||
#await ac_set_hlouver( 0b00100000 ) # не работает, сбрасывает в swing off
|
||||
#await ac_set_hlouver( 0b01000000 ) # не работает, сбрасывает в swing off
|
||||
#await ac_set_hlouver( 0b01100000 ) # не работает, сбрасывает в swing off
|
||||
#await ac_set_hlouver( 0b10000000 ) # не работает, сбрасывает в swing off
|
||||
#await ac_set_hlouver( 0b10100000 ) # не работает, сбрасывает в swing off
|
||||
#await ac_set_hlouver( 0b11000000 ) # не работает, сбрасывает в swing off
|
||||
#time.sleep(5)
|
||||
|
||||
async def test_byte(bt):
|
||||
await api.execute_service(
|
||||
service,
|
||||
data={
|
||||
#display on
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
#"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
|
||||
#display off
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00],
|
||||
# swing on
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
#"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x90, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
|
||||
# swing off
|
||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
#"data_buf": [0xBB, 0x00, 0x06, 0x80, 0x00, 0x00, 0x0F, 0x00, 0x01, 0x01, 0x97, 0xE0, 0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00],
|
||||
}
|
||||
)
|
||||
'''
|
||||
не проходит команда, если байт 1 или 7 не 0x00
|
||||
не проходит команда, если байт 3 не 0x80
|
||||
|
||||
проходит и не меняется, если меняю байт 4 или 5
|
||||
'''
|
||||
|
||||
#await test_byte(0b10000110)
|
||||
#await test_byte(0b01000110)
|
||||
#await test_byte(0b00100110)
|
||||
#await test_byte(0b00010110)
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
parser = createParser()
|
||||
namespace = parser.parse_args()
|
||||
print("IP: ", namespace.ip[0])
|
||||
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
try:
|
||||
#asyncio.ensure_future(main())
|
||||
#loop.run_forever()
|
||||
loop.run_until_complete(main())
|
||||
except aioesphomeapi.InvalidAuthAPIError as e:
|
||||
print(e)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
loop.close()
|
||||
pass
|
||||
@@ -1,121 +0,0 @@
|
||||
external_components:
|
||||
- source: github://GrKoR/esphome_aux_ac_component@dev
|
||||
components: [ aux_ac ]
|
||||
refresh: 0s
|
||||
|
||||
substitutions:
|
||||
devicename: test_aux_ac_ext_esp32
|
||||
upper_devicename: Test AUX
|
||||
|
||||
esphome:
|
||||
name: $devicename
|
||||
platform: ESP32
|
||||
board: nodemcu-32s
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_pass
|
||||
manual_ip:
|
||||
static_ip: 192.168.0.151 # Для примера
|
||||
gateway: !secret wifi_gateway
|
||||
subnet: !secret wifi_subnet
|
||||
dns1: 8.8.8.8
|
||||
dns2: 1.1.1.1
|
||||
reboot_timeout: 0s
|
||||
ap:
|
||||
ssid: Test AUX Fallback Hotspot
|
||||
password: !secret wifi_ap_pass
|
||||
|
||||
logger:
|
||||
level: DEBUG
|
||||
baud_rate: 0
|
||||
|
||||
api:
|
||||
password: !secret api_pass
|
||||
reboot_timeout: 0s
|
||||
|
||||
ota:
|
||||
password: !secret ota_pass
|
||||
|
||||
uart:
|
||||
id: ac_uart_bus
|
||||
#tx_pin: GPIO1
|
||||
#rx_pin: GPIO3
|
||||
tx_pin: TX
|
||||
rx_pin: RX
|
||||
baud_rate: 4800
|
||||
data_bits: 8
|
||||
parity: EVEN
|
||||
stop_bits: 1
|
||||
|
||||
sensor:
|
||||
- platform: uptime
|
||||
name: Uptime Sensor
|
||||
|
||||
climate:
|
||||
- platform: aux_ac
|
||||
name: $upper_devicename
|
||||
id: aux_id
|
||||
uart_id: ac_uart_bus
|
||||
period: 7s
|
||||
show_action: true
|
||||
display_inverted: true
|
||||
indoor_temperature:
|
||||
name: $upper_devicename Indoor Temperature
|
||||
id: ${devicename}_indoor_temp
|
||||
internal: false
|
||||
display_state:
|
||||
name: $upper_devicename Display State
|
||||
id: ${devicename}_display_state
|
||||
internal: false
|
||||
outdoor_temperature:
|
||||
name: $upper_devicename Outdoor Temperature
|
||||
id: ${devicename}_outdoor_temp
|
||||
internal: false
|
||||
outbound_temperature:
|
||||
name: $upper_devicename Coolant Outbound Temperature
|
||||
id: ${devicename}_outbound_temp
|
||||
internal: false
|
||||
inbound_temperature:
|
||||
name: $upper_devicename Coolant Inbound Temperature
|
||||
id: ${devicename}_inbound_temp
|
||||
internal: false
|
||||
compressor_temperature:
|
||||
name: $upper_devicename Compressor Temperature
|
||||
id: ${devicename}_strange_temp
|
||||
internal: false
|
||||
defrost_state:
|
||||
name: $upper_devicename Defrost State
|
||||
id: ${devicename}_defrost_state
|
||||
internal: false
|
||||
inverter_power:
|
||||
name: $upper_devicename Invertor Power
|
||||
id: ${devicename}_invertor_power
|
||||
internal: false
|
||||
preset_reporter:
|
||||
name: $upper_devicename Preset Reporter
|
||||
id: ${devicename}_preset_reporter
|
||||
internal: false
|
||||
visual:
|
||||
min_temperature: 16
|
||||
max_temperature: 32
|
||||
temperature_step: 0.5
|
||||
supported_modes:
|
||||
- HEAT_COOL
|
||||
- COOL
|
||||
- HEAT
|
||||
- DRY
|
||||
- FAN_ONLY
|
||||
custom_fan_modes:
|
||||
- MUTE
|
||||
- TURBO
|
||||
supported_presets:
|
||||
- SLEEP
|
||||
custom_presets:
|
||||
- CLEAN
|
||||
- HEALTH
|
||||
- ANTIFUNGUS
|
||||
supported_swing_modes:
|
||||
- VERTICAL
|
||||
- HORIZONTAL
|
||||
- BOTH
|
||||
@@ -1,156 +0,0 @@
|
||||
external_components:
|
||||
- source: github://GrKoR/esphome_aux_ac_component@dev
|
||||
components: [ aux_ac ]
|
||||
refresh: 0s
|
||||
|
||||
substitutions:
|
||||
devicename: test_aux_ac_ext_engeneer
|
||||
upper_devicename: Test AUX
|
||||
|
||||
esphome:
|
||||
name: $devicename
|
||||
platform: ESP8266
|
||||
board: esp12e
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_pass
|
||||
manual_ip:
|
||||
static_ip: !secret wifi_ip
|
||||
gateway: !secret wifi_gateway
|
||||
subnet: !secret wifi_subnet
|
||||
dns1: 8.8.8.8
|
||||
dns2: 1.1.1.1
|
||||
reboot_timeout: 0s
|
||||
ap:
|
||||
ssid: Test AUX Fallback Hotspot
|
||||
password: !secret wifi_ap_pass
|
||||
|
||||
logger:
|
||||
level: DEBUG
|
||||
baud_rate: 0
|
||||
|
||||
api:
|
||||
password: !secret api_pass
|
||||
reboot_timeout: 0s
|
||||
services:
|
||||
# этот сервис можно вызвать из Home Assistant или Python. Он отправляет полученные байты в кондиционер
|
||||
- service: send_data
|
||||
variables:
|
||||
data_buf: int[]
|
||||
then:
|
||||
# ВАЖНО! Только для инженеров!
|
||||
# Вызывайте метод aux_ac.send_packet только если понимаете, что делаете! Он не проверяет данные, а передаёт
|
||||
# кондиционеру всё как есть. Какой эффект получится от передачи кондиционеру рандомных байт, никто не знает.
|
||||
# Вы действуете на свой страх и риск.
|
||||
- aux_ac.send_packet:
|
||||
id: aux_id
|
||||
data: !lambda |-
|
||||
std::vector<uint8_t> data{};
|
||||
for (int n : data_buf) {
|
||||
data.push_back( (uint8_t) n );
|
||||
}
|
||||
return data;
|
||||
|
||||
ota:
|
||||
password: !secret ota_pass
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
uart:
|
||||
id: ac_uart_bus
|
||||
tx_pin: GPIO1
|
||||
rx_pin: GPIO3
|
||||
baud_rate: 4800
|
||||
data_bits: 8
|
||||
parity: EVEN
|
||||
stop_bits: 1
|
||||
|
||||
sensor:
|
||||
- platform: uptime
|
||||
name: Uptime Sensor
|
||||
|
||||
climate:
|
||||
- platform: aux_ac
|
||||
name: $upper_devicename
|
||||
id: aux_id
|
||||
uart_id: ac_uart_bus
|
||||
period: 7s
|
||||
show_action: true
|
||||
display_inverted: true
|
||||
optimistic: true
|
||||
indoor_temperature:
|
||||
name: $upper_devicename Indoor Temperature
|
||||
id: ${devicename}_indoor_temp
|
||||
internal: false
|
||||
display_state:
|
||||
name: $upper_devicename Display State
|
||||
id: ${devicename}_display_state
|
||||
internal: false
|
||||
outdoor_temperature:
|
||||
name: $upper_devicename Outdoor Temperature
|
||||
id: ${devicename}_outdoor_temp
|
||||
internal: false
|
||||
outbound_temperature:
|
||||
name: $upper_devicename Coolant Outbound Temperature
|
||||
id: ${devicename}_outbound_temp
|
||||
internal: false
|
||||
inbound_temperature:
|
||||
name: $upper_devicename Coolant Inbound Temperature
|
||||
id: ${devicename}_inbound_temp
|
||||
internal: false
|
||||
compressor_temperature:
|
||||
name: $upper_devicename Compressor Temperature
|
||||
id: ${devicename}_strange_temp
|
||||
internal: false
|
||||
defrost_state:
|
||||
name: $upper_devicename Defrost State
|
||||
id: ${devicename}_defrost_state
|
||||
internal: false
|
||||
inverter_power:
|
||||
name: $upper_devicename Invertor Power
|
||||
id: ${devicename}_invertor_power
|
||||
internal: false
|
||||
preset_reporter:
|
||||
name: $upper_devicename Preset Reporter
|
||||
id: ${devicename}_preset_reporter
|
||||
internal: false
|
||||
visual:
|
||||
min_temperature: 16
|
||||
max_temperature: 32
|
||||
temperature_step: 0.5
|
||||
supported_modes:
|
||||
- HEAT_COOL
|
||||
- COOL
|
||||
- HEAT
|
||||
- DRY
|
||||
- FAN_ONLY
|
||||
custom_fan_modes:
|
||||
- MUTE
|
||||
- TURBO
|
||||
supported_presets:
|
||||
- SLEEP
|
||||
custom_presets:
|
||||
- CLEAN
|
||||
- HEALTH
|
||||
- ANTIFUNGUS
|
||||
supported_swing_modes:
|
||||
- VERTICAL
|
||||
- HORIZONTAL
|
||||
- BOTH
|
||||
|
||||
|
||||
switch:
|
||||
- platform: template
|
||||
name: AC Display
|
||||
lambda: |-
|
||||
if (id(${devicename}_display_state).state) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
turn_on_action:
|
||||
- aux_ac.display_on: aux_id
|
||||
turn_off_action:
|
||||
- aux_ac.display_off: aux_id
|
||||
@@ -1,162 +0,0 @@
|
||||
external_components:
|
||||
- source: github://GrKoR/esphome_aux_ac_component@dev
|
||||
components: [ aux_ac ]
|
||||
refresh: 0s
|
||||
|
||||
substitutions:
|
||||
devicename: test_ext_power_limitations
|
||||
upper_devicename: Test AUX
|
||||
|
||||
esphome:
|
||||
name: $devicename
|
||||
platform: ESP8266
|
||||
board: esp12e
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_pass
|
||||
manual_ip:
|
||||
static_ip: !secret wifi_ip
|
||||
gateway: !secret wifi_gateway
|
||||
subnet: !secret wifi_subnet
|
||||
dns1: 8.8.8.8
|
||||
dns2: 1.1.1.1
|
||||
reboot_timeout: 0s
|
||||
ap:
|
||||
ssid: Test AUX Fallback Hotspot
|
||||
password: !secret wifi_ap_pass
|
||||
|
||||
logger:
|
||||
level: DEBUG
|
||||
baud_rate: 0
|
||||
|
||||
api:
|
||||
password: !secret api_pass
|
||||
reboot_timeout: 0s
|
||||
|
||||
ota:
|
||||
password: !secret ota_pass
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
uart:
|
||||
id: ac_uart_bus
|
||||
tx_pin: GPIO1
|
||||
rx_pin: GPIO3
|
||||
baud_rate: 4800
|
||||
data_bits: 8
|
||||
parity: EVEN
|
||||
stop_bits: 1
|
||||
|
||||
sensor:
|
||||
- platform: uptime
|
||||
name: Uptime Sensor
|
||||
|
||||
climate:
|
||||
- platform: aux_ac
|
||||
name: $upper_devicename
|
||||
id: aux_id
|
||||
uart_id: ac_uart_bus
|
||||
period: 7s
|
||||
show_action: true
|
||||
display_inverted: true
|
||||
timeout: 150
|
||||
indoor_temperature:
|
||||
name: $upper_devicename Indoor Temperature
|
||||
id: ${devicename}_indoor_temp
|
||||
internal: false
|
||||
display_state:
|
||||
name: $upper_devicename Display State
|
||||
id: ${devicename}_display_state
|
||||
internal: false
|
||||
outdoor_temperature:
|
||||
name: $upper_devicename Outdoor Temperature
|
||||
id: ${devicename}_outdoor_temp
|
||||
internal: false
|
||||
outbound_temperature:
|
||||
name: $upper_devicename Coolant Outbound Temperature
|
||||
id: ${devicename}_outbound_temp
|
||||
internal: false
|
||||
inbound_temperature:
|
||||
name: $upper_devicename Coolant Inbound Temperature
|
||||
id: ${devicename}_inbound_temp
|
||||
internal: false
|
||||
compressor_temperature:
|
||||
name: $upper_devicename Compressor Temperature
|
||||
id: ${devicename}_strange_temp
|
||||
internal: false
|
||||
defrost_state:
|
||||
name: $upper_devicename Defrost State
|
||||
id: ${devicename}_defrost_state
|
||||
internal: false
|
||||
inverter_power:
|
||||
name: $upper_devicename Inverter Power
|
||||
id: ${devicename}_invertor_power
|
||||
internal: false
|
||||
preset_reporter:
|
||||
name: $upper_devicename Preset Reporter
|
||||
id: ${devicename}_preset_reporter
|
||||
internal: false
|
||||
inverter_power_limit_value:
|
||||
name: $upper_devicename Inverter Power Limit Value
|
||||
id: ${devicename}_inverter_power_limit_value
|
||||
internal: false
|
||||
inverter_power_limit_state:
|
||||
name: $upper_devicename Inverter Power Limit State
|
||||
id: ${devicename}_inverter_power_limit_state
|
||||
internal: false
|
||||
visual:
|
||||
min_temperature: 16
|
||||
max_temperature: 32
|
||||
temperature_step: 0.5
|
||||
supported_modes:
|
||||
- HEAT_COOL
|
||||
- COOL
|
||||
- HEAT
|
||||
- DRY
|
||||
- FAN_ONLY
|
||||
custom_fan_modes:
|
||||
- MUTE
|
||||
- TURBO
|
||||
supported_presets:
|
||||
- SLEEP
|
||||
custom_presets:
|
||||
- CLEAN
|
||||
- HEALTH
|
||||
- ANTIFUNGUS
|
||||
supported_swing_modes:
|
||||
- VERTICAL
|
||||
- HORIZONTAL
|
||||
- BOTH
|
||||
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
name: ${upper_devicename} IPower Limit Off
|
||||
icon: "mdi:power-plug-off-outline"
|
||||
on_press:
|
||||
- aux_ac.power_limit_off: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} IPower Limit On Half
|
||||
icon: "mdi:fraction-one-half"
|
||||
on_press:
|
||||
- aux_ac.power_limit_on:
|
||||
id: aux_id
|
||||
limit: 50
|
||||
|
||||
number:
|
||||
- platform: template
|
||||
name: ${upper_devicename} IPower Limit Value
|
||||
id: ${devicename}_ipower_limit_value
|
||||
icon: "mdi:battery-unknown"
|
||||
mode: "slider"
|
||||
min_value: 30
|
||||
max_value: 100
|
||||
step: 1
|
||||
set_action:
|
||||
then:
|
||||
- lambda: !lambda |-
|
||||
id(aux_id).powerLimitationOnSequence( x );
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
external_components:
|
||||
- source:
|
||||
type: local
|
||||
path: ../components
|
||||
|
||||
substitutions:
|
||||
devicename: test_local_airflow_dir
|
||||
upper_devicename: Test AUX
|
||||
|
||||
esphome:
|
||||
name: $devicename
|
||||
platform: ESP8266
|
||||
board: esp12e
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_pass
|
||||
manual_ip:
|
||||
static_ip: !secret wifi_ip
|
||||
gateway: !secret wifi_gateway
|
||||
subnet: !secret wifi_subnet
|
||||
dns1: 8.8.8.8
|
||||
dns2: 1.1.1.1
|
||||
reboot_timeout: 0s
|
||||
ap:
|
||||
ssid: $upper_devicename Fallback Hotspot
|
||||
password: !secret wifi_ap_pass
|
||||
|
||||
logger:
|
||||
level: DEBUG
|
||||
baud_rate: 0
|
||||
|
||||
api:
|
||||
password: !secret api_pass
|
||||
reboot_timeout: 0s
|
||||
|
||||
ota:
|
||||
password: !secret ota_pass
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
uart:
|
||||
id: ac_uart_bus
|
||||
tx_pin: GPIO1
|
||||
rx_pin: GPIO3
|
||||
baud_rate: 4800
|
||||
data_bits: 8
|
||||
parity: EVEN
|
||||
stop_bits: 1
|
||||
|
||||
|
||||
sensor:
|
||||
- platform: uptime
|
||||
name: Uptime Sensor
|
||||
|
||||
|
||||
climate:
|
||||
- platform: aux_ac
|
||||
name: $upper_devicename
|
||||
id: aux_id
|
||||
uart_id: ac_uart_bus
|
||||
period: 7s
|
||||
show_action: true
|
||||
display_inverted: true
|
||||
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Stop
|
||||
icon: "mdi:circle-small"
|
||||
on_press:
|
||||
- aux_ac.vlouver_stop: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Swing
|
||||
icon: "mdi:pan-vertical"
|
||||
on_press:
|
||||
- aux_ac.vlouver_swing: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Top
|
||||
icon: "mdi:pan-up"
|
||||
on_press:
|
||||
- aux_ac.vlouver_top: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Middle Above
|
||||
icon: "mdi:pan-top-left"
|
||||
on_press:
|
||||
- aux_ac.vlouver_middle_above: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Middle
|
||||
icon: "mdi:pan-left"
|
||||
on_press:
|
||||
- aux_ac.vlouver_middle: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Middle Below
|
||||
icon: "mdi:pan-bottom-left"
|
||||
on_press:
|
||||
- aux_ac.vlouver_middle_below: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} VLouver Bottom
|
||||
icon: "mdi:pan-down"
|
||||
on_press:
|
||||
- aux_ac.vlouver_bottom: aux_id
|
||||
|
||||
|
||||
number:
|
||||
- platform: template
|
||||
name: ${upper_devicename} Vertical Louver
|
||||
id: ${devicename}_vlouver
|
||||
icon: "mdi:circle-small"
|
||||
mode: "slider"
|
||||
min_value: 0
|
||||
max_value: 6
|
||||
step: 1
|
||||
set_action:
|
||||
then:
|
||||
- lambda: !lambda |-
|
||||
if (x == 6) x = 7; // делаем так, чтобы выключение отрабатывать корректно
|
||||
id(aux_id).setVLouverSequence( static_cast<esphome::aux_ac::ac_louver_V>(x) );
|
||||
@@ -1,162 +0,0 @@
|
||||
external_components:
|
||||
- source:
|
||||
type: local
|
||||
path: ../components
|
||||
|
||||
substitutions:
|
||||
devicename: test_local_power_limitations
|
||||
upper_devicename: Test AUX
|
||||
|
||||
esphome:
|
||||
name: $devicename
|
||||
platform: ESP8266
|
||||
board: esp12e
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_pass
|
||||
manual_ip:
|
||||
static_ip: !secret wifi_ip
|
||||
gateway: !secret wifi_gateway
|
||||
subnet: !secret wifi_subnet
|
||||
dns1: 8.8.8.8
|
||||
dns2: 1.1.1.1
|
||||
reboot_timeout: 0s
|
||||
ap:
|
||||
ssid: Test AUX Fallback Hotspot
|
||||
password: !secret wifi_ap_pass
|
||||
|
||||
logger:
|
||||
level: DEBUG
|
||||
baud_rate: 0
|
||||
|
||||
api:
|
||||
password: !secret api_pass
|
||||
reboot_timeout: 0s
|
||||
|
||||
ota:
|
||||
password: !secret ota_pass
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
uart:
|
||||
id: ac_uart_bus
|
||||
tx_pin: GPIO1
|
||||
rx_pin: GPIO3
|
||||
baud_rate: 4800
|
||||
data_bits: 8
|
||||
parity: EVEN
|
||||
stop_bits: 1
|
||||
|
||||
sensor:
|
||||
- platform: uptime
|
||||
name: Uptime Sensor
|
||||
|
||||
climate:
|
||||
- platform: aux_ac
|
||||
name: $upper_devicename
|
||||
id: aux_id
|
||||
uart_id: ac_uart_bus
|
||||
period: 7s
|
||||
show_action: true
|
||||
display_inverted: true
|
||||
timeout: 150
|
||||
indoor_temperature:
|
||||
name: $upper_devicename Indoor Temperature
|
||||
id: ${devicename}_indoor_temp
|
||||
internal: false
|
||||
display_state:
|
||||
name: $upper_devicename Display State
|
||||
id: ${devicename}_display_state
|
||||
internal: false
|
||||
outdoor_temperature:
|
||||
name: $upper_devicename Outdoor Temperature
|
||||
id: ${devicename}_outdoor_temp
|
||||
internal: false
|
||||
outbound_temperature:
|
||||
name: $upper_devicename Coolant Outbound Temperature
|
||||
id: ${devicename}_outbound_temp
|
||||
internal: false
|
||||
inbound_temperature:
|
||||
name: $upper_devicename Coolant Inbound Temperature
|
||||
id: ${devicename}_inbound_temp
|
||||
internal: false
|
||||
compressor_temperature:
|
||||
name: $upper_devicename Compressor Temperature
|
||||
id: ${devicename}_strange_temp
|
||||
internal: false
|
||||
defrost_state:
|
||||
name: $upper_devicename Defrost State
|
||||
id: ${devicename}_defrost_state
|
||||
internal: false
|
||||
inverter_power:
|
||||
name: $upper_devicename Inverter Power
|
||||
id: ${devicename}_invertor_power
|
||||
internal: false
|
||||
preset_reporter:
|
||||
name: $upper_devicename Preset Reporter
|
||||
id: ${devicename}_preset_reporter
|
||||
internal: false
|
||||
inverter_power_limit_value:
|
||||
name: $upper_devicename Inverter Power Limit Value
|
||||
id: ${devicename}_inverter_power_limit_value
|
||||
internal: false
|
||||
inverter_power_limit_state:
|
||||
name: $upper_devicename Inverter Power Limit State
|
||||
id: ${devicename}_inverter_power_limit_state
|
||||
internal: false
|
||||
visual:
|
||||
min_temperature: 16
|
||||
max_temperature: 32
|
||||
temperature_step: 0.5
|
||||
supported_modes:
|
||||
- HEAT_COOL
|
||||
- COOL
|
||||
- HEAT
|
||||
- DRY
|
||||
- FAN_ONLY
|
||||
custom_fan_modes:
|
||||
- MUTE
|
||||
- TURBO
|
||||
supported_presets:
|
||||
- SLEEP
|
||||
custom_presets:
|
||||
- CLEAN
|
||||
- HEALTH
|
||||
- ANTIFUNGUS
|
||||
supported_swing_modes:
|
||||
- VERTICAL
|
||||
- HORIZONTAL
|
||||
- BOTH
|
||||
|
||||
|
||||
button:
|
||||
- platform: template
|
||||
name: ${upper_devicename} IPower Limit Off
|
||||
icon: "mdi:power-plug-off-outline"
|
||||
on_press:
|
||||
- aux_ac.power_limit_off: aux_id
|
||||
|
||||
- platform: template
|
||||
name: ${upper_devicename} IPower Limit On Half
|
||||
icon: "mdi:fraction-one-half"
|
||||
on_press:
|
||||
- aux_ac.power_limit_on:
|
||||
id: aux_id
|
||||
limit: 50
|
||||
|
||||
number:
|
||||
- platform: template
|
||||
name: ${upper_devicename} IPower Limit Value
|
||||
id: ${devicename}_ipower_limit_value
|
||||
icon: "mdi:battery-unknown"
|
||||
mode: "slider"
|
||||
min_value: 30
|
||||
max_value: 100
|
||||
step: 1
|
||||
set_action:
|
||||
then:
|
||||
- lambda: !lambda |-
|
||||
id(aux_id).powerLimitationOnSequence( x );
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
external_components:
|
||||
- source:
|
||||
type: local
|
||||
path: ../components
|
||||
|
||||
substitutions:
|
||||
devicename: test_local_airflow_dir
|
||||
upper_devicename: Test AUX
|
||||
|
||||
esphome:
|
||||
name: $devicename
|
||||
platform: ESP8266
|
||||
board: esp12e
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_pass
|
||||
manual_ip:
|
||||
static_ip: !secret wifi_ip
|
||||
gateway: !secret wifi_gateway
|
||||
subnet: !secret wifi_subnet
|
||||
dns1: 8.8.8.8
|
||||
dns2: 1.1.1.1
|
||||
reboot_timeout: 0s
|
||||
ap:
|
||||
ssid: Test AUX Fallback Hotspot
|
||||
password: !secret wifi_ap_pass
|
||||
|
||||
logger:
|
||||
level: DEBUG
|
||||
baud_rate: 0
|
||||
|
||||
api:
|
||||
password: !secret api_pass
|
||||
reboot_timeout: 0s
|
||||
|
||||
ota:
|
||||
password: !secret ota_pass
|
||||
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
uart:
|
||||
id: ac_uart_bus
|
||||
tx_pin: GPIO1
|
||||
rx_pin: GPIO3
|
||||
baud_rate: 4800
|
||||
data_bits: 8
|
||||
parity: EVEN
|
||||
stop_bits: 1
|
||||
|
||||
sensor:
|
||||
- platform: uptime
|
||||
name: Uptime Sensor
|
||||
|
||||
climate:
|
||||
- platform: aux_ac
|
||||
name: $upper_devicename
|
||||
id: aux_id
|
||||
uart_id: ac_uart_bus
|
||||
period: 7s
|
||||
show_action: true
|
||||
display_inverted: true
|
||||
optimistic: true
|
||||
indoor_temperature:
|
||||
name: $upper_devicename Indoor Temperature
|
||||
id: ${devicename}_indoor_temp
|
||||
internal: false
|
||||
display_state:
|
||||
name: $upper_devicename Display State
|
||||
id: ${devicename}_display_state
|
||||
internal: false
|
||||
outdoor_temperature:
|
||||
name: $upper_devicename Outdoor Temperature
|
||||
id: ${devicename}_outdoor_temp
|
||||
internal: false
|
||||
outbound_temperature:
|
||||
name: $upper_devicename Coolant Outbound Temperature
|
||||
id: ${devicename}_outbound_temp
|
||||
internal: false
|
||||
inbound_temperature:
|
||||
name: $upper_devicename Coolant Inbound Temperature
|
||||
id: ${devicename}_inbound_temp
|
||||
internal: false
|
||||
compressor_temperature:
|
||||
name: $upper_devicename Compressor Temperature
|
||||
id: ${devicename}_strange_temp
|
||||
internal: false
|
||||
defrost_state:
|
||||
name: $upper_devicename Defrost State
|
||||
id: ${devicename}_defrost_state
|
||||
internal: false
|
||||
inverter_power:
|
||||
name: $upper_devicename Invertor Power
|
||||
id: ${devicename}_invertor_power
|
||||
internal: false
|
||||
preset_reporter:
|
||||
name: $upper_devicename Preset Reporter
|
||||
id: ${devicename}_preset_reporter
|
||||
internal: false
|
||||
visual:
|
||||
min_temperature: 16
|
||||
max_temperature: 32
|
||||
temperature_step: 0.5
|
||||
supported_modes:
|
||||
- HEAT_COOL
|
||||
- COOL
|
||||
- HEAT
|
||||
- DRY
|
||||
- FAN_ONLY
|
||||
custom_fan_modes:
|
||||
- MUTE
|
||||
- TURBO
|
||||
supported_presets:
|
||||
- SLEEP
|
||||
custom_presets:
|
||||
- CLEAN
|
||||
- HEALTH
|
||||
- ANTIFUNGUS
|
||||
supported_swing_modes:
|
||||
- VERTICAL
|
||||
- HORIZONTAL
|
||||
- BOTH
|
||||
@@ -1,48 +0,0 @@
|
||||
external_components:
|
||||
- source:
|
||||
type: local
|
||||
path: ../components
|
||||
#- source: github://GrKoR/esphome_aux_ac_component@dev
|
||||
#components: [ aux_ac ]
|
||||
#refresh: 0s
|
||||
|
||||
substitutions:
|
||||
devicename: test_local_minimal
|
||||
upper_devicename: Test AUX
|
||||
|
||||
esphome:
|
||||
name: $devicename
|
||||
platform: ESP8266
|
||||
board: esp12e
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_pass
|
||||
reboot_timeout: 0s
|
||||
ap:
|
||||
ssid: Test AUX Fallback Hotspot
|
||||
password: !secret wifi_ap_pass
|
||||
|
||||
logger:
|
||||
level: DEBUG
|
||||
baud_rate: 0
|
||||
|
||||
api:
|
||||
password: !secret api_pass
|
||||
reboot_timeout: 0s
|
||||
|
||||
ota:
|
||||
password: !secret ota_pass
|
||||
|
||||
uart:
|
||||
id: ac_uart_bus
|
||||
tx_pin: GPIO1
|
||||
rx_pin: GPIO3
|
||||
baud_rate: 4800
|
||||
data_bits: 8
|
||||
parity: EVEN
|
||||
stop_bits: 1
|
||||
|
||||
climate:
|
||||
- platform: aux_ac
|
||||
name: $upper_devicename
|
||||
Reference in New Issue
Block a user