12 #include <driver/rmt.h> 16 namespace remote_base {
20 void mark(uint32_t length) { this->
data_.push_back(length); }
22 void space(uint32_t length) { this->
data_.push_back(-length); }
37 void set_data(
const std::vector<int32_t> &data) {
39 this->
data_.reserve(data.size());
41 this->
data_.push_back(dat);
49 std::vector<int32_t>::iterator
begin() {
return this->
data_.begin(); }
51 std::vector<int32_t>::iterator
end() {
return this->
data_.end(); }
62 bool peek_mark(uint32_t length, uint32_t offset = 0) {
63 if (int32_t(this->index_ + offset) >= this->size())
65 int32_t value = this->peek(offset);
66 const int32_t lo = this->lower_bound_(length);
67 const int32_t hi = this->upper_bound_(length);
68 return value >= 0 && lo <= value && value <= hi;
72 if (int32_t(this->index_ + offset) >= this->size())
74 int32_t value = this->peek(offset);
75 const int32_t lo = this->lower_bound_(length);
76 const int32_t hi = this->upper_bound_(length);
77 return value <= 0 && lo <= -value && -value <= hi;
81 if (int32_t(this->index_ + offset) >= this->size())
83 int32_t value = this->pos(this->index_ + offset);
84 const int32_t lo = this->lower_bound_(length);
85 return value <= 0 && lo <= -value;
89 return this->peek_mark(mark, offset) && this->peek_space(space, offset + 1);
92 int32_t
peek(uint32_t offset = 0) {
return (*
this)[this->index_ + offset]; }
94 void advance(uint32_t amount = 1) { this->index_ += amount; }
97 if (this->peek_mark(length)) {
105 if (this->peek_space(length)) {
113 if (this->peek_item(mark, space)) {
121 if (this->peek_mark(mark, 0) && this->peek_space_at_least(space, 1)) {
132 int32_t
pos(uint32_t index)
const {
return (*this->
data_)[index]; }
134 int32_t
operator[](uint32_t index)
const {
return this->pos(index); }
141 int32_t
lower_bound_(uint32_t length) {
return int32_t(100 - this->tolerance_) * length / 100U; }
142 int32_t
upper_bound_(uint32_t length) {
return int32_t(100 + this->tolerance_) * length / 100U; }
155 virtual void dump(
const T &data) = 0;
171 void config_rmt(rmt_config_t &rmt);
176 const uint32_t ticks_per_ten_us = 80000000u / this->clock_divider_ / 100000u;
177 return us * ticks_per_ten_us / 10;
180 const uint32_t ticks_per_ten_us = 80000000u / this->clock_divider_ / 100000u;
181 return (ticks * 10) / ticks_per_ten_us;
184 rmt_channel_t channel_{RMT_CHANNEL_0};
186 uint8_t clock_divider_{80};
200 void perform() { this->parent_->send_(this->send_times_, this->send_wait_); }
204 uint32_t send_times_{1};
205 uint32_t send_wait_{0};
214 void send_(uint32_t send_times, uint32_t send_wait);
215 virtual void send_internal(uint32_t send_times, uint32_t send_wait) = 0;
239 this->secondary_dumpers_.push_back(dumper);
241 this->dumpers_.push_back(dumper);
248 bool success =
false;
249 for (
auto *listener : this->listeners_) {
251 if (listener->on_receive(data))
257 bool success =
false;
258 for (
auto *dumper : this->dumpers_) {
260 if (dumper->dump(data))
264 for (
auto *dumper : this->secondary_dumpers_) {
271 if (this->call_listeners_())
274 this->call_dumpers_();
281 uint8_t tolerance_{25};
289 void dump_config()
override;
292 if (this->matches(src)) {
293 this->publish_state(
true);
295 this->publish_state(
false);
309 auto res = proto.decode(src);
310 return res.has_value() && *res == this->
data_;
324 auto res = proto.decode(src);
325 if (res.has_value()) {
337 TEMPLATABLE_VALUE(uint32_t, send_times);
338 TEMPLATABLE_VALUE(uint32_t, send_wait);
341 auto call = this->parent_->transmit();
342 this->encode(call.get_data(), x...);
343 call.set_send_times(this->send_times_.value_or(x..., 1));
344 call.set_send_wait(this->send_wait_.value_or(x..., 0));
358 auto decoded = proto.decode(src);
359 if (!decoded.has_value())
361 proto.dump(*decoded);
366 #define DECLARE_REMOTE_PROTOCOL_(prefix) \ 367 using prefix##BinarySensor = RemoteReceiverBinarySensor<prefix##Protocol, prefix##Data>; \ 368 using prefix##Trigger = RemoteReceiverTrigger<prefix##Protocol, prefix##Data>; \ 369 using prefix##Dumper = RemoteReceiverDumper<prefix##Protocol, prefix##Data>; 370 #define DECLARE_REMOTE_PROTOCOL(prefix) DECLARE_REMOTE_PROTOCOL_(prefix) uint32_t carrier_frequency_
void register_listener(RemoteReceiverListener *listener)
bool expect_pulse_with_gap(uint32_t mark, uint32_t space)
RemoteTransmitData temp_
Use same vector for all transmits, avoids many allocations.
int32_t operator[](uint32_t index) const
RemoteReceiveData(std::vector< int32_t > *data, uint8_t tolerance)
void set_carrier_frequency(uint32_t carrier_frequency)
std::vector< int32_t > data_
uint32_t get_carrier_frequency() const
bool on_receive(RemoteReceiveData src) override
void item(uint32_t mark, uint32_t space)
int32_t peek(uint32_t offset=0)
std::vector< int32_t > * get_raw_data()
bool expect_space(uint32_t length)
void call_listeners_dumpers_()
std::vector< int32_t > * data_
std::vector< int32_t >::iterator begin()
bool peek_space(uint32_t length, uint32_t offset=0)
std::vector< RemoteReceiverDumperBase * > dumpers_
bool expect_mark(uint32_t length)
std::vector< RemoteReceiverDumperBase * > secondary_dumpers_
const std::vector< int32_t > & get_data() const
TransmitCall(RemoteTransmitterBase *parent)
RemoteComponentBase(InternalGPIOPin *pin)
RemoteTransmitterBase * parent_
RemoteComponentBase * remote_base_
int32_t upper_bound_(uint32_t length)
RemoteReceiverBinarySensorBase()
bool dump(RemoteReceiveData src) override
std::vector< int32_t >::iterator end()
std::vector< int32_t > temp_
bool peek_mark(uint32_t length, uint32_t offset=0)
RemoteReceiverBinarySensor()
int32_t lower_bound_(uint32_t length)
void mark(uint32_t length)
void play(Ts... x) override
RemoteTransmitterBase(InternalGPIOPin *pin)
std::vector< RemoteReceiverListener * > listeners_
bool on_receive(RemoteReceiveData src) override
int32_t pos(uint32_t index) const
void set_data(const std::vector< int32_t > &data)
RemoteTransmitData * get_data()
RemoteReceiverBase(InternalGPIOPin *pin)
void set_send_wait(uint32_t send_wait)
void set_clock_divider(uint8_t clock_divider)
void set_parent(RemoteTransmitterBase *parent)
bool matches(RemoteReceiveData src) override
void IRAM_ATTR HOT yield()
void space(uint32_t length)
bool peek_item(uint32_t mark, uint32_t space, uint32_t offset=0)
void register_dumper(RemoteReceiverDumperBase *dumper)
void reserve(uint32_t len)
virtual bool is_secondary()
void set_send_times(uint32_t send_times)
bool expect_item(uint32_t mark, uint32_t space)
void advance(uint32_t amount=1)
void set_tolerance(uint8_t tolerance)
uint32_t to_microseconds_(uint32_t ticks)
bool peek_space_at_least(uint32_t length, uint32_t offset=0)
uint32_t from_microseconds_(uint32_t us)