ESPHome 2026.5.1
Loading...
Searching...
No Matches
daikin_arc.cpp
Go to the documentation of this file.
1#include "daikin_arc.h"
2
3#include <cmath>
4
6#include "esphome/core/log.h"
7
9
10static const char *const TAG = "daikin.climate";
11
14
15 // Never send nan to HA
16 if (std::isnan(this->target_humidity))
17 this->target_humidity = 0;
18 if (std::isnan(this->current_temperature))
19 this->current_temperature = 0;
20 if (std::isnan(this->current_humidity))
21 this->current_humidity = 0;
22}
23
25 uint8_t remote_header[8] = {0x11, 0xDA, 0x27, 0x00, 0x84, 0x87, 0x20, 0x00};
26
27 // Calculate checksum
28 for (size_t i = 0; i < sizeof(remote_header) - 1; i++) {
29 remote_header[sizeof(remote_header) - 1] += remote_header[i];
30 }
31
32 auto transmit = this->transmitter_->transmit();
33 auto *data = transmit.get_data();
34 data->set_carrier_frequency(DAIKIN_IR_FREQUENCY);
35
36 data->mark(DAIKIN_ARC_PRE_MARK);
37 data->space(DAIKIN_ARC_PRE_SPACE);
38
39 data->mark(DAIKIN_HEADER_MARK);
40 data->space(DAIKIN_HEADER_SPACE);
41
42 for (uint8_t i : remote_header) {
43 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
44 data->mark(DAIKIN_BIT_MARK);
45 bool bit = i & mask;
46 data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE);
47 }
48 }
49 data->mark(DAIKIN_BIT_MARK);
50 data->space(0);
51
52 transmit.perform();
53}
54
56 // 0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x00, 0xD7, 0x11, 0xDA, 0x27, 0x00,
57 // 0x42, 0x49, 0x05, 0xA2,
58 uint8_t remote_header[20] = {0x11, 0xDA, 0x27, 0x00, 0x02, 0xd0, 0x02, 0x03, 0x80, 0x03, 0x82, 0x30, 0x41, 0x1f, 0x82,
59 0xf4,
60 /* とつど */
61 /* 0x13 */
62 0x00, 0x24, 0x00, 0x00};
63
64 // 05 0 [1:3]MODE 1 [OFF TMR] [ON TMR] Power
65 // 06-07 TEMP
66 // 08 [0:3] SPEED [4:7] Swing
67 // 09 00
68 // 10 00
69 // 11, 12: timer
70 // 13 [0:6] 0000000 [7] POWERMODE
71 // 14 0a
72 // 15 c4
73 // 16 [0:3] 8 00 [6:7] SENSOR WIND = 11 / NORMAL = 00
74 // 17 24
75
76 uint8_t remote_state[19] = {
77 0x11, 0xDA, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, 0x00, 0x0a, 0xC4,
78 /* MODE TEMP HUMD FANH FANL
79 パワフル音声応答 */
80 /* ON
81 0x01入 0x0a */
82 /* OF
83 0x00切 0x02 */
84 0x80, 0x24, 0x00
85 /* センサー風 */
86 /* ON 0x83 */
87 /* OF 0x80 */
88 };
89
90 remote_state[5] = this->operation_mode_() | 0x08;
91 remote_state[6] = this->temperature_();
92 remote_state[7] = this->humidity_();
93 if (remote_state[7] != this->last_humidity_ && this->mode != climate::CLIMATE_MODE_OFF) {
94 ESP_LOGD(TAG, "Set Humditiy: %d, %d\n", (int) this->target_humidity, (int) remote_state[7]);
95 remote_header[9] |= 0x10;
96 this->last_humidity_ = remote_state[7];
97 }
98 uint16_t fan_speed = this->fan_speed_();
99 remote_state[8] = fan_speed >> 8;
100 remote_state[9] = fan_speed & 0xff;
101
102 // Calculate checksum
103 for (size_t i = 0; i < sizeof(remote_header) - 1; i++) {
104 remote_header[sizeof(remote_header) - 1] += remote_header[i];
105 }
106
107 // Calculate checksum
108 for (int i = 0; i < DAIKIN_STATE_FRAME_SIZE - 1; i++) {
109 remote_state[DAIKIN_STATE_FRAME_SIZE - 1] += remote_state[i];
110 }
111
112 auto transmit = this->transmitter_->transmit();
113 auto *data = transmit.get_data();
114 data->set_carrier_frequency(DAIKIN_IR_FREQUENCY);
115
116 data->mark(DAIKIN_ARC_PRE_MARK);
117 data->space(DAIKIN_ARC_PRE_SPACE);
118
119 data->mark(DAIKIN_HEADER_MARK);
120 data->space(DAIKIN_HEADER_SPACE);
121
122 for (uint8_t i : remote_header) {
123 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
124 data->mark(DAIKIN_BIT_MARK);
125 bool bit = i & mask;
126 data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE);
127 }
128 }
129 data->mark(DAIKIN_BIT_MARK);
130 data->space(DAIKIN_MESSAGE_SPACE);
131
132 data->mark(DAIKIN_HEADER_MARK);
133 data->space(DAIKIN_HEADER_SPACE);
134
135 for (uint8_t i : remote_state) {
136 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
137 data->mark(DAIKIN_BIT_MARK);
138 bool bit = i & mask;
139 data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE);
140 }
141 }
142 data->mark(DAIKIN_BIT_MARK);
143 data->space(0);
144
145 transmit.perform();
146}
147
149 uint8_t operating_mode = DAIKIN_MODE_ON;
150 switch (this->mode) {
152 operating_mode |= DAIKIN_MODE_COOL;
153 break;
155 operating_mode |= DAIKIN_MODE_DRY;
156 break;
158 operating_mode |= DAIKIN_MODE_HEAT;
159 break;
161 operating_mode |= DAIKIN_MODE_AUTO;
162 break;
164 operating_mode |= DAIKIN_MODE_FAN;
165 break;
167 default:
168 operating_mode = DAIKIN_MODE_OFF;
169 break;
170 }
171
172 return operating_mode;
173}
174
176 uint16_t fan_speed;
177 switch (this->fan_mode.value_or(climate::CLIMATE_FAN_ON)) {
179 fan_speed = DAIKIN_FAN_1 << 8;
180 break;
182 fan_speed = DAIKIN_FAN_3 << 8;
183 break;
185 fan_speed = DAIKIN_FAN_5 << 8;
186 break;
188 default:
189 fan_speed = DAIKIN_FAN_AUTO << 8;
190 }
191
192 // If swing is enabled switch first 4 bits to 1111
193 switch (this->swing_mode) {
195 fan_speed |= 0x0F00;
196 break;
198 fan_speed |= 0x000F;
199 break;
201 fan_speed |= 0x0F0F;
202 break;
203 default:
204 break;
205 }
206 return fan_speed;
207}
208
210 // Force special temperatures depending on the mode
211 switch (this->mode) {
213 return 0x32;
216 return 0xc0;
217 default:
218 float new_temp = clamp<float>(this->target_temperature, DAIKIN_TEMP_MIN, DAIKIN_TEMP_MAX);
219 uint8_t temperature = (uint8_t) floor(new_temp);
220 return temperature << 1 | (new_temp - temperature > 0 ? 0x01 : 0);
221 }
222}
223
225 if (this->target_humidity == 39) {
226 return 0;
227 } else if (this->target_humidity <= 40 || this->target_humidity == 44) {
228 return 40;
229 } else if (this->target_humidity <= 45 || this->target_humidity == 49) // 41 - 45
230 {
231 return 45;
232 } else if (this->target_humidity <= 50 || this->target_humidity == 52) // 45 - 50
233 {
234 return 50;
235 } else {
236 return 0xff;
237 }
238}
239
247
248bool DaikinArcClimate::parse_state_frame_(const uint8_t frame[]) {
249 uint8_t checksum = 0;
250 for (int i = 0; i < (DAIKIN_STATE_FRAME_SIZE - 1); i++) {
251 checksum += frame[i];
252 }
253 if (frame[DAIKIN_STATE_FRAME_SIZE - 1] != checksum) {
254 ESP_LOGI(TAG, "checksum error");
255 return false;
256 }
257
258 char buf[DAIKIN_STATE_FRAME_SIZE * 3 + 1] = {0};
259 size_t pos = 0;
260 for (size_t i = 0; i < DAIKIN_STATE_FRAME_SIZE; i++) {
261 pos = buf_append_printf(buf, sizeof(buf), pos, "%02x ", frame[i]);
262 }
263 ESP_LOGD(TAG, "FRAME %s", buf);
264
265 uint8_t mode = frame[5];
266 if (mode & DAIKIN_MODE_ON) {
267 switch (mode & 0xF0) {
268 case DAIKIN_MODE_COOL:
269 this->mode = climate::CLIMATE_MODE_COOL;
270 break;
271 case DAIKIN_MODE_DRY:
272 this->mode = climate::CLIMATE_MODE_DRY;
273 break;
274 case DAIKIN_MODE_HEAT:
275 this->mode = climate::CLIMATE_MODE_HEAT;
276 break;
277 case DAIKIN_MODE_AUTO:
279 break;
280 case DAIKIN_MODE_FAN:
282 break;
283 }
284 } else {
285 this->mode = climate::CLIMATE_MODE_OFF;
286 }
287 uint8_t temperature = frame[6];
288 if (!(temperature & 0xC0)) {
289 this->target_temperature = temperature >> 1;
290 this->target_temperature += (temperature & 0x1) ? 0.5 : 0;
291 }
292 this->target_humidity = frame[7]; // 0, 40, 45, 50, 0xff
293 uint8_t fan_mode = frame[8];
294 uint8_t swing_mode = frame[9];
295 if (fan_mode & 0xF && swing_mode & 0xF) {
296 this->swing_mode = climate::CLIMATE_SWING_BOTH;
297 } else if (fan_mode & 0xF) {
298 this->swing_mode = climate::CLIMATE_SWING_VERTICAL;
299 } else if (swing_mode & 0xF) {
300 this->swing_mode = climate::CLIMATE_SWING_HORIZONTAL;
301 } else {
302 this->swing_mode = climate::CLIMATE_SWING_OFF;
303 }
304 switch (fan_mode & 0xF0) {
305 case DAIKIN_FAN_1:
306 case DAIKIN_FAN_2:
308 this->fan_mode = climate::CLIMATE_FAN_LOW;
309 break;
310 case DAIKIN_FAN_3:
311 this->fan_mode = climate::CLIMATE_FAN_MEDIUM;
312 break;
313 case DAIKIN_FAN_4:
314 case DAIKIN_FAN_5:
315 this->fan_mode = climate::CLIMATE_FAN_HIGH;
316 break;
317 case DAIKIN_FAN_AUTO:
318 this->fan_mode = climate::CLIMATE_FAN_AUTO;
319 break;
320 }
321 /*
322 05 0 [1:3]MODE 1 [OFF TMR] [ON TMR] Power
323 06-07 TEMP
324 08 [0:3] SPEED [4:7] Swing
325 09 00
326 10 00
327 11, 12: timer
328 13 [0:6] 0000000 [7] POWERMODE
329 14 0a
330 15 c4
331 16 [0:3] 8 00 [6:7] SENSOR WIND = 11 / NORMAL = 00
332 17 24
333 05 06 07 08 09 10 11 12 13 14 15 16 17 18
334 None FRAME 11 da 27 00 00 49 2e 00 b0 00 00 06 60 00 0a c4 80 24 11
335 1H FRAME 11 da 27 00 00 4d 2e 00 b0 00 00 c6 30 00 2a c4 80 24 c5
336 1H30 FRAME 11 da 27 00 00 4d 2e 00 b0 00 00 a6 32 00 2a c4 80 24 a7
337 2H FRAME 11 da 27 00 00 4d 2e 00 b0 00 00 86 34 00 2a c4 80 24 89
338
339 */
340 this->publish_state();
341 return true;
342}
343
345 uint8_t state_frame[DAIKIN_STATE_FRAME_SIZE] = {};
346
347 bool valid_daikin_frame = false;
348 if (data.expect_item(DAIKIN_HEADER_MARK, DAIKIN_HEADER_SPACE)) {
349 valid_daikin_frame = true;
350 size_t bytes_count = data.size() / 2 / 8;
351 // Header (20) + state (19) = 39 bytes max; truncates gracefully via buf_append_printf
352 char buf[40 * 3 + 1] = {};
353 constexpr size_t buf_size = sizeof(buf);
354 size_t buf_pos = 0;
355 for (size_t i = 0; i < bytes_count; i++) {
356 uint8_t byte = 0;
357 for (int8_t bit = 0; bit < 8; bit++) {
358 if (data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ONE_SPACE)) {
359 byte |= 1 << bit;
360 } else if (!data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ZERO_SPACE)) {
361 valid_daikin_frame = false;
362 break;
363 }
364 }
365 buf_pos = buf_append_printf(buf, buf_size, buf_pos, "%02x ", byte);
366 }
367 ESP_LOGD(TAG, "WHOLE FRAME %s size: %d", buf, data.size());
368 }
369 if (!valid_daikin_frame) {
370 char sbuf[16 * 10 + 1] = {0};
371 size_t sbuf_pos = 0;
372 for (size_t j = 0; j < static_cast<size_t>(data.size()); j++) {
373 if ((j - 2) % 16 == 0) {
374 if (j > 0) {
375 ESP_LOGD(TAG, "DATA %04x: %s", (j - 16 > 0xffff ? 0 : j - 16), sbuf);
376 }
377 sbuf_pos = 0;
378 }
379 char type_ch = ' ';
380 // debug_tolerance = 25%
381
382 if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_MARK)) <= data[j] &&
383 data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_MARK)))
384 type_ch = 'P';
385 if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_SPACE)) <= -data[j] &&
386 -data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_SPACE)))
387 type_ch = 'a';
388 if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_HEADER_MARK)) <= data[j] &&
389 data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_HEADER_MARK)))
390 type_ch = 'H';
391 if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_HEADER_SPACE)) <= -data[j] &&
392 -data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_HEADER_SPACE)))
393 type_ch = 'h';
394 if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_BIT_MARK)) <= data[j] &&
395 data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_BIT_MARK)))
396 type_ch = 'B';
397 if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ONE_SPACE)) <= -data[j] &&
398 -data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ONE_SPACE)))
399 type_ch = '1';
400 if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ZERO_SPACE)) <= -data[j] &&
401 -data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ZERO_SPACE)))
402 type_ch = '0';
403
404 if (abs(data[j]) > 100000) {
405 sbuf_pos = buf_append_printf(sbuf, sizeof(sbuf), sbuf_pos, "%-5d[%c] ", data[j] > 0 ? 99999 : -99999, type_ch);
406 } else {
407 sbuf_pos =
408 buf_append_printf(sbuf, sizeof(sbuf), sbuf_pos, "%-5d[%c] ", (int) (round(data[j] / 10.) * 10), type_ch);
409 }
410 if (j + 1 == static_cast<size_t>(data.size())) {
411 ESP_LOGD(TAG, "DATA %04x: %s", (j - 8 > 0xffff ? 0 : j - 8), sbuf);
412 }
413 }
414 }
415
416 data.reset();
417
418 if (!data.expect_item(DAIKIN_HEADER_MARK, DAIKIN_HEADER_SPACE)) {
419 ESP_LOGI(TAG, "non daikin_arc expect item");
420 return false;
421 }
422
423 for (uint8_t pos = 0; pos < DAIKIN_STATE_FRAME_SIZE; pos++) {
424 uint8_t byte = 0;
425 for (int8_t bit = 0; bit < 8; bit++) {
426 if (data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ONE_SPACE)) {
427 byte |= 1 << bit;
428 } else if (!data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ZERO_SPACE)) {
429 ESP_LOGI(TAG, "non daikin_arc expect item pos: %d", pos);
430 return false;
431 }
432 }
433 state_frame[pos] = byte;
434 if (pos == 0) {
435 // frame header
436 if (byte != 0x11) {
437 ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
438 return false;
439 }
440 } else if (pos == 1) {
441 // frame header
442 if (byte != 0xDA) {
443 ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
444 return false;
445 }
446 } else if (pos == 2) {
447 // frame header
448 if (byte != 0x27) {
449 ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
450 return false;
451 }
452 } else if (pos == 3) { // NOLINT(bugprone-branch-clone)
453 // frame header
454 if (byte != 0x00) {
455 ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
456 return false;
457 }
458 } else if (pos == 4) {
459 // frame type
460 if (byte != 0x00) {
461 ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
462 return false;
463 }
464 } else if (pos == 5) {
465 if (data.size() == 385) {
466 /*
467 11 da 27 00 00 1a 0c 04 2c 21 61 07 00 07 0c 00 18 00 0e 3c 00 6c 1b 61
468 Inside Temp
469 Outside Temp
470 Humdidity
471
472 */
473 this->current_temperature = state_frame[5]; // Inside temperature
474 // this->current_temperature = state_frame[6]; // Outside temperature
475 this->publish_state();
476 return true;
477 } else if ((byte & 0x40) != 0x40) {
478 ESP_LOGI(TAG, "non daikin_arc expect pos: %d header: %02x", pos, byte);
479 return false;
480 }
481 }
482 }
483 return this->parse_state_frame_(state_frame);
484}
485
487 auto target_humidity = call.get_target_humidity();
488 if (target_humidity.has_value()) {
490 }
492}
493
494} // namespace esphome::daikin_arc
uint8_t checksum
Definition bl0906.h:3
This class is used to encode all control actions on a climate device.
Definition climate.h:34
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
float current_humidity
The current humidity of the climate device, as reported from the integration.
Definition climate.h:270
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition climate.h:299
float current_temperature
The current temperature of the climate device, as reported from the integration.
Definition climate.h:267
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition climate.cpp:437
float target_humidity
The target humidity of the climate device.
Definition climate.h:284
void add_feature_flags(uint32_t feature_flags)
void set_visual_min_humidity(float visual_min_humidity)
void set_visual_max_humidity(float visual_max_humidity)
void control(const climate::ClimateCall &call) override
Override control to change settings of the climate device.
climate::ClimateTraits traits() override
Return the traits of this controller.
Definition climate_ir.cpp:8
void control(const climate::ClimateCall &call) override
bool parse_state_frame_(const uint8_t frame[])
climate::ClimateTraits traits() override
bool on_receive(remote_base::RemoteReceiveData data) override
@ CLIMATE_SUPPORTS_CURRENT_TEMPERATURE
@ 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.
@ 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_HIGH
The fan mode is set to High.
const uint32_t DAIKIN_ZERO_SPACE
Definition daikin_arc.h:38
const uint32_t DAIKIN_HEADER_SPACE
Definition daikin_arc.h:35
const uint32_t DAIKIN_ARC_PRE_SPACE
Definition daikin_arc.h:33
const uint8_t DAIKIN_MODE_AUTO
Definition daikin_arc.h:13
const uint32_t DAIKIN_ARC_PRE_MARK
Definition daikin_arc.h:32
const uint32_t DAIKIN_MESSAGE_SPACE
Definition daikin_arc.h:39
const uint8_t DAIKIN_TEMP_MIN
Definition daikin_arc.h:9
const uint32_t DAIKIN_HEADER_MARK
Definition daikin_arc.h:34
const uint8_t DAIKIN_FAN_2
Definition daikin_arc.h:25
const uint8_t DAIKIN_FAN_5
Definition daikin_arc.h:28
const uint32_t DAIKIN_ONE_SPACE
Definition daikin_arc.h:37
const uint8_t DAIKIN_MODE_COOL
Definition daikin_arc.h:14
const uint32_t DAIKIN_BIT_MARK
Definition daikin_arc.h:36
const uint8_t DAIKIN_FAN_3
Definition daikin_arc.h:26
const uint8_t DAIKIN_FAN_4
Definition daikin_arc.h:27
const uint8_t DAIKIN_FAN_1
Definition daikin_arc.h:24
const uint32_t DAIKIN_IR_FREQUENCY
Definition daikin_arc.h:31
const uint8_t DAIKIN_MODE_FAN
Definition daikin_arc.h:17
const uint8_t DAIKIN_TEMP_MAX
Definition daikin_arc.h:10
const uint8_t DAIKIN_MODE_HEAT
Definition daikin_arc.h:15
const uint8_t DAIKIN_MODE_DRY
Definition daikin_arc.h:16
const uint8_t DAIKIN_STATE_FRAME_SIZE
Definition daikin_arc.h:46
const uint8_t DAIKIN_MODE_OFF
Definition daikin_arc.h:18
const uint8_t DAIKIN_FAN_SILENT
Definition daikin_arc.h:23
const uint8_t DAIKIN_FAN_AUTO
Definition daikin_arc.h:22
const uint8_t DAIKIN_MODE_ON
Definition daikin_arc.h:19
size_t size_t pos
Definition helpers.h:1038
uint16_t temperature
Definition sun_gtil2.cpp:12