mirror of
https://github.com/GrKoR/esphome_aux_ac_component.git
synced 2026-01-30 22:50:32 +03:00
new: Soft custom fan mode for new ACs
This commit is contained in:
@@ -98,6 +98,7 @@ namespace esphome
|
|||||||
|
|
||||||
static const std::string MUTE;
|
static const std::string MUTE;
|
||||||
static const std::string TURBO;
|
static const std::string TURBO;
|
||||||
|
static const std::string SOFT;
|
||||||
static const std::string CLEAN;
|
static const std::string CLEAN;
|
||||||
static const std::string HEALTH;
|
static const std::string HEALTH;
|
||||||
static const std::string ANTIFUNGUS;
|
static const std::string ANTIFUNGUS;
|
||||||
@@ -130,6 +131,7 @@ namespace esphome
|
|||||||
// custom fan modes
|
// custom fan modes
|
||||||
const std::string Constants::MUTE = "mute";
|
const std::string Constants::MUTE = "mute";
|
||||||
const std::string Constants::TURBO = "turbo";
|
const std::string Constants::TURBO = "turbo";
|
||||||
|
const std::string Constants::SOFT = "soft";
|
||||||
|
|
||||||
// custom presets
|
// custom presets
|
||||||
const std::string Constants::CLEAN = "Clean";
|
const std::string Constants::CLEAN = "Clean";
|
||||||
@@ -482,13 +484,13 @@ namespace esphome
|
|||||||
AC_HEALTH_UNTOUCHED = 0xFF
|
AC_HEALTH_UNTOUCHED = 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
// Статус ионизатора. Если бит поднят, то обнаружена ошибка ключения ионизатора
|
// Режим потока при закрытых жалюзи (функции SOFT и HEALTH)
|
||||||
#define AC_HEALTH_STATUS_MASK 0b00000001
|
#define AC_LOUVER_CLOSED_FLOW_MASK 0b00000001
|
||||||
enum ac_health_status : uint8_t
|
enum ac_louver_closed_flow : uint8_t
|
||||||
{
|
{
|
||||||
AC_HEALTH_STATUS_OFF = 0x00,
|
AC_LOUVER_CLOSED_FLOW_OFF = 0x00,
|
||||||
AC_HEALTH_STATUS_ON = 0x01,
|
AC_LOUVER_CLOSED_FLOW_ON = 0x01,
|
||||||
AC_HEALTH_STATUS_UNTOUCHED = 0xFF
|
AC_LOUVER_CLOSED_FLOW_UNTOUCHED = 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
// целевая температура
|
// целевая температура
|
||||||
@@ -720,7 +722,7 @@ namespace esphome
|
|||||||
struct ac_command_t
|
struct ac_command_t
|
||||||
{
|
{
|
||||||
AC_COMMAND_BASE;
|
AC_COMMAND_BASE;
|
||||||
ac_health_status health_status;
|
ac_louver_closed_flow louver_closed_flow;
|
||||||
float temp_ambient; // внутренняя температура
|
float temp_ambient; // внутренняя температура
|
||||||
int8_t temp_outdoor; // внешняя температура
|
int8_t temp_outdoor; // внешняя температура
|
||||||
int8_t temp_inbound; // температура входящая
|
int8_t temp_inbound; // температура входящая
|
||||||
@@ -1142,7 +1144,7 @@ namespace esphome
|
|||||||
cmd->fanSpeed = AC_FANSPEED_UNTOUCHED;
|
cmd->fanSpeed = AC_FANSPEED_UNTOUCHED;
|
||||||
cmd->fanTurbo = AC_FANTURBO_UNTOUCHED;
|
cmd->fanTurbo = AC_FANTURBO_UNTOUCHED;
|
||||||
cmd->health = AC_HEALTH_UNTOUCHED;
|
cmd->health = AC_HEALTH_UNTOUCHED;
|
||||||
cmd->health_status = AC_HEALTH_STATUS_UNTOUCHED;
|
cmd->louver_closed_flow = AC_LOUVER_CLOSED_FLOW_UNTOUCHED;
|
||||||
cmd->louver.louver_h = AC_LOUVERH_UNTOUCHED;
|
cmd->louver.louver_h = AC_LOUVERH_UNTOUCHED;
|
||||||
cmd->louver.louver_v = AC_LOUVERV_UNTOUCHED;
|
cmd->louver.louver_v = AC_LOUVERV_UNTOUCHED;
|
||||||
cmd->mildew = AC_MILDEW_UNTOUCHED;
|
cmd->mildew = AC_MILDEW_UNTOUCHED;
|
||||||
@@ -1522,9 +1524,9 @@ namespace esphome
|
|||||||
stateChangedFlag = stateChangedFlag || (_current_ac_state.health != (ac_health)stateByte);
|
stateChangedFlag = stateChangedFlag || (_current_ac_state.health != (ac_health)stateByte);
|
||||||
_current_ac_state.health = (ac_health)stateByte;
|
_current_ac_state.health = (ac_health)stateByte;
|
||||||
|
|
||||||
stateByte = small_info_body->status & AC_HEALTH_STATUS_MASK;
|
stateByte = small_info_body->status & AC_LOUVER_CLOSED_FLOW_MASK;
|
||||||
stateChangedFlag = stateChangedFlag || (_current_ac_state.health_status != (ac_health_status)stateByte);
|
stateChangedFlag = stateChangedFlag || (_current_ac_state.louver_closed_flow != (ac_louver_closed_flow)stateByte);
|
||||||
_current_ac_state.health_status = (ac_health_status)stateByte;
|
_current_ac_state.louver_closed_flow = (ac_louver_closed_flow)stateByte;
|
||||||
|
|
||||||
stateByte = small_info_body->status & AC_CLEAN_MASK;
|
stateByte = small_info_body->status & AC_CLEAN_MASK;
|
||||||
stateChangedFlag = stateChangedFlag || (_current_ac_state.clean != (ac_clean)stateByte);
|
stateChangedFlag = stateChangedFlag || (_current_ac_state.clean != (ac_clean)stateByte);
|
||||||
@@ -2027,10 +2029,10 @@ namespace esphome
|
|||||||
pack->body[10] = (pack->body[10] & ~AC_HEALTH_MASK) | cmd->health;
|
pack->body[10] = (pack->body[10] & ~AC_HEALTH_MASK) | cmd->health;
|
||||||
}
|
}
|
||||||
|
|
||||||
// какой то флаг ионизатора
|
// Режим потока при закрытых жалюзи
|
||||||
if (cmd->health_status != AC_HEALTH_STATUS_UNTOUCHED)
|
if (cmd->louver_closed_flow != AC_LOUVER_CLOSED_FLOW_UNTOUCHED)
|
||||||
{
|
{
|
||||||
pack->body[10] = (pack->body[10] & ~AC_HEALTH_STATUS_MASK) | cmd->health_status;
|
pack->body[10] = (pack->body[10] & ~AC_LOUVER_CLOSED_FLOW_MASK) | cmd->louver_closed_flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// дисплей
|
// дисплей
|
||||||
@@ -2647,62 +2649,43 @@ namespace esphome
|
|||||||
|
|
||||||
_debugMsg(F("Climate fan mode: %i"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, this->fan_mode);
|
_debugMsg(F("Climate fan mode: %i"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, this->fan_mode);
|
||||||
|
|
||||||
/*************************** TURBO FAN MODE ***************************/
|
/*************************** CUSTOM FAN MODES ***************************/
|
||||||
// TURBO работает в режимах FAN, COOL, HEAT, HEAT_COOL
|
// SOFT, TURBO и MUTE являются взаимоисключающими
|
||||||
// в режиме DRY изменение скорости вентилятора никак не влияло на его скорость, может сплит просто не вышел еще на режим? Надо попробовать долгую работу в этом режиме.
|
if (_current_ac_state.louver_closed_flow == AC_LOUVER_CLOSED_FLOW_ON)
|
||||||
switch (_current_ac_state.fanTurbo)
|
{
|
||||||
|
#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0)
|
||||||
|
this->set_custom_fan_mode_(Constants::SOFT.c_str());
|
||||||
|
#else
|
||||||
|
this->custom_fan_mode = Constants::SOFT;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (_current_ac_state.fanTurbo == AC_FANTURBO_ON)
|
||||||
{
|
{
|
||||||
case AC_FANTURBO_ON:
|
|
||||||
#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0)
|
#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0)
|
||||||
this->set_custom_fan_mode_(Constants::TURBO.c_str());
|
this->set_custom_fan_mode_(Constants::TURBO.c_str());
|
||||||
#else
|
#else
|
||||||
this->custom_fan_mode = Constants::TURBO;
|
this->custom_fan_mode = Constants::TURBO;
|
||||||
#endif
|
#endif
|
||||||
break;
|
|
||||||
|
|
||||||
case AC_FANTURBO_OFF:
|
|
||||||
default:
|
|
||||||
#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0)
|
|
||||||
if (this->has_custom_fan_mode()) {
|
|
||||||
if (strcmp(this->get_custom_fan_mode(), Constants::TURBO.c_str()) == 0)
|
|
||||||
this->clear_custom_fan_mode_();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (this->custom_fan_mode == Constants::TURBO)
|
|
||||||
this->custom_fan_mode = (std::string) "";
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else if (_current_ac_state.fanMute == AC_FANMUTE_ON)
|
||||||
_debugMsg(F("Climate fan TURBO mode: %i"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, _current_ac_state.fanTurbo);
|
|
||||||
|
|
||||||
/*************************** MUTE FAN MODE ***************************/
|
|
||||||
// MUTE работает в режиме FAN. В режимах HEAT, COOL, HEAT_COOL не работает. DRY не проверял.
|
|
||||||
// проверку на несовместимые режимы выпилили, т.к. нет уверенности, что это поведение одинаково для всех
|
|
||||||
switch (_current_ac_state.fanMute)
|
|
||||||
{
|
{
|
||||||
case AC_FANMUTE_ON:
|
|
||||||
#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0)
|
#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0)
|
||||||
this->set_custom_fan_mode_(Constants::MUTE.c_str());
|
this->set_custom_fan_mode_(Constants::MUTE.c_str());
|
||||||
#else
|
#else
|
||||||
this->custom_fan_mode = Constants::MUTE;
|
this->custom_fan_mode = Constants::MUTE;
|
||||||
#endif
|
#endif
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
case AC_FANMUTE_OFF:
|
{
|
||||||
default:
|
|
||||||
#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0)
|
#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0)
|
||||||
if (this->has_custom_fan_mode()) {
|
this->clear_custom_fan_mode_();
|
||||||
if (strcmp(this->get_custom_fan_mode(), Constants::MUTE.c_str()) == 0)
|
|
||||||
this->clear_custom_fan_mode_();
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
if (this->custom_fan_mode == Constants::MUTE)
|
this->custom_fan_mode = (std::string) "";
|
||||||
this->custom_fan_mode = (std::string) "";
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_debugMsg(F("Climate fan LOUVER_CLOSED_FLOW mode: %i"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, _current_ac_state.louver_closed_flow);
|
||||||
|
_debugMsg(F("Climate fan TURBO mode: %i"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, _current_ac_state.fanTurbo);
|
||||||
_debugMsg(F("Climate fan MUTE mode: %i"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, _current_ac_state.fanMute);
|
_debugMsg(F("Climate fan MUTE mode: %i"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, _current_ac_state.fanMute);
|
||||||
|
|
||||||
//======================== ОТОБРАЖЕНИЕ ПРЕСЕТОВ ================================
|
//======================== ОТОБРАЖЕНИЕ ПРЕСЕТОВ ================================
|
||||||
@@ -3109,21 +3092,26 @@ namespace esphome
|
|||||||
|
|
||||||
if (strcmp(customfanmode, Constants::TURBO.c_str()) == 0)
|
if (strcmp(customfanmode, Constants::TURBO.c_str()) == 0)
|
||||||
{
|
{
|
||||||
// TURBO fan mode is suitable in COOL and HEAT modes.
|
|
||||||
// Other modes don't accept TURBO fan mode.
|
|
||||||
hasCommand = true;
|
hasCommand = true;
|
||||||
cmd.fanTurbo = AC_FANTURBO_ON;
|
cmd.fanTurbo = AC_FANTURBO_ON;
|
||||||
cmd.fanMute = AC_FANMUTE_OFF;
|
cmd.fanMute = AC_FANMUTE_OFF;
|
||||||
|
cmd.louver_closed_flow = AC_LOUVER_CLOSED_FLOW_OFF;
|
||||||
this->set_custom_fan_mode_(customfanmode);
|
this->set_custom_fan_mode_(customfanmode);
|
||||||
}
|
}
|
||||||
else if (strcmp(customfanmode, Constants::MUTE.c_str()) == 0)
|
else if (strcmp(customfanmode, Constants::MUTE.c_str()) == 0)
|
||||||
{
|
{
|
||||||
// MUTE fan mode is suitable in FAN mode only for Rovex air conditioner.
|
|
||||||
// In COOL mode AC receives command without any changes.
|
|
||||||
// May be other AUX-based air conditioners do the same.
|
|
||||||
hasCommand = true;
|
hasCommand = true;
|
||||||
cmd.fanMute = AC_FANMUTE_ON;
|
cmd.fanMute = AC_FANMUTE_ON;
|
||||||
cmd.fanTurbo = AC_FANTURBO_OFF;
|
cmd.fanTurbo = AC_FANTURBO_OFF;
|
||||||
|
cmd.louver_closed_flow = AC_LOUVER_CLOSED_FLOW_OFF;
|
||||||
|
this->set_custom_fan_mode_(customfanmode);
|
||||||
|
}
|
||||||
|
else if (strcmp(customfanmode, Constants::SOFT.c_str()) == 0)
|
||||||
|
{
|
||||||
|
hasCommand = true;
|
||||||
|
cmd.louver_closed_flow = AC_LOUVER_CLOSED_FLOW_ON;
|
||||||
|
cmd.fanMute = AC_FANMUTE_OFF;
|
||||||
|
cmd.fanTurbo = AC_FANTURBO_OFF;
|
||||||
this->set_custom_fan_mode_(customfanmode);
|
this->set_custom_fan_mode_(customfanmode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3134,39 +3122,27 @@ namespace esphome
|
|||||||
|
|
||||||
if (customfanmode == Constants::TURBO)
|
if (customfanmode == Constants::TURBO)
|
||||||
{
|
{
|
||||||
// TURBO fan mode is suitable in COOL and HEAT modes.
|
|
||||||
// Other modes don't accept TURBO fan mode.
|
|
||||||
/*
|
|
||||||
if ( cmd.mode == AC_MODE_COOL
|
|
||||||
or cmd.mode == AC_MODE_HEAT
|
|
||||||
or _current_ac_state.mode == AC_MODE_COOL
|
|
||||||
or _current_ac_state.mode == AC_MODE_HEAT) {
|
|
||||||
*/
|
|
||||||
hasCommand = true;
|
hasCommand = true;
|
||||||
cmd.fanTurbo = AC_FANTURBO_ON;
|
cmd.fanTurbo = AC_FANTURBO_ON;
|
||||||
cmd.fanMute = AC_FANMUTE_OFF; // зависимость от fanturbo
|
cmd.fanMute = AC_FANMUTE_OFF;
|
||||||
|
cmd.louver_closed_flow = AC_LOUVER_CLOSED_FLOW_OFF;
|
||||||
this->custom_fan_mode = customfanmode;
|
this->custom_fan_mode = customfanmode;
|
||||||
/*
|
|
||||||
} else {
|
|
||||||
_debugMsg(F("TURBO fan mode is suitable in COOL and HEAT modes only."), ESPHOME_LOG_LEVEL_WARN, __LINE__);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
else if (customfanmode == Constants::MUTE)
|
else if (customfanmode == Constants::MUTE)
|
||||||
{
|
{
|
||||||
// MUTE fan mode is suitable in FAN mode only for Rovex air conditioner.
|
|
||||||
// In COOL mode AC receives command without any changes.
|
|
||||||
// May be other AUX-based air conditioners do the same.
|
|
||||||
// if ( cmd.mode == AC_MODE_FAN
|
|
||||||
// or _current_ac_state.mode == AC_MODE_FAN) {
|
|
||||||
|
|
||||||
hasCommand = true;
|
hasCommand = true;
|
||||||
cmd.fanMute = AC_FANMUTE_ON;
|
cmd.fanMute = AC_FANMUTE_ON;
|
||||||
cmd.fanTurbo = AC_FANTURBO_OFF; // зависимость от fanmute
|
cmd.fanTurbo = AC_FANTURBO_OFF;
|
||||||
|
cmd.louver_closed_flow = AC_LOUVER_CLOSED_FLOW_OFF;
|
||||||
|
this->custom_fan_mode = customfanmode;
|
||||||
|
}
|
||||||
|
else if (customfanmode == Constants::SOFT)
|
||||||
|
{
|
||||||
|
hasCommand = true;
|
||||||
|
cmd.louver_closed_flow = AC_LOUVER_CLOSED_FLOW_ON;
|
||||||
|
cmd.fanMute = AC_FANMUTE_OFF;
|
||||||
|
cmd.fanTurbo = AC_FANTURBO_OFF;
|
||||||
this->custom_fan_mode = customfanmode;
|
this->custom_fan_mode = customfanmode;
|
||||||
//} else {
|
|
||||||
// _debugMsg(F("MUTE fan mode is suitable in FAN mode only."), ESPHOME_LOG_LEVEL_WARN, __LINE__);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -3192,8 +3168,8 @@ namespace esphome
|
|||||||
{
|
{
|
||||||
hasCommand = true;
|
hasCommand = true;
|
||||||
cmd.sleep = AC_SLEEP_ON;
|
cmd.sleep = AC_SLEEP_ON;
|
||||||
cmd.health = AC_HEALTH_OFF; // для логики пресетов
|
cmd.health = AC_HEALTH_OFF;
|
||||||
cmd.health_status = AC_HEALTH_STATUS_OFF;
|
cmd.louver_closed_flow = AC_LOUVER_CLOSED_FLOW_OFF;
|
||||||
this->preset = preset;
|
this->preset = preset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -3206,7 +3182,6 @@ namespace esphome
|
|||||||
// выбран пустой пресет, сбрасываем все настройки
|
// выбран пустой пресет, сбрасываем все настройки
|
||||||
hasCommand = true;
|
hasCommand = true;
|
||||||
cmd.health = AC_HEALTH_OFF;
|
cmd.health = AC_HEALTH_OFF;
|
||||||
// cmd.health_status = AC_HEALTH_STATUS_OFF; // GK: не нужно ставить, т.к. этот флаг устанавливается самим сплитом
|
|
||||||
cmd.sleep = AC_SLEEP_OFF;
|
cmd.sleep = AC_SLEEP_OFF;
|
||||||
cmd.mildew = AC_MILDEW_OFF;
|
cmd.mildew = AC_MILDEW_OFF;
|
||||||
cmd.clean = AC_CLEAN_OFF;
|
cmd.clean = AC_CLEAN_OFF;
|
||||||
@@ -3321,7 +3296,6 @@ namespace esphome
|
|||||||
{
|
{
|
||||||
hasCommand = true;
|
hasCommand = true;
|
||||||
cmd.health = AC_HEALTH_ON;
|
cmd.health = AC_HEALTH_ON;
|
||||||
// cmd.health_status = AC_HEALTH_STATUS_ON; // GK: статус кондей сам поднимает
|
|
||||||
cmd.fanTurbo = AC_FANTURBO_OFF; // зависимость от health
|
cmd.fanTurbo = AC_FANTURBO_OFF; // зависимость от health
|
||||||
cmd.fanMute = AC_FANMUTE_OFF; // зависимость от health
|
cmd.fanMute = AC_FANMUTE_OFF; // зависимость от health
|
||||||
cmd.sleep = AC_SLEEP_OFF; // для логики пресетов
|
cmd.sleep = AC_SLEEP_OFF; // для логики пресетов
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ from esphome.components.climate import (
|
|||||||
ClimateSwingMode,
|
ClimateSwingMode,
|
||||||
)
|
)
|
||||||
|
|
||||||
AUX_AC_FIRMWARE_VERSION = '0.3.2'
|
AUX_AC_FIRMWARE_VERSION = '0.3.3'
|
||||||
AC_PACKET_TIMEOUT_MIN = 150
|
AC_PACKET_TIMEOUT_MIN = 150
|
||||||
AC_PACKET_TIMEOUT_MAX = 600
|
AC_PACKET_TIMEOUT_MAX = 600
|
||||||
AC_POWER_LIMIT_MIN = 30
|
AC_POWER_LIMIT_MIN = 30
|
||||||
@@ -174,6 +174,7 @@ validate_swing_modes = cv.enum(ALLOWED_CLIMATE_SWING_MODES, upper=True)
|
|||||||
CUSTOM_FAN_MODES = {
|
CUSTOM_FAN_MODES = {
|
||||||
"MUTE": Capabilities.MUTE,
|
"MUTE": Capabilities.MUTE,
|
||||||
"TURBO": Capabilities.TURBO,
|
"TURBO": Capabilities.TURBO,
|
||||||
|
"SOFT": Capabilities.SOFT,
|
||||||
}
|
}
|
||||||
validate_custom_fan_modes = cv.enum(CUSTOM_FAN_MODES, upper=True)
|
validate_custom_fan_modes = cv.enum(CUSTOM_FAN_MODES, upper=True)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user