ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
midea_protocol.cpp
Go to the documentation of this file.
1#include "midea_protocol.h"
2#include "esphome/core/log.h"
3
4namespace esphome::remote_base {
5
6static const char *const TAG = "remote.midea";
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
17uint8_t MideaData::calc_cs_() const {
18 uint8_t cs = 0;
19 for (uint8_t idx = 0; idx < OFFSET_CS; idx++)
20 cs -= reverse_bits(this->data_[idx]);
21 return reverse_bits(cs);
22}
23
24bool MideaData::is_compliment(const MideaData &rhs) const {
25 return std::equal(this->data_.begin(), this->data_.end(), rhs.data_.begin(),
26 [](const uint8_t &a, const uint8_t &b) { return a + b == 255; });
27}
28
30 dst->set_carrier_frequency(38000);
31 dst->reserve(2 + 48 * 2 + 2 + 2 + 48 * 2 + 1);
32 dst->item(HEADER_MARK_US, HEADER_SPACE_US);
33 for (unsigned idx = 0; idx < 6; idx++) {
34 for (uint8_t mask = 1 << 7; mask; mask >>= 1)
35 dst->item(BIT_MARK_US, (src[idx] & mask) ? BIT_ONE_SPACE_US : BIT_ZERO_SPACE_US);
36 }
37 dst->item(FOOTER_MARK_US, FOOTER_SPACE_US);
38 dst->item(HEADER_MARK_US, HEADER_SPACE_US);
39 for (unsigned idx = 0; idx < 6; idx++) {
40 for (uint8_t mask = 1 << 7; mask; mask >>= 1)
41 dst->item(BIT_MARK_US, (src[idx] & mask) ? BIT_ZERO_SPACE_US : BIT_ONE_SPACE_US);
42 }
43 dst->mark(FOOTER_MARK_US);
44}
45
46static bool decode_data(RemoteReceiveData &src, MideaData &dst) {
47 for (unsigned idx = 0; idx < 6; idx++) {
48 uint8_t data = 0;
49 for (uint8_t mask = 1 << 7; mask; mask >>= 1) {
50 if (!src.expect_mark(BIT_MARK_US))
51 return false;
52 if (src.expect_space(BIT_ONE_SPACE_US)) {
53 data |= mask;
54 } else if (!src.expect_space(BIT_ZERO_SPACE_US)) {
55 return false;
56 }
57 }
58 dst[idx] = data;
59 }
60 return true;
61}
62
63optional<MideaData> MideaProtocol::decode(RemoteReceiveData src) {
64 MideaData out, inv;
65 if (src.expect_item(HEADER_MARK_US, HEADER_SPACE_US) && decode_data(src, out) && out.is_valid() &&
66 src.expect_item(FOOTER_MARK_US, FOOTER_SPACE_US) && src.expect_item(HEADER_MARK_US, HEADER_SPACE_US) &&
67 decode_data(src, inv) && src.expect_mark(FOOTER_MARK_US) && out.is_compliment(inv))
68 return out;
69 return {};
70}
71
72void MideaProtocol::dump(const MideaData &data) {
73 char buf[MideaData::TO_STR_BUFFER_SIZE];
74 ESP_LOGI(TAG, "Received Midea: %s", data.to_str(buf));
75}
76
77} // namespace esphome::remote_base
std::array< uint8_t, 6 > data_
static constexpr uint8_t OFFSET_CS
bool is_compliment(const MideaData &rhs) const
void dump(const MideaData &data) override
void encode(RemoteTransmitData *dst, const MideaData &src) override
optional< MideaData > decode(RemoteReceiveData src) 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
uint8_t reverse_bits(uint8_t x)
Reverse the order of 8 bits.
Definition helpers.h:898