ESPHome 2026.2.1
Loading...
Searching...
No Matches
emmeti.cpp
Go to the documentation of this file.
1#include "emmeti.h"
3
4namespace esphome {
5namespace emmeti {
6
7static const char *const TAG = "emmeti.climate";
8
9// setters
11 return (uint8_t) roundf(clamp<float>(this->target_temperature, EMMETI_TEMP_MIN, EMMETI_TEMP_MAX) - EMMETI_TEMP_MIN);
12}
13
29
31 switch (this->fan_mode.value()) {
33 return EMMETI_FAN_1;
35 return EMMETI_FAN_2;
37 return EMMETI_FAN_3;
39 default:
40 return EMMETI_FAN_AUTO;
41 }
42}
43
46 switch (this->blades_) {
47 case EMMETI_BLADES_1:
48 case EMMETI_BLADES_2:
51 break;
52 case EMMETI_BLADES_3:
55 break;
56 case EMMETI_BLADES_4:
57 case EMMETI_BLADES_5:
60 break;
61 default:
63 break;
64 }
65 } else {
66 switch (this->blades_) {
67 case EMMETI_BLADES_1:
68 case EMMETI_BLADES_2:
71 break;
72 case EMMETI_BLADES_3:
75 break;
76 case EMMETI_BLADES_4:
77 case EMMETI_BLADES_5:
80 break;
81 default:
83 break;
84 }
85 }
86 return this->blades_;
87}
88
89uint8_t EmmetiClimate::gen_checksum_() { return (this->set_temp_() + this->set_mode_() + 2) % 16; }
90
91// getters
92float EmmetiClimate::get_temp_(uint8_t temp) { return (float) (temp + EMMETI_TEMP_MIN); }
93
110
112 switch (fan_speed) {
113 case EMMETI_FAN_1:
115 case EMMETI_FAN_2:
117 case EMMETI_FAN_3:
119 case EMMETI_FAN_AUTO:
120 default:
122 }
123}
124
128
129template<typename T> T EmmetiClimate::reverse_(T val, size_t len) {
130 T result = 0;
131 for (size_t i = 0; i < len; i++) {
132 result |= ((val & 1 << i) != 0) << (len - 1 - i);
133 }
134 return result;
135}
136
137template<typename T> void EmmetiClimate::add_(T val, size_t len, esphome::remote_base::RemoteTransmitData *data) {
138 for (size_t i = len; i > 0; i--) {
139 data->mark(EMMETI_BIT_MARK);
140 data->space((val & (1 << (i - 1))) ? EMMETI_ONE_SPACE : EMMETI_ZERO_SPACE);
141 }
142}
143
145 data->mark(EMMETI_BIT_MARK);
147}
148
149template<typename T>
151 this->add_(this->reverse_(val, len), len, data);
152}
153
155 uint8_t expected = this->gen_checksum_();
156 ESP_LOGV(TAG,
157 "Expected checksum: %X\n"
158 "Checksum received: %X",
159 expected, checksum);
160
161 return checksum == expected;
162}
163
165 auto transmit = this->transmitter_->transmit();
166 auto *data = transmit.get_data();
168
169 data->mark(EMMETI_HEADER_MARK);
170 data->space(EMMETI_HEADER_SPACE);
171
172 if (this->mode != climate::CLIMATE_MODE_OFF) {
173 this->reverse_add_(this->set_mode_(), 3, data);
174 this->add_(1, data);
175 this->reverse_add_(this->set_fan_speed_(), 2, data);
176 this->add_(this->swing_mode != climate::CLIMATE_SWING_OFF, data);
177 this->add_(0, data); // sleep mode
178 this->reverse_add_(this->set_temp_(), 4, data);
179 this->add_(0, 8, data); // zeros
180 this->add_(0, data); // turbo mode
181 this->add_(1, data); // light
182 this->add_(1, data); // tree icon thingy
183 this->add_(0, data); // blow mode
184 this->add_(0x52, 11, data); // idk
185
186 data->mark(EMMETI_BIT_MARK);
187 data->space(EMMETI_MESSAGE_SPACE);
188
189 this->reverse_add_(this->set_blades_(), 4, data);
190 this->add_(0, 4, data); // zeros
191 this->reverse_add_(2, 2, data); // thermometer
192 this->add_(0, 18, data); // zeros
193 this->reverse_add_(this->gen_checksum_(), 4, data);
194 } else {
195 this->add_(9, 12, data);
196 this->add_(0, 8, data);
197 this->add_(0x2052, 15, data);
198 data->mark(EMMETI_BIT_MARK);
199 data->space(EMMETI_MESSAGE_SPACE);
200 this->add_(0, 8, data);
201 this->add_(1, 2, data);
202 this->add_(0, 18, data);
203 this->add_(0x0C, 4, data);
204 }
205 data->mark(EMMETI_BIT_MARK);
206 data->space(0);
207
208 transmit.perform();
209}
210
212 this->mode = this->get_mode_(curr_state.mode);
213 this->fan_mode = this->get_fan_speed_(curr_state.fan_speed);
214 this->target_temperature = this->get_temp_(curr_state.temp);
215 this->swing_mode = this->get_swing_(curr_state.bitmap);
216 // this->blades_ = curr_state.fan_pos;
217 if (!(curr_state.bitmap & 0x01)) {
219 }
220
221 this->publish_state();
222 return true;
223}
224
227 return false;
228 }
229 ESP_LOGD(TAG, "Received emmeti frame");
230
231 EmmetiState curr_state;
232
233 for (size_t pos = 0; pos < 3; pos++) {
235 curr_state.mode |= 1 << pos;
236 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
237 return false;
238 }
239 }
240
241 ESP_LOGD(TAG, "Mode: %d", curr_state.mode);
242
244 curr_state.bitmap |= 1 << 0;
245 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
246 return false;
247 }
248
249 ESP_LOGD(TAG, "On: %d", curr_state.bitmap & 0x01);
250
251 for (size_t pos = 0; pos < 2; pos++) {
253 curr_state.fan_speed |= 1 << pos;
254 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
255 return false;
256 }
257 }
258
259 ESP_LOGD(TAG, "Fan speed: %d", curr_state.fan_speed);
260
261 for (size_t pos = 0; pos < 2; pos++) {
263 curr_state.bitmap |= 1 << (pos + 1);
264 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
265 return false;
266 }
267 }
268
269 ESP_LOGD(TAG,
270 "Swing: %d\n"
271 "Sleep: %d",
272 (curr_state.bitmap >> 1) & 0x01, (curr_state.bitmap >> 2) & 0x01);
273
274 for (size_t pos = 0; pos < 4; pos++) {
276 curr_state.temp |= 1 << pos;
277 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
278 return false;
279 }
280 }
281
282 ESP_LOGD(TAG, "Temp: %d", curr_state.temp);
283
284 for (size_t pos = 0; pos < 8; pos++) {
286 return false;
287 }
288 }
289
290 for (size_t pos = 0; pos < 4; pos++) {
292 curr_state.bitmap |= 1 << (pos + 3);
293 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
294 return false;
295 }
296 }
297
298 ESP_LOGD(TAG,
299 "Turbo: %d\n"
300 "Light: %d\n"
301 "Tree: %d\n"
302 "Blow: %d",
303 (curr_state.bitmap >> 3) & 0x01, (curr_state.bitmap >> 4) & 0x01, (curr_state.bitmap >> 5) & 0x01,
304 (curr_state.bitmap >> 6) & 0x01);
305
306 uint16_t control_data = 0;
307 for (size_t pos = 0; pos < 11; pos++) {
309 control_data |= 1 << pos;
310 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
311 return false;
312 }
313 }
314
315 if (control_data != 0x250) {
316 return false;
317 }
318
319 return this->parse_state_frame_(curr_state);
320}
321
322} // namespace emmeti
323} // namespace esphome
BedjetMode mode
BedJet operating mode.
uint8_t checksum
Definition bl0906.h:3
ClimateMode mode
The active mode of the climate device.
Definition climate.h:262
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition climate.h:256
float target_temperature
The target temperature of the climate device.
Definition climate.h:243
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition climate.h:268
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition climate.cpp:437
bool on_receive(remote_base::RemoteReceiveData data) override
Definition emmeti.cpp:225
climate::ClimateSwingMode get_swing_(uint8_t bitmap)
Definition emmeti.cpp:125
void transmit_state() override
Definition emmeti.cpp:164
void add_(T val, size_t len, esphome::remote_base::RemoteTransmitData *ata)
Definition emmeti.cpp:137
bool parse_state_frame_(EmmetiState curr_state)
Definition emmeti.cpp:211
climate::ClimateFanMode get_fan_speed_(uint8_t fan)
Definition emmeti.cpp:111
T reverse_(T val, size_t len)
Definition emmeti.cpp:129
void reverse_add_(T val, size_t len, esphome::remote_base::RemoteTransmitData *data)
Definition emmeti.cpp:150
bool check_checksum_(uint8_t checksum)
Definition emmeti.cpp:154
float get_temp_(uint8_t temp)
Definition emmeti.cpp:92
climate::ClimateMode get_mode_(uint8_t mode)
Definition emmeti.cpp:94
value_type const & value() const
Definition optional.h:94
bool expect_item(uint32_t mark, uint32_t space)
void set_carrier_frequency(uint32_t carrier_frequency)
Definition remote_base.h:30
mopeka_std_values val[4]
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_VERTICAL
The fan mode is set to Vertical.
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_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.
const uint32_t EMMETI_MESSAGE_SPACE
Definition emmeti.h:52
const uint32_t EMMETI_ZERO_SPACE
Definition emmeti.h:51
const uint32_t EMMETI_HEADER_MARK
Definition emmeti.h:47
@ EMMETI_MODE_HEAT_COOL
Definition emmeti.h:14
const uint32_t EMMETI_IR_FREQUENCY
Definition emmeti.h:46
const uint32_t EMMETI_HEADER_SPACE
Definition emmeti.h:48
const uint32_t EMMETI_BIT_MARK
Definition emmeti.h:49
const uint8_t EMMETI_TEMP_MAX
Definition emmeti.h:9
@ EMMETI_BLADES_FULL
Definition emmeti.h:34
@ EMMETI_BLADES_MID
Definition emmeti.h:41
@ EMMETI_BLADES_STOP
Definition emmeti.h:33
@ EMMETI_BLADES_HIGH
Definition emmeti.h:42
@ EMMETI_BLADES_LOW
Definition emmeti.h:40
const uint8_t EMMETI_TEMP_MIN
Definition emmeti.h:8
const uint32_t EMMETI_ONE_SPACE
Definition emmeti.h:50
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
std::string size_t len
Definition helpers.h:692
size_t size_t pos
Definition helpers.h:729