@@ -50,6 +50,7 @@ constexpr int PROTOCOL_OUTDOOR_TEMPERATURE_OFFSET = -64;
5050constexpr uint8_t CONTROL_MESSAGE_RETRIES = 5 ;
5151constexpr std::chrono::milliseconds CONTROL_MESSAGE_RETRIES_INTERVAL = std::chrono::milliseconds(500 );
5252constexpr size_t ALARM_STATUS_REQUEST_INTERVAL_MS = 600000 ;
53+ constexpr size_t AIRFLOW_SELECT_DEBOUNCE_MS = 10000 ;
5354const uint8_t ONE_BUF [] = {0x00 , 0x01 };
5455const uint8_t ZERO_BUF [] = {0x00 , 0x00 };
5556
@@ -107,6 +108,13 @@ esphome::optional<hon_protocol::VerticalSwingMode> HonClimate::get_vertical_airf
107108 (this ->current_vertical_swing_ .value () == hon_protocol::VerticalSwingMode::AUTO_SPECIAL )) {
108109 return this ->settings_ .last_vertical_swing ;
109110 }
111+ // During debounce period after user set, return saved setting to avoid jump-back
112+ if (this ->vertical_direction_set_time_ .has_value () &&
113+ std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now () -
114+ this ->vertical_direction_set_time_ .value ())
115+ .count () < AIRFLOW_SELECT_DEBOUNCE_MS ) {
116+ return this ->settings_ .last_vertical_swing ;
117+ }
110118 return this ->current_vertical_swing_ ;
111119};
112120
@@ -125,6 +133,7 @@ void HonClimate::set_vertical_airflow(hon_protocol::VerticalSwingMode direction)
125133#ifdef USE_SELECT
126134 this ->update_vertical_airflow_select_state_ ();
127135#endif
136+ this ->vertical_direction_set_time_ = std::chrono::steady_clock::now ();
128137}
129138
130139esphome::optional<hon_protocol::HorizontalSwingMode> HonClimate::get_horizontal_airflow () const {
@@ -134,6 +143,13 @@ esphome::optional<hon_protocol::HorizontalSwingMode> HonClimate::get_horizontal_
134143 if (this ->current_horizontal_swing_ .value () == hon_protocol::HorizontalSwingMode::AUTO ) {
135144 return this ->settings_ .last_horizontal_swing ;
136145 }
146+ // During debounce period after user set, return saved setting to avoid jump-back
147+ if (this ->horizontal_direction_set_time_ .has_value () &&
148+ std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now () -
149+ this ->horizontal_direction_set_time_ .value ())
150+ .count () < AIRFLOW_SELECT_DEBOUNCE_MS ) {
151+ return this ->settings_ .last_horizontal_swing ;
152+ }
137153 return this ->current_horizontal_swing_ ;
138154}
139155
@@ -151,6 +167,7 @@ void HonClimate::set_horizontal_airflow(hon_protocol::HorizontalSwingMode direct
151167#ifdef USE_SELECT
152168 this ->update_horizontal_airflow_select_state_ ();
153169#endif
170+ this ->horizontal_direction_set_time_ = std::chrono::steady_clock::now ();
154171}
155172
156173std::string HonClimate::get_cleaning_status_text () const {
@@ -920,6 +937,13 @@ void HonClimate::update_vertical_airflow_select_state_() {
920937 if (this ->vertical_airflow_select_ == nullptr ) {
921938 return ;
922939 }
940+ // Skip update during debounce period after user-initiated change
941+ if (this ->vertical_direction_set_time_ .has_value () &&
942+ std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now () -
943+ this ->vertical_direction_set_time_ .value ())
944+ .count () < AIRFLOW_SELECT_DEBOUNCE_MS ) {
945+ return ;
946+ }
923947 auto mode_it = std::find (VERTICAL_SWING_MODES_ORDER .begin (), VERTICAL_SWING_MODES_ORDER .end (),
924948 this ->settings_ .last_vertical_swing );
925949 if (mode_it == VERTICAL_SWING_MODES_ORDER .end ()) {
@@ -938,6 +962,13 @@ void HonClimate::update_horizontal_airflow_select_state_() {
938962 if (this ->horizontal_airflow_select_ == nullptr ) {
939963 return ;
940964 }
965+ // Skip update during debounce period after user-initiated change
966+ if (this ->horizontal_direction_set_time_ .has_value () &&
967+ std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now () -
968+ this ->horizontal_direction_set_time_ .value ())
969+ .count () < AIRFLOW_SELECT_DEBOUNCE_MS ) {
970+ return ;
971+ }
941972 auto mode_it = std::find (HORIZONTAL_SWING_MODES_ORDER .begin (), HORIZONTAL_SWING_MODES_ORDER .end (),
942973 this ->settings_ .last_horizontal_swing );
943974 if (mode_it == HORIZONTAL_SWING_MODES_ORDER .end ()) {
@@ -1187,10 +1218,21 @@ haier_protocol::HandlerError HonClimate::process_status_message_(const uint8_t *
11871218 // Saving last known non auto mode for vertical and horizontal swing
11881219 this ->current_vertical_swing_ = (hon_protocol::VerticalSwingMode) packet.control .vertical_swing_mode ;
11891220 this ->current_horizontal_swing_ = (hon_protocol::HorizontalSwingMode) packet.control .horizontal_swing_mode ;
1190- bool save_vertical = (this ->current_vertical_swing_ .value () != hon_protocol::VerticalSwingMode::AUTO ) &&
1221+ auto now = std::chrono::steady_clock::now ();
1222+ bool debounce_vertical = this ->vertical_direction_set_time_ .has_value () &&
1223+ std::chrono::duration_cast<std::chrono::milliseconds>(
1224+ now - this ->vertical_direction_set_time_ .value ())
1225+ .count () < AIRFLOW_SELECT_DEBOUNCE_MS ;
1226+ bool debounce_horizontal = this ->horizontal_direction_set_time_ .has_value () &&
1227+ std::chrono::duration_cast<std::chrono::milliseconds>(
1228+ now - this ->horizontal_direction_set_time_ .value ())
1229+ .count () < AIRFLOW_SELECT_DEBOUNCE_MS ;
1230+ bool save_vertical = !debounce_vertical &&
1231+ (this ->current_vertical_swing_ .value () != hon_protocol::VerticalSwingMode::AUTO ) &&
11911232 (this ->current_vertical_swing_ .value () != hon_protocol::VerticalSwingMode::AUTO_SPECIAL ) &&
11921233 (this ->current_vertical_swing_ .value () != this ->settings_ .last_vertical_swing );
1193- bool save_horizontal = (this ->current_horizontal_swing_ .value () != hon_protocol::HorizontalSwingMode::AUTO ) &&
1234+ bool save_horizontal = !debounce_horizontal &&
1235+ (this ->current_horizontal_swing_ .value () != hon_protocol::HorizontalSwingMode::AUTO ) &&
11941236 (this ->current_horizontal_swing_ .value () != this ->settings_ .last_horizontal_swing );
11951237 if (save_vertical || save_horizontal) {
11961238 if (save_vertical) {
0 commit comments