ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
gree.cpp
Go to the documentation of this file.
1#include "gree.h"
3
4namespace esphome::gree {
5
6static const char *const TAG = "gree.climate";
7
10 // ClimateIR unconditionally includes HEAT_COOL in the base mode set; remove it when heat is not supported.
11 if (!this->supports_heat_) {
12 auto modes = t.get_supported_modes();
14 t.set_supported_modes(modes);
15 }
16 return t;
17}
18
20 if (model == GREE_YAN) {
21 // YAN only has a vertical vane; the horizontal swing IR bytes are not defined for this model.
24 }
25 if (model == GREE_YX1FF) {
26 this->fan_modes_.insert(climate::CLIMATE_FAN_QUIET); // YX1FF 4 speed
27 this->presets_.insert(climate::CLIMATE_PRESET_NONE); // YX1FF sleep mode
28 this->presets_.insert(climate::CLIMATE_PRESET_SLEEP); // YX1FF sleep mode
29 }
30
31 this->model_ = model;
32}
33
34void GreeClimate::set_mode_bit(uint8_t bit_mask, bool enabled) {
35 if (enabled) {
36 this->mode_bits_ |= bit_mask;
37 } else {
38 this->mode_bits_ &= ~bit_mask;
39 }
40 this->transmit_state();
41}
42
44 uint8_t remote_state[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00};
45
46 remote_state[0] = this->fan_speed_() | this->operation_mode_();
47 remote_state[1] = this->temperature_();
48
49 if (this->model_ == GREE_YAN) {
50 remote_state[2] = 0x20; // bits 0..3 always 0000, bits 4..7 TURBO, LIGHT, HEALTH, X-FAN
51 remote_state[3] = 0x50; // bits 4..7 always 0101
52 remote_state[4] = this->vertical_swing_();
53 }
54
55 if (this->model_ == GREE_YX1FF || this->model_ == GREE_YAG) {
56 remote_state[2] = 0x60;
57 remote_state[3] = 0x50;
58 remote_state[4] = this->vertical_swing_();
59 }
60
61 if (this->model_ == GREE_YAG) {
62 remote_state[5] = 0x40;
63
64 if (this->vertical_swing_() == GREE_VDIR_SWING || this->horizontal_swing_() == GREE_HDIR_SWING) {
65 remote_state[0] |= (1 << 6);
66 }
67 }
68
69 if (this->model_ == GREE_YAC || this->model_ == GREE_YAG) {
70 remote_state[4] |= (this->horizontal_swing_() << 4);
71 }
72
73 if (this->model_ == GREE_YAA || this->model_ == GREE_YAC || this->model_ == GREE_YAC1FB9) {
74 remote_state[2] = 0x20; // bits 0..3 always 0000, bits 4..7 TURBO, LIGHT, HEALTH, X-FAN
75 remote_state[3] = 0x50; // bits 4..7 always 0101
76 remote_state[6] = 0x20; // YAA1FB, FAA1FB1, YB1F2 bits 4..7 always 0010
77
78 if (this->vertical_swing_() == GREE_VDIR_SWING) {
79 remote_state[0] |= (1 << 6); // Enable swing by setting bit 6
80 } else if (this->vertical_swing_() != GREE_VDIR_AUTO) {
81 remote_state[5] = this->vertical_swing_();
82 }
83 }
84
85 if (this->model_ == GREE_YAN || this->model_ == GREE_YAA || this->model_ == GREE_YAC ||
86 this->model_ == GREE_YAC1FB9) {
87 // Merge the mode bits into remote_state[2]
88 // Clear the mode bits (bits 4-7) and OR in the current mode_bits_
89 remote_state[2] = (remote_state[2] & 0x0F) | this->mode_bits_;
90 }
91
92 if (this->model_ == GREE_YX1FF) {
93 if (this->fan_speed_() == GREE_FAN_TURBO) {
94 remote_state[2] |= GREE_FAN_TURBO_BIT;
95 }
96
97 if (this->preset_() == GREE_PRESET_SLEEP) {
98 remote_state[0] |= GREE_PRESET_SLEEP_BIT;
99 }
100 }
101
102 // Calculate the checksum
103 if (this->model_ == GREE_YAN || this->model_ == GREE_YX1FF) {
104 remote_state[7] = ((remote_state[0] << 4) + (remote_state[1] << 4) + 0xC0);
105 } else {
106 remote_state[7] =
107 ((((remote_state[0] & 0x0F) + (remote_state[1] & 0x0F) + (remote_state[2] & 0x0F) + (remote_state[3] & 0x0F) +
108 ((remote_state[4] & 0xF0) >> 4) + ((remote_state[5] & 0xF0) >> 4) + ((remote_state[6] & 0xF0) >> 4) + 0x0A) &
109 0x0F)
110 << 4);
111 }
112
113 auto transmit = this->transmitter_->transmit();
114 auto *data = transmit.get_data();
115 data->set_carrier_frequency(GREE_IR_FREQUENCY);
116
117 data->mark(GREE_HEADER_MARK);
118 if (this->model_ == GREE_YAC1FB9) {
119 data->space(GREE_YAC1FB9_HEADER_SPACE);
120 } else {
121 data->space(GREE_HEADER_SPACE);
122 }
123
124 for (int i = 0; i < 4; i++) {
125 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
126 data->mark(GREE_BIT_MARK);
127 bool bit = remote_state[i] & mask;
128 data->space(bit ? GREE_ONE_SPACE : GREE_ZERO_SPACE);
129 }
130 }
131
132 data->mark(GREE_BIT_MARK);
133 data->space(GREE_ZERO_SPACE);
134 data->mark(GREE_BIT_MARK);
135 data->space(GREE_ONE_SPACE);
136 data->mark(GREE_BIT_MARK);
137 data->space(GREE_ZERO_SPACE);
138
139 data->mark(GREE_BIT_MARK);
140 if (this->model_ == GREE_YAC1FB9) {
141 data->space(GREE_YAC1FB9_MESSAGE_SPACE);
142 } else {
143 data->space(GREE_MESSAGE_SPACE);
144 }
145
146 for (int i = 4; i < 8; i++) {
147 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
148 data->mark(GREE_BIT_MARK);
149 bool bit = remote_state[i] & mask;
150 data->space(bit ? GREE_ONE_SPACE : GREE_ZERO_SPACE);
151 }
152 }
153
154 data->mark(GREE_BIT_MARK);
155 data->space(0);
156
157 transmit.perform();
158}
159
161 uint8_t operating_mode = GREE_MODE_ON;
162
163 switch (this->mode) {
165 operating_mode |= GREE_MODE_COOL;
166 break;
168 operating_mode |= GREE_MODE_DRY;
169 break;
171 operating_mode |= GREE_MODE_HEAT;
172 break;
174 operating_mode |= GREE_MODE_AUTO;
175 break;
177 operating_mode |= GREE_MODE_FAN;
178 break;
180 default:
181 operating_mode = GREE_MODE_OFF;
182 break;
183 }
184
185 return operating_mode;
186}
187
189 // YX1FF has 4 fan speeds -- we treat low as quiet and turbo as high
190 if (this->model_ == GREE_YX1FF) {
191 switch (this->fan_mode.value_or(climate::CLIMATE_FAN_ON)) {
193 return GREE_FAN_1;
195 return GREE_FAN_2;
197 return GREE_FAN_3;
199 return GREE_FAN_TURBO;
201 default:
202 return GREE_FAN_AUTO;
203 }
204 }
205
206 switch (this->fan_mode.value_or(climate::CLIMATE_FAN_ON)) {
208 return GREE_FAN_1;
210 return GREE_FAN_2;
212 return GREE_FAN_3;
214 default:
215 return GREE_FAN_AUTO;
216 }
217}
218
220 switch (this->swing_mode) {
223 return GREE_HDIR_SWING;
224 default:
225 return GREE_HDIR_MANUAL;
226 }
227}
228
230 switch (this->swing_mode) {
233 return GREE_VDIR_SWING;
234 default:
235 return GREE_VDIR_MANUAL;
236 }
237}
238
240 return (uint8_t) roundf(clamp<float>(this->target_temperature, GREE_TEMP_MIN, GREE_TEMP_MAX));
241}
242
244 // YX1FF has sleep preset
245 if (this->model_ == GREE_YX1FF) {
246 switch (this->preset.value_or(climate::CLIMATE_PRESET_NONE)) {
248 return GREE_PRESET_NONE;
250 return GREE_PRESET_SLEEP;
251 default:
252 return GREE_PRESET_NONE;
253 }
254 }
255
256 return GREE_PRESET_NONE;
257}
258
259} // namespace esphome::gree
constexpr void insert(ValueType value)
Add a single value to the set (std::set compatibility)
constexpr void erase(ValueType value)
Remove a value from the set (std::set compatibility)
ClimateMode mode
The active mode of the climate device.
Definition climate.h:293
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition climate.h:287
float target_temperature
The target temperature of the climate device.
Definition climate.h:274
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition climate.h:299
optional< ClimatePreset > preset
The active preset of the climate device.
Definition climate.h:290
climate::ClimatePresetMask presets_
Definition climate_ir.h:67
climate::ClimateFanModeMask fan_modes_
Definition climate_ir.h:65
climate::ClimateSwingModeMask swing_modes_
Definition climate_ir.h:66
climate::ClimateTraits traits() override
Return the traits of this controller.
Definition climate_ir.cpp:8
void set_mode_bit(uint8_t bit_mask, bool enabled)
Definition gree.cpp:34
void set_model(Model model)
Definition gree.cpp:19
uint8_t horizontal_swing_()
Definition gree.cpp:219
climate::ClimateTraits traits() override
Definition gree.cpp:8
void transmit_state() override
Definition gree.cpp:43
@ CLIMATE_PRESET_NONE
No preset is active.
@ CLIMATE_PRESET_SLEEP
Device is prepared for sleep.
@ 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.
@ 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.
@ 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_QUIET
The fan mode is set to Quiet.
@ CLIMATE_FAN_HIGH
The fan mode is set to High.
@ GREE_YAC1FB9
Definition gree.h:80
@ GREE_YX1FF
Definition gree.h:80