ESPHome  2024.11.0
dooya_protocol.cpp
Go to the documentation of this file.
1 #include "dooya_protocol.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace remote_base {
6 
7 static const char *const TAG = "remote.dooya";
8 
9 static const uint32_t HEADER_HIGH_US = 5000;
10 static const uint32_t HEADER_LOW_US = 1500;
11 static const uint32_t BIT_ZERO_HIGH_US = 350;
12 static const uint32_t BIT_ZERO_LOW_US = 750;
13 static const uint32_t BIT_ONE_HIGH_US = 750;
14 static const uint32_t BIT_ONE_LOW_US = 350;
15 
17  dst->set_carrier_frequency(0);
18  dst->reserve(2 + 40 * 2u);
19 
20  dst->item(HEADER_HIGH_US, HEADER_LOW_US);
21 
22  for (uint32_t mask = 1UL << (23); mask != 0; mask >>= 1) {
23  if (data.id & mask) {
24  dst->item(BIT_ONE_HIGH_US, BIT_ONE_LOW_US);
25  } else {
26  dst->item(BIT_ZERO_HIGH_US, BIT_ZERO_LOW_US);
27  }
28  }
29 
30  for (uint32_t mask = 1UL << (7); mask != 0; mask >>= 1) {
31  if (data.channel & mask) {
32  dst->item(BIT_ONE_HIGH_US, BIT_ONE_LOW_US);
33  } else {
34  dst->item(BIT_ZERO_HIGH_US, BIT_ZERO_LOW_US);
35  }
36  }
37 
38  for (uint32_t mask = 1UL << (3); mask != 0; mask >>= 1) {
39  if (data.button & mask) {
40  dst->item(BIT_ONE_HIGH_US, BIT_ONE_LOW_US);
41  } else {
42  dst->item(BIT_ZERO_HIGH_US, BIT_ZERO_LOW_US);
43  }
44  }
45 
46  for (uint32_t mask = 1UL << (3); mask != 0; mask >>= 1) {
47  if (data.check & mask) {
48  dst->item(BIT_ONE_HIGH_US, BIT_ONE_LOW_US);
49  } else {
50  dst->item(BIT_ZERO_HIGH_US, BIT_ZERO_LOW_US);
51  }
52  }
53 }
55  DooyaData out{
56  .id = 0,
57  .channel = 0,
58  .button = 0,
59  .check = 0,
60  };
61  if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US))
62  return {};
63 
64  for (uint8_t i = 0; i < 24; i++) {
65  if (src.expect_item(BIT_ONE_HIGH_US, BIT_ONE_LOW_US)) {
66  out.id = (out.id << 1) | 1;
67  } else if (src.expect_item(BIT_ZERO_HIGH_US, BIT_ZERO_LOW_US)) {
68  out.id = (out.id << 1) | 0;
69  } else {
70  return {};
71  }
72  }
73 
74  for (uint8_t i = 0; i < 8; i++) {
75  if (src.expect_item(BIT_ONE_HIGH_US, BIT_ONE_LOW_US)) {
76  out.channel = (out.channel << 1) | 1;
77  } else if (src.expect_item(BIT_ZERO_HIGH_US, BIT_ZERO_LOW_US)) {
78  out.channel = (out.channel << 1) | 0;
79  } else {
80  return {};
81  }
82  }
83 
84  for (uint8_t i = 0; i < 4; i++) {
85  if (src.expect_item(BIT_ONE_HIGH_US, BIT_ONE_LOW_US)) {
86  out.button = (out.button << 1) | 1;
87  } else if (src.expect_item(BIT_ZERO_HIGH_US, BIT_ZERO_LOW_US)) {
88  out.button = (out.button << 1) | 0;
89  } else {
90  return {};
91  }
92  }
93 
94  for (uint8_t i = 0; i < 3; i++) {
95  if (src.expect_item(BIT_ONE_HIGH_US, BIT_ONE_LOW_US)) {
96  out.check = (out.check << 1) | 1;
97  } else if (src.expect_item(BIT_ZERO_HIGH_US, BIT_ZERO_LOW_US)) {
98  out.check = (out.check << 1) | 0;
99  } else {
100  return {};
101  }
102  }
103  // Last bit is not received properly but can be decoded
104  if (src.expect_mark(BIT_ONE_HIGH_US)) {
105  out.check = (out.check << 1) | 1;
106  } else if (src.expect_mark(BIT_ZERO_HIGH_US)) {
107  out.check = (out.check << 1) | 0;
108  } else {
109  return {};
110  }
111 
112  return out;
113 }
114 void DooyaProtocol::dump(const DooyaData &data) {
115  ESP_LOGI(TAG, "Received Dooya: id=0x%08" PRIX32 ", channel=%d, button=%d, check=%d", data.id, data.channel,
116  data.button, data.check);
117 }
118 
119 } // namespace remote_base
120 } // namespace esphome
void set_carrier_frequency(uint32_t carrier_frequency)
Definition: remote_base.h:34
void item(uint32_t mark, uint32_t space)
Definition: remote_base.h:29
void encode(RemoteTransmitData *dst, const DooyaData &data) override
void dump(const DooyaData &data) override
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
optional< DooyaData > decode(RemoteReceiveData src) override
bool expect_item(uint32_t mark, uint32_t space)
Definition: remote_base.cpp:74