Skip to content

Commit 072b7cf

Browse files
committed
Airflow control select improvements
1 parent a5bb594 commit 072b7cf

16 files changed

Lines changed: 328 additions & 224 deletions

README.rst

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ Turn off health mode.
291291
``climate.haier.set_vertical_airflow`` Action
292292
*********************************************
293293

294-
(supported only by hOn) Set direction for vertical airflow if the vertical swing is disabled. Possible values: Health_Up, Max_Up, Up, Center, Down, Health_Down.
294+
(supported only by hOn) Set direction for vertical airflow if the vertical swing is disabled. Possible values: ``Auto``, ``Health_Up``, ``Max_Up``, ``Up``, ``Center``, ``Down``, ``Max_Down``, ``Health_Down``.
295295

296296
.. code-block:: yaml
297297
@@ -304,15 +304,15 @@ Turn off health mode.
304304
``climate.haier.set_horizontal_airflow`` Action
305305
***********************************************
306306

307-
(supported only by hOn) Set direction for horizontal airflow if the horizontal swing is disabled. Possible values: ``Max_Left``, ``Left``, ``Center``, ``Right``, ``Max_Right``.
307+
(supported only by hOn) Set direction for horizontal airflow if the horizontal swing is disabled. Possible values: ``Auto``, ``Max_Left``, ``Left``, ``Center``, ``Right``, ``Max_Right``.
308308

309309
.. code-block:: yaml
310310
311311
on_...:
312312
then:
313313
- climate.haier.set_horizontal_airflow:
314314
id: device_id
315-
vertical_airflow: Right
315+
horizontal_airflow: Right
316316
317317
``climate.haier.start_self_cleaning`` Action
318318
********************************************
@@ -512,31 +512,43 @@ Haier Climate Select
512512

513513
Select components to support vertical and horizontal airflow directions settings for Haier AC.
514514

515+
Vertical airflow select:
516+
515517
.. code-block:: yaml
516518
517-
# Example configuration entry
518519
select:
519520
- platform: haier
520-
horizontal_airflow:
521-
name: Haier airflow horizontal
521+
haier_id: ${device_id}
522522
vertical_airflow:
523-
name: Haier airflow vertical
523+
name: ${device_name} airflow vertical
524+
525+
526+
Horizontal airflow select:
527+
528+
.. code-block:: yaml
529+
530+
select:
531+
- platform: haier
532+
haier_id: ${device_id}
533+
horizontal_airflow:
534+
name: ${device_name} airflow horizontal
535+
524536
525537
Configuration variables:
526538
------------------------
527539

528540
- **haier_id** (**Required**, `ID <https://esphome.io/guides/configuration-types.html#config-id>`_): The id of Haier climate component
529-
- **horizontal_airflow** (*Optional*): (supported only by hOn) Select component to control horizontal airflow mode (if supported by AC).
541+
- **horizontal_airflow** (*Optional*): (supported only by hOn) Select component to control horizontal airflow mode (if supported by AC). The current state becomes ``Auto`` while horizontal swing is enabled.
530542
All options from `Select <https://esphome.io/components/select/index.html#base-select-configuration>`_.
531-
- **vertical_airflow** (*Optional*): (supported only by hOn) Select component to control vertical airflow mode (if supported by AC).
543+
- **vertical_airflow** (*Optional*): (supported only by hOn) Select component to control vertical airflow mode (if supported by AC). The current state becomes ``Auto`` while vertical swing is enabled.
532544
All options from `Select <https://esphome.io/components/select/index.html#base-select-configuration>`_.
533545

534546
.. Generated from esphome-docs/switch/haier.rst
535547
536548
Haier Climate Switches
537549
======================
538550

539-
Switches to support additional features for Haier AC.
551+
Switches to support additional features for Haier AC.
540552

541553
.. code-block:: yaml
542554
@@ -615,6 +627,7 @@ See Also
615627
- `ESPHome Haier Climate Binary Sensors <https://esphome.io/components/binary_sensor/haier.html>`_
616628
- `ESPHome Haier Climate Text Sensors <https://esphome.io/components/text_sensor/haier.html>`_
617629
- `ESPHome Haier Climate Buttons <https://esphome.io/components/button/haier.html>`_
630+
- `ESPHome Haier Climate Select <https://esphome.io/components/select/haier.html>`_
618631
- `ESPHome Haier Climate Switches <https://esphome.io/components/switch/haier.html>`_
619632
- `Climate Component <https://esphome.io/components/climate/>`_
620633
- `API Reference <https://esphome.io/api/haier__base_8h.html>`_

