ESPHome  2024.11.0
climate_ir_lg.cpp
Go to the documentation of this file.
1 #include "climate_ir_lg.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace climate_ir_lg {
6 
7 static const char *const TAG = "climate.climate_ir_lg";
8 
9 // Commands
10 const uint32_t COMMAND_MASK = 0xFF000;
11 const uint32_t COMMAND_OFF = 0xC0000;
12 const uint32_t COMMAND_SWING = 0x10000;
13 
14 const uint32_t COMMAND_ON_COOL = 0x00000;
15 const uint32_t COMMAND_ON_DRY = 0x01000;
16 const uint32_t COMMAND_ON_FAN_ONLY = 0x02000;
17 const uint32_t COMMAND_ON_AI = 0x03000;
18 const uint32_t COMMAND_ON_HEAT = 0x04000;
19 
20 const uint32_t COMMAND_COOL = 0x08000;
21 const uint32_t COMMAND_DRY = 0x09000;
22 const uint32_t COMMAND_FAN_ONLY = 0x0A000;
23 const uint32_t COMMAND_AI = 0x0B000;
24 const uint32_t COMMAND_HEAT = 0x0C000;
25 
26 // Fan speed
27 const uint32_t FAN_MASK = 0xF0;
28 const uint32_t FAN_AUTO = 0x50;
29 const uint32_t FAN_MIN = 0x00;
30 const uint32_t FAN_MED = 0x20;
31 const uint32_t FAN_MAX = 0x40;
32 
33 // Temperature
34 const uint8_t TEMP_RANGE = TEMP_MAX - TEMP_MIN + 1;
35 const uint32_t TEMP_MASK = 0XF00;
36 const uint32_t TEMP_SHIFT = 8;
37 
38 const uint16_t BITS = 28;
39 
41  uint32_t remote_state = 0x8800000;
42 
43  // ESP_LOGD(TAG, "climate_lg_ir mode_before_ code: 0x%02X", modeBefore_);
44 
45  // Set command
46  if (send_swing_cmd_) {
47  send_swing_cmd_ = false;
48  remote_state |= COMMAND_SWING;
49  } else {
50  bool climate_is_off = (mode_before_ == climate::CLIMATE_MODE_OFF);
51  switch (this->mode) {
53  remote_state |= climate_is_off ? COMMAND_ON_COOL : COMMAND_COOL;
54  break;
56  remote_state |= climate_is_off ? COMMAND_ON_DRY : COMMAND_DRY;
57  break;
59  remote_state |= climate_is_off ? COMMAND_ON_FAN_ONLY : COMMAND_FAN_ONLY;
60  break;
62  remote_state |= climate_is_off ? COMMAND_ON_AI : COMMAND_AI;
63  break;
65  remote_state |= climate_is_off ? COMMAND_ON_HEAT : COMMAND_HEAT;
66  break;
68  default:
69  remote_state |= COMMAND_OFF;
70  break;
71  }
72  }
73 
74  mode_before_ = this->mode;
75 
76  ESP_LOGD(TAG, "climate_lg_ir mode code: 0x%02X", this->mode);
77 
78  // Set fan speed
79  if (this->mode == climate::CLIMATE_MODE_OFF) {
80  remote_state |= FAN_AUTO;
81  } else {
82  switch (this->fan_mode.value()) {
84  remote_state |= FAN_MAX;
85  break;
87  remote_state |= FAN_MED;
88  break;
90  remote_state |= FAN_MIN;
91  break;
93  default:
94  remote_state |= FAN_AUTO;
95  break;
96  }
97  }
98 
99  // Set temperature
101  auto temp = (uint8_t) roundf(clamp<float>(this->target_temperature, TEMP_MIN, TEMP_MAX));
102  remote_state |= ((temp - 15) << TEMP_SHIFT);
103  }
104 
105  transmit_(remote_state);
106  this->publish_state();
107 }
108 
110  uint8_t nbits = 0;
111  uint32_t remote_state = 0;
112 
113  if (!data.expect_item(this->header_high_, this->header_low_))
114  return false;
115 
116  for (nbits = 0; nbits < 32; nbits++) {
117  if (data.expect_item(this->bit_high_, this->bit_one_low_)) {
118  remote_state = (remote_state << 1) | 1;
119  } else if (data.expect_item(this->bit_high_, this->bit_zero_low_)) {
120  remote_state = (remote_state << 1) | 0;
121  } else if (nbits == BITS) {
122  break;
123  } else {
124  return false;
125  }
126  }
127 
128  ESP_LOGD(TAG, "Decoded 0x%02" PRIX32, remote_state);
129  if ((remote_state & 0xFF00000) != 0x8800000)
130  return false;
131 
132  // Get command
133  if ((remote_state & COMMAND_MASK) == COMMAND_OFF) {
135  } else if ((remote_state & COMMAND_MASK) == COMMAND_SWING) {
136  this->swing_mode =
138  } else {
139  switch (remote_state & COMMAND_MASK) {
140  case COMMAND_DRY:
141  case COMMAND_ON_DRY:
143  break;
144  case COMMAND_FAN_ONLY:
145  case COMMAND_ON_FAN_ONLY:
147  break;
148  case COMMAND_AI:
149  case COMMAND_ON_AI:
151  break;
152  case COMMAND_HEAT:
153  case COMMAND_ON_HEAT:
155  break;
156  case COMMAND_COOL:
157  case COMMAND_ON_COOL:
158  default:
160  break;
161  }
162 
163  // Get fan speed
164  if (this->mode == climate::CLIMATE_MODE_HEAT_COOL) {
166  } else if (this->mode == climate::CLIMATE_MODE_COOL || this->mode == climate::CLIMATE_MODE_DRY ||
168  if ((remote_state & FAN_MASK) == FAN_AUTO) {
170  } else if ((remote_state & FAN_MASK) == FAN_MIN) {
172  } else if ((remote_state & FAN_MASK) == FAN_MED) {
174  } else if ((remote_state & FAN_MASK) == FAN_MAX) {
176  }
177  }
178 
179  // Get temperature
181  this->target_temperature = ((remote_state & TEMP_MASK) >> TEMP_SHIFT) + 15;
182  }
183  }
184  this->publish_state();
185 
186  return true;
187 }
188 
189 void LgIrClimate::transmit_(uint32_t value) {
190  calc_checksum_(value);
191  ESP_LOGD(TAG, "Sending climate_lg_ir code: 0x%02" PRIX32, value);
192 
193  auto transmit = this->transmitter_->transmit();
194  auto *data = transmit.get_data();
195 
196  data->set_carrier_frequency(38000);
197  data->reserve(2 + BITS * 2u);
198 
199  data->item(this->header_high_, this->header_low_);
200 
201  for (uint32_t mask = 1UL << (BITS - 1); mask != 0; mask >>= 1) {
202  if (value & mask) {
203  data->item(this->bit_high_, this->bit_one_low_);
204  } else {
205  data->item(this->bit_high_, this->bit_zero_low_);
206  }
207  }
208  data->mark(this->bit_high_);
209  transmit.perform();
210 }
211 void LgIrClimate::calc_checksum_(uint32_t &value) {
212  uint32_t mask = 0xF;
213  uint32_t sum = 0;
214  for (uint8_t i = 1; i < 8; i++) {
215  sum += (value & (mask << (i * 4))) >> (i * 4);
216  }
217 
218  value |= (sum & mask);
219 }
220 
221 } // namespace climate_ir_lg
222 } // namespace esphome
const uint32_t COMMAND_ON_HEAT
The fan mode is set to Low.
Definition: climate_mode.h:54
const uint32_t COMMAND_DRY
value_type const & value() const
Definition: optional.h:89
const uint32_t COMMAND_MASK
climate::ClimateMode mode_before_
Definition: climate_ir_lg.h:53
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition: climate.h:202
const uint8_t TEMP_MIN
Definition: climate_ir_lg.h:11
const uint32_t COMMAND_FAN_ONLY
float target_temperature
The target temperature of the climate device.
Definition: climate.h:186
const uint32_t FAN_MED
void set_carrier_frequency(uint32_t carrier_frequency)
Definition: remote_base.h:34
const uint32_t COMMAND_ON_FAN_ONLY
const uint32_t TEMP_MASK
The climate device is set to heat to reach the target temperature.
Definition: climate_mode.h:18
const uint32_t COMMAND_AI
ClimateMode mode
The active mode of the climate device.
Definition: climate.h:173
bool on_receive(remote_base::RemoteReceiveData data) override
Handle received IR Buffer.
The climate device is set to dry/humidity mode.
Definition: climate_mode.h:22
const uint32_t COMMAND_OFF
The climate device is set to cool to reach the target temperature.
Definition: climate_mode.h:16
The fan mode is set to Auto.
Definition: climate_mode.h:52
const uint32_t COMMAND_COOL
const uint32_t COMMAND_ON_AI
void calc_checksum_(uint32_t &value)
RemoteTransmitterBase * transmitter_
Definition: remote_base.h:276
const uint32_t FAN_AUTO
const uint32_t FAN_MASK
The climate device is set to heat/cool to reach the target temperature.
Definition: climate_mode.h:14
The fan mode is set to Vertical.
Definition: climate_mode.h:76
const uint32_t COMMAND_SWING
void transmit_state() override
Transmit via IR the state of this climate controller.
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 TEMP_SHIFT
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
Definition: climate.h:199
const uint32_t COMMAND_HEAT
const uint32_t COMMAND_ON_DRY
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
const uint8_t TEMP_MAX
Definition: climate_ir_lg.h:12
The fan mode is set to Medium.
Definition: climate_mode.h:56
bool expect_item(uint32_t mark, uint32_t space)
Definition: remote_base.cpp:74
const uint32_t FAN_MIN
The climate device only has the fan enabled, no heating or cooling is taking place.
Definition: climate_mode.h:20
const uint8_t TEMP_RANGE
const uint32_t COMMAND_ON_COOL
const uint32_t FAN_MAX