ESPHome 2025.5.0
Loading...
Searching...
No Matches
daikin.cpp
Go to the documentation of this file.
1#include "daikin.h"
3
4namespace esphome {
5namespace daikin {
6
7static const char *const TAG = "daikin.climate";
8
10 uint8_t remote_state[35] = {0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x00, 0xD7, 0x11, 0xDA, 0x27, 0x00,
11 0x42, 0x49, 0x05, 0xA2, 0x11, 0xDA, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00,
12 0x00, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00};
13
14 remote_state[21] = this->operation_mode_();
15 remote_state[22] = this->temperature_();
16 uint16_t fan_speed = this->fan_speed_();
17 remote_state[24] = fan_speed >> 8;
18 remote_state[25] = fan_speed & 0xff;
19
20 // Calculate checksum
21 for (int i = 16; i < 34; i++) {
22 remote_state[34] += remote_state[i];
23 }
24
25 auto transmit = this->transmitter_->transmit();
26 auto *data = transmit.get_data();
28
29 data->mark(DAIKIN_HEADER_MARK);
30 data->space(DAIKIN_HEADER_SPACE);
31 for (int i = 0; i < 8; i++) {
32 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
33 data->mark(DAIKIN_BIT_MARK);
34 bool bit = remote_state[i] & mask;
35 data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE);
36 }
37 }
38 data->mark(DAIKIN_BIT_MARK);
39 data->space(DAIKIN_MESSAGE_SPACE);
40 data->mark(DAIKIN_HEADER_MARK);
41 data->space(DAIKIN_HEADER_SPACE);
42
43 for (int i = 8; i < 16; i++) {
44 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
45 data->mark(DAIKIN_BIT_MARK);
46 bool bit = remote_state[i] & mask;
47 data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE);
48 }
49 }
50 data->mark(DAIKIN_BIT_MARK);
51 data->space(DAIKIN_MESSAGE_SPACE);
52 data->mark(DAIKIN_HEADER_MARK);
53 data->space(DAIKIN_HEADER_SPACE);
54
55 for (int i = 16; i < 35; i++) {
56 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
57 data->mark(DAIKIN_BIT_MARK);
58 bool bit = remote_state[i] & mask;
59 data->space(bit ? DAIKIN_ONE_SPACE : DAIKIN_ZERO_SPACE);
60 }
61 }
62 data->mark(DAIKIN_BIT_MARK);
63 data->space(0);
64
65 transmit.perform();
66}
67
69 uint8_t operating_mode = DAIKIN_MODE_ON;
70 switch (this->mode) {
72 operating_mode |= DAIKIN_MODE_COOL;
73 break;
75 operating_mode |= DAIKIN_MODE_DRY;
76 break;
78 operating_mode |= DAIKIN_MODE_HEAT;
79 break;
81 operating_mode |= DAIKIN_MODE_AUTO;
82 break;
84 operating_mode |= DAIKIN_MODE_FAN;
85 break;
87 default:
88 operating_mode = DAIKIN_MODE_OFF;
89 break;
90 }
91
92 return operating_mode;
93}
94
95uint16_t DaikinClimate::fan_speed_() const {
96 uint16_t fan_speed;
97 switch (this->fan_mode.value()) {
99 fan_speed = DAIKIN_FAN_SILENT << 8;
100 break;
102 fan_speed = DAIKIN_FAN_1 << 8;
103 break;
105 fan_speed = DAIKIN_FAN_3 << 8;
106 break;
108 fan_speed = DAIKIN_FAN_5 << 8;
109 break;
111 default:
112 fan_speed = DAIKIN_FAN_AUTO << 8;
113 }
114
115 // If swing is enabled switch first 4 bits to 1111
116 switch (this->swing_mode) {
118 fan_speed |= 0x0F00;
119 break;
121 fan_speed |= 0x000F;
122 break;
124 fan_speed |= 0x0F0F;
125 break;
126 default:
127 break;
128 }
129 return fan_speed;
130}
131
133 // Force special temperatures depending on the mode
134 switch (this->mode) {
136 return 0x32;
138 return 0xc0;
139 default:
140 uint8_t temperature = (uint8_t) roundf(clamp<float>(this->target_temperature, DAIKIN_TEMP_MIN, DAIKIN_TEMP_MAX));
141 return temperature << 1;
142 }
143}
144
145bool DaikinClimate::parse_state_frame_(const uint8_t frame[]) {
146 uint8_t checksum = 0;
147 for (int i = 0; i < (DAIKIN_STATE_FRAME_SIZE - 1); i++) {
148 checksum += frame[i];
149 }
150 if (frame[DAIKIN_STATE_FRAME_SIZE - 1] != checksum)
151 return false;
152 uint8_t mode = frame[5];
153 // Temperature is given in degrees celcius * 2
154 // only update for states that use the temperature
155 uint8_t temperature = frame[6];
156 if (mode & DAIKIN_MODE_ON) {
157 switch (mode & 0xF0) {
158 case DAIKIN_MODE_COOL:
159 this->mode = climate::CLIMATE_MODE_COOL;
160 this->target_temperature = static_cast<float>(temperature * 0.5f);
161 break;
162 case DAIKIN_MODE_DRY:
163 this->mode = climate::CLIMATE_MODE_DRY;
164 break;
165 case DAIKIN_MODE_HEAT:
166 this->mode = climate::CLIMATE_MODE_HEAT;
167 this->target_temperature = static_cast<float>(temperature * 0.5f);
168 break;
169 case DAIKIN_MODE_AUTO:
171 this->target_temperature = static_cast<float>(temperature * 0.5f);
172 break;
173 case DAIKIN_MODE_FAN:
175 break;
176 }
177 } else {
178 this->mode = climate::CLIMATE_MODE_OFF;
179 }
180 uint8_t fan_mode = frame[8];
181 uint8_t swing_mode = frame[9];
182 if (fan_mode & 0xF && swing_mode & 0xF) {
183 this->swing_mode = climate::CLIMATE_SWING_BOTH;
184 } else if (fan_mode & 0xF) {
185 this->swing_mode = climate::CLIMATE_SWING_VERTICAL;
186 } else if (swing_mode & 0xF) {
187 this->swing_mode = climate::CLIMATE_SWING_HORIZONTAL;
188 } else {
189 this->swing_mode = climate::CLIMATE_SWING_OFF;
190 }
191 switch (fan_mode & 0xF0) {
192 case DAIKIN_FAN_1:
193 case DAIKIN_FAN_2:
194 this->fan_mode = climate::CLIMATE_FAN_LOW;
195 break;
196 case DAIKIN_FAN_3:
197 this->fan_mode = climate::CLIMATE_FAN_MEDIUM;
198 break;
199 case DAIKIN_FAN_4:
200 case DAIKIN_FAN_5:
201 this->fan_mode = climate::CLIMATE_FAN_HIGH;
202 break;
203 case DAIKIN_FAN_AUTO:
204 this->fan_mode = climate::CLIMATE_FAN_AUTO;
205 break;
207 this->fan_mode = climate::CLIMATE_FAN_QUIET;
208 break;
209 }
210 this->publish_state();
211 return true;
212}
213
215 uint8_t state_frame[DAIKIN_STATE_FRAME_SIZE] = {};
217 return false;
218 }
219 for (uint8_t pos = 0; pos < DAIKIN_STATE_FRAME_SIZE; pos++) {
220 uint8_t byte = 0;
221 for (int8_t bit = 0; bit < 8; bit++) {
223 byte |= 1 << bit;
224 } else if (!data.expect_item(DAIKIN_BIT_MARK, DAIKIN_ZERO_SPACE)) {
225 return false;
226 }
227 }
228 state_frame[pos] = byte;
229 if (pos == 0) {
230 // frame header
231 if (byte != 0x11)
232 return false;
233 } else if (pos == 1) {
234 // frame header
235 if (byte != 0xDA)
236 return false;
237 } else if (pos == 2) {
238 // frame header
239 if (byte != 0x27)
240 return false;
241 } else if (pos == 3) { // NOLINT(bugprone-branch-clone)
242 // frame header
243 if (byte != 0x00)
244 return false;
245 } else if (pos == 4) {
246 // frame type
247 if (byte != 0x00)
248 return false;
249 }
250 }
251 return this->parse_state_frame_(state_frame);
252}
253
254} // namespace daikin
255} // namespace esphome
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 parse_state_frame_(const uint8_t frame[])
Definition daikin.cpp:145
uint8_t temperature_() const
Definition daikin.cpp:132
uint8_t operation_mode_() const
Definition daikin.cpp:68
uint16_t fan_speed_() const
Definition daikin.cpp:95
void transmit_state() override
Definition daikin.cpp:9
bool on_receive(remote_base::RemoteReceiveData data) override
Definition daikin.cpp:214
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
@ 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_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.
const uint8_t DAIKIN_MODE_AUTO
Definition daikin.h:14
const uint8_t DAIKIN_MODE_OFF
Definition daikin.h:19
const uint8_t DAIKIN_STATE_FRAME_SIZE
Definition daikin.h:41
const uint32_t DAIKIN_BIT_MARK
Definition daikin.h:35
const uint8_t DAIKIN_TEMP_MIN
Definition daikin.h:10
const uint32_t DAIKIN_IR_FREQUENCY
Definition daikin.h:32
const uint8_t DAIKIN_FAN_4
Definition daikin.h:28
const uint32_t DAIKIN_HEADER_MARK
Definition daikin.h:33
const uint8_t DAIKIN_MODE_COOL
Definition daikin.h:15
const uint8_t DAIKIN_FAN_5
Definition daikin.h:29
const uint32_t DAIKIN_MESSAGE_SPACE
Definition daikin.h:38
const uint32_t DAIKIN_HEADER_SPACE
Definition daikin.h:34
const uint8_t DAIKIN_FAN_SILENT
Definition daikin.h:24
const uint32_t DAIKIN_ZERO_SPACE
Definition daikin.h:37
const uint8_t DAIKIN_MODE_DRY
Definition daikin.h:17
const uint32_t DAIKIN_ONE_SPACE
Definition daikin.h:36
const uint8_t DAIKIN_FAN_2
Definition daikin.h:26
const uint8_t DAIKIN_MODE_ON
Definition daikin.h:20
const uint8_t DAIKIN_FAN_1
Definition daikin.h:25
const uint8_t DAIKIN_FAN_AUTO
Definition daikin.h:23
const uint8_t DAIKIN_FAN_3
Definition daikin.h:27
const uint8_t DAIKIN_TEMP_MAX
Definition daikin.h:11
const uint8_t DAIKIN_MODE_HEAT
Definition daikin.h:16
const uint8_t DAIKIN_MODE_FAN
Definition daikin.h:18
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
uint16_t temperature
Definition sun_gtil2.cpp:12