ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
haier_tundra.cpp
Go to the documentation of this file.
1#include "haier_tundra.h"
2
3namespace esphome::haier_tundra {
4
5// Number of bytes in decoded packet sans checksum
6static constexpr uint8_t HAIER_TUNDRA_FRAME_SIZE = 13;
7
9 // Button value does not seem to matter too much except
10 // when toggling light, as it has no bit flag of its own
11 // So in the default case we can simply set it to POWER
12 this->transmit_(HAIER_BUTTON_POWER);
13}
14
15void HaierTundra::transmit_(uint8_t button) {
16 // Force Quiet and Turbo off if we're not in Cool or Heat mode
18#ifdef USE_SWITCH
19 if (this->quiet_mode_switch_ != nullptr) {
20 this->quiet_mode_switch_->publish_state(false);
21 }
22 if (this->turbo_mode_switch_ != nullptr) {
23 this->turbo_mode_switch_->publish_state(false);
24 }
25#endif
26
27 this->quiet_mode_ = false;
28 this->turbo_mode_ = false;
29 }
30
31 const uint8_t frame[HAIER_TUNDRA_FRAME_SIZE] = {
32 this->unit_,
33 static_cast<uint8_t>(this->temperature_() << 4 | this->vertical_swing_()),
34 static_cast<uint8_t>(this->horizontal_swing_() << 5),
35 static_cast<uint8_t>(this->health_() << 1),
36 static_cast<uint8_t>(this->power_() << 6),
37 static_cast<uint8_t>(this->fan_speed_() << 5),
38 static_cast<uint8_t>(this->quiet_() << 7 | this->turbo_() << 6),
39 static_cast<uint8_t>(this->operation_mode_() << 5),
40 0x00,
41 0x00,
42 static_cast<uint8_t>((button == HAIER_BUTTON_SELF_CLEAN ? 1 : 0) << 4),
43 0x00,
44 button,
45 };
46
47 auto transmit = this->transmitter_->transmit();
48 remote_base::HaierProtocol().encode(transmit.get_data(), frame, sizeof(frame));
49 transmit.perform();
50}
51
53 return (uint8_t) roundf(clamp<float>(this->target_temperature, HAIER_TEMP_MIN, HAIER_TEMP_MAX)) - HAIER_TEMP_MIN;
54}
55
57 if (this->mode == climate::CLIMATE_MODE_OFF) {
58 return HAIER_SWING_V_OFF;
59 }
60 switch (this->swing_mode) {
63 return HAIER_SWING_V_AUTO;
64 default:
65 if (this->mode == climate::CLIMATE_MODE_HEAT) {
66 return HAIER_SWING_V_1BOT;
67 }
68 return HAIER_SWING_V_1TOP; // Cool/Dry/Auto
69 }
70}
71
73 switch (this->swing_mode) {
76 return HAIER_SWING_H_AUTO;
77 default:
78 return HAIER_SWING_H_MIDDLE;
79 }
80}
81
82uint8_t HaierTundra::health_() { return this->health_mode_ ? 1 : 0; }
83
84uint8_t HaierTundra::power_() { return this->mode == climate::CLIMATE_MODE_OFF ? 0 : 1; }
85
87 switch (this->fan_mode.value_or(climate::CLIMATE_FAN_ON)) {
89 return HAIER_FAN_LOW;
91 return HAIER_FAN_MED;
93 return HAIER_FAN_HIGH;
95 default:
96 return HAIER_FAN_AUTO;
97 }
98}
99
100uint8_t HaierTundra::quiet_() { return this->quiet_mode_ ? 1 : 0; }
101
102uint8_t HaierTundra::turbo_() { return this->turbo_mode_ ? 1 : 0; }
103
105 switch (this->mode) {
107 return HAIER_MODE_COOL;
109 return HAIER_MODE_DRY;
111 return HAIER_MODE_HEAT;
113 return HAIER_MODE_FAN;
115 default:
116 return HAIER_MODE_AUTO;
117 }
118}
119
121 auto haier = remote_base::HaierProtocol().decode(data);
122 if (haier.has_value()) {
123 return this->on_haier_(*haier);
124 }
125 return false;
126}
127
129 // Verify frame length and header
130 if (haier.data.size() != HAIER_TUNDRA_FRAME_SIZE || haier.data[0] != this->unit_) {
131 return false;
132 }
133
134 this->target_temperature = this->get_temperature_(haier.data[1] >> 4);
135 this->swing_mode = this->get_swing_mode_(haier.data[1] & 0xF, haier.data[2] >> 5);
136 this->health_mode_ = haier.data[3] & 0x2;
137 this->mode = this->get_operation_mode_(haier.data[4] & 0x40, haier.data[7] >> 5);
138 this->fan_mode = this->get_fan_speed_(haier.data[5] >> 5);
139 this->quiet_mode_ = haier.data[6] & 0x80;
140 this->turbo_mode_ = haier.data[6] & 0x40;
141
142#ifdef USE_SWITCH
143 if (this->health_mode_switch_ != nullptr) {
144 this->health_mode_switch_->publish_state(this->health_mode_);
145 }
146 if (this->quiet_mode_switch_ != nullptr) {
147 this->quiet_mode_switch_->publish_state(this->quiet_mode_);
148 }
149 if (this->turbo_mode_switch_ != nullptr) {
150 this->turbo_mode_switch_->publish_state(this->turbo_mode_);
151 }
152#endif
153
154 this->publish_state();
155
156 return true;
157}
158
159float HaierTundra::get_temperature_(uint8_t temp) { return temp + HAIER_TEMP_MIN; }
160
162 if (swing_v == HAIER_SWING_V_AUTO) {
163 if (swing_h == HAIER_SWING_H_AUTO) {
165 }
166
168 } else if (swing_h == HAIER_SWING_H_AUTO) {
170 }
171
173}
174
176 if (!power) {
178 }
179
180 switch (mode) {
181 case HAIER_MODE_COOL:
183 case HAIER_MODE_DRY:
185 case HAIER_MODE_HEAT:
187 case HAIER_MODE_FAN:
189 case HAIER_MODE_AUTO:
190 default:
192 }
193}
194
196 switch (fan) {
197 case HAIER_FAN_LOW:
199 case HAIER_FAN_MED:
201 case HAIER_FAN_HIGH:
203 case HAIER_FAN_AUTO:
204 default:
206 }
207}
208
209void HaierTundra::set_health_mode(bool health, bool transmit) {
210 this->health_mode_ = health;
211
212 if (transmit && this->mode != climate::CLIMATE_MODE_OFF) {
213 this->transmit_(HAIER_BUTTON_HEALTH);
214 }
215}
216
217void HaierTundra::set_quiet_mode(bool quiet, bool transmit) {
218 // Quiet & Turbo cannot be enabled at the same time
219 if (quiet) {
220#ifdef USE_SWITCH
221 if (this->turbo_mode_switch_ != nullptr) {
222 this->turbo_mode_switch_->publish_state(false);
223 }
224#endif
225 this->turbo_mode_ = false;
226 }
227
228 this->quiet_mode_ = quiet;
229 if (transmit)
230 this->transmit_(HAIER_BUTTON_TURBO_QUIET);
231}
232
233void HaierTundra::set_turbo_mode(bool turbo, bool transmit) {
234 // Quiet & Turbo cannot be enabled at the same time
235 if (turbo) {
236#ifdef USE_SWITCH
237 if (this->quiet_mode_switch_ != nullptr) {
238 this->quiet_mode_switch_->publish_state(false);
239 }
240#endif
241 this->quiet_mode_ = false;
242 }
243
244 this->turbo_mode_ = turbo;
245 if (transmit)
246 this->transmit_(HAIER_BUTTON_TURBO_QUIET);
247}
248
250 if (this->mode != climate::CLIMATE_MODE_OFF) {
251 this->transmit_(HAIER_BUTTON_LIGHT);
252 }
253}
254
256 // Can be started when off
257 this->transmit_(HAIER_BUTTON_SELF_CLEAN);
258}
259
260} // namespace esphome::haier_tundra
BedjetMode mode
BedJet operating mode.
ClimateMode mode
The active mode of the climate device.
Definition climate.h:304
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition climate.h:298
float target_temperature
The target temperature of the climate device.
Definition climate.h:285
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition climate.h:310
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition climate.cpp:429
void set_quiet_mode(bool quiet, bool transmit=true)
climate::ClimateSwingMode get_swing_mode_(uint8_t swing_v, uint8_t swing_h)
bool on_haier_(const remote_base::HaierData &haier)
void set_turbo_mode(bool turbo, bool transmit=true)
climate::ClimateFanMode get_fan_speed_(uint8_t fan)
climate::ClimateMode get_operation_mode_(uint8_t power, uint8_t mode)
void set_health_mode(bool health, bool transmit=true)
bool on_receive(remote_base::RemoteReceiveData data) override
void encode(RemoteTransmitData *dst, const HaierData &data)
optional< HaierData > decode(RemoteReceiveData src)
ClimateSwingMode
Enum for all modes a climate swing can be in NOTE: If adding values, update ClimateSwingModeMask in c...
@ CLIMATE_SWING_OFF
The swing mode is set to Off.
@ CLIMATE_SWING_HORIZONTAL
The fan mode is set to Horizontal.
@ CLIMATE_SWING_VERTICAL
The fan mode is set to Vertical.
@ CLIMATE_SWING_BOTH
The fan mode is set to Both.
ClimateMode
Enum for all modes a climate device can be in.
@ CLIMATE_MODE_DRY
The climate device is set to dry/humidity mode.
@ CLIMATE_MODE_FAN_ONLY
The climate device only has the fan enabled, no heating or cooling is taking place.
@ CLIMATE_MODE_HEAT
The climate device is set to heat to reach the target temperature.
@ CLIMATE_MODE_COOL
The climate device is set to cool to reach the target temperature.
@ CLIMATE_MODE_HEAT_COOL
The climate device is set to heat/cool to reach the target temperature.
@ CLIMATE_MODE_OFF
The climate device is off.
ClimateFanMode
NOTE: If adding values, update ClimateFanModeMask in climate_traits.h to use the new last value.
@ CLIMATE_FAN_MEDIUM
The fan mode is set to Medium.
@ CLIMATE_FAN_ON
The fan mode is set to On.
@ CLIMATE_FAN_AUTO
The fan mode is set to Auto.
@ CLIMATE_FAN_LOW
The fan mode is set to Low.
@ CLIMATE_FAN_HIGH
The fan mode is set to High.
std::vector< uint8_t > data