ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
ballu.cpp
Go to the documentation of this file.
1#include "ballu.h"
2#include "esphome/core/log.h"
3
4namespace esphome::ballu {
5
6ESPHOME_LOG_TAG(TAG, "ballu.climate");
7
8const uint16_t BALLU_HEADER_MARK = 9000;
9const uint16_t BALLU_HEADER_SPACE = 4500;
10const uint16_t BALLU_BIT_MARK = 575;
11static constexpr remote_base::BitTimings BALLU_BIT_TIMINGS{
12 .bit_mark = BALLU_BIT_MARK, .one_space = 1675, .zero_space = 550};
13
15
16const uint8_t BALLU_STATE_LENGTH = 13;
17
18const uint8_t BALLU_AUTO = 0;
19const uint8_t BALLU_COOL = 0x20;
20const uint8_t BALLU_DRY = 0x40;
21const uint8_t BALLU_HEAT = 0x80;
22const uint8_t BALLU_FAN = 0xc0;
23
24const uint8_t BALLU_FAN_AUTO = 0xa0;
25const uint8_t BALLU_FAN_HIGH = 0x20;
26const uint8_t BALLU_FAN_MED = 0x40;
27const uint8_t BALLU_FAN_LOW = 0x60;
28
29const uint8_t BALLU_SWING_VER = 0x07;
30const uint8_t BALLU_SWING_HOR = 0xe0;
31const uint8_t BALLU_POWER = 0x20;
32
34 uint8_t remote_state[BALLU_STATE_LENGTH] = {0};
35
36 auto temp = (uint8_t) roundf(clamp(this->target_temperature, YKR_K_002E_TEMP_MIN, YKR_K_002E_TEMP_MAX));
37 auto swing_ver =
39 auto swing_hor =
41
42 remote_state[0] = 0xc3;
43 remote_state[1] = ((temp - 8) << 3) | (swing_ver ? 0 : BALLU_SWING_VER);
44 remote_state[2] = swing_hor ? 0 : BALLU_SWING_HOR;
45 remote_state[9] = (this->mode == climate::CLIMATE_MODE_OFF) ? 0 : BALLU_POWER;
46 remote_state[11] = 0x1e;
47
48 // Fan speed
49 switch (this->fan_mode.value_or(climate::CLIMATE_FAN_ON)) {
51 remote_state[4] |= BALLU_FAN_HIGH;
52 break;
54 remote_state[4] |= BALLU_FAN_MED;
55 break;
57 remote_state[4] |= BALLU_FAN_LOW;
58 break;
60 remote_state[4] |= BALLU_FAN_AUTO;
61 break;
62 default:
63 break;
64 }
65
66 // Mode
67 switch (this->mode) {
69 remote_state[6] |= BALLU_AUTO;
70 break;
72 remote_state[6] |= BALLU_HEAT;
73 break;
75 remote_state[6] |= BALLU_COOL;
76 break;
78 remote_state[6] |= BALLU_DRY;
79 break;
81 remote_state[6] |= BALLU_FAN;
82 break;
84 remote_state[6] |= BALLU_AUTO;
85 default:
86 break;
87 }
88
89 // Checksum
90 for (uint8_t i = 0; i < BALLU_STATE_LENGTH - 1; i++)
91 remote_state[12] += remote_state[i];
92
93 ESP_LOGV(TAG, "Sending: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", remote_state[0],
94 remote_state[1], remote_state[2], remote_state[3], remote_state[4], remote_state[5], remote_state[6],
95 remote_state[7], remote_state[8], remote_state[9], remote_state[10], remote_state[11], remote_state[12]);
96
97 // Send code
98 auto transmit = this->transmitter_->transmit();
99 auto *data = transmit.get_data();
100
101 data->set_carrier_frequency(38000);
102
103 // Header
104 data->mark(BALLU_HEADER_MARK);
105 data->space(BALLU_HEADER_SPACE);
106 // Data
107 data->item_bytes<BALLU_BIT_TIMINGS>(remote_state, BALLU_STATE_LENGTH);
108 // Footer
109 data->mark(BALLU_BIT_MARK);
110
111 transmit.perform();
112}
113
115 // Validate header
116 if (!data.expect_item(BALLU_HEADER_MARK, BALLU_HEADER_SPACE)) {
117 ESP_LOGV(TAG, "Header fail");
118 return false;
119 }
120
121 uint8_t remote_state[BALLU_STATE_LENGTH];
122 if (!data.expect_bytes<BALLU_BIT_TIMINGS>(remote_state, BALLU_STATE_LENGTH)) {
123 ESP_LOGV(TAG, "Data fail");
124 return false;
125 }
126 // Validate footer
127 if (!data.expect_mark(BALLU_BIT_MARK)) {
128 ESP_LOGV(TAG, "Footer fail");
129 return false;
130 }
131
132 const uint8_t checksum = sum_bytes(remote_state, BALLU_STATE_LENGTH - 1);
133
134 if (checksum != remote_state[BALLU_STATE_LENGTH - 1]) {
135 ESP_LOGVV(TAG, "Checksum fail");
136 return false;
137 }
138
139 ESP_LOGV(TAG, "Received: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", remote_state[0],
140 remote_state[1], remote_state[2], remote_state[3], remote_state[4], remote_state[5], remote_state[6],
141 remote_state[7], remote_state[8], remote_state[9], remote_state[10], remote_state[11], remote_state[12]);
142
143 // verify header remote code
144 if (remote_state[0] != 0xc3)
145 return false;
146
147 // powr on/off button
148 ESP_LOGV(TAG, "Power: %02X", (remote_state[9] & BALLU_POWER));
149
150 if ((remote_state[9] & BALLU_POWER) != BALLU_POWER) {
152 } else {
153 auto mode = remote_state[6] & 0xe0;
154 ESP_LOGV(TAG, "Mode: %02X", mode);
155 switch (mode) {
156 case BALLU_HEAT:
158 break;
159 case BALLU_COOL:
161 break;
162 case BALLU_DRY:
164 break;
165 case BALLU_FAN:
167 break;
168 case BALLU_AUTO:
170 break;
171 default:
172 break;
173 }
174 }
175
176 // Set received temp
177 int temp = remote_state[1] & 0xf8;
178 ESP_LOGVV(TAG, "Temperature Raw: %02X", temp);
179 temp = ((uint8_t) temp >> 3) + 8;
180 ESP_LOGVV(TAG, "Temperature Climate: %u", temp);
181 this->target_temperature = temp;
182
183 // Set received fan speed
184 auto fan = remote_state[4] & 0xe0;
185 ESP_LOGVV(TAG, "Fan: %02X", fan);
186 switch (fan) {
187 case BALLU_FAN_HIGH:
189 break;
190 case BALLU_FAN_MED:
192 break;
193 case BALLU_FAN_LOW:
195 break;
196 case BALLU_FAN_AUTO:
197 default:
199 break;
200 }
201
202 // Set received swing status
203 ESP_LOGVV(TAG, "Swing status: %02X %02X", remote_state[1] & BALLU_SWING_VER, remote_state[2] & BALLU_SWING_HOR);
204 if (((remote_state[1] & BALLU_SWING_VER) != BALLU_SWING_VER) &&
205 ((remote_state[2] & BALLU_SWING_HOR) != BALLU_SWING_HOR)) {
207 } else if ((remote_state[1] & BALLU_SWING_VER) != BALLU_SWING_VER) {
209 } else if ((remote_state[2] & BALLU_SWING_HOR) != BALLU_SWING_HOR) {
211 } else {
213 }
214
215 this->publish_state();
216 return true;
217}
218
219} // namespace esphome::ballu
uint8_t checksum
Definition bl0906.h:3
void transmit_state() override
Transmit via IR the state of this climate controller.
Definition ballu.cpp:33
bool on_receive(remote_base::RemoteReceiveData data) override
Handle received IR Buffer.
Definition ballu.cpp:114
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
const uint16_t BALLU_HEADER_SPACE
Definition ballu.cpp:9
ESPHOME_LOG_TAG(TAG, "ballu.climate")
const uint8_t BALLU_COOL
Definition ballu.cpp:19
const uint8_t BALLU_AUTO
Definition ballu.cpp:18
const uint16_t BALLU_BIT_MARK
Definition ballu.cpp:10
const float YKR_K_002E_TEMP_MIN
Definition ballu.h:10
const uint8_t BALLU_DRY
Definition ballu.cpp:20
const uint8_t BALLU_FAN
Definition ballu.cpp:22
const uint8_t BALLU_STATE_LENGTH
Definition ballu.cpp:16
const uint32_t BALLU_CARRIER_FREQUENCY
Definition ballu.cpp:14
const float YKR_K_002E_TEMP_MAX
Definition ballu.h:11
const uint8_t BALLU_SWING_VER
Definition ballu.cpp:29
const uint8_t BALLU_FAN_LOW
Definition ballu.cpp:27
const uint8_t BALLU_HEAT
Definition ballu.cpp:21
const uint8_t BALLU_FAN_AUTO
Definition ballu.cpp:24
const uint16_t BALLU_HEADER_MARK
Definition ballu.cpp:8
const uint8_t BALLU_FAN_HIGH
Definition ballu.cpp:25
const uint8_t BALLU_POWER
Definition ballu.cpp:31
const uint8_t BALLU_SWING_HOR
Definition ballu.cpp:30
const uint8_t BALLU_FAN_MED
Definition ballu.cpp:26
@ CLIMATE_SWING_OFF
The swing mode is set to Off.
@ CLIMATE_SWING_HORIZONTAL
The fan mode is set to Horizontal.
@ CLIMATE_SWING_VERTICAL
The fan mode is set to Vertical.
@ 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_OFF
The climate device is off.
@ CLIMATE_MODE_AUTO
The climate device is adjusting the temperature dynamically.
@ CLIMATE_FAN_MEDIUM
The fan mode is set to Medium.
@ CLIMATE_FAN_ON
The fan mode is set to On.
@ 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.
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
static void uint32_t
A bit is a mark (one_mark or zero_mark, both bit_mark unless set) and a space (one_space or zero_spac...
Definition remote_base.h:29