components/haier/hon_climate.cpp

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <algorithm>
2+
#include <array>
13
#include <chrono>
24
#include <string>
35
#include "esphome/components/climate/climate.h"
@@ -32,6 +34,32 @@ const std::vector<hon_protocol::HorizontalSwingMode> HORIZONTAL_SWING_MODES_ORDE
3234
hon_protocol::HorizontalSwingMode::RIGHT,
3335
hon_protocol::HorizontalSwingMode::MAX_RIGHT,
3436
};
37+
38+
static const std::array<const char *, 8> VERTICAL_SWING_MODE_OPTIONS = {
39+
"Auto", "Health Up", "Max Up", "Up", "Center", "Down", "Max Down", "Health Down"};
40+
static const std::array<const char *, 6> HORIZONTAL_SWING_MODE_OPTIONS = {
41+
"Auto", "Max Left", "Left", "Center", "Right", "Max Right"};
42+
43+
static std::string vertical_swing_mode_to_string_(hon_protocol::VerticalSwingMode mode) {
44+
if (mode == hon_protocol::VerticalSwingMode::AUTO_SPECIAL) {
45+
return VERTICAL_SWING_MODE_OPTIONS[0];
46+
}
47+
auto mode_it = std::find(VERTICAL_SWING_MODES_ORDER.begin(), VERTICAL_SWING_MODES_ORDER.end(), mode);
48+
if (mode_it == VERTICAL_SWING_MODES_ORDER.end()) {
49+
ESP_LOGW("haier.climate", "Unsupported vertical airflow mode: 0x%X", static_cast<uint8_t>(mode));
50+
return VERTICAL_SWING_MODE_OPTIONS[4];
51+
}
52+
return VERTICAL_SWING_MODE_OPTIONS[mode_it - VERTICAL_SWING_MODES_ORDER.begin()];
53+
}
54+
55+
static std::string horizontal_swing_mode_to_string_(hon_protocol::HorizontalSwingMode mode) {
56+
auto mode_it = std::find(HORIZONTAL_SWING_MODES_ORDER.begin(), HORIZONTAL_SWING_MODES_ORDER.end(), mode);
57+
if (mode_it == HORIZONTAL_SWING_MODES_ORDER.end()) {
58+
ESP_LOGW("haier.climate", "Unsupported horizontal airflow mode: 0x%X", static_cast<uint8_t>(mode));
59+
return HORIZONTAL_SWING_MODE_OPTIONS[3];
60+
}
61+
return HORIZONTAL_SWING_MODE_OPTIONS[mode_it - HORIZONTAL_SWING_MODES_ORDER.begin()];
62+
}
3563
#endif // USE_SELECT
3664

3765
static const char *const TAG = "haier.climate";
@@ -843,17 +871,18 @@ void HonClimate::set_quiet_mode_switch(switch_::Switch *sw) {
843871

844872
#ifdef USE_SELECT
845873
void HonClimate::set_vertical_airflow_select(select::Select *sel) {
846-
// this->vertical_airflow_select_ = sel;
847-
// if (this->current_vertical_swing_.has_value() && (this->vertical_airflow_select_ != nullptr)) {
848-
// this->vertical_airflow_select_->publish_state(VerticalAirflowSelect::vertical_airflow_to_string(this->current_vertical_swing_.value()));
849-
// }
874+
this->vertical_airflow_select_ = sel;
875+
if ((this->vertical_airflow_select_ != nullptr) && this->current_vertical_swing_.has_value()) {
876+
this->vertical_airflow_select_->publish_state(vertical_swing_mode_to_string_(this->current_vertical_swing_.value()));
877+
}
850878
}
851879

852880
void HonClimate::set_horizontal_airflow_select(select::Select *sel) {
853-
// this->horizontal_airflow_select_ = sel;
854-
// if (this->horizontal_airflow_select_ != nullptr) {
855-
// this->horizontal_airflow_select_->publish_state((uint8_t) this->settings_.last_horizontal_swing);
856-
// }
881+
this->horizontal_airflow_select_ = sel;
882+
if ((this->horizontal_airflow_select_ != nullptr) && this->current_horizontal_swing_.has_value()) {
883+
this->horizontal_airflow_select_->publish_state(
884+
horizontal_swing_mode_to_string_(this->current_horizontal_swing_.value()));
885+
}
857886
}
858887
#endif // USE_SELECT
859888

@@ -1101,6 +1130,15 @@ haier_protocol::HandlerError HonClimate::process_status_message_(const uint8_t *
11011130
this->settings_.last_horizontal_swing = this->current_horizontal_swing_.value();
11021131
this->hon_rtc_.save(&this->settings_);
11031132
}
1133+
#ifdef USE_SELECT
1134+
if (this->vertical_airflow_select_ != nullptr) {
1135+
this->vertical_airflow_select_->publish_state(vertical_swing_mode_to_string_(this->current_vertical_swing_.value()));
1136+
}
1137+
if (this->horizontal_airflow_select_ != nullptr) {
1138+
this->horizontal_airflow_select_->publish_state(
1139+
horizontal_swing_mode_to_string_(this->current_horizontal_swing_.value()));
1140+
}
1141+
#endif // USE_SELECT
11041142
should_publish = should_publish || (old_swing_mode != this->swing_mode);
11051143
}
11061144
this->last_valid_status_timestamp_ = std::chrono::steady_clock::now();

