Skip to content

Commit e86da60

Browse files
committed
Added debounce for select
1 parent fcef064 commit e86da60

3 files changed

Lines changed: 79 additions & 24 deletions

File tree

components/haier/hon_climate.cpp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ constexpr int PROTOCOL_OUTDOOR_TEMPERATURE_OFFSET = -64;
5050
constexpr uint8_t CONTROL_MESSAGE_RETRIES = 5;
5151
constexpr std::chrono::milliseconds CONTROL_MESSAGE_RETRIES_INTERVAL = std::chrono::milliseconds(500);
5252
constexpr size_t ALARM_STATUS_REQUEST_INTERVAL_MS = 600000;
53+
constexpr size_t AIRFLOW_SELECT_DEBOUNCE_MS = 10000;
5354
const uint8_t ONE_BUF[] = {0x00, 0x01};
5455
const 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

130139
esphome::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

156173
std::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) {

components/haier/hon_climate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ class HonClimate : public HaierClimateBase {
214214
uint8_t big_data_counter_{0};
215215
esphome::optional<hon_protocol::VerticalSwingMode> current_vertical_swing_{};
216216
esphome::optional<hon_protocol::HorizontalSwingMode> current_horizontal_swing_{};
217+
esphome::optional<std::chrono::steady_clock::time_point> vertical_direction_set_time_{};
218+
esphome::optional<std::chrono::steady_clock::time_point> horizontal_direction_set_time_{};
217219
HonSettings settings_{};
218220
ESPPreferenceObject hon_rtc_;
219221
SwitchState quiet_mode_state_{SwitchState::OFF};

docs/hon_example.rst

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
1-
.. This file is automatically generated by ./docs/script/process_examples.py Python script.
2-
Please, don't change. In case you need to make corrections or changes change
3-
source documentation in ./doc folder or script.
4-
1+
.. This file is automatically generated by ./docs/script/process_examples.py Python script.
2+
Please, don't change. In case you need to make corrections or changes change
3+
source documentation in ./doc folder or script.
4+
55
Example of climate configuration for hOn protocol
66
=================================================
77

88
Configuration of your climate will depend on capabilities specific model.
99

1010
Minimal configuration will look like this:
1111

12-
.. code-block:: yaml
13-
12+
.. code-block:: yaml
13+
1414
uart:
1515
baud_rate: 9600
1616
tx_pin: 17
1717
rx_pin: 16
18-
18+
1919
climate:
2020
- platform: haier
2121
protocol: hon
2222
name: Haier hOn Climate
23-
23+
2424
2525
Maximum configuration witch will use all possible options will look like this:
2626

27-
.. code-block:: yaml
28-
27+
.. code-block:: yaml
28+
2929
uart:
3030
baud_rate: 9600
3131
tx_pin: 17
3232
rx_pin: 16
3333
id: haier_uart
34-
34+
3535
api:
3636
services:
3737
- service: turn_on
@@ -40,7 +40,7 @@ Maximum configuration witch will use all possible options will look like this:
4040
- service: turn_off
4141
then:
4242
- climate.haier.power_off: haier_ac
43-
43+
4444
climate:
4545
- platform: haier
4646
id: haier_ac
@@ -51,7 +51,7 @@ Maximum configuration witch will use all possible options will look like this:
5151
visual:
5252
min_temperature: 16 °C
5353
max_temperature: 30 °C
54-
temperature_step:
54+
temperature_step:
5555
target_temperature: 1
5656
current_temperature: 0.5
5757
supported_modes:
@@ -77,7 +77,7 @@ Maximum configuration witch will use all possible options will look like this:
7777
domain: climate
7878
name: Haier hOn Climate
7979
data_template:
80-
message: "Alarm activated ({{ alarm_code }}): {{alarm_message}}"
80+
message: "Alarm activated ({{ alarm_code }}): {{alarm_message}}"
8181
variables:
8282
alarm_message: !lambda "return message;"
8383
alarm_code: !lambda "return code;"
@@ -98,27 +98,27 @@ Maximum configuration witch will use all possible options will look like this:
9898
domain: climate
9999
name: Haier hOn Climate
100100
data_template:
101-
message: "Alarm deactivated ({{ alarm_code }}): {{alarm_message}}"
101+
message: "Alarm deactivated ({{ alarm_code }}): {{alarm_message}}"
102102
variables:
103103
alarm_message: !lambda "return message;"
104104
alarm_code: !lambda "return code;"
105-
105+
106106
button:
107107
- platform: haier
108108
haier_id: haier_ac
109109
self_cleaning:
110110
name: Haier hOn Climate start self cleaning
111111
steri_cleaning:
112112
name: Haier hOn Climate start 56°C steri-cleaning
113-
113+
114114
text_sensor:
115115
- platform: haier
116116
haier_id: haier_ac
117117
cleaning_status:
118118
name: Haier hOn Climate cleaning status
119119
protocol_version:
120120
name: Haier hOn Climate protocol version
121-
121+
122122
switch:
123123
- platform: haier
124124
beeper:
@@ -129,7 +129,7 @@ Maximum configuration witch will use all possible options will look like this:
129129
name: Haier hOn Climate display
130130
quiet_mode:
131131
name: Haier hOn Climate quiet mode
132-
132+
133133
select:
134134
- platform: template
135135
id: haier_ac_vertical_direction
@@ -145,6 +145,7 @@ Maximum configuration witch will use all possible options will look like this:
145145
- Down
146146
- Max Down
147147
- Health Down
148+
- Auto
148149
lambda: >-
149150
switch (id(haier_ac).get_vertical_airflow().value_or(esphome::haier::hon_protocol::VerticalSwingMode::CENTER))
150151
{
@@ -163,6 +164,9 @@ Maximum configuration witch will use all possible options will look like this:
163164
return std::string("Max Down");
164165
case esphome::haier::hon_protocol::VerticalSwingMode::HEALTH_DOWN:
165166
return std::string("Health Down");
167+
case esphome::haier::hon_protocol::VerticalSwingMode::AUTO:
168+
case esphome::haier::hon_protocol::VerticalSwingMode::AUTO_SPECIAL:
169+
return std::string("Auto");
166170
}
167171
set_action:
168172
- climate.haier.set_vertical_airflow:
@@ -180,6 +184,8 @@ Maximum configuration witch will use all possible options will look like this:
180184
return esphome::haier::hon_protocol::VerticalSwingMode::MAX_DOWN;
181185
else if (x == "Health Down")
182186
return esphome::haier::hon_protocol::VerticalSwingMode::HEALTH_DOWN;
187+
else if (x == "Auto")
188+
return esphome::haier::hon_protocol::VerticalSwingMode::AUTO;
183189
else
184190
return esphome::haier::hon_protocol::VerticalSwingMode::CENTER;
185191
- platform: template
@@ -194,6 +200,7 @@ Maximum configuration witch will use all possible options will look like this:
194200
- Center
195201
- Right
196202
- Max Right
203+
- Auto
197204
lambda: >-
198205
switch (id(haier_ac).get_horizontal_airflow().value_or(esphome::haier::hon_protocol::HorizontalSwingMode::CENTER))
199206
{
@@ -208,6 +215,8 @@ Maximum configuration witch will use all possible options will look like this:
208215
return std::string("Right");
209216
case esphome::haier::hon_protocol::HorizontalSwingMode::MAX_RIGHT:
210217
return std::string("Max Right");
218+
case esphome::haier::hon_protocol::HorizontalSwingMode::AUTO:
219+
return std::string("Auto");
211220
}
212221
set_action:
213222
- climate.haier.set_horizontal_airflow:
@@ -221,9 +230,11 @@ Maximum configuration witch will use all possible options will look like this:
221230
return esphome::haier::hon_protocol::HorizontalSwingMode::RIGHT;
222231
else if (x == "Max Right")
223232
return esphome::haier::hon_protocol::HorizontalSwingMode::MAX_RIGHT;
233+
else if (x == "Auto")
234+
return esphome::haier::hon_protocol::HorizontalSwingMode::AUTO;
224235
else
225236
return esphome::haier::hon_protocol::HorizontalSwingMode::CENTER;
226-
237+
227238
sensor:
228239
- platform: haier
229240
haier_id: haier_ac
@@ -249,7 +260,7 @@ Maximum configuration witch will use all possible options will look like this:
249260
name: Haier hOn Climate outdoor temperature
250261
power:
251262
name: Haier hOn Climate Power
252-
263+
253264
binary_sensor:
254265
- platform: haier
255266
haier_id: haier_ac
@@ -265,4 +276,4 @@ Maximum configuration witch will use all possible options will look like this:
265276
name: Haier hOn Climate Indoor Fan Status
266277
outdoor_fan_status:
267278
name: Haier hOn Climate Outdoor Fan Status
268-
279+

0 commit comments

Comments
 (0)