ESPHome  2024.11.0
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->reserve(2 + 32 + (data.data.size() * 2) + 1);
20 
21  dst->item(HEADER_HIGH_US, HEADER_LOW_US);
22 
23  for (uint16_t mask = 1 << 15; mask != 0; mask >>= 1) {
24  if (data.address & mask) {
25  dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
26  } else {
27  dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
28  }
29  }
30 
31  for (uint8_t bit : data.data) {
32  for (uint8_t mask = 1 << 7; mask != 0; mask >>= 1) {
33  if (bit & mask) {
34  dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
35  } else {
36  dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
37  }
38  }
39  }
40 
41  dst->mark(TRAILER);
42 }
44  AEHAData out{
45  .address = 0,
46  .data = {},
47  };
48  if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US))
49  return {};
50 
51  for (uint16_t mask = 1 << 15; mask != 0; mask >>= 1) {
52  if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
53  out.address |= mask;
54  } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
55  out.address &= ~mask;
56  } else {
57  return {};
58  }
59  }
60 
61  for (uint8_t pos = 0; pos < 35; pos++) {
62  uint8_t data = 0;
63  for (uint8_t mask = 1 << 7; mask != 0; mask >>= 1) {
64  if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
65  data |= mask;
66  } else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
67  data &= ~mask;
68  } else if (pos > 1 && src.expect_mark(TRAILER)) {
69  return out;
70  } else {
71  return {};
72  }
73  }
74 
75  out.data.push_back(data);
76  }
77 
78  if (src.expect_mark(TRAILER)) {
79  return out;
80  }
81 
82  return {};
83 }
84 
85 std::string AEHAProtocol::format_data_(const std::vector<uint8_t> &data) {
86  std::string out;
87  for (uint8_t byte : data) {
88  char buf[6];
89  sprintf(buf, "0x%02X,", byte);
90  out += buf;
91  }
92  out.pop_back();
93  return out;
94 }
95 
96 void AEHAProtocol::dump(const AEHAData &data) {
97  auto data_str = format_data_(data.data);
98  ESP_LOGI(TAG, "Received AEHA: address=0x%04X, data=[%s]", data.address, data_str.c_str());
99 }
100 
101 } // namespace remote_base
102 } // namespace esphome
void item(uint32_t mark, uint32_t space)
Definition: remote_base.h:29
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:74
void dump(const AEHAData &data) override
void encode(RemoteTransmitData *dst, const AEHAData &data) override