components/haier/select/__init__.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@
22
import esphome.config_validation as cv
33
from esphome.components import select
44
from esphome.const import (
5-
CONF_OPTIONS,
65
ENTITY_CATEGORY_CONFIG,
76
)
87
from ..climate import (
98
CONF_HAIER_ID,
109
HonClimate,
1110
haier_ns,
12-
hon_protocol_ns,
1311
CONF_VERTICAL_AIRFLOW,
1412
CONF_HORIZONTAL_AIRFLOW,
1513
)
@@ -18,9 +16,6 @@
1816
VerticalAirflowSelect = haier_ns.class_("VerticalAirflowSelect", select.Select)
1917
HorizontalAirflowSelect = haier_ns.class_("HorizontalAirflowSelect", select.Select)
2018

21-
VerticalSwingMode = hon_protocol_ns.enum("VerticalSwingMode", True)
22-
HorizontalSwingMode = hon_protocol_ns.enum("HorizontalSwingMode", True)
23-
2419
# Additional icons
2520
ICON_ARROW_HORIZONTAL = "mdi:arrow-expand-horizontal"
2621
ICON_ARROW_VERTICAL = "mdi:arrow-expand-vertical"
@@ -62,7 +57,7 @@
6257
)
6358

6459
async def to_code(config):
65-
full_id, parent = await cg.get_variable_with_full_id(config[CONF_HAIER_ID])
60+
parent = await cg.get_variable(config[CONF_HAIER_ID])
6661

6762
if conf := config.get(CONF_VERTICAL_AIRFLOW):
6863
sel_var = await select.new_select(conf, options=AIRFLOW_VERTICAL_DIRECTION_OPTIONS)

components/haier/select/horizontal_airflow.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
#include "horizontal_airflow.h"
2+
3+
#include <algorithm>
4+
25
#include <protocol/haier_protocol.h>
36

