ESPHome  2024.3.1
remote_base.cpp
Go to the documentation of this file.
1 #include "remote_base.h"
2 #include "esphome/core/log.h"
3 
4 #include <cinttypes>
5 
6 namespace esphome {
7 namespace remote_base {
8 
9 static const char *const TAG = "remote_base";
10 
11 #ifdef USE_ESP32
12 RemoteRMTChannel::RemoteRMTChannel(uint8_t mem_block_num) : mem_block_num_(mem_block_num) {
13  static rmt_channel_t next_rmt_channel = RMT_CHANNEL_0;
14  this->channel_ = next_rmt_channel;
15  next_rmt_channel = rmt_channel_t(int(next_rmt_channel) + mem_block_num);
16 }
17 
18 void RemoteRMTChannel::config_rmt(rmt_config_t &rmt) {
19  if (rmt_channel_t(int(this->channel_) + this->mem_block_num_) > RMT_CHANNEL_MAX) {
20  this->mem_block_num_ = int(RMT_CHANNEL_MAX) - int(this->channel_);
21  ESP_LOGW(TAG, "Not enough RMT memory blocks available, reduced to %i blocks.", this->mem_block_num_);
22  }
23  rmt.channel = this->channel_;
24  rmt.clk_div = this->clock_divider_;
25  rmt.mem_block_num = this->mem_block_num_;
26 }
27 #endif
28 
29 /* RemoteReceiveData */
30 
31 bool RemoteReceiveData::peek_mark(uint32_t length, uint32_t offset) const {
32  if (!this->is_valid(offset))
33  return false;
34  const int32_t value = this->peek(offset);
35  const int32_t lo = this->lower_bound_(length);
36  const int32_t hi = this->upper_bound_(length);
37  return value >= 0 && lo <= value && value <= hi;
38 }
39 
40 bool RemoteReceiveData::peek_space(uint32_t length, uint32_t offset) const {
41  if (!this->is_valid(offset))
42  return false;
43  const int32_t value = this->peek(offset);
44  const int32_t lo = this->lower_bound_(length);
45  const int32_t hi = this->upper_bound_(length);
46  return value <= 0 && lo <= -value && -value <= hi;
47 }
48 
49 bool RemoteReceiveData::peek_space_at_least(uint32_t length, uint32_t offset) const {
50  if (!this->is_valid(offset))
51  return false;
52  const int32_t value = this->peek(offset);
53  const int32_t lo = this->lower_bound_(length);
54  return value <= 0 && lo <= -value;
55 }
56 
58  if (!this->peek_mark(length))
59  return false;
60  this->advance();
61  return true;
62 }
63 
65  if (!this->peek_space(length))
66  return false;
67  this->advance();
68  return true;
69 }
70 
71 bool RemoteReceiveData::expect_item(uint32_t mark, uint32_t space) {
72  if (!this->peek_item(mark, space))
73  return false;
74  this->advance(2);
75  return true;
76 }
77 
78 bool RemoteReceiveData::expect_pulse_with_gap(uint32_t mark, uint32_t space) {
79  if (!this->peek_space_at_least(space, 1) || !this->peek_mark(mark))
80  return false;
81  this->advance(2);
82  return true;
83 }
84 
85 /* RemoteReceiverBinarySensorBase */
86 
88  if (!this->matches(src))
89  return false;
90  this->publish_state(true);
91  yield();
92  this->publish_state(false);
93  return true;
94 }
95 
96 /* RemoteReceiverBase */
97 
99  if (dumper->is_secondary()) {
100  this->secondary_dumpers_.push_back(dumper);
101  } else {
102  this->dumpers_.push_back(dumper);
103  }
104 }
105 
107  for (auto *listener : this->listeners_)
108  listener->on_receive(RemoteReceiveData(this->temp_, this->tolerance_));
109 }
110 
112  bool success = false;
113  for (auto *dumper : this->dumpers_) {
114  if (dumper->dump(RemoteReceiveData(this->temp_, this->tolerance_)))
115  success = true;
116  }
117  if (!success) {
118  for (auto *dumper : this->secondary_dumpers_)
119  dumper->dump(RemoteReceiveData(this->temp_, this->tolerance_));
120  }
121 }
122 
123 void RemoteReceiverBinarySensorBase::dump_config() { LOG_BINARY_SENSOR("", "Remote Receiver Binary Sensor", this); }
124 
125 void RemoteTransmitterBase::send_(uint32_t send_times, uint32_t send_wait) {
126 #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE
127  const auto &vec = this->temp_.get_data();
128  char buffer[256];
129  uint32_t buffer_offset = 0;
130  buffer_offset += sprintf(buffer, "Sending times=%" PRIu32 " wait=%" PRIu32 "ms: ", send_times, send_wait);
131 
132  for (size_t i = 0; i < vec.size(); i++) {
133  const int32_t value = vec[i];
134  const uint32_t remaining_length = sizeof(buffer) - buffer_offset;
135  int written;
136 
137  if (i + 1 < vec.size()) {
138  written = snprintf(buffer + buffer_offset, remaining_length, "%" PRId32 ", ", value);
139  } else {
140  written = snprintf(buffer + buffer_offset, remaining_length, "%" PRId32, value);
141  }
142 
143  if (written < 0 || written >= int(remaining_length)) {
144  // write failed, flush...
145  buffer[buffer_offset] = '\0';
146  ESP_LOGVV(TAG, "%s", buffer);
147  buffer_offset = 0;
148  written = sprintf(buffer, " ");
149  if (i + 1 < vec.size()) {
150  written += sprintf(buffer + written, "%" PRId32 ", ", value);
151  } else {
152  written += sprintf(buffer + written, "%" PRId32, value);
153  }
154  }
155 
156  buffer_offset += written;
157  }
158  if (buffer_offset != 0) {
159  ESP_LOGVV(TAG, "%s", buffer);
160  }
161 #endif
162  this->send_internal(send_times, send_wait);
163 }
164 } // namespace remote_base
165 } // namespace esphome
void config_rmt(rmt_config_t &rmt)
Definition: remote_base.cpp:18
bool expect_pulse_with_gap(uint32_t mark, uint32_t space)
Definition: remote_base.cpp:78
RemoteRMTChannel(uint8_t mem_block_num=1)
Definition: remote_base.cpp:12
bool peek_space(uint32_t length, uint32_t offset=0) const
Definition: remote_base.cpp:40
bool peek_mark(uint32_t length, uint32_t offset=0) const
Definition: remote_base.cpp:31
bool on_receive(RemoteReceiveData src) override
Definition: remote_base.cpp:87
void IRAM_ATTR HOT yield()
Definition: core.cpp:24
uint16_t length
Definition: tt21100.cpp:12
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void register_dumper(RemoteReceiverDumperBase *dumper)
Definition: remote_base.cpp:98
bool expect_item(uint32_t mark, uint32_t space)
Definition: remote_base.cpp:71
void send_(uint32_t send_times, uint32_t send_wait)
bool peek_space_at_least(uint32_t length, uint32_t offset=0) const
Definition: remote_base.cpp:49