8 static const char *
const TAG =
"noblex.climate";
19 IR_NOBLEX_MODE_AUTO = 0b000,
20 IR_NOBLEX_MODE_COOL = 0b100,
21 IR_NOBLEX_MODE_DRY = 0b010,
22 IR_NOBLEX_MODE_FAN = 0b110,
23 IR_NOBLEX_MODE_HEAT = 0b001,
27 IR_NOBLEX_FAN_AUTO = 0b00,
28 IR_NOBLEX_FAN_LOW = 0b10,
29 IR_NOBLEX_FAN_MEDIUM = 0b01,
30 IR_NOBLEX_FAN_HIGH = 0
b11,
35 uint8_t remote_state[8] = {0x80, 0x10, 0x00, 0x0A, 0x50, 0x00, 0x20, 0x00};
39 remote_state[0] |= 0x10;
40 remote_state[2] = 0x02;
50 remote_state[0] |= (IRNoblexMode::IR_NOBLEX_MODE_AUTO << 5);
51 remote_state[1] = 0x90;
54 remote_state[0] |= (IRNoblexMode::IR_NOBLEX_MODE_COOL << 5);
57 remote_state[0] |= (IRNoblexMode::IR_NOBLEX_MODE_DRY << 5);
60 remote_state[0] |= (IRNoblexMode::IR_NOBLEX_MODE_FAN << 5);
63 remote_state[0] |= (IRNoblexMode::IR_NOBLEX_MODE_HEAT << 5);
69 remote_state[0] &= 0xEF;
70 remote_state[2] = 0x00;
76 remote_state[0] |= (IRNoblexFan::IR_NOBLEX_FAN_LOW << 2);
79 remote_state[0] |= (IRNoblexFan::IR_NOBLEX_FAN_MEDIUM << 2);
82 remote_state[0] |= (IRNoblexFan::IR_NOBLEX_FAN_HIGH << 2);
86 remote_state[0] |= (IRNoblexFan::IR_NOBLEX_FAN_AUTO << 2);
92 remote_state[0] |= 0x02;
93 remote_state[4] = 0x58;
97 remote_state[0] &= 0xFD;
98 remote_state[4] = 0x50;
103 for (uint8_t i : remote_state) {
108 ESP_LOGD(TAG,
"Sending noblex code: %02X%02X %02X%02X %02X%02X %02X%02X", remote_state[0], remote_state[1],
109 remote_state[2], remote_state[3], remote_state[4], remote_state[5], remote_state[6], remote_state[7]);
111 ESP_LOGV(TAG,
"CRC: %01X", crc);
118 data->mark(NOBLEX_HEADER_MARK);
119 data->space(NOBLEX_HEADER_SPACE);
121 for (uint8_t i : remote_state) {
122 for (int8_t j = 7; j >= 0; j--) {
123 if ((i == 4) & (j == 4)) {
125 data->mark(NOBLEX_BIT_MARK);
126 data->space(NOBLEX_GAP);
128 data->mark(NOBLEX_BIT_MARK);
129 bool bit = i & (1 << j);
130 data->space(bit ? NOBLEX_ONE_SPACE : NOBLEX_ZERO_SPACE);
135 for (int8_t i = 3; i >= 0; i--) {
136 data->mark(NOBLEX_BIT_MARK);
137 bool bit = crc & (1 << i);
138 data->space(bit ? NOBLEX_ONE_SPACE : NOBLEX_ZERO_SPACE);
141 data->mark(NOBLEX_BIT_MARK);
148 uint8_t remote_state[8] = {0};
149 uint8_t
crc = 0, crc_calculated = 0;
153 if (data.
expect_item(NOBLEX_HEADER_MARK, NOBLEX_HEADER_SPACE)) {
154 ESP_LOGV(TAG,
"Header");
157 for (
int i = 0; i < 5; i++) {
159 for (
int j = 7; j >= 0; j--) {
160 if ((i == 4) & (j == 4)) {
161 remote_state[i] |= 1 << j;
163 ESP_LOGVV(TAG,
"GAP");
165 }
else if (data.
expect_item(NOBLEX_BIT_MARK, NOBLEX_ONE_SPACE)) {
166 remote_state[i] |= 1 << j;
167 }
else if (!data.
expect_item(NOBLEX_BIT_MARK, NOBLEX_ZERO_SPACE)) {
168 ESP_LOGVV(TAG,
"Byte %d bit %d fail", i, j);
172 ESP_LOGV(TAG,
"Byte %d %02X", i, remote_state[i]);
176 ESP_LOGV(TAG,
"Header fail");
183 for (
int i = 4; i < 8; i++) {
185 for (
int j = 7; j >= 0; j--) {
186 if ((i == 4) & (j >= 4)) {
188 }
else if (data.
expect_item(NOBLEX_BIT_MARK, NOBLEX_ONE_SPACE)) {
189 remote_state[i] |= 1 << j;
190 }
else if (!data.
expect_item(NOBLEX_BIT_MARK, NOBLEX_ZERO_SPACE)) {
191 ESP_LOGVV(TAG,
"Byte %d bit %d fail", i, j);
195 ESP_LOGV(TAG,
"Byte %d %02X", i, remote_state[i]);
199 for (
int i = 3; i >= 0; i--) {
200 if (data.
expect_item(NOBLEX_BIT_MARK, NOBLEX_ONE_SPACE)) {
202 }
else if (!data.
expect_item(NOBLEX_BIT_MARK, NOBLEX_ZERO_SPACE)) {
203 ESP_LOGVV(TAG,
"Bit %d CRC fail", i);
207 ESP_LOGV(TAG,
"CRC %02X", crc);
211 ESP_LOGV(TAG,
"Footer fail");
217 for (uint8_t i : remote_state)
219 crc_calculated =
reverse_bits(uint8_t(crc_calculated & 0x0F)) >> 4;
220 ESP_LOGVV(TAG,
"CRC calc %02X", crc_calculated);
222 if (crc != crc_calculated) {
223 ESP_LOGV(TAG,
"CRC fail");
227 ESP_LOGD(TAG,
"Received noblex code: %02X%02X %02X%02X %02X%02X %02X%02X", remote_state[0], remote_state[1],
228 remote_state[2], remote_state[3], remote_state[4], remote_state[5], remote_state[6], remote_state[7]);
230 auto powered_on =
false;
231 if ((remote_state[0] & NOBLEX_POWER) == NOBLEX_POWER) {
240 ESP_LOGV(TAG,
"Power: %01X", powered_on);
244 auto mode = (remote_state[0] & 0xE0) >> 5;
245 ESP_LOGV(TAG,
"Mode: %02X",
mode);
247 case IRNoblexMode::IR_NOBLEX_MODE_AUTO:
250 case IRNoblexMode::IR_NOBLEX_MODE_COOL:
253 case IRNoblexMode::IR_NOBLEX_MODE_DRY:
256 case IRNoblexMode::IR_NOBLEX_MODE_FAN:
259 case IRNoblexMode::IR_NOBLEX_MODE_HEAT:
266 uint8_t temp = remote_state[1];
267 ESP_LOGVV(TAG,
"Temperature Raw: %02X", temp);
271 ESP_LOGV(TAG,
"Temperature Climate: %u", temp);
275 auto fan = (remote_state[0] & 0x0C) >> 2;
276 ESP_LOGV(TAG,
"Fan: %02X", fan);
278 case IRNoblexFan::IR_NOBLEX_FAN_HIGH:
281 case IRNoblexFan::IR_NOBLEX_FAN_MEDIUM:
284 case IRNoblexFan::IR_NOBLEX_FAN_LOW:
287 case IRNoblexFan::IR_NOBLEX_FAN_AUTO:
294 if (remote_state[0] & 0x02) {
295 ESP_LOGV(TAG,
"Swing vertical");
298 ESP_LOGV(TAG,
"Swing OFF");
302 for (uint8_t &i : remote_state)
The fan mode is set to Low.
value_type const & value() const
ClimateSwingMode swing_mode
The active swing mode of the climate device.
float target_temperature
The target temperature of the climate device.
void set_carrier_frequency(uint32_t carrier_frequency)
The climate device is set to heat to reach the target temperature.
const uint8_t NOBLEX_TEMP_MAX
const uint32_t NOBLEX_GAP
ClimateMode mode
The active mode of the climate device.
The climate device is set to dry/humidity mode.
const uint8_t NOBLEX_TEMP_MIN
enum IRNoblexMode { IR_NOBLEX_MODE_AUTO=0b000, IR_NOBLEX_MODE_COOL=0b100, IR_NOBLEX_MODE_DRY=0b010, IR_NOBLEX_MODE_FAN=0b110, IR_NOBLEX_MODE_HEAT=0b001, } IRNoblexMode
bool expect_mark(uint32_t length)
uint8_t reverse_bits(uint8_t x)
Reverse the order of 8 bits.
The climate device is set to cool to reach the target temperature.
The fan mode is set to Auto.
void transmit_state() override
Transmit via IR the state of this climate controller.
const uint16_t NOBLEX_HEADER_MARK
RemoteTransmitterBase * transmitter_
The climate device is set to heat/cool to reach the target temperature.
The fan mode is set to Vertical.
void publish_state()
Publish the state of the climate device, to be called from integrations.
The fan mode is set to High.
RemoteTransmitData * get_data()
The swing mode is set to Off.
The climate device is off.
const uint8_t NOBLEX_POWER
optional< ClimateFanMode > fan_mode
The active fan mode of the climate device.
enum IRNoblexFan { IR_NOBLEX_FAN_AUTO=0b00, IR_NOBLEX_FAN_LOW=0b10, IR_NOBLEX_FAN_MEDIUM=0b01, IR_NOBLEX_FAN_HIGH=0b11, } IRNoblexFan
const uint16_t NOBLEX_BIT_MARK
Implementation of SPI Controller mode.
bool on_receive(remote_base::RemoteReceiveData data) override
Handle received IR Buffer.
const uint16_t NOBLEX_HEADER_SPACE
The fan mode is set to Medium.
bool expect_item(uint32_t mark, uint32_t space)
The climate device only has the fan enabled, no heating or cooling is taking place.
const uint16_t NOBLEX_ZERO_SPACE
const uint16_t NOBLEX_ONE_SPACE