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