49 template<BitTimings T>
void item_bytes(
const uint8_t *bytes,
size_t len) {
50 static_assert(T.one_mark != 0 && T.zero_mark != 0,
"set bit_mark, or one_mark and zero_mark");
51 for (
size_t i = 0; i <
len; i++) {
52 for (uint8_t bit = 0; bit < 8; bit++) {
54 const bool one = (bytes[i] & mask) != 0;
55 if constexpr (T.space_first) {
56 this->
space(one ? T.one_space : T.zero_space);
57 this->
mark(one ? T.one_mark : T.zero_mark);
59 this->
item(one ? T.one_mark : T.zero_mark, one ? T.one_space : T.zero_space);
117 static_assert(!T.space_first && T.one_mark != T.zero_mark,
"the last bit must be told apart by its mark");
132 static_assert(T.one_mark != 0 && T.zero_mark != 0,
"set bit_mark, or one_mark and zero_mark");
133 for (
size_t i = 0; i <
len; i++) {
135 for (uint8_t bit = 0; bit < 8; bit++) {
137 if (LAST_MARK && i + 1 ==
len && bit == 7) {
155 if constexpr (T.space_first) {
168 return int32_t(100 - this->
tolerance_) * length / 100U;
176 return int32_t(100 + this->
tolerance_) * length / 100U;
196#include <soc/soc_caps.h>
206 return us * ticks_per_ten_us / 10;
210 return (ticks * 10) / ticks_per_ten_us;
221#ifdef USE_IR_RF_TRANSMIT_COMPLETE
232 { proto.decode(
src) } -> std::same_as<optional<typename T::ProtocolData>>;
239 requires(T proto, RemoteTransmitData *dst,
const typename T::ProtocolData &data) { proto.encode(dst, data); };
262 template<RemoteProtocolEncoder Protocol>
274 typename Protocol::ProtocolData
data{};
289 template<
typename... Args>
void encode(
const Args &...args) { Protocol().encode(this->
get_data(), args...); }
300 Protocol().encode(dst, *
static_cast<const typename Protocol::ProtocolData *
>(data));
308#ifdef USE_IR_RF_TRANSMIT_COMPLETE
342#ifdef REMOTE_BASE_LISTENER_COUNT
346 static_assert(
sizeof(T) == 0,
"No listener slot: register it from to_code() with remote_base.add_listener");
349#ifdef REMOTE_BASE_DUMPER_COUNT
353 static_assert(
sizeof(T) == 0,
"No dumper slot: register it from to_code() with remote_base.add_dumper");
364#ifdef REMOTE_BASE_LISTENER_COUNT
367#ifdef REMOTE_BASE_DUMPER_COUNT
402 auto res = proto.decode(
src);
403 return res.has_value() && *res == this->
data_;
413template<RemoteProtocolDecoder T>
418 auto res = proto.decode(
src);
419 if (res.has_value()) {
434 template<RemoteProtocolEncoder Protocol>
442 TEMPLATABLE_VALUE(
uint32_t, send_times)
443 TEMPLATABLE_VALUE(
uint32_t, send_wait)
446 void play(
const Ts &...
x)
override {
448 this->
encode(call.get_data(),
x...);
449 call.set_send_times(this->send_times_.value_or(
x..., 1));
450 call.set_send_wait(this->send_wait_.value_or(
x..., 0));
460 auto decoded = proto.decode(
src);
461 if (!decoded.has_value())
463 proto.dump(*decoded);
468#define DECLARE_REMOTE_PROTOCOL_(prefix) \
469 using prefix##BinarySensor = RemoteReceiverBinarySensor<prefix##Protocol>; \
470 using prefix##Trigger = RemoteReceiverTrigger<prefix##Protocol>; \
471 using prefix##Dumper = RemoteReceiverDumper<prefix##Protocol>;
472#define DECLARE_REMOTE_PROTOCOL(prefix) DECLARE_REMOTE_PROTOCOL_(prefix)
Minimal static vector - saves memory by avoiding std::vector overhead.
void trigger(const Ts &...x) ESPHOME_ALWAYS_INLINE
RemoteComponentBase(InternalGPIOPin *pin)
RemoteComponentBase * remote_base_
void set_rmt_symbols(uint32_t rmt_symbols)
uint32_t to_microseconds_(uint32_t ticks)
uint32_t clock_resolution_
uint32_t from_microseconds_(uint32_t us)
void set_clock_resolution(uint32_t clock_resolution)
int32_t operator[](uint32_t index) const
bool peek_mark_at_most(uint32_t length, uint32_t offset=0) const
uint32_t get_index() const
bool expect_item(uint32_t mark, uint32_t space)
bool peek_space(uint32_t length, uint32_t offset=0) const
bool peek_space_at_most(uint32_t length, uint32_t offset=0) const
int32_t peek(uint32_t offset=0) const
bool peek_item(uint32_t mark, uint32_t space, uint32_t offset=0) const
bool expect_bytes_last_mark(uint8_t *out, size_t len)
As expect_bytes, but the last bit is only its mark: its space runs into the gap after the frame.
bool expect_bytes_(uint8_t *out, size_t len)
bool expect_space(uint32_t length)
bool expect_bit_(uint32_t mark, uint32_t space)
One bit in T's order, consumed only when both its parts match.
int32_t upper_bound_(uint32_t length) const
bool expect_mark(uint32_t length)
bool is_valid(uint32_t offset=0) const
const RawTimings & get_raw_data() const
ToleranceMode tolerance_mode_
void advance(uint32_t amount=1)
RemoteReceiveData(const RawTimings &data, uint32_t tolerance, ToleranceMode tolerance_mode)
bool expect_bytes(uint8_t *out, size_t len)
False at the first bit matching neither the one nor the zero timings, leaving it unread.
void set_tolerance(uint32_t tolerance, ToleranceMode tolerance_mode)
bool peek_space_at_least(uint32_t length, uint32_t offset=0) const
ToleranceMode get_tolerance_mode()
int32_t lower_bound_(uint32_t length) const
bool peek_mark(uint32_t length, uint32_t offset=0) const
bool expect_pulse_with_gap(uint32_t mark, uint32_t space)
bool peek_mark_at_least(uint32_t length, uint32_t offset=0) const
ToleranceMode tolerance_mode_
void register_dumper(T *)
void call_listeners_dumpers_()
void register_dumper(RemoteReceiverDumperBase *dumper)
void register_listener(T *)
StaticVector< RemoteReceiverDumperBase *, REMOTE_BASE_DUMPER_COUNT > dumpers_
void set_tolerance(uint32_t tolerance, ToleranceMode tolerance_mode)
void register_listener(RemoteReceiverListener *listener)
RemoteReceiverDumperBase * secondary_dumper_
RemoteReceiverBase(InternalGPIOPin *pin)
StaticVector< RemoteReceiverListener *, REMOTE_BASE_LISTENER_COUNT > listeners_
virtual bool matches(RemoteReceiveData src)=0
RemoteReceiverBinarySensorBase()
bool on_receive(RemoteReceiveData src) override
void dump_config() override
RemoteReceiverBinarySensor()
bool matches(RemoteReceiveData src) override
void set_data(T::ProtocolData data)
virtual bool is_secondary()
virtual bool dump(RemoteReceiveData src)=0
bool dump(RemoteReceiveData src) override
virtual bool on_receive(RemoteReceiveData data)=0
bool on_receive(RemoteReceiveData src) override
bool set_data_from_base64url(const std::string &base64url)
Set data from base64url-encoded little-endian int32 values Base64url is URL-safe: uses '-' instead of...
uint32_t get_carrier_frequency() const
void space(uint32_t length)
void set_carrier_frequency(uint32_t carrier_frequency)
void mark(uint32_t length)
void item(uint32_t mark, uint32_t space)
void item_bytes(const uint8_t *bytes, size_t len)
One item per bit of each byte.
const RawTimings & get_data() const
void set_data(const RawTimings &data)
void reserve(uint32_t len)
void set_data_from_packed_sint32(const uint8_t *data, size_t len, size_t count)
Set data from packed protobuf sint32 buffer (zigzag + varint encoded)
uint32_t carrier_frequency_
RemoteTransmitterBase * transmitter_
void set_transmitter(RemoteTransmitterBase *transmitter)
void transmit_(const typename Protocol::ProtocolData &data, uint32_t send_times=1, uint32_t send_wait=0)
RemoteTransmittable(RemoteTransmitterBase *transmitter)
virtual void encode(RemoteTransmitData *dst, Ts... x)=0
void play(const Ts &...x) override
A transmit call whose encode() runs one of Protocol's encoders on its data, for a payload the protoco...
EncodeCall(TransmitCall call)
void encode(const Args &...args)
Protocol data filled field by field, then sent by perform(); the call a generated transmit action bui...
RemoteTransmitterBase * parent_
ProtocolCall(RemoteTransmitterBase *parent)
void set_send_times(uint32_t send_times)
void set_send_wait(uint32_t send_wait)
Protocol::ProtocolData data
uint16_t get_seq() const
Identifies this transmission in the completion hook.
void set_send_times(uint32_t send_times)
void set_send_wait(uint32_t send_wait)
RemoteTransmitterBase * parent_
RemoteTransmitData * get_data()
TransmitCall(RemoteTransmitterBase *parent, uint16_t seq)
EncodeCall< Protocol > encode_call()
void notify_complete_(bool)
RemoteTransmitterBase(InternalGPIOPin *pin)
void send_(uint32_t send_times, uint32_t send_wait, uint16_t seq)
void(*)(RemoteTransmitData *dst, const void *data) EncodeFn
ProtocolCall< Protocol > protocol_call()
static void encode_thunk(RemoteTransmitData *dst, const void *data)
static uint16_t take_seq_()
void transmit(const typename Protocol::ProtocolData &data, uint32_t send_times=1, uint32_t send_wait=0)
virtual void send_internal(uint32_t send_times, uint32_t send_wait)=0
void transmit_encoded_(EncodeFn encode, const void *data, uint32_t send_times, uint32_t send_wait)
void notify_complete_(bool sent)
Reports the frame handed to the platform last, after its final repeat and before the on_complete trig...
RemoteTransmitData temp_
Use same vector for all transmits, avoids many allocations.
virtual void flush_pending_completion()
Platforms that report completion later wait out the previous frame here, before send_() assigns the n...
std::vector< uint8_t > & out
void ir_rf_transmit_complete(RemoteTransmitterBase *transmitter, uint16_t seq, bool sent)
Defined by ir_rf_base: answers the API request waiting on the entity that submitted seq; sent is fals...
std::vector< int32_t > RawTimings
@ TOLERANCE_MODE_PERCENTAGE
A bit is a mark (one_mark or zero_mark, both bit_mark unless set) and a space (one_space or zero_spac...