ESPHome  2024.3.1
daikin_brc.cpp
Go to the documentation of this file.
1 #include "daikin_brc.h"
3 
4 namespace esphome {
5 namespace daikin_brc {
6 
7 static const char *const TAG = "daikin_brc.climate";
8 
10  this->mode_button_ = 0x00;
11  if (call.get_mode().has_value()) {
12  // Need to determine if this is call due to Mode button pressed so that we can set the Mode button byte
14  }
15  ClimateIR::control(call);
16 }
17 
19  uint8_t remote_state[DAIKIN_BRC_TRANSMIT_FRAME_SIZE] = {0x11, 0xDA, 0x17, 0x18, 0x04, 0x00, 0x1E, 0x11,
20  0xDA, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
21  0x00, 0x00, 0x00, 0x00, 0x20, 0x00};
22 
23  remote_state[12] = this->alt_mode_();
24  remote_state[13] = this->mode_button_;
25  remote_state[14] = this->operation_mode_();
26  remote_state[17] = this->temperature_();
27  remote_state[18] = this->fan_speed_swing_();
28 
29  // Calculate checksum
30  for (int i = DAIKIN_BRC_PREAMBLE_SIZE; i < DAIKIN_BRC_TRANSMIT_FRAME_SIZE - 1; i++) {
31  remote_state[DAIKIN_BRC_TRANSMIT_FRAME_SIZE - 1] += remote_state[i];
32  }
33 
34  auto transmit = this->transmitter_->transmit();
35  auto *data = transmit.get_data();
37 
38  data->mark(DAIKIN_BRC_HEADER_MARK);
39  data->space(DAIKIN_BRC_HEADER_SPACE);
40  for (int i = 0; i < DAIKIN_BRC_PREAMBLE_SIZE; i++) {
41  for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
42  data->mark(DAIKIN_BRC_BIT_MARK);
43  bool bit = remote_state[i] & mask;
44  data->space(bit ? DAIKIN_BRC_ONE_SPACE : DAIKIN_BRC_ZERO_SPACE);
45  }
46  }
47  data->mark(DAIKIN_BRC_BIT_MARK);
48  data->space(DAIKIN_BRC_MESSAGE_SPACE);
49  data->mark(DAIKIN_BRC_HEADER_MARK);
50  data->space(DAIKIN_BRC_HEADER_SPACE);
51 
52  for (int i = DAIKIN_BRC_PREAMBLE_SIZE; i < DAIKIN_BRC_TRANSMIT_FRAME_SIZE; i++) {
53  for (uint8_t mask = 1; mask > 0; mask <<= 1) { // iterate through bit mask
54  data->mark(DAIKIN_BRC_BIT_MARK);
55  bool bit = remote_state[i] & mask;
56  data->space(bit ? DAIKIN_BRC_ONE_SPACE : DAIKIN_BRC_ZERO_SPACE);
57  }
58  }
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()) {
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.8) + 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 
163 bool DaikinBrcClimate::parse_state_frame_(const uint8_t frame[]) {
164  uint8_t checksum = 0;
165  for (int i = 0; i < (DAIKIN_BRC_STATE_FRAME_SIZE - 1); i++) {
166  checksum += frame[i];
167  }
168  if (frame[DAIKIN_BRC_STATE_FRAME_SIZE - 1] != checksum) {
169  ESP_LOGCONFIG(TAG, "Bad CheckSum %x", checksum);
170  return false;
171  }
172 
173  uint8_t mode = frame[7];
174  if (mode & DAIKIN_BRC_MODE_ON) {
175  switch (mode & 0xF0) {
177  this->mode = climate::CLIMATE_MODE_COOL;
178  break;
179  case DAIKIN_BRC_MODE_DRY:
180  this->mode = climate::CLIMATE_MODE_DRY;
181  break;
183  this->mode = climate::CLIMATE_MODE_HEAT;
184  break;
186  this->mode = climate::CLIMATE_MODE_HEAT_COOL;
187  break;
188  case DAIKIN_BRC_MODE_FAN:
189  this->mode = climate::CLIMATE_MODE_FAN_ONLY;
190  break;
191  }
192  } else {
193  this->mode = climate::CLIMATE_MODE_OFF;
194  }
195 
196  uint8_t temperature = frame[10];
197  float temperature_c;
198  if (this->fahrenheit_) {
199  temperature_c = clamp<float>(((temperature - 32) / 1.8), DAIKIN_BRC_TEMP_MIN_C, DAIKIN_BRC_TEMP_MAX_C);
200  } else {
201  temperature_c = (temperature >> 1) + 9;
202  }
203 
204  this->target_temperature = temperature_c;
205 
206  uint8_t fan_mode = frame[11];
207  uint8_t swing_mode = frame[11];
208  switch (swing_mode & 0xF) {
210  this->swing_mode = climate::CLIMATE_SWING_BOTH;
211  break;
213  this->swing_mode = climate::CLIMATE_SWING_OFF;
214  break;
215  }
216 
217  switch (fan_mode & 0xF0) {
218  case DAIKIN_BRC_FAN_1:
219  this->fan_mode = climate::CLIMATE_FAN_LOW;
220  break;
221  case DAIKIN_BRC_FAN_2:
222  this->fan_mode = climate::CLIMATE_FAN_MEDIUM;
223  break;
224  case DAIKIN_BRC_FAN_3:
225  this->fan_mode = climate::CLIMATE_FAN_HIGH;
226  break;
227  }
228  this->publish_state();
229  return true;
230 }
231 
233  uint8_t state_frame[DAIKIN_BRC_STATE_FRAME_SIZE] = {};
235  return false;
236  }
237  for (uint8_t pos = 0; pos < DAIKIN_BRC_STATE_FRAME_SIZE; pos++) {
238  uint8_t byte = 0;
239  for (int8_t bit = 0; bit < 8; bit++) {
241  byte |= 1 << bit;
243  return false;
244  }
245  }
246  state_frame[pos] = byte;
247  if (pos == 0) {
248  // frame header
249  if (byte != 0x11)
250  return false;
251  } else if (pos == 1) {
252  // frame header
253  if (byte != 0xDA)
254  return false;
255  } else if (pos == 2) {
256  // frame header
257  if (byte != 0x17)
258  return false;
259  } else if (pos == 3) {
260  // frame header
261  if (byte != 0x18)
262  return false;
263  } else if (pos == 4) {
264  // frame type
265  if (byte != 0x00)
266  return false;
267  }
268  }
269  return this->parse_state_frame_(state_frame);
270 }
271 
272 } // namespace daikin_brc
273 } // namespace esphome
This class is used to encode all control actions on a climate device.
Definition: climate.h:33
The fan mode is set to Low.
Definition: climate_mode.h:54
value_type const & value() const
Definition: optional.h:89
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition: climate.h:202
The fan mode is set to Both.
Definition: climate_mode.h:74
const uint8_t DAIKIN_BRC_MODE_ON
Definition: daikin_brc.h:22
const uint32_t DAIKIN_BRC_IR_FREQUENCY
Definition: daikin_brc.h:31
const uint8_t DAIKIN_BRC_IR_SWING_OFF
Definition: daikin_brc.h:42
float target_temperature
The target temperature of the climate device.
Definition: climate.h:186
void set_carrier_frequency(uint32_t carrier_frequency)
Definition: remote_base.h:29
const optional< ClimateMode > & get_mode() const
Definition: climate.cpp:273
const uint32_t DAIKIN_BRC_HEADER_MARK
Definition: daikin_brc.h:32
The climate device is set to heat to reach the target temperature.
Definition: climate_mode.h:18
const uint8_t DAIKIN_BRC_TEMP_MAX_F
Definition: daikin_brc.h:11
ClimateMode mode
The active mode of the climate device.
Definition: climate.h:173
float temperature
Definition: qmp6988.h:71
const uint8_t DAIKIN_BRC_TEMP_MIN_F
Definition: daikin_brc.h:10
const uint8_t DAIKIN_BRC_MODE_COOL
Definition: daikin_brc.h:17
const uint8_t DAIKIN_BRC_MODE_DRY
Definition: daikin_brc.h:19
const float DAIKIN_BRC_TEMP_MIN_C
Definition: daikin_brc.h:12
bool has_value() const
Definition: optional.h:87
The climate device is set to dry/humidity mode.
Definition: climate_mode.h:22
bool on_receive(remote_base::RemoteReceiveData data) override
Definition: daikin_brc.cpp:232
const uint8_t DAIKIN_BRC_MODE_AUTO
Definition: daikin_brc.h:16
const uint8_t DAIKIN_BRC_FAN_3
Definition: daikin_brc.h:27
const uint8_t DAIKIN_BRC_STATE_FRAME_SIZE
Definition: daikin_brc.h:46
const uint32_t DAIKIN_BRC_BIT_MARK
Definition: daikin_brc.h:34
const uint8_t DAIKIN_BRC_IR_DRY_FAN_TEMP_F
Definition: daikin_brc.h:39
The climate device is set to cool to reach the target temperature.
Definition: climate_mode.h:16
const uint8_t DAIKIN_BRC_IR_SWING_ON
Definition: daikin_brc.h:41
RemoteTransmitterBase * transmitter_
Definition: remote_base.h:244
void control(const climate::ClimateCall &call) override
Definition: daikin_brc.cpp:9
The climate device is set to heat/cool to reach the target temperature.
Definition: climate_mode.h:14
const uint8_t DAIKIN_BRC_MODE_FAN
Definition: daikin_brc.h:20
uint8_t checksum
Definition: bl0939.h:35
const uint8_t DAIKIN_BRC_FAN_2
Definition: daikin_brc.h:26
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition: climate.cpp:395
The fan mode is set to High.
Definition: climate_mode.h:58
The swing mode is set to Off.
Definition: climate_mode.h:72
The climate device is off.
Definition: climate_mode.h:12
const uint32_t DAIKIN_BRC_ZERO_SPACE
Definition: daikin_brc.h:36
const float DAIKIN_BRC_TEMP_MAX_C
Definition: daikin_brc.h:13
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition: climate.h:199
const uint8_t DAIKIN_BRC_FAN_1
Definition: daikin_brc.h:25
bool parse_state_frame_(const uint8_t frame[])
Definition: daikin_brc.cpp:163
const uint8_t DAIKIN_BRC_PREAMBLE_SIZE
Definition: daikin_brc.h:48
const uint8_t DAIKIN_BRC_MODE_OFF
Definition: daikin_brc.h:21
const uint8_t DAIKIN_BRC_IR_DRY_FAN_TEMP_C
Definition: daikin_brc.h:40
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
const uint32_t DAIKIN_BRC_ONE_SPACE
Definition: daikin_brc.h:35
const uint8_t DAIKIN_BRC_MODE_HEAT
Definition: daikin_brc.h:18
The fan mode is set to Medium.
Definition: climate_mode.h:56
const uint8_t DAIKIN_BRC_TRANSMIT_FRAME_SIZE
Definition: daikin_brc.h:50
const uint32_t DAIKIN_BRC_MESSAGE_SPACE
Definition: daikin_brc.h:37
bool expect_item(uint32_t mark, uint32_t space)
Definition: remote_base.cpp:71
The climate device only has the fan enabled, no heating or cooling is taking place.
Definition: climate_mode.h:20
const uint8_t DAIKIN_BRC_IR_MODE_BUTTON
Definition: daikin_brc.h:43
const uint32_t DAIKIN_BRC_HEADER_SPACE
Definition: daikin_brc.h:33