ESPHome 2025.5.0
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, "Expected checksum: %X", expected);
157 ESP_LOGV(TAG, "Checksum received: %X", checksum);
158
159 return checksum == expected;
160}
161
163 auto transmit = this->transmitter_->transmit();
164 auto *data = transmit.get_data();
166
167 data->mark(EMMETI_HEADER_MARK);
168 data->space(EMMETI_HEADER_SPACE);
169
170 if (this->mode != climate::CLIMATE_MODE_OFF) {
171 this->reverse_add_(this->set_mode_(), 3, data);
172 this->add_(1, data);
173 this->reverse_add_(this->set_fan_speed_(), 2, data);
174 this->add_(this->swing_mode != climate::CLIMATE_SWING_OFF, data);
175 this->add_(0, data); // sleep mode
176 this->reverse_add_(this->set_temp_(), 4, data);
177 this->add_(0, 8, data); // zeros
178 this->add_(0, data); // turbo mode
179 this->add_(1, data); // light
180 this->add_(1, data); // tree icon thingy
181 this->add_(0, data); // blow mode
182 this->add_(0x52, 11, data); // idk
183
184 data->mark(EMMETI_BIT_MARK);
185 data->space(EMMETI_MESSAGE_SPACE);
186
187 this->reverse_add_(this->set_blades_(), 4, data);
188 this->add_(0, 4, data); // zeros
189 this->reverse_add_(2, 2, data); // thermometer
190 this->add_(0, 18, data); // zeros
191 this->reverse_add_(this->gen_checksum_(), 4, data);
192 } else {
193 this->add_(9, 12, data);
194 this->add_(0, 8, data);
195 this->add_(0x2052, 15, data);
196 data->mark(EMMETI_BIT_MARK);
197 data->space(EMMETI_MESSAGE_SPACE);
198 this->add_(0, 8, data);
199 this->add_(1, 2, data);
200 this->add_(0, 18, data);
201 this->add_(0x0C, 4, data);
202 }
203 data->mark(EMMETI_BIT_MARK);
204 data->space(0);
205
206 transmit.perform();
207}
208
210 this->mode = this->get_mode_(curr_state.mode);
211 this->fan_mode = this->get_fan_speed_(curr_state.fan_speed);
212 this->target_temperature = this->get_temp_(curr_state.temp);
213 this->swing_mode = this->get_swing_(curr_state.bitmap);
214 // this->blades_ = curr_state.fan_pos;
215 if (!(curr_state.bitmap & 0x01)) {
217 }
218
219 this->publish_state();
220 return true;
221}
222
225 return false;
226 }
227 ESP_LOGD(TAG, "Received emmeti frame");
228
229 EmmetiState curr_state;
230
231 for (size_t pos = 0; pos < 3; pos++) {
233 curr_state.mode |= 1 << pos;
234 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
235 return false;
236 }
237 }
238
239 ESP_LOGD(TAG, "Mode: %d", curr_state.mode);
240
242 curr_state.bitmap |= 1 << 0;
243 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
244 return false;
245 }
246
247 ESP_LOGD(TAG, "On: %d", curr_state.bitmap & 0x01);
248
249 for (size_t pos = 0; pos < 2; pos++) {
251 curr_state.fan_speed |= 1 << pos;
252 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
253 return false;
254 }
255 }
256
257 ESP_LOGD(TAG, "Fan speed: %d", curr_state.fan_speed);
258
259 for (size_t pos = 0; pos < 2; pos++) {
261 curr_state.bitmap |= 1 << (pos + 1);
262 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
263 return false;
264 }
265 }
266
267 ESP_LOGD(TAG, "Swing: %d", (curr_state.bitmap >> 1) & 0x01);
268 ESP_LOGD(TAG, "Sleep: %d", (curr_state.bitmap >> 2) & 0x01);
269
270 for (size_t pos = 0; pos < 4; pos++) {
272 curr_state.temp |= 1 << pos;
273 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
274 return false;
275 }
276 }
277
278 ESP_LOGD(TAG, "Temp: %d", curr_state.temp);
279
280 for (size_t pos = 0; pos < 8; pos++) {
282 return false;
283 }
284 }
285
286 for (size_t pos = 0; pos < 4; pos++) {
288 curr_state.bitmap |= 1 << (pos + 3);
289 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
290 return false;
291 }
292 }
293
294 ESP_LOGD(TAG, "Turbo: %d", (curr_state.bitmap >> 3) & 0x01);
295 ESP_LOGD(TAG, "Light: %d", (curr_state.bitmap >> 4) & 0x01);
296 ESP_LOGD(TAG, "Tree: %d", (curr_state.bitmap >> 5) & 0x01);
297 ESP_LOGD(TAG, "Blow: %d", (curr_state.bitmap >> 6) & 0x01);
298
299 uint16_t control_data = 0;
300 for (size_t pos = 0; pos < 11; pos++) {
302 control_data |= 1 << pos;
303 } else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
304 return false;
305 }
306 }
307
308 if (control_data != 0x250) {
309 return false;
310 }
311
312 return this->parse_state_frame_(curr_state);
313}
314
315} // namespace emmeti
316} // 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:173
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition climate.h:199
float target_temperature
The target temperature of the climate device.
Definition climate.h:186
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition climate.h:202
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition climate.cpp:395
bool on_receive(remote_base::RemoteReceiveData data) override
Definition emmeti.cpp:223
climate::ClimateSwingMode get_swing_(uint8_t bitmap)
Definition emmeti.cpp:125
void transmit_state() override
Definition emmeti.cpp:162
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:209
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:89
bool expect_item(uint32_t mark, uint32_t space)
void set_carrier_frequency(uint32_t carrier_frequency)
Definition remote_base.h:34
mopeka_std_values val[4]
ClimateSwingMode
Enum for all modes a climate swing can be in.
@ 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.
@ 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:301