ESPHome 2026.3.0-dev
Loading...
Searching...
No Matches
infrared.cpp
Go to the documentation of this file.
1#include "infrared.h"
2#include "esphome/core/log.h"
3
4#ifdef USE_API
6#endif
7
9
10static const char *const TAG = "infrared";
11
12// ========== InfraredCall ==========
13
18
19InfraredCall &InfraredCall::set_raw_timings(const std::vector<int32_t> &timings) {
20 this->raw_timings_ = &timings;
21 this->packed_data_ = nullptr;
22 this->base64url_ptr_ = nullptr;
23 return *this;
24}
25
27 this->base64url_ptr_ = &base64url;
28 this->raw_timings_ = nullptr;
29 this->packed_data_ = nullptr;
30 return *this;
31}
32
33InfraredCall &InfraredCall::set_raw_timings_packed(const uint8_t *data, uint16_t length, uint16_t count) {
34 this->packed_data_ = data;
35 this->packed_length_ = length;
36 this->packed_count_ = count;
37 this->raw_timings_ = nullptr;
38 this->base64url_ptr_ = nullptr;
39 return *this;
40}
41
43 this->repeat_count_ = count;
44 return *this;
45}
46
48 if (this->parent_ != nullptr) {
49 this->parent_->control(*this);
50 }
51}
52
53// ========== Infrared ==========
54
56 // Set up traits based on configuration
59
60 // Register as listener for received IR data
61 if (this->receiver_ != nullptr) {
62 this->receiver_->register_listener(this);
63 }
64}
65
67 ESP_LOGCONFIG(TAG,
68 "Infrared '%s'\n"
69 " Supports Transmitter: %s\n"
70 " Supports Receiver: %s",
71 this->get_name().c_str(), YESNO(this->traits_.get_supports_transmitter()),
72 YESNO(this->traits_.get_supports_receiver()));
73}
74
76
78 if (this->transmitter_ == nullptr) {
79 ESP_LOGW(TAG, "No transmitter configured");
80 return;
81 }
82
83 if (!call.has_raw_timings()) {
84 ESP_LOGE(TAG, "No raw timings provided");
85 return;
86 }
87
88 // Create transmit data object
89 auto transmit_call = this->transmitter_->transmit();
90 auto *transmit_data = transmit_call.get_data();
91
92 // Set carrier frequency
93 if (call.get_carrier_frequency().has_value()) {
94 transmit_data->set_carrier_frequency(call.get_carrier_frequency().value());
95 }
96
97 // Set timings based on format
98 if (call.is_packed()) {
99 // Zero-copy from packed protobuf data
100 transmit_data->set_data_from_packed_sint32(call.get_packed_data(), call.get_packed_length(),
101 call.get_packed_count());
102 ESP_LOGD(TAG, "Transmitting packed raw timings: count=%u, repeat=%u", call.get_packed_count(),
103 call.get_repeat_count());
104 } else if (call.is_base64url()) {
105 // Decode base64url (URL-safe) into transmit buffer
106 if (!transmit_data->set_data_from_base64url(call.get_base64url_data())) {
107 ESP_LOGE(TAG, "Invalid base64url data");
108 return;
109 }
110 // Sanity check: validate timing values are within reasonable bounds
111 constexpr int32_t max_timing_us = 500000; // 500ms absolute max
112 for (int32_t timing : transmit_data->get_data()) {
113 int32_t abs_timing = timing < 0 ? -timing : timing;
114 if (abs_timing > max_timing_us) {
115 ESP_LOGE(TAG, "Invalid timing value: %d µs (max %d)", timing, max_timing_us);
116 return;
117 }
118 }
119 ESP_LOGD(TAG, "Transmitting base64url raw timings: count=%zu, repeat=%u", transmit_data->get_data().size(),
120 call.get_repeat_count());
121 } else {
122 // From vector (lambdas/automations)
123 transmit_data->set_data(call.get_raw_timings());
124 ESP_LOGD(TAG, "Transmitting raw timings: count=%zu, repeat=%u", call.get_raw_timings().size(),
125 call.get_repeat_count());
126 }
127
128 // Set repeat count
129 if (call.get_repeat_count() > 0) {
130 transmit_call.set_send_times(call.get_repeat_count());
131 }
132
133 // Perform transmission
134 transmit_call.perform();
135}
136
138 uint32_t flags = 0;
139
140 // Add transmit/receive capability based on traits
143 if (this->traits_.get_supports_receiver())
145
146 return flags;
147}
148
150 // Forward received IR data to API server
151#if defined(USE_API) && defined(USE_IR_RF)
152 if (api::global_api_server != nullptr) {
153#ifdef USE_DEVICES
154 uint32_t device_id = this->get_device_id();
155#else
156 uint32_t device_id = 0;
157#endif
159 }
160#endif
161 return false; // Don't consume the event, allow other listeners to process it
162}
163
164} // namespace esphome::infrared
uint16_le_t frequency
Definition bl0942.h:6
ESPDEPRECATED("object_id mangles names and all object_id methods are planned for removal " "(see https://github.com/esphome/backlog/issues/76). " "Now is the time to stop using object_id. If still needed, use get_object_id_to() " "which will remain available longer. get_object_id() will be removed in 2026.7.0", "2025.12.0") std uint32_t get_object_id_hash()
const StringRef & get_name() const
uint32_t get_device_id() const
void send_infrared_rf_receive_event(uint32_t device_id, uint32_t key, const std::vector< int32_t > *timings)
InfraredCall - Builder pattern for transmitting infrared signals.
Definition infrared.h:25
InfraredCall & set_raw_timings(const std::vector< int32_t > &timings)
Set the raw timings from a vector (positive = mark, negative = space)
Definition infrared.cpp:19
InfraredCall & set_carrier_frequency(uint32_t frequency)
Set the carrier frequency in Hz.
Definition infrared.cpp:14
InfraredCall & set_repeat_count(uint32_t count)
Set the number of times to repeat transmission (1 = transmit once, 2 = transmit twice,...
Definition infrared.cpp:42
void perform()
Perform the transmission.
Definition infrared.cpp:47
InfraredCall & set_raw_timings_packed(const uint8_t *data, uint16_t length, uint16_t count)
Set the raw timings from packed protobuf sint32 data (zigzag + varint encoded)
Definition infrared.cpp:33
const std::string * base64url_ptr_
Definition infrared.h:88
optional< uint32_t > carrier_frequency_
Definition infrared.h:84
const uint8_t * packed_data_
Definition infrared.h:90
InfraredCall & set_raw_timings_base64url(const std::string &base64url)
Set the raw timings from base64url-encoded little-endian int32 data.
Definition infrared.cpp:26
const std::vector< int32_t > * raw_timings_
Definition infrared.h:86
void dump_config() override
Definition infrared.cpp:66
remote_base::RemoteReceiverBase * receiver_
Definition infrared.h:148
bool on_receive(remote_base::RemoteReceiveData data) override
Called when IR data is received (from RemoteReceiverListener)
Definition infrared.cpp:149
InfraredCall make_call()
Create a call object for transmitting.
Definition infrared.cpp:75
virtual void control(const InfraredCall &call)
Perform the actual transmission (called by InfraredCall)
Definition infrared.cpp:77
remote_base::RemoteTransmitterBase * transmitter_
Definition infrared.h:149
bool has_transmitter() const
Check if this infrared has a transmitter configured.
Definition infrared.h:124
bool has_receiver() const
Check if this infrared has a receiver configured.
Definition infrared.h:126
uint32_t get_capability_flags() const
Get capability flags for this infrared instance.
Definition infrared.cpp:137
bool get_supports_transmitter() const
Definition infrared.h:98
void set_supports_transmitter(bool supports)
Definition infrared.h:99
void set_supports_receiver(bool supports)
Definition infrared.h:102
const RawTimings & get_raw_data() const
Definition remote_base.h:59
void register_listener(RemoteReceiverListener *listener)
uint16_t flags
APIServer * global_api_server
uint16_t length
Definition tt21100.cpp:0