ESPHome 2025.5.0
Loading...
Searching...
No Matches
climate_ir_lg.cpp
Go to the documentation of this file.
1#include "climate_ir_lg.h"
2#include "esphome/core/log.h"
3
4namespace esphome {
5namespace climate_ir_lg {
6
7static const char *const TAG = "climate.climate_ir_lg";
8
9// Commands
10const uint32_t COMMAND_MASK = 0xFF000;
11const uint32_t COMMAND_OFF = 0xC0000;
12const uint32_t COMMAND_SWING = 0x10000;
13
14const uint32_t COMMAND_ON_COOL = 0x00000;
15const uint32_t COMMAND_ON_DRY = 0x01000;
16const uint32_t COMMAND_ON_FAN_ONLY = 0x02000;
17const uint32_t COMMAND_ON_AI = 0x03000;
18const uint32_t COMMAND_ON_HEAT = 0x04000;
19
20const uint32_t COMMAND_COOL = 0x08000;
21const uint32_t COMMAND_DRY = 0x09000;
22const uint32_t COMMAND_FAN_ONLY = 0x0A000;
23const uint32_t COMMAND_AI = 0x0B000;
24const uint32_t COMMAND_HEAT = 0x0C000;
25
26// Fan speed
27const uint32_t FAN_MASK = 0xF0;
28const uint32_t FAN_AUTO = 0x50;
29const uint32_t FAN_MIN = 0x00;
30const uint32_t FAN_MED = 0x20;
31const uint32_t FAN_MAX = 0x40;
32
33// Temperature
34const uint8_t TEMP_RANGE = TEMP_MAX - TEMP_MIN + 1;
35const uint32_t TEMP_MASK = 0xF00;
36const uint32_t TEMP_SHIFT = 8;
37
38const 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 (this->send_swing_cmd_) {
47 this->send_swing_cmd_ = false;
48 remote_state |= COMMAND_SWING;
49 } else {
50 bool climate_is_off = (this->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 this->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 this->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:
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
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
189void LgIrClimate::transmit_(uint32_t value) {
190 this->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}
211void 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
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 on_receive(remote_base::RemoteReceiveData data) override
Handle received IR Buffer.
void transmit_state() override
Transmit via IR the state of this climate controller.
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
const uint32_t COMMAND_OFF
const uint32_t COMMAND_COOL
const uint32_t COMMAND_ON_FAN_ONLY
const uint32_t TEMP_SHIFT
const uint32_t COMMAND_ON_DRY
const uint32_t COMMAND_MASK
const uint32_t COMMAND_FAN_ONLY
const uint32_t COMMAND_ON_COOL
const uint32_t COMMAND_AI
const uint32_t COMMAND_DRY
const uint32_t COMMAND_HEAT
const uint32_t COMMAND_SWING
const uint32_t COMMAND_ON_AI
const uint32_t COMMAND_ON_HEAT
@ CLIMATE_SWING_OFF
The swing mode is set to Off.
@ CLIMATE_SWING_VERTICAL
The fan mode is set to Vertical.
@ 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_HIGH
The fan mode is set to High.
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7