ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
daikin_brc.cpp
Go to the documentation of this file.
1#include "daikin_brc.h"
4
6
7ESPHOME_LOG_TAG(TAG, "daikin_brc.climate");
8
9static constexpr uint8_t DAIKIN_BRC_HEADER_BYTE0 = 0x11;
10static constexpr uint8_t DAIKIN_BRC_HEADER_BYTE1 = 0xDA;
11static constexpr uint8_t DAIKIN_BRC_HEADER_BYTE2 = 0x17;
12static constexpr uint8_t DAIKIN_BRC_HEADER_BYTE3 = 0x18;
13static constexpr uint8_t DAIKIN_BRC_FRAME_TYPE_STATE = 0x00;
14
16 this->mode_button_ = 0x00;
17 if (call.get_mode().has_value()) {
18 // Need to determine if this is call due to Mode button pressed so that we can set the Mode button byte
20 }
21 ClimateIR::control(call);
22}
23
25 uint8_t remote_state[DAIKIN_BRC_TRANSMIT_FRAME_SIZE] = {0x11, 0xDA, 0x17, 0x18, 0x04, 0x00, 0x1E, 0x11,
26 0xDA, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
27 0x00, 0x00, 0x00, 0x00, 0x20, 0x00};
28
29 // The low 3 bits of the frame header byte address the indoor unit, in the preamble and the state frame
30 remote_state[3] |= this->sub_unit_;
31 remote_state[10] |= this->sub_unit_;
32 remote_state[6] += this->sub_unit_; // preamble checksum covers byte 3
33
34 remote_state[12] = this->alt_mode_();
35 remote_state[13] = this->mode_button_;
36 remote_state[14] = this->operation_mode_();
37 remote_state[17] = this->temperature_();
38 remote_state[18] = this->fan_speed_swing_();
39
40 // Calculate state frame checksum
42 remote_state[DAIKIN_BRC_TRANSMIT_FRAME_SIZE - 1] += remote_state[i];
43 }
44
45 auto transmit = this->transmitter_->transmit();
46 auto *data = transmit.get_data();
47 data->set_carrier_frequency(DAIKIN_BRC_IR_FREQUENCY);
48
49 data->mark(DAIKIN_BRC_HEADER_MARK);
50 data->space(DAIKIN_BRC_HEADER_SPACE);
51 data->item_bytes<DAIKIN_BRC_BIT_TIMINGS>(remote_state, DAIKIN_BRC_PREAMBLE_SIZE);
52 data->mark(DAIKIN_BRC_BIT_MARK);
53 data->space(DAIKIN_BRC_MESSAGE_SPACE);
54 data->mark(DAIKIN_BRC_HEADER_MARK);
55 data->space(DAIKIN_BRC_HEADER_SPACE);
56
57 data->item_bytes<DAIKIN_BRC_BIT_TIMINGS>(remote_state + DAIKIN_BRC_PREAMBLE_SIZE,
59
60 data->mark(DAIKIN_BRC_BIT_MARK);
61 data->space(0);
62
63 transmit.perform();
64}
65
67 uint8_t alt_mode = 0x00;
68 switch (this->mode) {
70 alt_mode = 0x23;
71 break;
73 alt_mode = 0x63;
74 break;
78 default:
79 alt_mode = 0x73;
80 break;
81 }
82 return alt_mode;
83}
84
86 uint8_t operating_mode = DAIKIN_BRC_MODE_ON;
87 switch (this->mode) {
89 operating_mode |= DAIKIN_BRC_MODE_COOL;
90 break;
92 operating_mode |= DAIKIN_BRC_MODE_DRY;
93 break;
95 operating_mode |= DAIKIN_BRC_MODE_HEAT;
96 break;
98 operating_mode |= DAIKIN_BRC_MODE_AUTO;
99 break;
101 operating_mode |= DAIKIN_BRC_MODE_FAN;
102 break;
104 default:
105 operating_mode = DAIKIN_BRC_MODE_OFF;
106 break;
107 }
108
109 return operating_mode;
110}
111
113 uint16_t fan_speed;
114 switch (this->fan_mode.value_or(climate::CLIMATE_FAN_ON)) {
116 fan_speed = DAIKIN_BRC_FAN_1;
117 break;
119 fan_speed = DAIKIN_BRC_FAN_2;
120 break;
122 fan_speed = DAIKIN_BRC_FAN_3;
123 break;
124 default:
125 fan_speed = DAIKIN_BRC_FAN_1;
126 }
127
128 // If swing is enabled switch first 4 bits to 1111
129 switch (this->swing_mode) {
131 fan_speed |= DAIKIN_BRC_IR_SWING_ON;
132 break;
133 default:
134 fan_speed |= DAIKIN_BRC_IR_SWING_OFF;
135 break;
136 }
137 return fan_speed;
138}
139
141 // Force special temperatures depending on the mode
142 switch (this->mode) {
145 if (this->fahrenheit_) {
147 }
150 default:
151 uint8_t temperature;
152 // Temperature in remote is in F
153 if (this->fahrenheit_) {
154 temperature = (uint8_t) roundf(
155 clamp<float>(((this->target_temperature * 1.8f) + 32), DAIKIN_BRC_TEMP_MIN_F, DAIKIN_BRC_TEMP_MAX_F));
156 } else {
157 temperature = ((uint8_t) roundf(this->target_temperature) - 9) << 1;
158 }
159 return temperature;
160 }
161}
162
163bool DaikinBrcClimate::parse_state_frame_(const uint8_t frame[]) {
164 const uint8_t checksum = sum_bytes(frame, DAIKIN_BRC_STATE_FRAME_SIZE - 1);
165 if (frame[DAIKIN_BRC_STATE_FRAME_SIZE - 1] != checksum) {
166 ESP_LOGCONFIG(TAG, "Bad CheckSum %x", checksum);
167 return false;
168 }
169
170 uint8_t mode = frame[7];
171 if (mode & DAIKIN_BRC_MODE_ON) {
172 switch (mode & 0xF0) {
174 this->mode = climate::CLIMATE_MODE_COOL;
175 break;
177 this->mode = climate::CLIMATE_MODE_DRY;
178 break;
180 this->mode = climate::CLIMATE_MODE_HEAT;
181 break;
184 break;
187 break;
188 }
189 } else {
190 this->mode = climate::CLIMATE_MODE_OFF;
191 }
192
193 uint8_t temperature = frame[10];
194 float temperature_c;
195 if (this->fahrenheit_) {
196 temperature_c = clamp<float>(((temperature - 32) / 1.8), DAIKIN_BRC_TEMP_MIN_C, DAIKIN_BRC_TEMP_MAX_C);
197 } else {
198 temperature_c = (temperature >> 1) + 9;
199 }
200
201 this->target_temperature = temperature_c;
202
203 uint8_t fan_mode = frame[11];
204 uint8_t swing_mode = frame[11];
205 switch (swing_mode & 0xF) {
207 this->swing_mode = climate::CLIMATE_SWING_BOTH;
208 break;
210 this->swing_mode = climate::CLIMATE_SWING_OFF;
211 break;
212 }
213
214 switch (fan_mode & 0xF0) {
215 case DAIKIN_BRC_FAN_1:
216 this->fan_mode = climate::CLIMATE_FAN_LOW;
217 break;
218 case DAIKIN_BRC_FAN_2:
219 this->fan_mode = climate::CLIMATE_FAN_MEDIUM;
220 break;
221 case DAIKIN_BRC_FAN_3:
222 this->fan_mode = climate::CLIMATE_FAN_HIGH;
223 break;
224 }
225 this->publish_state();
226 return true;
227}
228
230 uint8_t state_frame[DAIKIN_BRC_STATE_FRAME_SIZE];
231 if (!data.expect_item(DAIKIN_BRC_HEADER_MARK, DAIKIN_BRC_HEADER_SPACE)) {
232 return false;
233 }
234 // Frame header, with this unit's address in the low 3 bits of byte 3, then the frame type
235 if (!data.expect_bytes<DAIKIN_BRC_BIT_TIMINGS>(state_frame, DAIKIN_BRC_STATE_FRAME_SIZE) ||
236 state_frame[0] != DAIKIN_BRC_HEADER_BYTE0 || state_frame[1] != DAIKIN_BRC_HEADER_BYTE1 ||
237 state_frame[2] != DAIKIN_BRC_HEADER_BYTE2 || state_frame[3] != (DAIKIN_BRC_HEADER_BYTE3 | this->sub_unit_) ||
238 state_frame[4] != DAIKIN_BRC_FRAME_TYPE_STATE) {
239 return false;
240 }
241 return this->parse_state_frame_(state_frame);
242}
243
244} // 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:31
const optional< ClimateMode > & get_mode() const
Definition climate.cpp:315
ClimateMode mode
The active mode of the climate device.
Definition climate.h:317
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition climate.h:311
float target_temperature
The target temperature of the climate device.
Definition climate.h:298
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition climate.h:323
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition climate.cpp:432
bool parse_state_frame_(const uint8_t frame[])
void control(const climate::ClimateCall &call) override
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 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
ESPHOME_LOG_TAG(TAG, "daikin_brc.climate")
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_IR_FREQUENCY
Definition daikin_brc.h:30
const uint8_t DAIKIN_BRC_IR_DRY_FAN_TEMP_F
Definition daikin_brc.h:38
constexpr uint8_t sum_bytes(const uint8_t *data, size_t len, uint8_t sum=0)
Add up the bytes of data with size len, truncated to 8 bits: the checksum many serial and IR protocol...
Definition helpers.h:894
uint16_t temperature
Definition sun_gtil2.cpp:12