ESPHome 2026.1.0-dev
Loading...
Searching...
No Matches
gree.cpp
Go to the documentation of this file.
1#include "gree.h"
3
4namespace esphome {
5namespace gree {
6
7static const char *const TAG = "gree.climate";
8
10 if (model == GREE_YX1FF) {
11 this->fan_modes_.insert(climate::CLIMATE_FAN_QUIET); // YX1FF 4 speed
12 this->presets_.insert(climate::CLIMATE_PRESET_NONE); // YX1FF sleep mode
13 this->presets_.insert(climate::CLIMATE_PRESET_SLEEP); // YX1FF sleep mode
14 }
15
16 this->model_ = model;
17}
18
19void GreeClimate::set_mode_bit(uint8_t bit_mask, bool enabled) {
20 if (enabled) {
21 this->mode_bits_ |= bit_mask;
22 } else {
23 this->mode_bits_ &= ~bit_mask;
24 }
25 this->transmit_state();
26}
27
29 uint8_t remote_state[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00};
30
31 remote_state[0] = this->fan_speed_() | this->operation_mode_();
32 remote_state[1] = this->temperature_();
33
34 if (this->model_ == GREE_YAN) {
35 remote_state[2] = 0x20; // bits 0..3 always 0000, bits 4..7 TURBO, LIGHT, HEALTH, X-FAN
36 remote_state[3] = 0x50; // bits 4..7 always 0101
37 remote_state[4] = this->vertical_swing_();
38 }
39
40 if (this->model_ == GREE_YX1FF || this->model_ == GREE_YAG) {
41 remote_state[2] = 0x60;
42 remote_state[3] = 0x50;
43 remote_state[4] = this->vertical_swing_();
44 }
45
46 if (this->model_ == GREE_YAG) {
47 remote_state[5] = 0x40;
48
49 if (this->vertical_swing_() == GREE_VDIR_SWING || this->horizontal_swing_() == GREE_HDIR_SWING) {
50 remote_state[0] |= (1 << 6);
51 }
52 }
53
54 if (this->model_ == GREE_YAC || this->model_ == GREE_YAG) {
55 remote_state[4] |= (this->horizontal_swing_() << 4);
56 }
57
58 if (this->model_ == GREE_YAA || this->model_ == GREE_YAC || this->model_ == GREE_YAC1FB9) {
59 remote_state[2] = 0x20; // bits 0..3 always 0000, bits 4..7 TURBO, LIGHT, HEALTH, X-FAN
60 remote_state[3] = 0x50; // bits 4..7 always 0101
61 remote_state[6] = 0x20; // YAA1FB, FAA1FB1, YB1F2 bits 4..7 always 0010
62
63 if (this->vertical_swing_() == GREE_VDIR_SWING) {
64 remote_state[0] |= (1 << 6); // Enable swing by setting bit 6
65 } else if (this->vertical_swing_() != GREE_VDIR_AUTO) {
66 remote_state[5] = this->vertical_swing_();
67 }
68 }
69
70 if (this->model_ == GREE_YAN || this->model_ == GREE_YAA || this->model_ == GREE_YAC ||
71 this->model_ == GREE_YAC1FB9) {
72 // Merge the mode bits into remote_state[2]
73 // Clear the mode bits (bits 4-7) and OR in the current mode_bits_
74 remote_state[2] = (remote_state[2] & 0x0F) | this->mode_bits_;
75 }
76
77 if (this->model_ == GREE_YX1FF) {
78 if (this->fan_speed_() == GREE_FAN_TURBO) {
79 remote_state[2] |= GREE_FAN_TURBO_BIT;
80 }
81
82 if (this->preset_() == GREE_PRESET_SLEEP) {
83 remote_state[0] |= GREE_PRESET_SLEEP_BIT;
84 }
85 }
86
87 // Calculate the checksum
88 if (this->model_ == GREE_YAN || this->model_ == GREE_YX1FF) {
89 remote_state[7] = ((remote_state[0] << 4) + (remote_state[1] << 4) + 0xC0);
90 } else if (this->model_ == GREE_YAG) {
91 remote_state[7] =
92 ((((remote_state[0] & 0x0F) + (remote_state[1] & 0x0F) + (remote_state[2] & 0x0F) + (remote_state[3] & 0x0F) +
93 ((remote_state[4] & 0xF0) >> 4) + ((remote_state[5] & 0xF0) >> 4) + ((remote_state[6] & 0xF0) >> 4) + 0x0A) &
94 0x0F)
95 << 4);
96 } else {
97 remote_state[7] =
98 ((((remote_state[0] & 0x0F) + (remote_state[1] & 0x0F) + (remote_state[2] & 0x0F) + (remote_state[3] & 0x0F) +
99 ((remote_state[5] & 0xF0) >> 4) + ((remote_state[6] & 0xF0) >> 4) + ((remote_state[7] & 0xF0) >> 4) + 0x0A) &
100 0x0F)
101 << 4) |
102 (remote_state[7] & 0x0F);
103 }
104
105 auto transmit = this->transmitter_->transmit();
106 auto *data = transmit.get_data();
107 data->set_carrier_frequency(GREE_IR_FREQUENCY);
108
109 data->mark(GREE_HEADER_MARK);
110 if (this->model_ == GREE_YAC1FB9) {
111 data->space(GREE_YAC1FB9_HEADER_SPACE);
112 } else {
113 data->space(GREE_HEADER_SPACE);
114 }
115
116 for (int i = 0; i < 4; i++) {
117 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
118 data->mark(GREE_BIT_MARK);
119 bool bit = remote_state[i] & mask;
120 data->space(bit ? GREE_ONE_SPACE : GREE_ZERO_SPACE);
121 }
122 }
123
124 data->mark(GREE_BIT_MARK);
125 data->space(GREE_ZERO_SPACE);
126 data->mark(GREE_BIT_MARK);
127 data->space(GREE_ONE_SPACE);
128 data->mark(GREE_BIT_MARK);
129 data->space(GREE_ZERO_SPACE);
130
131 data->mark(GREE_BIT_MARK);
132 if (this->model_ == GREE_YAC1FB9) {
133 data->space(GREE_YAC1FB9_MESSAGE_SPACE);
134 } else {
135 data->space(GREE_MESSAGE_SPACE);
136 }
137
138 for (int i = 4; i < 8; i++) {
139 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
140 data->mark(GREE_BIT_MARK);
141 bool bit = remote_state[i] & mask;
142 data->space(bit ? GREE_ONE_SPACE : GREE_ZERO_SPACE);
143 }
144 }
145
146 data->mark(GREE_BIT_MARK);
147 data->space(0);
148
149 transmit.perform();
150}
151
153 uint8_t operating_mode = GREE_MODE_ON;
154
155 switch (this->mode) {
157 operating_mode |= GREE_MODE_COOL;
158 break;
160 operating_mode |= GREE_MODE_DRY;
161 break;
163 operating_mode |= GREE_MODE_HEAT;
164 break;
166 operating_mode |= GREE_MODE_AUTO;
167 break;
169 operating_mode |= GREE_MODE_FAN;
170 break;
172 default:
173 operating_mode = GREE_MODE_OFF;
174 break;
175 }
176
177 return operating_mode;
178}
179
181 // YX1FF has 4 fan speeds -- we treat low as quiet and turbo as high
182 if (this->model_ == GREE_YX1FF) {
183 switch (this->fan_mode.value()) {
185 return GREE_FAN_1;
187 return GREE_FAN_2;
189 return GREE_FAN_3;
191 return GREE_FAN_TURBO;
193 default:
194 return GREE_FAN_AUTO;
195 }
196 }
197
198 switch (this->fan_mode.value()) {
200 return GREE_FAN_1;
202 return GREE_FAN_2;
204 return GREE_FAN_3;
206 default:
207 return GREE_FAN_AUTO;
208 }
209}
210
212 switch (this->swing_mode) {
215 return GREE_HDIR_SWING;
216 default:
217 return GREE_HDIR_MANUAL;
218 }
219}
220
222 switch (this->swing_mode) {
225 return GREE_VDIR_SWING;
226 default:
227 return GREE_VDIR_MANUAL;
228 }
229}
230
232 return (uint8_t) roundf(clamp<float>(this->target_temperature, GREE_TEMP_MIN, GREE_TEMP_MAX));
233}
234
236 // YX1FF has sleep preset
237 if (this->model_ == GREE_YX1FF) {
238 switch (this->preset.value()) {
240 return GREE_PRESET_NONE;
242 return GREE_PRESET_SLEEP;
243 default:
244 return GREE_PRESET_NONE;
245 }
246 }
247
248 return GREE_PRESET_NONE;
249}
250
251} // namespace gree
252} // namespace esphome
constexpr void insert(ValueType value)
Add a single value to the set (std::set compatibility)
ClimateMode mode
The active mode of the climate device.
Definition climate.h:261
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition climate.h:255
float target_temperature
The target temperature of the climate device.
Definition climate.h:242
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition climate.h:267
optional< ClimatePreset > preset
The active preset of the climate device.
Definition climate.h:258
climate::ClimatePresetMask presets_
Definition climate_ir.h:68
climate::ClimateFanModeMask fan_modes_
Definition climate_ir.h:66
void set_mode_bit(uint8_t bit_mask, bool enabled)
Definition gree.cpp:19
void set_model(Model model)
Definition gree.cpp:9
uint8_t horizontal_swing_()
Definition gree.cpp:211
void transmit_state() override
Definition gree.cpp:28
value_type const & value() const
Definition optional.h:94
void set_carrier_frequency(uint32_t carrier_frequency)
Definition remote_base.h:30
@ 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_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
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7