ESPHome 2025.5.0
Loading...
Searching...
No Matches
rf_bridge.cpp
Go to the documentation of this file.
1#include "rf_bridge.h"
2#include "esphome/core/log.h"
4#include <cinttypes>
5#include <cstring>
6
7namespace esphome {
8namespace rf_bridge {
9
10static const char *const TAG = "rf_bridge";
11
13 ESP_LOGV(TAG, "Sending ACK");
14 this->write(RF_CODE_START);
15 this->write(RF_CODE_ACK);
16 this->write(RF_CODE_STOP);
17 this->flush();
18}
19
21 size_t at = this->rx_buffer_.size();
22 this->rx_buffer_.push_back(byte);
23 const uint8_t *raw = &this->rx_buffer_[0];
24
25 ESP_LOGVV(TAG, "Processing byte: 0x%02X", byte);
26
27 // Byte 0: Start
28 if (at == 0)
29 return byte == RF_CODE_START;
30
31 // Byte 1: Action
32 if (at == 1)
33 return byte >= RF_CODE_ACK && byte <= RF_CODE_RFIN_BUCKET;
34 uint8_t action = raw[1];
35
36 switch (action) {
37 case RF_CODE_ACK:
38 ESP_LOGD(TAG, "Action OK");
39 break;
40 case RF_CODE_LEARN_KO:
41 ESP_LOGD(TAG, "Learning timeout");
42 break;
43 case RF_CODE_LEARN_OK:
44 case RF_CODE_RFIN: {
45 if (byte != RF_CODE_STOP || at < RF_MESSAGE_SIZE + 2)
46 return true;
47
48 RFBridgeData data;
49 data.sync = (raw[2] << 8) | raw[3];
50 data.low = (raw[4] << 8) | raw[5];
51 data.high = (raw[6] << 8) | raw[7];
52 data.code = (raw[8] << 16) | (raw[9] << 8) | raw[10];
53
54 if (action == RF_CODE_LEARN_OK) {
55 ESP_LOGD(TAG, "Learning success");
56 }
57
58 ESP_LOGI(TAG,
59 "Received RFBridge Code: sync=0x%04" PRIX16 " low=0x%04" PRIX16 " high=0x%04" PRIX16
60 " code=0x%06" PRIX32,
61 data.sync, data.low, data.high, data.code);
62 this->data_callback_.call(data);
63 break;
64 }
65 case RF_CODE_LEARN_OK_NEW:
66 case RF_CODE_ADVANCED_RFIN: {
67 if (byte != RF_CODE_STOP) {
68 return at < (raw[2] + 3);
69 }
70
72
73 data.length = raw[2];
74 data.protocol = raw[3];
75 char next_byte[3];
76 for (uint8_t i = 0; i < data.length - 1; i++) {
77 sprintf(next_byte, "%02X", raw[4 + i]);
78 data.code += next_byte;
79 }
80
81 ESP_LOGI(TAG, "Received RFBridge Advanced Code: length=0x%02X protocol=0x%02X code=0x%s", data.length,
82 data.protocol, data.code.c_str());
83 this->advanced_data_callback_.call(data);
84 break;
85 }
86 case RF_CODE_RFIN_BUCKET: {
87 if (byte != RF_CODE_STOP) {
88 return true;
89 }
90
91 uint8_t buckets = raw[2] << 1;
92 std::string str;
93 char next_byte[3];
94
95 for (uint32_t i = 0; i <= at; i++) {
96 sprintf(next_byte, "%02X", raw[i]);
97 str += next_byte;
98 if ((i > 3) && buckets) {
99 buckets--;
100 }
101 if ((i < 3) || (buckets % 2) || (i == at - 1)) {
102 str += " ";
103 }
104 }
105 ESP_LOGI(TAG, "Received RFBridge Bucket: %s", str.c_str());
106 break;
107 }
108 default:
109 ESP_LOGW(TAG, "Unknown action: 0x%02X", action);
110 break;
111 }
112
113 ESP_LOGVV(TAG, "Parsed: 0x%02X", byte);
114
115 if (byte == RF_CODE_STOP && action != RF_CODE_ACK)
116 this->ack_();
117
118 // return false to reset buffer
119 return false;
120}
121
122void RFBridgeComponent::write_byte_str_(const std::string &codes) {
123 uint8_t code;
124 int size = codes.length();
125 for (int i = 0; i < size; i += 2) {
126 code = strtol(codes.substr(i, 2).c_str(), nullptr, 16);
127 this->write(code);
128 }
129}
130
132 const uint32_t now = App.get_loop_component_start_time();
133 if (now - this->last_bridge_byte_ > 50) {
134 this->rx_buffer_.clear();
135 this->last_bridge_byte_ = now;
136 }
137
138 while (this->available()) {
139 uint8_t byte;
140 this->read_byte(&byte);
141 if (this->parse_bridge_byte_(byte)) {
142 ESP_LOGVV(TAG, "Parsed: 0x%02X", byte);
143 this->last_bridge_byte_ = now;
144 } else {
145 this->rx_buffer_.clear();
146 }
147 }
148}
149
151 ESP_LOGD(TAG, "Sending code: sync=0x%04" PRIX16 " low=0x%04" PRIX16 " high=0x%04" PRIX16 " code=0x%06" PRIX32,
152 data.sync, data.low, data.high, data.code);
153 this->write(RF_CODE_START);
154 this->write(RF_CODE_RFOUT);
155 this->write((data.sync >> 8) & 0xFF);
156 this->write(data.sync & 0xFF);
157 this->write((data.low >> 8) & 0xFF);
158 this->write(data.low & 0xFF);
159 this->write((data.high >> 8) & 0xFF);
160 this->write(data.high & 0xFF);
161 this->write((data.code >> 16) & 0xFF);
162 this->write((data.code >> 8) & 0xFF);
163 this->write(data.code & 0xFF);
164 this->write(RF_CODE_STOP);
165 this->flush();
166}
167
169 ESP_LOGD(TAG, "Sending advanced code: length=0x%02X protocol=0x%02X code=0x%s", data.length, data.protocol,
170 data.code.c_str());
171 this->write(RF_CODE_START);
172 this->write(RF_CODE_RFOUT_NEW);
173 this->write(data.length & 0xFF);
174 this->write(data.protocol & 0xFF);
175 this->write_byte_str_(data.code);
176 this->write(RF_CODE_STOP);
177 this->flush();
178}
179
181 ESP_LOGD(TAG, "Learning mode");
182 this->write(RF_CODE_START);
183 this->write(RF_CODE_LEARN);
184 this->write(RF_CODE_STOP);
185 this->flush();
186}
187
189 ESP_LOGCONFIG(TAG, "RF_Bridge:");
190 this->check_uart_settings(19200);
191}
192
194 ESP_LOGI(TAG, "Advanced Sniffing on");
195 this->write(RF_CODE_START);
196 this->write(RF_CODE_SNIFFING_ON);
197 this->write(RF_CODE_STOP);
198 this->flush();
199}
200
202 ESP_LOGI(TAG, "Advanced Sniffing off");
203 this->write(RF_CODE_START);
204 this->write(RF_CODE_SNIFFING_OFF);
205 this->write(RF_CODE_STOP);
206 this->flush();
207}
208
210 ESP_LOGI(TAG, "Raw Bucket Sniffing on");
211 this->write(RF_CODE_START);
212 this->write(RF_CODE_RFIN_BUCKET);
213 this->write(RF_CODE_STOP);
214 this->flush();
215}
216
217void RFBridgeComponent::send_raw(const std::string &raw_code) {
218 ESP_LOGD(TAG, "Sending Raw Code: %s", raw_code.c_str());
219
220 this->write_byte_str_(raw_code);
221 this->flush();
222}
223
224void RFBridgeComponent::beep(uint16_t ms) {
225 ESP_LOGD(TAG, "Beeping for %hu ms", ms);
226
227 this->write(RF_CODE_START);
228 this->write(RF_CODE_BEEP);
229 this->write((ms >> 8) & 0xFF);
230 this->write(ms & 0xFF);
231 this->write(RF_CODE_STOP);
232 this->flush();
233}
234
235} // namespace rf_bridge
236} // namespace esphome
uint8_t raw[35]
Definition bl0939.h:0
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
void send_raw(const std::string &code)
CallbackManager< void(RFBridgeAdvancedData)> advanced_data_callback_
Definition rf_bridge.h:76
void send_advanced_code(const RFBridgeAdvancedData &data)
CallbackManager< void(RFBridgeData)> data_callback_
Definition rf_bridge.h:75
void write_byte_str_(const std::string &codes)
void send_code(RFBridgeData data)
std::vector< uint8_t > rx_buffer_
Definition rf_bridge.h:72
void check_uart_settings(uint32_t baud_rate, uint8_t stop_bits=1, UARTParityOptions parity=UART_CONFIG_PARITY_NONE, uint8_t data_bits=8)
Check that the configuration of the UART bus matches the provided values and otherwise print a warnin...
Definition uart.cpp:13
bool read_byte(uint8_t *data)
Definition uart.h:29
size_t write(uint8_t data)
Definition uart.h:52
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
Application App
Global storage of Application pointer - only one Application can exist.