ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
daikin_brc.cpp
Go to the documentation of this file.
1#include "daikin_brc.h"
3
5
6static const char *const TAG = "daikin_brc.climate";
7
9 this->mode_button_ = 0x00;
10 if (call.get_mode().has_value()) {
11 // Need to determine if this is call due to Mode button pressed so that we can set the Mode button byte
13 }
14 ClimateIR::control(call);
15}
16
18 uint8_t remote_state[DAIKIN_BRC_TRANSMIT_FRAME_SIZE] = {0x11, 0xDA, 0x17, 0x18, 0x04, 0x00, 0x1E, 0x11,
19 0xDA, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
20 0x00, 0x00, 0x00, 0x00, 0x20, 0x00};
21
22 remote_state[12] = this->alt_mode_();
23 remote_state[13] = this->mode_button_;
24 remote_state[14] = this->operation_mode_();
25 remote_state[17] = this->temperature_();
26 remote_state[18] = this->fan_speed_swing_();
27
28 // Calculate checksum
30 remote_state[DAIKIN_BRC_TRANSMIT_FRAME_SIZE - 1] += remote_state[i];
31 }
32
33 auto transmit = this->transmitter_->transmit();
34 auto *data = transmit.get_data();
35 data->set_carrier_frequency(DAIKIN_BRC_IR_FREQUENCY);
36
37 data->mark(DAIKIN_BRC_HEADER_MARK);
38 data->space(DAIKIN_BRC_HEADER_SPACE);
39 for (int i = 0; i < DAIKIN_BRC_PREAMBLE_SIZE; i++) {
40 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
41 data->mark(DAIKIN_BRC_BIT_MARK);
42 bool bit = remote_state[i] & mask;
44 }
45 }
46 data->mark(DAIKIN_BRC_BIT_MARK);
47 data->space(DAIKIN_BRC_MESSAGE_SPACE);
48 data->mark(DAIKIN_BRC_HEADER_MARK);
49 data->space(DAIKIN_BRC_HEADER_SPACE);
50
52 for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
53 data->mark(DAIKIN_BRC_BIT_MARK);
54 bool bit = remote_state[i] & mask;
56 }
57 }
58
59 data->mark(DAIKIN_BRC_BIT_MARK);
60 data->space(0);
61
62 transmit.perform();
63}
64
66 uint8_t alt_mode = 0x00;
67 switch (this->mode) {
69 alt_mode = 0x23;
70 break;
72 alt_mode = 0x63;
73 break;
77 default:
78 alt_mode = 0x73;
79 break;
80 }
81 return alt_mode;
82}
83
85 uint8_t operating_mode = DAIKIN_BRC_MODE_ON;
86 switch (this->mode) {
88 operating_mode |= DAIKIN_BRC_MODE_COOL;
89 break;
91 operating_mode |= DAIKIN_BRC_MODE_DRY;
92 break;
94 operating_mode |= DAIKIN_BRC_MODE_HEAT;
95 break;
97 operating_mode |= DAIKIN_BRC_MODE_AUTO;
98 break;
100 operating_mode |= DAIKIN_BRC_MODE_FAN;
101 break;
103 default:
104 operating_mode = DAIKIN_BRC_MODE_OFF;
105 break;
106 }
107
108 return operating_mode;
109}
110
112 uint16_t fan_speed;
113 switch (this->fan_mode.value_or(climate::CLIMATE_FAN_ON)) {
115 fan_speed = DAIKIN_BRC_FAN_1;
116 break;
118 fan_speed = DAIKIN_BRC_FAN_2;
119 break;
121 fan_speed = DAIKIN_BRC_FAN_3;
122 break;
123 default:
124 fan_speed = DAIKIN_BRC_FAN_1;
125 }
126
127 // If swing is enabled switch first 4 bits to 1111
128 switch (this->swing_mode) {
130 fan_speed |= DAIKIN_BRC_IR_SWING_ON;
131 break;
132 default:
133 fan_speed |= DAIKIN_BRC_IR_SWING_OFF;
134 break;
135 }
136 return fan_speed;
137}
138
140 // Force special temperatures depending on the mode
141 switch (this->mode) {
144 if (this->fahrenheit_) {
146 }
149 default:
150 uint8_t temperature;
151 // Temperature in remote is in F
152 if (this->fahrenheit_) {
153 temperature = (uint8_t) roundf(
154 clamp<float>(((this->target_temperature * 1.8) + 32), DAIKIN_BRC_TEMP_MIN_F, DAIKIN_BRC_TEMP_MAX_F));
155 } else {
156 temperature = ((uint8_t) roundf(this->target_temperature) - 9) << 1;
157 }
158 return temperature;
159 }
160}
161
162bool DaikinBrcClimate::parse_state_frame_(const uint8_t frame[]) {
163 uint8_t checksum = 0;
164 for (int i = 0; i < (DAIKIN_BRC_STATE_FRAME_SIZE - 1); i++) {
165 checksum += frame[i];
166 }
167 if (frame[DAIKIN_BRC_STATE_FRAME_SIZE - 1] != checksum) {
168 ESP_LOGCONFIG(TAG, "Bad CheckSum %x", checksum);
169 return false;
170 }
171
172 uint8_t mode = frame[7];
173 if (mode & DAIKIN_BRC_MODE_ON) {
174 switch (mode & 0xF0) {
176 this->mode = climate::CLIMATE_MODE_COOL;
177 break;
179 this->mode = climate::CLIMATE_MODE_DRY;
180 break;
182 this->mode = climate::CLIMATE_MODE_HEAT;
183 break;
186 break;
189 break;
190 }
191 } else {
192 this->mode = climate::CLIMATE_MODE_OFF;
193 }
194
195 uint8_t temperature = frame[10];
196 float temperature_c;
197 if (this->fahrenheit_) {
198 temperature_c = clamp<float>(((temperature - 32) / 1.8), DAIKIN_BRC_TEMP_MIN_C, DAIKIN_BRC_TEMP_MAX_C);
199 } else {
200 temperature_c = (temperature >> 1) + 9;
201 }
202
203 this->target_temperature = temperature_c;
204
205 uint8_t fan_mode = frame[11];
206 uint8_t swing_mode = frame[11];
207 switch (swing_mode & 0xF) {
209 this->swing_mode = climate::CLIMATE_SWING_BOTH;
210 break;
212 this->swing_mode = climate::CLIMATE_SWING_OFF;
213 break;
214 }
215
216 switch (fan_mode & 0xF0) {
217 case DAIKIN_BRC_FAN_1:
218 this->fan_mode = climate::CLIMATE_FAN_LOW;
219 break;
220 case DAIKIN_BRC_FAN_2:
221 this->fan_mode = climate::CLIMATE_FAN_MEDIUM;
222 break;
223 case DAIKIN_BRC_FAN_3:
224 this->fan_mode = climate::CLIMATE_FAN_HIGH;
225 break;
226 }
227 this->publish_state();
228 return true;
229}
230
232 uint8_t state_frame[DAIKIN_BRC_STATE_FRAME_SIZE] = {};
233 if (!data.expect_item(DAIKIN_BRC_HEADER_MARK, DAIKIN_BRC_HEADER_SPACE)) {
234 return false;
235 }
236 for (uint8_t pos = 0; pos < DAIKIN_BRC_STATE_FRAME_SIZE; pos++) {
237 uint8_t byte = 0;
238 for (int8_t bit = 0; bit < 8; bit++) {
239 if (data.expect_item(DAIKIN_BRC_BIT_MARK, DAIKIN_BRC_ONE_SPACE)) {
240 byte |= 1 << bit;
241 } else if (!data.expect_item(DAIKIN_BRC_BIT_MARK, DAIKIN_BRC_ZERO_SPACE)) {
242 return false;
243 }
244 }
245 state_frame[pos] = byte;
246 if (pos == 0) {
247 // frame header
248 if (byte != 0x11)
249 return false;
250 } else if (pos == 1) {
251 // frame header
252 if (byte != 0xDA)
253 return false;
254 } else if (pos == 2) {
255 // frame header
256 if (byte != 0x17)
257 return false;
258 } else if (pos == 3) {
259 // frame header
260 if (byte != 0x18)
261 return false;
262 } else if (pos == 4) {
263 // frame type
264 if (byte != 0x00)
265 return false;
266 }
267 }
268 return this->parse_state_frame_(state_frame);
269}
270
271} // namespace esphome::daikin_brc
uint8_t checksum
Definition bl0906.h:3
This class is used to encode all control actions on a climate device.
Definition climate.h:34
const optional< ClimateMode > & get_mode() const
Definition climate.cpp:312
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
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition climate.h:299
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition climate.cpp:437
bool parse_state_frame_(const uint8_t frame[])
void control(const climate::ClimateCall &call) override
Definition daikin_brc.cpp:8
bool on_receive(remote_base::RemoteReceiveData data) override
@ CLIMATE_SWING_OFF
The swing mode is set to Off.
@ 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_LOW
The fan mode is set to Low.
@ CLIMATE_FAN_HIGH
The fan mode is set to High.
const uint8_t DAIKIN_BRC_FAN_2
Definition daikin_brc.h:25
const uint8_t DAIKIN_BRC_MODE_FAN
Definition daikin_brc.h:19
const uint8_t DAIKIN_BRC_MODE_OFF
Definition daikin_brc.h:20
const uint32_t DAIKIN_BRC_ONE_SPACE
Definition daikin_brc.h:34
const uint8_t DAIKIN_BRC_IR_SWING_OFF
Definition daikin_brc.h:41
const uint8_t DAIKIN_BRC_TEMP_MIN_F
Definition daikin_brc.h:9
const uint32_t DAIKIN_BRC_HEADER_MARK
Definition daikin_brc.h:31
const uint8_t DAIKIN_BRC_FAN_1
Definition daikin_brc.h:24
const uint8_t DAIKIN_BRC_MODE_DRY
Definition daikin_brc.h:18
const uint8_t DAIKIN_BRC_TEMP_MAX_F
Definition daikin_brc.h:10
const uint8_t DAIKIN_BRC_IR_DRY_FAN_TEMP_C
Definition daikin_brc.h:39
const uint8_t DAIKIN_BRC_MODE_COOL
Definition daikin_brc.h:16
const uint8_t DAIKIN_BRC_TRANSMIT_FRAME_SIZE
Definition daikin_brc.h:49
const uint8_t DAIKIN_BRC_IR_MODE_BUTTON
Definition daikin_brc.h:42
const uint8_t DAIKIN_BRC_FAN_3
Definition daikin_brc.h:26
const uint32_t DAIKIN_BRC_HEADER_SPACE
Definition daikin_brc.h:32
const uint8_t DAIKIN_BRC_IR_SWING_ON
Definition daikin_brc.h:40
const uint8_t DAIKIN_BRC_PREAMBLE_SIZE
Definition daikin_brc.h:47
const uint8_t DAIKIN_BRC_MODE_AUTO
Definition daikin_brc.h:15
const float DAIKIN_BRC_TEMP_MIN_C
Definition daikin_brc.h:11
const uint32_t DAIKIN_BRC_BIT_MARK
Definition daikin_brc.h:33
const float DAIKIN_BRC_TEMP_MAX_C
Definition daikin_brc.h:12
const uint8_t DAIKIN_BRC_STATE_FRAME_SIZE
Definition daikin_brc.h:45
const uint32_t DAIKIN_BRC_MESSAGE_SPACE
Definition daikin_brc.h:36
const uint8_t DAIKIN_BRC_MODE_ON
Definition daikin_brc.h:21
const uint8_t DAIKIN_BRC_MODE_HEAT
Definition daikin_brc.h:17
const uint32_t DAIKIN_BRC_ZERO_SPACE
Definition daikin_brc.h:35
const uint32_t DAIKIN_BRC_IR_FREQUENCY
Definition daikin_brc.h:30
const uint8_t DAIKIN_BRC_IR_DRY_FAN_TEMP_F
Definition daikin_brc.h:38
size_t size_t pos
Definition helpers.h:1038
uint16_t temperature
Definition sun_gtil2.cpp:12