ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
coolix_protocol.cpp
Go to the documentation of this file.
1#include "coolix_protocol.h"
2#include "esphome/core/log.h"
3
4namespace esphome::remote_base {
5
6static const char *const TAG = "remote.coolix";
7
8static const int32_t TICK_US = 560;
9static const int32_t HEADER_MARK_US = 8 * TICK_US;
10static const int32_t HEADER_SPACE_US = 8 * TICK_US;
11static const int32_t BIT_MARK_US = 1 * TICK_US;
12static const int32_t BIT_ONE_SPACE_US = 3 * TICK_US;
13static const int32_t BIT_ZERO_SPACE_US = 1 * TICK_US;
14static const int32_t FOOTER_MARK_US = 1 * TICK_US;
15static const int32_t FOOTER_SPACE_US = 10 * TICK_US;
16
17bool CoolixData::operator==(const CoolixData &other) const {
18 if (this->first == 0)
19 return this->second == other.first || this->second == other.second;
20 if (other.first == 0)
21 return other.second == this->first || other.second == this->second;
22 return this->first == other.first && this->second == other.second;
23}
24
25static void encode_frame(RemoteTransmitData *dst, const uint32_t &src) {
26 // Append header
27 dst->item(HEADER_MARK_US, HEADER_SPACE_US);
28 // Break data into bytes, starting at the Most Significant
29 // Byte. Each byte then being sent normal, then followed inverted.
30 for (unsigned shift = 16;; shift -= 8) {
31 // Grab a bytes worth of data
32 const uint8_t byte = src >> shift;
33 // Normal
34 for (uint8_t mask = 1 << 7; mask; mask >>= 1)
35 dst->item(BIT_MARK_US, (byte & mask) ? BIT_ONE_SPACE_US : BIT_ZERO_SPACE_US);
36 // Inverted
37 for (uint8_t mask = 1 << 7; mask; mask >>= 1)
38 dst->item(BIT_MARK_US, (byte & mask) ? BIT_ZERO_SPACE_US : BIT_ONE_SPACE_US);
39 // End of frame
40 if (shift == 0) {
41 // Append footer
42 dst->mark(FOOTER_MARK_US);
43 break;
44 }
45 }
46}
47
49 dst->set_carrier_frequency(38000);
50 dst->reserve(100 + 100 * data.has_second());
51 encode_frame(dst, data.first);
52 if (data.has_second()) {
53 dst->space(FOOTER_SPACE_US);
54 encode_frame(dst, data.second);
55 }
56}
57
58static bool decode_frame(RemoteReceiveData &src, uint32_t &dst) {
59 // Checking for header
60 if (!src.expect_item(HEADER_MARK_US, HEADER_SPACE_US))
61 return false;
62 // Reading data
63 uint32_t data = 0;
64 for (unsigned n = 3;; data <<= 8) {
65 // Reading byte
66 for (uint32_t mask = 1 << 7; mask; mask >>= 1) {
67 if (!src.expect_mark(BIT_MARK_US))
68 return false;
69 if (src.expect_space(BIT_ONE_SPACE_US)) {
70 data |= mask;
71 } else if (!src.expect_space(BIT_ZERO_SPACE_US)) {
72 return false;
73 }
74 }
75 // Checking for inverted byte
76 for (uint32_t mask = 1 << 7; mask; mask >>= 1) {
77 if (!src.expect_item(BIT_MARK_US, (data & mask) ? BIT_ZERO_SPACE_US : BIT_ONE_SPACE_US))
78 return false;
79 }
80 // End of frame
81 if (--n == 0) {
82 // Checking for footer
83 if (!src.expect_mark(FOOTER_MARK_US))
84 return false;
85 dst = data;
86 return true;
87 }
88 }
89}
90
91optional<CoolixData> CoolixProtocol::decode(RemoteReceiveData data) {
92 CoolixData result;
93 const auto size = data.size();
94 if ((size != 200 && size != 100) || !decode_frame(data, result.first))
95 return {};
96 if (size == 100 || !data.expect_space(FOOTER_SPACE_US) || !decode_frame(data, result.second))
97 result.second = 0;
98 return result;
99}
100
102 if (data.is_strict()) {
103 ESP_LOGI(TAG, "Received Coolix: 0x%06" PRIX32, data.first);
104 } else if (data.has_second()) {
105 ESP_LOGI(TAG, "Received unstrict Coolix: [0x%06" PRIX32 ", 0x%06" PRIX32 "]", data.first, data.second);
106 } else {
107 ESP_LOGI(TAG, "Received unstrict Coolix: [0x%06" PRIX32 "]", data.first);
108 }
109}
110
111} // namespace esphome::remote_base
void dump(const CoolixData &data) override
optional< CoolixData > decode(RemoteReceiveData data) override
void encode(RemoteTransmitData *dst, const CoolixData &data) override
bool expect_item(uint32_t mark, uint32_t space)
void set_carrier_frequency(uint32_t carrier_frequency)
Definition remote_base.h:29
void item(uint32_t mark, uint32_t space)
Definition remote_base.h:24
const std::vector< uint8_t > & data
uint16_t size
Definition helpers.cpp:25
static void uint32_t
bool operator==(const CoolixData &other) const