33#include < chrono>
44#include < string>
55#include " esphome/components/climate/climate.h"
6- #include " esphome/core/controller_registry.h"
76#include " esphome/components/uart/uart.h"
87#include " esphome/core/helpers.h"
98#include " hon_climate.h"
@@ -34,23 +33,14 @@ const std::vector<hon_protocol::HorizontalSwingMode> HORIZONTAL_SWING_MODES_ORDE
3433 hon_protocol::HorizontalSwingMode::MAX_RIGHT ,
3534};
3635
37- static bool vertical_swing_mode_is_selectable_ (hon_protocol::VerticalSwingMode mode ) {
38- return (mode != hon_protocol::VerticalSwingMode:: AUTO ) && (mode != hon_protocol::VerticalSwingMode:: AUTO_SPECIAL );
36+ static bool vertical_axis_is_auto_ (climate::ClimateSwingMode swing_mode ) {
37+ return (swing_mode == climate:: CLIMATE_SWING_VERTICAL ) || (swing_mode == climate:: CLIMATE_SWING_BOTH );
3938}
4039
41- static bool horizontal_swing_mode_is_selectable_ (hon_protocol::HorizontalSwingMode mode ) {
42- return mode != hon_protocol::HorizontalSwingMode:: AUTO ;
40+ static bool horizontal_axis_is_auto_ (climate::ClimateSwingMode swing_mode ) {
41+ return (swing_mode == climate:: CLIMATE_SWING_HORIZONTAL ) || (swing_mode == climate:: CLIMATE_SWING_BOTH ) ;
4342}
4443
45- static void clear_airflow_select_state_ (select::Select *sel) {
46- if (sel == nullptr ) {
47- return ;
48- }
49- sel->set_has_state (false );
50- #if defined(USE_SELECT) && defined(USE_CONTROLLER_REGISTRY)
51- ControllerRegistry::notify_select_update (sel);
52- #endif
53- }
5444#endif // USE_SELECT
5545
5646static const char *const TAG = " haier.climate" ;
@@ -113,17 +103,31 @@ esphome::optional<hon_protocol::VerticalSwingMode> HonClimate::get_vertical_airf
113103};
114104
115105void HonClimate::set_vertical_airflow (hon_protocol::VerticalSwingMode direction) {
106+ if (this ->settings_ .last_vertiacal_swing != direction) {
107+ this ->settings_ .last_vertiacal_swing = direction;
108+ this ->hon_rtc_ .save (&this ->settings_ );
109+ }
116110 this ->pending_vertical_direction_ = direction;
117111 this ->force_send_control_ = true ;
112+ #ifdef USE_SELECT
113+ this ->update_vertical_airflow_select_state_ ();
114+ #endif
118115}
119116
120117esphome::optional<hon_protocol::HorizontalSwingMode> HonClimate::get_horizontal_airflow () const {
121118 return this ->current_horizontal_swing_ ;
122119}
123120
124121void HonClimate::set_horizontal_airflow (hon_protocol::HorizontalSwingMode direction) {
122+ if (this ->settings_ .last_horizontal_swing != direction) {
123+ this ->settings_ .last_horizontal_swing = direction;
124+ this ->hon_rtc_ .save (&this ->settings_ );
125+ }
125126 this ->pending_horizontal_direction_ = direction;
126127 this ->force_send_control_ = true ;
128+ #ifdef USE_SELECT
129+ this ->update_horizontal_airflow_select_state_ ();
130+ #endif
127131}
128132
129133std::string HonClimate::get_cleaning_status_text () const {
@@ -696,12 +700,17 @@ haier_protocol::HaierMessage HonClimate::get_control_message() {
696700 }
697701 }
698702 }
703+ const ClimateSwingMode target_swing_mode = this ->current_hvac_settings_ .swing_mode .value_or (this ->swing_mode );
699704 if (this ->pending_vertical_direction_ .has_value ()) {
700- out_data->vertical_swing_mode = (uint8_t ) this ->pending_vertical_direction_ .value ();
705+ if (!vertical_axis_is_auto_ (target_swing_mode)) {
706+ out_data->vertical_swing_mode = (uint8_t ) this ->pending_vertical_direction_ .value ();
707+ }
701708 this ->pending_vertical_direction_ .reset ();
702709 }
703710 if (this ->pending_horizontal_direction_ .has_value ()) {
704- out_data->horizontal_swing_mode = (uint8_t ) this ->pending_horizontal_direction_ .value ();
711+ if (!horizontal_axis_is_auto_ (target_swing_mode)) {
712+ out_data->horizontal_swing_mode = (uint8_t ) this ->pending_horizontal_direction_ .value ();
713+ }
705714 this ->pending_horizontal_direction_ .reset ();
706715 }
707716 {
@@ -875,17 +884,16 @@ void HonClimate::update_vertical_airflow_select_state_() {
875884 if (this ->vertical_airflow_select_ == nullptr ) {
876885 return ;
877886 }
878- if (!this ->current_vertical_swing_ .has_value () ||
879- !vertical_swing_mode_is_selectable_ (this ->current_vertical_swing_ .value ())) {
880- clear_airflow_select_state_ (this ->vertical_airflow_select_ );
881- return ;
882- }
883887 auto mode_it = std::find (VERTICAL_SWING_MODES_ORDER .begin (), VERTICAL_SWING_MODES_ORDER .end (),
884- this ->current_vertical_swing_ . value () );
888+ this ->settings_ . last_vertiacal_swing );
885889 if (mode_it == VERTICAL_SWING_MODES_ORDER .end ()) {
886- ESP_LOGW (TAG , " Unsupported vertical airflow mode: 0x%X" , static_cast <uint8_t >(this ->current_vertical_swing_ .value ()));
887- clear_airflow_select_state_ (this ->vertical_airflow_select_ );
888- return ;
890+ ESP_LOGW (TAG , " Unsupported saved vertical airflow mode: 0x%X, fallback to Center" ,
891+ static_cast <uint8_t >(this ->settings_ .last_vertiacal_swing ));
892+ mode_it = std::find (VERTICAL_SWING_MODES_ORDER .begin (), VERTICAL_SWING_MODES_ORDER .end (),
893+ hon_protocol::VerticalSwingMode::CENTER );
894+ if (mode_it == VERTICAL_SWING_MODES_ORDER .end ()) {
895+ return ;
896+ }
889897 }
890898 this ->vertical_airflow_select_ ->publish_state (static_cast <size_t >(mode_it - VERTICAL_SWING_MODES_ORDER .begin ()));
891899}
@@ -894,18 +902,16 @@ void HonClimate::update_horizontal_airflow_select_state_() {
894902 if (this ->horizontal_airflow_select_ == nullptr ) {
895903 return ;
896904 }
897- if (!this ->current_horizontal_swing_ .has_value () ||
898- !horizontal_swing_mode_is_selectable_ (this ->current_horizontal_swing_ .value ())) {
899- clear_airflow_select_state_ (this ->horizontal_airflow_select_ );
900- return ;
901- }
902905 auto mode_it = std::find (HORIZONTAL_SWING_MODES_ORDER .begin (), HORIZONTAL_SWING_MODES_ORDER .end (),
903- this ->current_horizontal_swing_ . value () );
906+ this ->settings_ . last_horizontal_swing );
904907 if (mode_it == HORIZONTAL_SWING_MODES_ORDER .end ()) {
905- ESP_LOGW (TAG , " Unsupported horizontal airflow mode: 0x%X" ,
906- static_cast <uint8_t >(this ->current_horizontal_swing_ .value ()));
907- clear_airflow_select_state_ (this ->horizontal_airflow_select_ );
908- return ;
908+ ESP_LOGW (TAG , " Unsupported saved horizontal airflow mode: 0x%X, fallback to Center" ,
909+ static_cast <uint8_t >(this ->settings_ .last_horizontal_swing ));
910+ mode_it = std::find (HORIZONTAL_SWING_MODES_ORDER .begin (), HORIZONTAL_SWING_MODES_ORDER .end (),
911+ hon_protocol::HorizontalSwingMode::CENTER );
912+ if (mode_it == HORIZONTAL_SWING_MODES_ORDER .end ()) {
913+ return ;
914+ }
909915 }
910916 this ->horizontal_airflow_select_ ->publish_state (static_cast <size_t >(mode_it - HORIZONTAL_SWING_MODES_ORDER .begin ()));
911917}
@@ -1334,8 +1340,10 @@ void HonClimate::fill_control_messages_queue_() {
13341340 (uint8_t ) hon_protocol::DataParameters::SET_POINT ,
13351341 buffer, 2 );
13361342 }
1343+ ClimateSwingMode target_swing_mode = this ->swing_mode ;
13371344 // Vertical swing mode
13381345 if (climate_control.swing_mode .has_value ()) {
1346+ target_swing_mode = climate_control.swing_mode .value ();
13391347 uint8_t vertical_swing_buf[] = {0x00 , (uint8_t ) hon_protocol::VerticalSwingMode::AUTO };
13401348 uint8_t horizontal_swing_buf[] = {0x00 , (uint8_t ) hon_protocol::HorizontalSwingMode::AUTO };
13411349 switch (climate_control.swing_mode .value ()) {
@@ -1361,6 +1369,26 @@ void HonClimate::fill_control_messages_queue_() {
13611369 (uint8_t ) hon_protocol::DataParameters::VERTICAL_SWING_MODE ,
13621370 vertical_swing_buf, 2 );
13631371 }
1372+ if (this ->pending_vertical_direction_ .has_value ()) {
1373+ if (!vertical_axis_is_auto_ (target_swing_mode)) {
1374+ uint8_t vertical_swing_buf[] = {0x00 , (uint8_t ) this ->pending_vertical_direction_ .value ()};
1375+ this ->control_messages_queue_ .emplace (haier_protocol::FrameType::CONTROL ,
1376+ (uint16_t ) hon_protocol::SubcommandsControl::SET_SINGLE_PARAMETER +
1377+ (uint8_t ) hon_protocol::DataParameters::VERTICAL_SWING_MODE ,
1378+ vertical_swing_buf, 2 );
1379+ }
1380+ this ->pending_vertical_direction_ .reset ();
1381+ }
1382+ if (this ->pending_horizontal_direction_ .has_value ()) {
1383+ if (!horizontal_axis_is_auto_ (target_swing_mode)) {
1384+ uint8_t horizontal_swing_buf[] = {0x00 , (uint8_t ) this ->pending_horizontal_direction_ .value ()};
1385+ this ->control_messages_queue_ .emplace (haier_protocol::FrameType::CONTROL ,
1386+ (uint16_t ) hon_protocol::SubcommandsControl::SET_SINGLE_PARAMETER +
1387+ (uint8_t ) hon_protocol::DataParameters::HORIZONTAL_SWING_MODE ,
1388+ horizontal_swing_buf, 2 );
1389+ }
1390+ this ->pending_horizontal_direction_ .reset ();
1391+ }
13641392 // Fan mode
13651393 if (climate_control.fan_mode .has_value ()) {
13661394 switch (climate_control.fan_mode .value ()) {
0 commit comments