47
namespace esphome {
58
namespace haier {
69

710
void HorizontalAirflowSelect::control(const std::string &value) {
811
hon_protocol::HorizontalSwingMode state;
9-
static const std::vector<std::string> options = this->traits.get_options();
10-
auto item_it = std::find(options.begin(), options.end(), value);
12+
const auto &options = this->traits.get_options();
13+
auto item_it = std::find_if(options.begin(), options.end(), [&value](const char *opt) { return value == opt; });
1114
if (item_it == options.end()) {
1215
ESP_LOGE("haier", "Invalid horizontal airflow mode: %s", value.c_str());
1316
return;

components/haier/select/vertical_airflow.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
#include "vertical_airflow.h"
2+
3+
#include <algorithm>
4+
25
#include <protocol/haier_protocol.h>
36

47
namespace esphome {
58
namespace haier {
69

710
void VerticalAirflowSelect::control(const std::string &value) {
811
hon_protocol::VerticalSwingMode state;
9-
static const std::vector<std::string> options = this->traits.get_options();
10-
auto item_it = std::find(options.begin(), options.end(), value);
12+
const auto &options = this->traits.get_options();
13+
auto item_it = std::find_if(options.begin(), options.end(), [&value](const char *opt) { return value == opt; });
1114
if (item_it == options.end()) {
1215
ESP_LOGE("haier", "Invalid vertical airflow mode: %s", value.c_str());
1316
return;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
select:
22
- platform: haier
3+
haier_id: ${device_id}
34
horizontal_airflow:
45
name: ${device_name} airflow horizontal
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
select:
22
- platform: haier
3+
haier_id: ${device_id}
34
vertical_airflow:
45
name: ${device_name} airflow vertical

docs/esphome-docs/climate/haier.rst

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -57,53 +57,53 @@ This component requires a :ref:`UART bus <uart>` to be setup.
5757

5858
.. code-block:: yaml
5959
60-
# Example configuration entry
61-
climate:
62-
- platform: haier
63-
id: haier_ac
64-
protocol: hon
65-
name: Haier AC
66-
uart_id: ac_port
67-
wifi_signal: true
68-
display: true
69-
visual:
70-
min_temperature: 16 °C
71-
max_temperature: 30 °C
72-
temperature_step: 1 °C
73-
supported_modes:
74-
- 'OFF'
75-
- HEAT_COOL
76-
- COOL
77-
- HEAT
78-
- DRY
79-
- FAN_ONLY
80-
supported_swing_modes:
81-
- 'OFF'
82-
- VERTICAL
83-
- HORIZONTAL
84-
- BOTH
85-
supported_presets:
86-
- AWAY
87-
- BOOST
88-
- SLEEP
89-
on_alarm_start:
90-
then:
91-
- logger.log:
92-
level: WARN
93-
format: "Alarm activated. Code: %d. Message: \"%s\""
94-
args: [ code, message]
95-
on_alarm_end:
96-
then:
97-
- logger.log:
98-
level: INFO
99-
format: "Alarm deactivated. Code: %d. Message: \"%s\""
100-
args: [ code, message]
101-
on_status_message:
102-
then:
103-
- logger.log:
104-
level: INFO
105-
format: "New status message received, size=%d, subcmd=%02X%02X"
106-
args: [ 'data_size', 'data[0]', 'data[1]' ]
60+
# Example configuration entry
61+
climate:
62+
- platform: haier
63+
id: haier_ac
64+
protocol: hon
65+
name: Haier AC
66+
uart_id: ac_port
67+
wifi_signal: true
68+
display: true
69+
visual:
70+
min_temperature: 16 °C
71+
max_temperature: 30 °C
72+
temperature_step: 1 °C
73+
supported_modes:
74+
- 'OFF'
75+
- HEAT_COOL
76+
- COOL
77+
- HEAT
78+
- DRY
79+
- FAN_ONLY
80+
supported_swing_modes:
81+
- 'OFF'
82+
- VERTICAL
83+
- HORIZONTAL
84+
- BOTH
85+
supported_presets:
86+
- AWAY
87+
- BOOST
88+
- SLEEP
89+
on_alarm_start:
90+
then:
91+
- logger.log:
92+
level: WARN
93+
format: "Alarm activated. Code: %d. Message: \"%s\""
94+
args: [ code, message]
95+
on_alarm_end:
96+
then:
97+
- logger.log:
98+
level: INFO
99+
format: "Alarm deactivated. Code: %d. Message: \"%s\""
100+
args: [ code, message]
101+
on_status_message:
102+
then:
103+
- logger.log:
104+
level: INFO
105+
format: "New status message received, size=%d, subcmd=%02X%02X"
106+
args: [ 'data_size', 'data[0]', 'data[1]' ]
107107
108108
109109
Configuration variables:
@@ -291,7 +291,7 @@ Turn off health mode.
291291
``climate.haier.set_vertical_airflow`` Action
292292
*********************************************
293293

294-
(supported only by hOn) Set direction for vertical airflow if the vertical swing is disabled. Possible values: Health_Up, Max_Up, Up, Center, Down, Health_Down.
294+
(supported only by hOn) Set direction for vertical airflow if the vertical swing is disabled. Possible values: ``Auto``, ``Health_Up``, ``Max_Up``, ``Up``, ``Center``, ``Down``, ``Max_Down``, ``Health_Down``.
295295

296296
.. code-block:: yaml
297297
@@ -304,15 +304,15 @@ Turn off health mode.
304304
``climate.haier.set_horizontal_airflow`` Action
305305
***********************************************
306306

307-
(supported only by hOn) Set direction for horizontal airflow if the horizontal swing is disabled. Possible values: ``Max_Left``, ``Left``, ``Center``, ``Right``, ``Max_Right``.
307+
(supported only by hOn) Set direction for horizontal airflow if the horizontal swing is disabled. Possible values: ``Auto``, ``Max_Left``, ``Left``, ``Center``, ``Right``, ``Max_Right``.
308308

309309
.. code-block:: yaml
310310
311311
on_...:
312312
then:
313313
- climate.haier.set_horizontal_airflow:
314314
id: device_id
315-
vertical_airflow: Right
315+
horizontal_airflow: Right
316316
317317
``climate.haier.start_self_cleaning`` Action
318318
********************************************
@@ -344,6 +344,7 @@ See Also
344344
- :doc:`Haier Climate Binary Sensors </components/binary_sensor/haier>`
345345
- :doc:`Haier Climate Text Sensors </components/text_sensor/haier>`
346346
- :doc:`Haier Climate Buttons </components/button/haier>`
347+
- :doc:`Haier Climate Select </components/select/haier>`
347348
- :doc:`Haier Climate Switches </components/switch/haier>`
348349
- :doc:`/components/climate/index`
349350
- :apiref:`haier/climate/haier_base.h`

0 commit comments

Comments
 (0)