ESPHome  2023.11.6
aeha_protocol.cpp
Go to the documentation of this file.
1 #include "aeha_protocol.h"
2 #include "esphome/core/log.h"
3 #include <cinttypes>
4 
5 namespace esphome {
6 namespace remote_base {
7 
8 static const char *const TAG = "remote.aeha";
9 
10 static const uint16_t BITWISE = 425;
11 static const uint16_t HEADER_HIGH_US = BITWISE * 8;
12 static const uint16_t HEADER_LOW_US = BITWISE * 4;
13 static const uint16_t BIT_HIGH_US = BITWISE;
14 static const uint16_t BIT_ONE_LOW_US = BITWISE * 3;
15 static const uint16_t BIT_ZERO_LOW_US = BITWISE;
16 static const uint16_t TRAILER = BITWISE;
17 
19  dst->set_carrier_frequency(38000);
20  dst->reserve(2 + 32 + (data.data.size() * 2) + 1);
21 
22  dst->item(HEADER_HIGH_US, HEADER_LOW_US);
23 
24  for (uint16_t mask = 1 << 15; mask != 0; mask >>= 1) {
25  if (data.address & mask) {
26  dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
27  } else {
28  dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
29  }
30  }
31 
32  for (uint8_t bit : data.data) {
33  for (uint8_t mask = 1 << 7; mask != 0; mask >>= 1) {
34  if (bit & mask) {
35  dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
36  } else {
37  dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
38  }
39  }
40  }
41 
42  dst->mark(TRAILER);
43 }
45  AEHAData out{
46  .address = 0,
47  .data = {},
48  };
49  if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US))
50  return {};
51 
52  for (uint16_t mask = 1 << 15; mask != 0; mask >>= 1) {
53  if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
54  out.address |= mask;
55  } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
56  out.address &= ~mask;
57  } else {
58  return {};
59  }
60  }
61 
62  for (uint8_t pos = 0; pos < 35; pos++) {
63  uint8_t data = 0;
64  for (uint8_t mask = 1 << 7; mask != 0; mask >>= 1) {
65  if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
66  data |= mask;
67  } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
68  data &= ~mask;
69  } else if (pos > 1 && src.expect_mark(TRAILER)) {
70  return out;
71  } else {
72  return {};
73  }
74  }
75 
76  out.data.push_back(data);
77  }
78 
79  if (src.expect_mark(TRAILER)) {
80  return out;
81  }
82 
83  return {};
84 }
85 
86 std::string AEHAProtocol::format_data_(const std::vector<uint8_t> &data) {
87  std::string out;
88  for (uint8_t byte : data) {
89  char buf[6];
90  sprintf(buf, "0x%02X,", byte);
91  out += buf;
92  }
93  out.pop_back();
94  return out;
95 }
96 
97 void AEHAProtocol::dump(const AEHAData &data) {
98  auto data_str = format_data_(data.data);
99  ESP_LOGI(TAG, "Received AEHA: address=0x%04X, data=[%s]", data.address, data_str.c_str());
100 }
101 
102 } // namespace remote_base
103 } // namespace esphome
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
optional< AEHAData > decode(RemoteReceiveData src) override
std::vector< uint8_t > data
Definition: aeha_protocol.h:12
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
bool expect_item(uint32_t mark, uint32_t space)
Definition: remote_base.cpp:71
void dump(const AEHAData &data) override
void encode(RemoteTransmitData *dst, const AEHAData &data) override