From bdb187cbfe70e560ae13169e7ac697944d3d6608 Mon Sep 17 00:00:00 2001 From: GrKoR Date: Thu, 22 Jan 2026 00:40:37 -0800 Subject: [PATCH 1/2] fix: ESPHome 2026.1.0 breaking changes --- README-EN.md | 3 +- README.md | 3 +- components/aux_ac/aux_ac.h | 265 +++-------------------------------- components/aux_ac/climate.py | 2 +- 4 files changed, 23 insertions(+), 250 deletions(-) diff --git a/README-EN.md b/README-EN.md index b328bbc..9a639eb 100644 --- a/README-EN.md +++ b/README-EN.md @@ -36,7 +36,8 @@ 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.2025.2.0 or above. You can try esphome before 2025.2.0 but I can't guarantee error-free compilation of the examples. +You need [ESPHome](https://esphome.io) v.2026.1.0 or above. +To compile it with earlier versions of ESPHome, use the component [v.0.3.2 or older](https://github.com/GrKoR/esphome_aux_ac_component/tags). ## Installing ## 1. Declare external component. Read [the manual](https://esphome.io/components/external_components.html?highlight=external) for details. diff --git a/README.md b/README.md index 3f93387..bac7292 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,8 @@ AUX - это один из нескольких OEM-производителей Для работы с кондиционером понадобится "железо" и прошивка. Описание электроники вынесено [в отдельный файл](docs/HARDWARE.md). ### Прошивка: интеграция aux_ac в вашу конфигурацию ESPHome ### -Для использования требуется [ESPHome](https://esphome.io) версией не ниже 2025.2.0. Работа с более ранними версиями возможна, но не гарантируется.
+Для использования требуется [ESPHome](https://esphome.io) версией не ниже 2026.1.0. +Для компиляции с ESPHome более ранних версий используйте компонент [v.0.3.2 или младше](https://github.com/GrKoR/esphome_aux_ac_component/tags). ## Установка ## 1. Подключите компонент. diff --git a/components/aux_ac/aux_ac.h b/components/aux_ac/aux_ac.h index c994ece..7c107a9 100644 --- a/components/aux_ac/aux_ac.h +++ b/components/aux_ac/aux_ac.h @@ -44,11 +44,9 @@ namespace esphome using climate::ClimatePreset; using climate::ClimateSwingMode; using climate::ClimateTraits; -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) using climate::ClimateModeMask; using climate::ClimateSwingModeMask; using climate::ClimatePresetMask; -#endif //**************************************************************************************************************************************************** //**************************************************** Packet logger configuration ******************************************************************* @@ -858,19 +856,11 @@ namespace esphome // как "в простое" (IDLE) bool _is_inverter = false; -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) ClimateModeMask _supported_modes{}; ClimateSwingModeMask _supported_swing_modes{}; ClimatePresetMask _supported_presets{}; std::vector _supported_custom_fan_modes{}; std::vector _supported_custom_presets{}; -#else - std::set _supported_modes{}; - std::set _supported_swing_modes{}; - std::set _supported_presets{}; - std::set _supported_custom_presets{}; - std::set _supported_custom_fan_modes{}; -#endif // The capabilities of the climate device // Шаблон параметров отображения виджета @@ -2404,13 +2394,8 @@ namespace esphome // первоначальная инициализация this->preset = climate::CLIMATE_PRESET_NONE; -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) this->clear_custom_preset_(); this->clear_custom_fan_mode_(); -#else - this->custom_preset = (std::string) ""; - this->custom_fan_mode = (std::string) ""; -#endif this->mode = climate::CLIMATE_MODE_OFF; this->action = climate::CLIMATE_ACTION_IDLE; this->fan_mode = climate::CLIMATE_FAN_LOW; @@ -2653,24 +2638,13 @@ namespace esphome switch (_current_ac_state.fanTurbo) { case AC_FANTURBO_ON: -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) this->set_custom_fan_mode_(Constants::TURBO.c_str()); -#else - this->custom_fan_mode = Constants::TURBO; -#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 + if (this->has_custom_fan_mode() && (this->get_custom_fan_mode() == Constants::TURBO)) + this->clear_custom_fan_mode_(); break; } @@ -2682,24 +2656,13 @@ namespace esphome switch (_current_ac_state.fanMute) { case AC_FANMUTE_ON: -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) this->set_custom_fan_mode_(Constants::MUTE.c_str()); -#else - this->custom_fan_mode = Constants::MUTE; -#endif break; case AC_FANMUTE_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::MUTE.c_str()) == 0) - this->clear_custom_fan_mode_(); - } -#else - if (this->custom_fan_mode == Constants::MUTE) - this->custom_fan_mode = (std::string) ""; -#endif + if (this->has_custom_fan_mode() && (this->get_custom_fan_mode() == Constants::MUTE)) + this->clear_custom_fan_mode_(); break; } @@ -2711,25 +2674,14 @@ namespace esphome if (_current_ac_state.health == AC_HEALTH_ON && _current_ac_state.power == AC_POWER_ON) { -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) this->set_custom_preset_(Constants::HEALTH.c_str()); -#else - this->custom_preset = Constants::HEALTH; -#endif } // AC_HEALTH_OFF // только в том случае, если до этого пресет был установлен -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) - else if (this->has_custom_preset() && strcmp(this->get_custom_preset(), Constants::HEALTH.c_str()) == 0) + else if (this->has_custom_preset() && (this->get_custom_preset() == Constants::HEALTH)) { this->clear_custom_preset_(); } -#else - else if (this->custom_preset == Constants::HEALTH) - { - this->custom_preset = (std::string) ""; - } -#endif _debugMsg(F("Climate HEALTH preset: %i"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, _current_ac_state.health); @@ -2757,25 +2709,14 @@ namespace esphome if (_current_ac_state.clean == AC_CLEAN_ON && _current_ac_state.power == AC_POWER_OFF) { -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) this->set_custom_preset_(Constants::CLEAN.c_str()); -#else - this->custom_preset = Constants::CLEAN; -#endif } // AC_CLEAN_OFF // только в том случае, если до этого пресет был установлен -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) - else if (this->has_custom_preset() && strcmp(this->get_custom_preset(), Constants::CLEAN.c_str()) == 0) + else if (this->has_custom_preset() && (this->get_custom_preset() == Constants::CLEAN)) { this->clear_custom_preset_(); } -#else - else if (this->custom_preset == Constants::CLEAN) - { - this->custom_preset = (std::string) ""; - } -#endif _debugMsg(F("Climate CLEAN preset: %i"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, _current_ac_state.clean); @@ -2798,25 +2739,13 @@ namespace esphome switch (_current_ac_state.mildew) { case AC_MILDEW_ON: -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) this->set_custom_preset_(Constants::ANTIFUNGUS.c_str()); -#else - this->custom_preset = Constants::ANTIFUNGUS; -#endif break; case AC_MILDEW_OFF: default: -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) - if (this->has_custom_preset() && strcmp(this->get_custom_preset(), Constants::ANTIFUNGUS.c_str()) == 0) - { + if (this->has_custom_preset() && (this->get_custom_preset() == Constants::ANTIFUNGUS)) this->clear_custom_preset_(); - } -#else - if (this->custom_preset == Constants::ANTIFUNGUS) - this->custom_preset = (std::string) ""; - break; -#endif } _debugMsg(F("Climate ANTIFUNGUS preset: %i"), ESPHOME_LOG_LEVEL_VERBOSE, __LINE__, _current_ac_state.mildew); @@ -2902,17 +2831,10 @@ namespace esphome { state_str += "SLEEP"; } -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) else if (this->has_custom_preset()) { state_str += this->get_custom_preset(); } -#else - else if (this->custom_preset.has_value() && this->custom_preset.value().length() > 0) - { - state_str += this->custom_preset.value().c_str(); - } -#endif else { state_str += "NONE"; @@ -3102,21 +3024,19 @@ namespace esphome break; } } -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) else if (call.has_custom_fan_mode()) { - const char *customfanmode = call.get_custom_fan_mode(); - - if (strcmp(customfanmode, Constants::TURBO.c_str()) == 0) + auto custom_fan_mode = call.get_custom_fan_mode(); + if (custom_fan_mode == Constants::TURBO) { // TURBO fan mode is suitable in COOL and HEAT modes. // Other modes don't accept TURBO fan mode. hasCommand = true; cmd.fanTurbo = AC_FANTURBO_ON; cmd.fanMute = AC_FANMUTE_OFF; - this->set_custom_fan_mode_(customfanmode); + this->set_custom_fan_mode_(custom_fan_mode); } - else if (strcmp(customfanmode, Constants::MUTE.c_str()) == 0) + else if (custom_fan_mode == Constants::MUTE) { // MUTE fan mode is suitable in FAN mode only for Rovex air conditioner. // In COOL mode AC receives command without any changes. @@ -3124,52 +3044,9 @@ namespace esphome hasCommand = true; cmd.fanMute = AC_FANMUTE_ON; cmd.fanTurbo = AC_FANTURBO_OFF; - this->set_custom_fan_mode_(customfanmode); + this->set_custom_fan_mode_(custom_fan_mode); } } -#else - else if (call.get_custom_fan_mode().has_value()) - { - std::string customfanmode = *call.get_custom_fan_mode(); - - 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; - cmd.fanTurbo = AC_FANTURBO_ON; - cmd.fanMute = AC_FANMUTE_OFF; // зависимость от fanturbo - 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) - { - // 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; - cmd.fanMute = AC_FANMUTE_ON; - cmd.fanTurbo = AC_FANTURBO_OFF; // зависимость от fanmute - this->custom_fan_mode = customfanmode; - //} else { - // _debugMsg(F("MUTE fan mode is suitable in FAN mode only."), ESPHOME_LOG_LEVEL_WARN, __LINE__); - //} - } - } -#endif // Пользователь выбрал пресет if (call.get_preset().has_value()) @@ -3220,28 +3097,25 @@ namespace esphome break; } } -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) else if (call.has_custom_preset()) { - const char *custom_preset = call.get_custom_preset(); - - if (strcmp(custom_preset, Constants::CLEAN.c_str()) == 0) + auto custom_preset = call.get_custom_preset(); + if (custom_preset == Constants::CLEAN) { // режим очистки кондиционера, включается (или должен включаться) при AC_POWER_OFF - // TODO: надо отдебажить выключение этого режима if (cmd.power == AC_POWER_OFF or _current_ac_state.power == AC_POWER_OFF) { hasCommand = true; cmd.clean = AC_CLEAN_ON; cmd.mildew = AC_MILDEW_OFF; - this->set_custom_preset_(custom_preset); + this->set_custom_preset_(Constants::CLEAN.c_str()); } else { _debugMsg(F("CLEAN preset is suitable in POWER_OFF mode only."), ESPHOME_LOG_LEVEL_WARN, __LINE__); } } - else if (strcmp(custom_preset, Constants::HEALTH.c_str()) == 0) + else if (custom_preset == Constants::HEALTH) { if (cmd.power == AC_POWER_ON || _current_ac_state.power == AC_POWER_ON) @@ -3266,81 +3140,7 @@ namespace esphome { cmd.fanSpeed = AC_FANSPEED_MEDIUM; // зависимость от health } - this->set_custom_preset_(custom_preset); - } - else - { - _debugMsg(F("HEALTH preset is suitable in POWER_ON mode only."), ESPHOME_LOG_LEVEL_WARN, __LINE__); - } - } - else if (strcmp(custom_preset, Constants::ANTIFUNGUS.c_str()) == 0) - { - // включение-выключение функции "Антиплесень". - // По факту: после выключения сплита он оставляет минут на 5 открытые жалюзи и глушит вентилятор. - // Уличный блок при этом гудит и тарахтит. Возможно, прогревается теплообменник для высыхания. - // Через некоторое время внешний блок замолкает и сплит закрывает жалюзи. - - // Brokly: - // включение-выключение функции "Антиплесень". - // у меня пульт отправляет 5 посылок и на включение и на выключение, но реагирует на эту кнопку - // только в режиме POWER_OFF - - // TODO: надо уточнить, в каких режимах штатно включается этот режим у кондиционера - cmd.mildew = AC_MILDEW_ON; - cmd.clean = AC_CLEAN_OFF; // для логики пресетов - - hasCommand = true; - this->set_custom_preset_(custom_preset); - } - } -#else - else if (call.get_custom_preset().has_value()) - { - std::string custom_preset = *call.get_custom_preset(); - - if (custom_preset == Constants::CLEAN) - { - // режим очистки кондиционера, включается (или должен включаться) при AC_POWER_OFF - // TODO: надо отдебажить выключение этого режима - if (cmd.power == AC_POWER_OFF or _current_ac_state.power == AC_POWER_OFF) - { - hasCommand = true; - cmd.clean = AC_CLEAN_ON; - cmd.mildew = AC_MILDEW_OFF; // для логики пресетов - this->custom_preset = custom_preset; - } - else - { - _debugMsg(F("CLEAN preset is suitable in POWER_OFF mode only."), ESPHOME_LOG_LEVEL_WARN, __LINE__); - } - } - else if (custom_preset == Constants::HEALTH) - { - if (cmd.power == AC_POWER_ON || - _current_ac_state.power == AC_POWER_ON) - { - hasCommand = true; - cmd.health = AC_HEALTH_ON; - // cmd.health_status = AC_HEALTH_STATUS_ON; // GK: статус кондей сам поднимает - cmd.fanTurbo = AC_FANTURBO_OFF; // зависимость от health - cmd.fanMute = AC_FANMUTE_OFF; // зависимость от health - cmd.sleep = AC_SLEEP_OFF; // для логики пресетов - - if (cmd.mode == AC_MODE_COOL || - cmd.mode == AC_MODE_HEAT || - cmd.mode == AC_MODE_AUTO || - _current_ac_state.mode == AC_MODE_COOL || - _current_ac_state.mode == AC_MODE_HEAT || - _current_ac_state.mode == AC_MODE_AUTO) - { - cmd.fanSpeed = AC_FANSPEED_AUTO; // зависимость от health - } - else if (cmd.mode == AC_MODE_FAN || - _current_ac_state.mode == AC_MODE_FAN) - { - cmd.fanSpeed = AC_FANSPEED_MEDIUM; // зависимость от health - } - this->custom_preset = custom_preset; + this->set_custom_preset_(Constants::HEALTH.c_str()); } else { @@ -3359,15 +3159,13 @@ namespace esphome // у меня пульт отправляет 5 посылок и на включение и на выключение, но реагирует на эту кнопку // только в режиме POWER_OFF - // TODO: надо уточнить, в каких режимах штатно включается этот режим у кондиционера cmd.mildew = AC_MILDEW_ON; cmd.clean = AC_CLEAN_OFF; // для логики пресетов hasCommand = true; - this->custom_preset = custom_preset; + this->set_custom_preset_(Constants::ANTIFUNGUS.c_str()); } } -#endif // User requested swing_mode change if (call.get_swing_mode().has_value()) @@ -3984,28 +3782,11 @@ namespace esphome void set_optimistic(bool optimistic) { this->_optimistic = optimistic; } bool get_optimistic() { return this->_optimistic; } -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) void set_supported_modes(ClimateModeMask modes) { this->_supported_modes = modes; } void set_supported_swing_modes(ClimateSwingModeMask modes) { this->_supported_swing_modes = modes; } void set_supported_presets(ClimatePresetMask presets) { this->_supported_presets = presets; } void set_custom_presets(std::initializer_list presets) { this->_supported_custom_presets = presets; } void set_custom_fan_modes(std::initializer_list modes) { this->_supported_custom_fan_modes = modes; } -#else - void set_supported_modes(const std::set &modes) { this->_supported_modes = modes; } - std::set get_supported_modes() { return this->_supported_modes; } - - void set_supported_swing_modes(const std::set &modes) { this->_supported_swing_modes = modes; } - std::set get_supported_swing_modes() { return this->_supported_swing_modes; } - - void set_supported_presets(const std::set &presets) { this->_supported_presets = presets; } - const std::set &get_supported_presets() { return this->_supported_presets; } - - void set_custom_presets(const std::set &presets) { this->_supported_custom_presets = presets; } - const std::set &get_supported_custom_presets() { return this->_supported_custom_presets; } - - void set_custom_fan_modes(const std::set &modes) { this->_supported_custom_fan_modes = modes; } - const std::set &get_supported_custom_fan_modes() { return this->_supported_custom_fan_modes; } -#endif #if defined(PRESETS_SAVING) void set_store_settings(bool store_settings) { this->_store_settings = store_settings; } @@ -4023,13 +3804,7 @@ namespace esphome // заполнение шаблона параметров отображения виджета // GK: всё же похоже правильнее это делать тут, а не в initAC() // initAC() в формируемом питоном коде вызывается до вызова aux_ac.set_supported_***() с установленными пользователем в конфиге параметрами -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) _traits.add_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_TEMPERATURE); - // NOT setting CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE - this device uses single target temperature -#else - _traits.set_supports_current_temperature(true); - _traits.set_supports_two_point_target_temperature(false); // if the climate device's target temperature should be split in target_temperature_low and target_temperature_high instead of just the single target_temperature -#endif _traits.set_supported_modes(this->_supported_modes); _traits.set_supported_swing_modes(this->_supported_swing_modes); @@ -4058,14 +3833,10 @@ namespace esphome //_traits.add_supported_preset(ClimatePreset::CLIMATE_PRESET_SLEEP); // if the climate device supports reporting the active current action of the device with the action property. -#if ESPHOME_VERSION_CODE >= VERSION_CODE(2025, 11, 0) if (this->_show_action) { _traits.add_feature_flags(climate::CLIMATE_SUPPORTS_ACTION); } -#else - _traits.set_supports_action(this->_show_action); -#endif }; void loop() override diff --git a/components/aux_ac/climate.py b/components/aux_ac/climate.py index 15a81ea..bf81dbd 100644 --- a/components/aux_ac/climate.py +++ b/components/aux_ac/climate.py @@ -34,7 +34,7 @@ from esphome.components.climate import ( ClimateSwingMode, ) -AUX_AC_FIRMWARE_VERSION = '0.3.2' +AUX_AC_FIRMWARE_VERSION = '0.3.3' AC_PACKET_TIMEOUT_MIN = 150 AC_PACKET_TIMEOUT_MAX = 600 AC_POWER_LIMIT_MIN = 30 From 24aa6dc8fd709b36098f59991b97ec5ada2a3ebb Mon Sep 17 00:00:00 2001 From: GrKoR Date: Thu, 22 Jan 2026 01:02:03 -0800 Subject: [PATCH 2/2] ref: move static constants to flash memory to reduce RAM usage --- components/aux_ac/aux_ac.h | 99 +++++++++++++++--------------------- components/aux_ac/climate.py | 24 ++------- 2 files changed, 44 insertions(+), 79 deletions(-) diff --git a/components/aux_ac/aux_ac.h b/components/aux_ac/aux_ac.h index 7c107a9..1d7539a 100644 --- a/components/aux_ac/aux_ac.h +++ b/components/aux_ac/aux_ac.h @@ -92,70 +92,51 @@ namespace esphome class Constants { public: - static const std::string AC_FIRMWARE_VERSION; + // AUX_AC_FIRMWARE_VERSION is defined by the ESPHome code generator at compile time + static constexpr const char* AC_FIRMWARE_VERSION = AUX_AC_FIRMWARE_VERSION; - static const std::string MUTE; - static const std::string TURBO; - static const std::string CLEAN; - static const std::string HEALTH; - static const std::string ANTIFUNGUS; + // custom fan modes + static constexpr const char* MUTE = "mute"; + static constexpr const char* TURBO = "turbo"; + + // custom presets + static constexpr const char* CLEAN = "Clean"; + static constexpr const char* HEALTH = "Health"; + static constexpr const char* ANTIFUNGUS = "Antifungus"; /// минимальная и максимальная температура в градусах Цельсия, ограничения самого кондиционера - static const float AC_MIN_TEMPERATURE; - static const float AC_MAX_TEMPERATURE; - /// шаг изменения целевой температуры, градусы Цельсия - static const float AC_TEMPERATURE_STEP; + static constexpr const float AC_MIN_TEMPERATURE = 16.0; + static constexpr const float AC_MAX_TEMPERATURE = 32.0; + /// Target temperature step, Celsius degrees + static constexpr const float AC_TEMPERATURE_STEP = 0.5; - /// минимальное и максимальное значение мощности инвертора при установке ограничений - static const uint8_t AC_MIN_INVERTER_POWER_LIMIT; - static const uint8_t AC_MAX_INVERTER_POWER_LIMIT; + /// Minimal and maximal values of invertor power + // AUX_AC_MIN_INVERTER_POWER_LIMIT and AUX_AC_MAX_INVERTER_POWER_LIMIT are defined by the ESPHome code generator at compile time + static constexpr const uint8_t AC_MIN_INVERTER_POWER_LIMIT = AUX_AC_MIN_INVERTER_POWER_LIMIT; + static constexpr const uint8_t AC_MAX_INVERTER_POWER_LIMIT = AUX_AC_MAX_INVERTER_POWER_LIMIT; // периодичность опроса кондиционера на предмет изменения состояния // изменение параметров с пульта не сообщается в UART, поэтому надо запрашивать состояние, чтобы быть в курсе // значение в миллисекундах - static const uint32_t AC_STATES_REQUEST_INTERVAL; + static constexpr const uint32_t AC_STATES_REQUEST_INTERVAL = 7000; // границы допустимого диапазона таймаута загрузки пакета // таймаут загрузки - через такое количиство миллисекунд конечный автомат перейдет из // состояния ACSM_RECEIVING_PACKET в ACSM_IDLE, если пакет не будет загружен - static const uint32_t AC_PACKET_TIMEOUT_MAX; - static const uint32_t AC_PACKET_TIMEOUT_MIN; + // По расчетам выходит: + // - получение и обработка посимвольно не должна длиться дольше 600 мсек. + // - получение и обработка пакетов целиком не должна длиться дольше 150 мсек. + // Мы будем обрабатывать пакетами, поэтому 150. + // Растягивать приём пакетов очередью команд нельзя, так как кондиционер иногда посылает + // информационные пакеты без запроса. Такие пакеты будут рушить последовательность команд, + // команды будут теряться. От такой коллизии мы не защищены в любом случае. Но чем меньше таймаут, + // тем меньше шансов на коллизию. + // Из этих соображений выбраны границы диапазона (_MIN и _MAX значения). + // AUX_AC_PACKET_TIMEOUT_MAX and AUX_AC_PACKET_TIMEOUT_MIN are defined by the ESPHome code generator at compile time + static constexpr const uint32_t AC_PACKET_TIMEOUT_MAX = AUX_AC_PACKET_TIMEOUT_MAX; + static constexpr const uint32_t AC_PACKET_TIMEOUT_MIN = AUX_AC_PACKET_TIMEOUT_MIN; }; - // AUX_AC_FIRMWARE_VERSION will be defined by the ESPHome code generator at compile time - const std::string Constants::AC_FIRMWARE_VERSION = AUX_AC_FIRMWARE_VERSION; - - // custom fan modes - const std::string Constants::MUTE = "mute"; - const std::string Constants::TURBO = "turbo"; - - // custom presets - const std::string Constants::CLEAN = "Clean"; - const std::string Constants::HEALTH = "Health"; - const std::string Constants::ANTIFUNGUS = "Antifungus"; - - // params - const float Constants::AC_MIN_TEMPERATURE = 16.0; - const float Constants::AC_MAX_TEMPERATURE = 32.0; - const float Constants::AC_TEMPERATURE_STEP = 0.5; - // AUX_AC_MIN_INVERTER_POWER_LIMIT and AUX_AC_MAX_INVERTER_POWER_LIMIT will be defined by the ESPHome code generator at compile time - const uint8_t Constants::AC_MIN_INVERTER_POWER_LIMIT = AUX_AC_MIN_INVERTER_POWER_LIMIT; - const uint8_t Constants::AC_MAX_INVERTER_POWER_LIMIT = AUX_AC_MAX_INVERTER_POWER_LIMIT; - const uint32_t Constants::AC_STATES_REQUEST_INTERVAL = 7000; - // таймаут загрузки пакета - // По расчетам выходит: - // - получение и обработка посимвольно не должна длиться дольше 600 мсек. - // - получение и обработка пакетов целиком не должна длиться дольше 150 мсек. - // Мы будем обрабатывать пакетами, поэтому 150. - // Растягивать приём пакетов очередью команд нельзя, так как кондиционер иногда посылает - // информационные пакеты без запроса. Такие пакеты будут рушить последовательность команд, - // команды будут теряться. От такой коллизии мы не защищены в любом случае. Но чем меньше таймаут, - // тем меньше шансов на коллизию. - // Из этих соображений выбраны границы диапазона (_MIN и _MAX значения). - // AUX_AC_PACKET_TIMEOUT_MAX and AUX_AC_PACKET_TIMEOUT_MIN will be defined by the ESPHome code generator at compile time - const uint32_t Constants::AC_PACKET_TIMEOUT_MAX = AUX_AC_PACKET_TIMEOUT_MAX; - const uint32_t Constants::AC_PACKET_TIMEOUT_MIN = AUX_AC_PACKET_TIMEOUT_MIN; - //**************************************************************************************************************************************************** //********************************************************* ОСНОВНЫЕ СТРУКТУРЫ *********************************************************************** //**************************************************************************************************************************************************** @@ -2638,7 +2619,7 @@ namespace esphome switch (_current_ac_state.fanTurbo) { case AC_FANTURBO_ON: - this->set_custom_fan_mode_(Constants::TURBO.c_str()); + this->set_custom_fan_mode_(Constants::TURBO); break; case AC_FANTURBO_OFF: @@ -2656,7 +2637,7 @@ namespace esphome switch (_current_ac_state.fanMute) { case AC_FANMUTE_ON: - this->set_custom_fan_mode_(Constants::MUTE.c_str()); + this->set_custom_fan_mode_(Constants::MUTE); break; case AC_FANMUTE_OFF: @@ -2674,7 +2655,7 @@ namespace esphome if (_current_ac_state.health == AC_HEALTH_ON && _current_ac_state.power == AC_POWER_ON) { - this->set_custom_preset_(Constants::HEALTH.c_str()); + this->set_custom_preset_(Constants::HEALTH); } // AC_HEALTH_OFF // только в том случае, если до этого пресет был установлен @@ -2709,7 +2690,7 @@ namespace esphome if (_current_ac_state.clean == AC_CLEAN_ON && _current_ac_state.power == AC_POWER_OFF) { - this->set_custom_preset_(Constants::CLEAN.c_str()); + this->set_custom_preset_(Constants::CLEAN); } // AC_CLEAN_OFF // только в том случае, если до этого пресет был установлен @@ -2739,7 +2720,7 @@ namespace esphome switch (_current_ac_state.mildew) { case AC_MILDEW_ON: - this->set_custom_preset_(Constants::ANTIFUNGUS.c_str()); + this->set_custom_preset_(Constants::ANTIFUNGUS); break; case AC_MILDEW_OFF: @@ -2853,7 +2834,7 @@ namespace esphome void dump_config() { ESP_LOGCONFIG(TAG, "AUX HVAC:"); - ESP_LOGCONFIG(TAG, " [x] Firmware version: %s", Constants::AC_FIRMWARE_VERSION.c_str()); + ESP_LOGCONFIG(TAG, " [x] Firmware version: %s", Constants::AC_FIRMWARE_VERSION); ESP_LOGCONFIG(TAG, " [x] Period: %" PRIu32 "ms", this->get_period()); ESP_LOGCONFIG(TAG, " [x] Show action: %s", TRUEFALSE(this->get_show_action())); ESP_LOGCONFIG(TAG, " [x] Display inverted: %s", TRUEFALSE(this->get_display_inverted())); @@ -3108,7 +3089,7 @@ namespace esphome hasCommand = true; cmd.clean = AC_CLEAN_ON; cmd.mildew = AC_MILDEW_OFF; - this->set_custom_preset_(Constants::CLEAN.c_str()); + this->set_custom_preset_(Constants::CLEAN); } else { @@ -3140,7 +3121,7 @@ namespace esphome { cmd.fanSpeed = AC_FANSPEED_MEDIUM; // зависимость от health } - this->set_custom_preset_(Constants::HEALTH.c_str()); + this->set_custom_preset_(Constants::HEALTH); } else { @@ -3163,7 +3144,7 @@ namespace esphome cmd.clean = AC_CLEAN_OFF; // для логики пресетов hasCommand = true; - this->set_custom_preset_(Constants::ANTIFUNGUS.c_str()); + this->set_custom_preset_(Constants::ANTIFUNGUS); } } diff --git a/components/aux_ac/climate.py b/components/aux_ac/climate.py index bf81dbd..58c4617 100644 --- a/components/aux_ac/climate.py +++ b/components/aux_ac/climate.py @@ -128,12 +128,6 @@ AirConPowerLimitationOnAction = aux_ac_ns.class_( ) -def use_new_api(): - esphome_current_version = tuple(map(int, __version__.split('.'))) - esphome_bc_version = tuple(map(int, "2025.11.0".split('.'))) - return esphome_current_version >= esphome_bc_version - - def validate_packet_timeout(value): minV = AC_PACKET_TIMEOUT_MIN maxV = AC_PACKET_TIMEOUT_MAX @@ -433,20 +427,10 @@ async def to_code(config): cg.add(var.set_supported_swing_modes(config[CONF_SUPPORTED_SWING_MODES])) if CONF_SUPPORTED_PRESETS in config: cg.add(var.set_supported_presets(config[CONF_SUPPORTED_PRESETS])) - if use_new_api(): - if CONF_CUSTOM_PRESETS in config: - presets = config[CONF_CUSTOM_PRESETS] - c_str_presets = [cg.RawExpression(f"aux_ac::Constants::{p}.c_str()") for p in presets] - cg.add(var.set_custom_presets(c_str_presets)) - if CONF_CUSTOM_FAN_MODES in config: - fan_modes = config[CONF_CUSTOM_FAN_MODES] - c_str_fan_modes = [cg.RawExpression(f"aux_ac::Constants::{p}.c_str()") for p in fan_modes] - cg.add(var.set_custom_fan_modes(c_str_fan_modes)) - else: - if CONF_CUSTOM_PRESETS in 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])) + if CONF_CUSTOM_PRESETS in 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(