33#include <esp_heap_caps.h>
37#include <freertos/FreeRTOS.h>
38#include <freertos/semphr.h>
39#elif defined(USE_LIBRETINY)
48#define HOT __attribute__((hot))
49#define ESPDEPRECATED(msg, when) __attribute__((deprecated(msg)))
50#define ESPHOME_ALWAYS_INLINE __attribute__((always_inline))
51#define PACKED __attribute__((packed))
63using std::is_trivially_copyable;
64using std::make_unique;
65using std::enable_if_t;
67using std::is_invocable;
68#if __cpp_lib_bit_cast >= 201806
73 typename To,
typename From,
74 enable_if_t<
sizeof(To) ==
sizeof(From) && is_trivially_copyable<From>::value && is_trivially_copyable<To>::value,
78 memcpy(&dst, &src,
sizeof(To));
84inline float lerp(
float completion,
float start,
float end) =
delete;
88template<
typename T>
constexpr T
byteswap(T n) {
90 for (
size_t i = 0; i <
sizeof(T); i++)
91 reinterpret_cast<uint8_t *
>(&
m)[i] =
reinterpret_cast<uint8_t *
>(&n)[
sizeof(T) - 1 - i];
94template<>
constexpr uint8_t
byteswap(uint8_t n) {
return n; }
97template<>
inline uint16_t
byteswap(uint16_t n) {
return __builtin_bswap16(n); }
98template<>
inline uint32_t
byteswap(uint32_t n) {
return __builtin_bswap32(n); }
99template<>
inline uint64_t
byteswap(uint64_t n) {
return __builtin_bswap64(n); }
100template<>
inline int8_t
byteswap(int8_t n) {
return n; }
101template<>
inline int16_t
byteswap(int16_t n) {
return __builtin_bswap16(n); }
102template<>
inline int32_t
byteswap(int32_t n) {
return __builtin_bswap32(n); }
103template<>
inline int64_t
byteswap(int64_t n) {
return __builtin_bswap64(n); }
105template<>
constexpr uint16_t
byteswap(uint16_t n) {
return __builtin_bswap16(n); }
106template<>
constexpr uint32_t
byteswap(uint32_t n) {
return __builtin_bswap32(n); }
107template<>
constexpr uint64_t
byteswap(uint64_t n) {
return __builtin_bswap64(n); }
108template<>
constexpr int8_t
byteswap(int8_t n) {
return n; }
109template<>
constexpr int16_t
byteswap(int16_t n) {
return __builtin_bswap16(n); }
110template<>
constexpr int32_t
byteswap(int32_t n) {
return __builtin_bswap32(n); }
111template<>
constexpr int64_t
byteswap(int64_t n) {
return __builtin_bswap64(n); }
144 delete[] this->
heap_;
149 if (other.is_inline_()) {
150 memcpy(this->
inline_, other.inline_, this->len_);
152 this->
heap_ = other.heap_;
153 other.heap_ =
nullptr;
160 if (
this != &other) {
162 delete[] this->
heap_;
163 this->
len_ = other.len_;
164 if (other.is_inline_()) {
165 memcpy(this->
inline_, other.inline_, this->len_);
167 this->
heap_ = other.heap_;
168 other.heap_ =
nullptr;
183 delete[] this->
heap_;
184 this->
heap_ =
nullptr;
187 if (size > InlineSize && (this->
is_inline_() || size != this->len_)) {
212 using iterator =
typename std::array<T, N>::iterator;
218 std::array<T, N> data_{};
227 while (first != last && count_ < N) {
228 data_[count_++] = *first++;
234 for (
const auto &
val : init) {
237 data_[count_++] =
val;
244 data_[count_++] = value;
252 template<
typename InputIt>
void assign(InputIt first, InputIt last) {
254 while (first != last && count_ < N) {
255 data_[count_++] = *first++;
266 return data_[count_++];
269 size_t size()
const {
return count_; }
270 bool empty()
const {
return count_ == 0; }
273 T *
data() {
return data_.data(); }
274 const T *
data()
const {
return data_.data(); }
292 operator std::span<T>() {
return std::span<T>(data_.data(), count_); }
293 operator std::span<const T>()
const {
return std::span<const T>(data_.data(), count_); }
306 void destroy_elements_() {
308 if constexpr (!std::is_trivially_destructible<T>::value) {
309 for (
size_t i = 0; i < size_; i++) {
317 if (data_ !=
nullptr) {
320 ::operator
delete(data_);
332 void assign_from_initializer_list_(std::initializer_list<T> init_list) {
333 init(init_list.size());
335 for (
const auto &item : init_list) {
336 new (data_ + idx) T(item);
339 size_ = init_list.size();
347 FixedVector(std::initializer_list<T> init_list) { assign_from_initializer_list_(init_list); }
361 operator std::vector<T>()
const {
return {data_, data_ + size_}; }
364 if (
this != &other) {
370 capacity_ = other.capacity_;
382 assign_from_initializer_list_(init_list);
396 data_ =
static_cast<T *
>(::operator
new(n *
sizeof(T)));
417 if (size_ < capacity_) {
419 new (&data_[size_]) T(value);
428 if (size_ < capacity_) {
430 new (&data_[size_]) T(std::move(value));
441 new (&data_[size_]) T(std::forward<Args>(args)...);
443 return data_[size_ - 1];
449 const T &
front()
const {
return data_[0]; }
453 T &
back() {
return data_[size_ - 1]; }
454 const T &
back()
const {
return data_[size_ - 1]; }
456 size_t size()
const {
return size_; }
457 bool empty()
const {
return size_ == 0; }
459 bool full()
const {
return size_ == capacity_; }
468 T &
at(
size_t i) {
return data_[i]; }
469 const T &
at(
size_t i)
const {
return data_[i]; }
473 T *
end() {
return data_ + size_; }
474 const T *
begin()
const {
return data_; }
475 const T *
end()
const {
return data_ + size_; }
486 if (
size <= STACK_SIZE) {
487 this->buffer_ = this->stack_buffer_;
489 this->heap_buffer_ =
new T[
size];
490 this->buffer_ = this->heap_buffer_;
501 T *
get() {
return this->buffer_; }
504 T stack_buffer_[STACK_SIZE];
505 T *heap_buffer_{
nullptr};
520 for (int8_t i = 0; i < exp; i++)
523 for (int8_t i = exp; i < 0; i++)
530template<
typename T,
typename U> T
remap(U value, U min, U max, T min_out, T max_out) {
531 return (value - min) * (max_out - min_out) / (max - min) + min_out;
535uint8_t
crc8(
const uint8_t *data, uint8_t
len, uint8_t crc = 0x00, uint8_t poly = 0x8C,
bool msb_first =
false);
538uint16_t
crc16(
const uint8_t *data, uint16_t
len, uint16_t crc = 0xffff, uint16_t reverse_poly = 0xa001,
539 bool refin =
false,
bool refout =
false);
540uint16_t
crc16be(
const uint8_t *data, uint16_t
len, uint16_t crc = 0, uint16_t poly = 0x1021,
bool refin =
false,
541 bool refout =
false);
555 using UnsignedT = std::make_unsigned_t<T>;
556 UnsignedT uvalue =
static_cast<UnsignedT
>(value);
557 for (
size_t i = 0; i <
sizeof(T); i++) {
559 hash ^= (uvalue >> (i * 8)) & 0xFF;
590 using UnsignedT = std::make_unsigned_t<T>;
591 UnsignedT uvalue =
static_cast<UnsignedT
>(value);
592 for (
size_t i = 0; i <
sizeof(T); i++) {
593 hash ^= (uvalue >> (i * 8)) & 0xFF;
625template<
typename ReturnT = u
int32_t>
inline constexpr ESPHOME_ALWAYS_INLINE ReturnT
micros_to_millis(uint64_t us) {
626 constexpr uint32_t d = 125U;
627 constexpr uint32_t q =
static_cast<uint32_t
>((1ULL << 32) / d);
628 constexpr uint32_t r =
static_cast<uint32_t
>((1ULL << 32) % d);
630 uint64_t
x = us >> 3;
631 uint32_t lo =
static_cast<uint32_t
>(
x);
632 uint32_t hi =
static_cast<uint32_t
>(
x >> 32);
634 uint32_t adj = hi * r + lo;
637 return static_cast<ReturnT
>(hi) * q + (adj < lo ? (adj + r) / d + q : adj / d);
654 return (
static_cast<uint16_t
>(msb) << 8) | (
static_cast<uint16_t
>(lsb));
657constexpr uint32_t
encode_uint24(uint8_t byte1, uint8_t byte2, uint8_t byte3) {
658 return (
static_cast<uint32_t
>(byte1) << 16) | (
static_cast<uint32_t
>(byte2) << 8) | (
static_cast<uint32_t
>(byte3));
661constexpr uint32_t
encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4) {
662 return (
static_cast<uint32_t
>(byte1) << 24) | (
static_cast<uint32_t
>(byte2) << 16) |
663 (
static_cast<uint32_t
>(byte3) << 8) | (
static_cast<uint32_t
>(byte4));
667template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
constexpr T
encode_value(
const uint8_t *bytes) {
669 for (
size_t i = 0; i <
sizeof(T); i++) {
676template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
681template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
683 std::array<uint8_t,
sizeof(T)> ret{};
684 for (
size_t i =
sizeof(T); i > 0; i--) {
685 ret[i - 1] =
val & 0xFF;
693 x = ((
x & 0xAA) >> 1) | ((
x & 0x55) << 1);
694 x = ((
x & 0xCC) >> 2) | ((
x & 0x33) << 2);
695 x = ((
x & 0xF0) >> 4) | ((
x & 0x0F) << 4);
704 return (
reverse_bits(
static_cast<uint16_t
>(
x & 0xFFFF)) << 16) |
710#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
719#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
741bool str_startswith(
const std::string &str,
const std::string &start);
760std::string
str_until(
const char *str,
char ch);
762std::string
str_until(
const std::string &str,
char ch);
771constexpr char to_snake_case_char(
char c) {
return (c ==
' ') ?
'_' : (c >=
'A' && c <=
'Z') ? c + (
'a' -
'A') : c; }
778 return (c ==
'-' || c ==
'_' || (c >=
'0' && c <=
'9') || (c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z')) ? c :
'_';
790char *
str_sanitize_to(
char *buffer,
size_t buffer_size,
const char *str);
807 for (
size_t i = 0; i <
len; i++) {
845#define buf_append_printf(buf, size, pos, fmt, ...) buf_append_printf_p(buf, size, pos, PSTR(fmt), ##__VA_ARGS__)
878std::string
make_name_with_suffix(
const std::string &name,
char sep,
const char *suffix_ptr,
size_t suffix_len);
888std::string
make_name_with_suffix(
const char *name,
size_t name_len,
char sep,
const char *suffix_ptr,
901 const char *suffix_ptr,
size_t suffix_len);
909template<
typename T, enable_if_t<(std::is_
integral<T>::value && std::is_
unsigned<T>::value),
int> = 0>
912 unsigned long value = ::strtoul(str, &
end, 10);
913 if (
end == str || *
end !=
'\0' || value > std::numeric_limits<T>::max())
918template<
typename T, enable_if_t<(std::is_
integral<T>::value && std::is_
unsigned<T>::value),
int> = 0>
923template<
typename T, enable_if_t<(std::is_
integral<T>::value && std::is_
signed<T>::value),
int> = 0>
926 signed long value = ::strtol(str, &
end, 10);
927 if (
end == str || *
end !=
'\0' || value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max())
932template<
typename T, enable_if_t<(std::is_
integral<T>::value && std::is_
signed<T>::value),
int> = 0>
937template<
typename T, enable_if_t<(std::is_same<T,
float>::value),
int> = 0> optional<T>
parse_number(
const char *str) {
939 float value = ::strtof(str, &
end);
940 if (
end == str || *
end !=
'\0' || value == HUGE_VALF)
945template<
typename T, enable_if_t<(std::is_same<T,
float>::value),
int> = 0>
961size_t parse_hex(
const char *str,
size_t len, uint8_t *data,
size_t count);
963inline bool parse_hex(
const char *str, uint8_t *data,
size_t count) {
964 return parse_hex(str, strlen(str), data, count) == 2 * count;
967inline bool parse_hex(
const std::string &str, uint8_t *data,
size_t count) {
968 return parse_hex(str.c_str(), str.length(), data, count) == 2 * count;
971inline bool parse_hex(
const char *str, std::vector<uint8_t> &data,
size_t count) {
973 return parse_hex(str, strlen(str), data.data(), count) == 2 * count;
976inline bool parse_hex(
const std::string &str, std::vector<uint8_t> &data,
size_t count) {
978 return parse_hex(str.c_str(), str.length(), data.data(), count) == 2 * count;
985template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
988 if (
len > 2 *
sizeof(T) ||
parse_hex(str,
len,
reinterpret_cast<uint8_t *
>(&
val),
sizeof(T)) == 0)
997template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
optional<T> parse_hex(
const std::string &str) {
1003static constexpr uint8_t INVALID_HEX_CHAR = 255;
1006 if (c >=
'0' && c <=
'9')
1008 if (c >=
'A' && c <=
'F')
1009 return c -
'A' + 10;
1010 if (c >=
'a' && c <=
'f')
1011 return c -
'a' + 10;
1012 return INVALID_HEX_CHAR;
1016inline char format_hex_char(uint8_t v,
char base) {
return v >= 10 ? base + (v - 10) :
'0' + v; }
1036 int32_t tens = v / 10;
1037 *buf++ =
'0' + tens;
1039 }
else if (v >= 10) {
1040 int32_t tens = v / 10;
1041 *buf++ =
'0' + tens;
1054 static_assert(N >= 3,
"Buffer must hold at least one hex byte (3 chars)");
1059template<size_t N, typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
1061 static_assert(N >=
sizeof(T) * 2 + 1,
"Buffer too small for type");
1063 return format_hex_to(buffer,
reinterpret_cast<const uint8_t *
>(&
val),
sizeof(T));
1067template<
size_t N>
inline char *
format_hex_to(
char (&buffer)[N],
const std::vector<uint8_t> &data) {
1072template<
size_t N,
size_t M>
inline char *
format_hex_to(
char (&buffer)[N],
const std::array<uint8_t, M> &data) {
1083template<size_t N, typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
1085 static_assert(N >=
sizeof(T) * 2 + 3,
"Buffer too small for prefixed hex");
1089 format_hex_to(buffer + 2, N - 2,
reinterpret_cast<const uint8_t *
>(&
val),
sizeof(T));
1095 static_assert(N >= 5,
"Buffer must hold at least '0x' + one hex byte + null");
1121 static_assert(N >= 3,
"Buffer must hold at least one hex byte");
1132template<
size_t N,
size_t M>
1158 static_assert(N >= 5,
"Buffer must hold at least one hex uint16_t");
1163static constexpr size_t MAC_ADDRESS_SIZE = 6;
1167static constexpr size_t MAC_ADDRESS_BUFFER_SIZE = MAC_ADDRESS_SIZE * 2 + 1;
1171 return format_hex_pretty_to(output, MAC_ADDRESS_PRETTY_BUFFER_SIZE, mac, MAC_ADDRESS_SIZE,
':');
1176 format_hex_to(output, MAC_ADDRESS_BUFFER_SIZE, mac, MAC_ADDRESS_SIZE);
1190std::string
format_hex(
const std::vector<uint8_t> &data);
1194template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0> std::string
format_hex(T
val) {
1196 return format_hex(
reinterpret_cast<uint8_t *
>(&
val),
sizeof(T));
1201template<std::
size_t N> std::string
format_hex(
const std::array<uint8_t, N> &data) {
1233std::string
format_hex_pretty(
const uint8_t *data,
size_t length,
char separator =
'.',
bool show_length =
true);
1258std::string
format_hex_pretty(
const uint16_t *data,
size_t length,
char separator =
'.',
bool show_length =
true);
1284std::string
format_hex_pretty(
const std::vector<uint8_t> &data,
char separator =
'.',
bool show_length =
true);
1309std::string
format_hex_pretty(
const std::vector<uint16_t> &data,
char separator =
'.',
bool show_length =
true);
1334std::string
format_hex_pretty(
const std::string &data,
char separator =
'.',
bool show_length =
true);
1362template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
1365 return format_hex_pretty(
reinterpret_cast<uint8_t *
>(&
val),
sizeof(T), separator, show_length);
1394 static_assert(N >= 9,
"Buffer must hold at least one binary byte (9 chars)");
1414template<size_t N, typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
1416 static_assert(N >=
sizeof(T) * 8 + 1,
"Buffer too small for type");
1418 return format_bin_to(buffer,
reinterpret_cast<const uint8_t *
>(&
val),
sizeof(T));
1428template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0> std::string
format_bin(T
val) {
1430 return format_bin(
reinterpret_cast<uint8_t *
>(&
val),
sizeof(T));
1444ESPDEPRECATED(
"Allocates heap memory. Use value_accuracy_to_buf() instead. Removed in 2026.7.0.",
"2026.1.0")
1448static constexpr
size_t VALUE_ACCURACY_MAX_LEN = 64;
1451size_t value_accuracy_to_buf(std::span<
char, VALUE_ACCURACY_MAX_LEN> buf,
float value, int8_t accuracy_decimals);
1454 int8_t accuracy_decimals, StringRef unit_of_measurement);
1459std::
string base64_encode(const uint8_t *buf,
size_t buf_len);
1462std::vector<uint8_t>
base64_decode(const std::
string &encoded_string);
1463size_t base64_decode(std::
string const &encoded_string, uint8_t *buf,
size_t buf_len);
1464size_t base64_decode(const uint8_t *encoded_data,
size_t encoded_len, uint8_t *buf,
size_t buf_len);
1479ESPDEPRECATED("Use LightState::gamma_correct_lut() instead. Removed in 2026.9.0.", "2026.3.0")
1483ESPDEPRECATED("Use LightState::gamma_uncorrect_lut() instead. Removed in 2026.9.0.", "2026.3.0")
1487void rgb_to_hsv(
float red,
float green,
float blue,
int &hue,
float &saturation,
float &value);
1489void hsv_to_rgb(
int hue,
float saturation,
float value,
float &red,
float &green,
float &blue);
1515 void add(std::function<
void(Ts...)> &&callback) { this->callbacks_.push_back(std::move(callback)); }
1519 for (
auto &cb : this->callbacks_)
1522 size_t size()
const {
return this->callbacks_.size(); }
1562 void add(std::function<
void(Ts...)> &&callback) {
1563 if (!this->callbacks_) {
1566 this->callbacks_->add(std::move(callback));
1571 if (this->callbacks_) {
1572 this->callbacks_->call(args...);
1577 size_t size()
const {
return this->callbacks_ ? this->callbacks_->size() : 0; }
1580 bool empty()
const {
return !this->callbacks_ || this->callbacks_->size() == 0; }
1653#if defined(USE_ESP32) || defined(USE_LIBRETINY)
1654 SemaphoreHandle_t handle_;
1700#if defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_ZEPHYR)
1814 size_t size = n * manual_size;
1818 ptr =
static_cast<T *
>(heap_caps_malloc(
size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT));
1821 ptr =
static_cast<T *
>(heap_caps_malloc(
size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT));
1825 ptr =
static_cast<T *
>(malloc(
size));
1833 size_t size = n * manual_size;
1837 ptr =
static_cast<T *
>(heap_caps_realloc(p,
size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT));
1840 ptr =
static_cast<T *
>(heap_caps_realloc(p,
size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT));
1844 ptr =
static_cast<T *
>(realloc(p,
size));
1858 return ESP.getFreeHeap();
1859#elif defined(USE_ESP32)
1861 this->flags_ &
ALLOC_INTERNAL ? heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL) : 0;
1863 this->flags_ &
ALLOC_EXTERNAL ? heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM) : 0;
1864 return max_internal + max_external;
1865#elif defined(USE_RP2040)
1866 return ::rp2040.getFreeHeap();
1867#elif defined(USE_LIBRETINY)
1868 return lt_heap_get_free();
1879 return ESP.getMaxFreeBlockSize();
1880#elif defined(USE_ESP32)
1882 this->flags_ &
ALLOC_INTERNAL ? heap_caps_get_largest_free_block(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL) : 0;
1884 this->flags_ &
ALLOC_EXTERNAL ? heap_caps_get_largest_free_block(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM) : 0;
1885 return std::max(max_internal, max_external);
1901template<
typename T,
typename U>
1903 { a > b } -> std::convertible_to<bool>;
1904 { a < b } -> std::convertible_to<bool>;
1907template<std::totally_ordered T, comparable_with<T> U> T
clamp_at_least(T value, U min) {
1912template<std::totally_ordered T, comparable_with<T> U> T
clamp_at_most(T value, U max) {
1925template<typename T, enable_if_t<!std::is_pointer<T>::value,
int> = 0> T
id(T value) {
return value; }
1930template<typename T, enable_if_t<std::is_pointer<T *>::value,
int> = 0> T &
id(T *value) {
return *value; }
void operator()(Ts... args)
Call all callbacks in this manager.
std::vector< std::function< void(Ts...)> > callbacks_
void call(Ts... args)
Call all callbacks in this manager.
void add(std::function< void(Ts...)> &&callback)
Add a callback to the list.
Lightweight read-only view over a const array stored in RODATA (will typically be in flash memory) Av...
const constexpr T & operator[](size_t i) const
constexpr bool empty() const
constexpr ConstVector(const T *data, size_t size)
constexpr size_t size() const
Helper class to deduplicate items in a series of values.
bool next(T value)
Feeds the next item in the series to the deduplicator and returns false if this is a duplicate.
bool has_value() const
Returns true if this deduplicator has processed any items.
bool next_unknown()
Returns true if the deduplicator's value was previously known.
Fixed-capacity vector - allocates once at runtime, never reallocates This avoids std::vector template...
const T & at(size_t i) const
FixedVector(FixedVector &&other) noexcept
FixedVector(std::initializer_list< T > init_list)
Constructor from initializer list - allocates exact size needed This enables brace initialization: Fi...
FixedVector & operator=(std::initializer_list< T > init_list)
Assignment from initializer list - avoids temporary and move overhead This enables: FixedVector<int> ...
T & front()
Access first element (no bounds checking - matches std::vector behavior) Caller must ensure vector is...
const T & operator[](size_t i) const
T & operator[](size_t i)
Access element without bounds checking (matches std::vector behavior) Caller must ensure index is val...
T & back()
Access last element (no bounds checking - matches std::vector behavior) Caller must ensure vector is ...
FixedVector & operator=(const FixedVector &)=delete
FixedVector(const FixedVector &)=delete
void push_back(T &&value)
Add element by move without bounds checking Caller must ensure sufficient capacity was allocated via ...
T & emplace_back(Args &&...args)
Emplace element without bounds checking - constructs in-place with arguments Caller must ensure suffi...
FixedVector & operator=(FixedVector &&other) noexcept
T & at(size_t i)
Access element with bounds checking (matches std::vector behavior) Note: No exception thrown on out o...
void push_back(const T &value)
Add element without bounds checking Caller must ensure sufficient capacity was allocated via init() S...
Helper class to request loop() to be called as fast as possible.
void stop()
Stop running the loop continuously.
static bool is_high_frequency()
Check whether the loop is running continuously.
static uint8_t num_requests
void start()
Start running the loop continuously.
Helper class to disable interrupts.
LazyCallbackManager & operator=(const LazyCallbackManager &)=delete
LazyCallbackManager(const LazyCallbackManager &)=delete
size_t size() const
Return the number of registered callbacks.
LazyCallbackManager()=default
void operator()(Ts... args)
Call all callbacks in this manager.
LazyCallbackManager & operator=(LazyCallbackManager &&)=delete
void add(std::function< void(Ts...)> &&callback)
Add a callback to the list. Allocates the underlying CallbackManager on first use.
~LazyCallbackManager()
Destructor - clean up allocated CallbackManager if any.
void call(Ts... args)
Call all callbacks in this manager. No-op if no callbacks registered.
bool empty() const
Check if any callbacks are registered.
LazyCallbackManager(LazyCallbackManager &&)=delete
Helper class that wraps a mutex with a RAII-style API.
Helper class to lock the lwIP TCPIP core when making lwIP API calls from non-TCPIP threads.
LwIPLock(const LwIPLock &)=delete
LwIPLock & operator=(const LwIPLock &)=delete
Mutex implementation, with API based on the unavailable std::mutex.
Mutex(const Mutex &)=delete
Mutex & operator=(const Mutex &)=delete
Helper class to easily give an object a parent of type T.
T * get_parent() const
Get the parent of this object.
void set_parent(T *parent)
Set the parent of this object.
An STL allocator that uses SPI or internal RAM.
constexpr RAMAllocator(uint8_t flags)
T * reallocate(T *p, size_t n, size_t manual_size)
size_t get_free_heap_size() const
Return the total heap space available via this allocator.
T * reallocate(T *p, size_t n)
void deallocate(T *p, size_t n)
size_t get_max_free_block_size() const
Return the maximum size block this allocator could allocate.
constexpr RAMAllocator(const RAMAllocator< U > &other)
T * allocate(size_t n, size_t manual_size)
constexpr RAMAllocator()=default
Helper class for efficient buffer allocation - uses stack for small sizes, heap for large This is use...
SmallBufferWithHeapFallback(const SmallBufferWithHeapFallback &)=delete
SmallBufferWithHeapFallback & operator=(SmallBufferWithHeapFallback &&)=delete
~SmallBufferWithHeapFallback()
SmallBufferWithHeapFallback & operator=(const SmallBufferWithHeapFallback &)=delete
SmallBufferWithHeapFallback(size_t size)
SmallBufferWithHeapFallback(SmallBufferWithHeapFallback &&)=delete
Small buffer optimization - stores data inline when small, heap-allocates for large data This avoids ...
SmallInlineBuffer()=default
SmallInlineBuffer(const SmallInlineBuffer &)=delete
void set(const uint8_t *src, size_t size)
Set buffer contents, allocating heap if needed.
SmallInlineBuffer & operator=(const SmallInlineBuffer &)=delete
uint8_t inline_[InlineSize]
SmallInlineBuffer & operator=(SmallInlineBuffer &&other) noexcept
const uint8_t * data() const
SmallInlineBuffer(SmallInlineBuffer &&other) noexcept
Minimal static vector - saves memory by avoiding std::vector overhead.
const_reverse_iterator rend() const
reverse_iterator rbegin()
const T & operator[](size_t i) const
void push_back(const T &value)
void assign(InputIt first, InputIt last)
const_reverse_iterator rbegin() const
std::reverse_iterator< const_iterator > const_reverse_iterator
typename std::array< T, N >::iterator iterator
typename std::array< T, N >::const_iterator const_iterator
std::reverse_iterator< iterator > reverse_iterator
const_iterator end() const
StaticVector(InputIt first, InputIt last)
StaticVector(std::initializer_list< T > init)
const_iterator begin() const
struct @65::@66 __attribute__
Functions to constrain the range of arithmetic values.
Providing packet encoding functions for exchanging data with a remote host.
T clamp_at_most(T value, U max)
bool random_bytes(uint8_t *data, size_t len)
Generate len number of random bytes.
constexpr uint32_t fnv1a_hash_extend(uint32_t hash, const char *str)
Extend a FNV-1a hash with additional string data.
float random_float()
Return a random float between 0 and 1.
float gamma_uncorrect(float value, float gamma)
uint16_t crc16(const uint8_t *data, uint16_t len, uint16_t crc, uint16_t reverse_poly, bool refin, bool refout)
Calculate a CRC-16 checksum of data with size len.
size_t make_name_with_suffix_to(char *buffer, size_t buffer_size, const char *name, size_t name_len, char sep, const char *suffix_ptr, size_t suffix_len)
Zero-allocation version: format name + separator + suffix directly into buffer.
std::string value_accuracy_to_string(float value, int8_t accuracy_decimals)
constexpr T convert_big_endian(T val)
Convert a value between host byte order and big endian (most significant byte first) order.
char format_hex_pretty_char(uint8_t v)
Convert a nibble (0-15) to uppercase hex char (used for pretty printing)
float gamma_correct(float value, float gamma)
constexpr char to_sanitized_char(char c)
Sanitize a single char: keep alphanumerics, dashes, underscores; replace others with underscore.
bool mac_address_is_valid(const uint8_t *mac)
Check if the MAC address is not all zeros or all ones.
void format_mac_addr_lower_no_sep(const uint8_t *mac, char *output)
Format MAC address as xxxxxxxxxxxxxx (lowercase, no separators)
constexpr uint32_t FNV1_OFFSET_BASIS
FNV-1 32-bit offset basis.
void rgb_to_hsv(float red, float green, float blue, int &hue, float &saturation, float &value)
Convert red, green and blue (all 0-1) values to hue (0-360), saturation (0-1) and value (0-1).
std::string format_hex(const uint8_t *data, size_t length)
Format the byte array data of length len in lowercased hex.
char format_hex_char(uint8_t v, char base)
Convert a nibble (0-15) to hex char with specified base ('a' for lowercase, 'A' for uppercase)
size_t value_accuracy_to_buf(std::span< char, VALUE_ACCURACY_MAX_LEN > buf, float value, int8_t accuracy_decimals)
Format value with accuracy to buffer, returns chars written (excluding null)
std::string str_lower_case(const std::string &str)
Convert the string to lower case.
ParseOnOffState parse_on_off(const char *str, const char *on, const char *off)
Parse a string that contains either on, off or toggle.
std::string format_bin(const uint8_t *data, size_t length)
Format the byte array data of length len in binary.
constexpr T convert_little_endian(T val)
Convert a value between host byte order and little endian (least significant byte first) order.
std::string str_sanitize(const std::string &str)
Sanitizes the input string by removing all characters but alphanumerics, dashes and underscores.
constexpr uint32_t fnv1_hash_extend(uint32_t hash, T value)
Extend a FNV-1 hash with an integer (hashes each byte).
bool base64_decode_int32_vector(const std::string &base64, std::vector< int32_t > &out)
Decode base64/base64url string directly into vector of little-endian int32 values.
constexpr size_t format_hex_prefixed_size(size_t byte_count)
Calculate buffer size needed for format_hex_prefixed_to: "0xXXXXXXXX...\0" = bytes * 2 + 3.
constexpr uint32_t encode_uint24(uint8_t byte1, uint8_t byte2, uint8_t byte3)
Encode a 24-bit value given three bytes in most to least significant byte order.
char * format_hex_prefixed_to(char(&buffer)[N], T val)
Format an unsigned integer as "0x" prefixed lowercase hex to buffer.
bool has_custom_mac_address()
Check if a custom MAC address is set (ESP32 & variants)
size_t parse_hex(const char *str, size_t length, uint8_t *data, size_t count)
Parse bytes from a hex-encoded string into a byte array.
char * format_hex_pretty_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length, char separator)
Format byte array as uppercase hex to buffer (base implementation).
uint32_t fnv1_hash_object_id(const char *str, size_t len)
Calculate FNV-1 hash of a string while applying snake_case + sanitize transformations.
uint32_t fnv1_hash(const char *str)
Calculate a FNV-1 hash of str.
T clamp_at_least(T value, U min)
optional< T > parse_number(const char *str)
Parse an unsigned decimal number from a null-terminated string.
std::string get_mac_address_pretty()
Get the device MAC address as a string, in colon-separated uppercase hex notation.
std::string str_snprintf(const char *fmt, size_t len,...)
void set_mac_address(uint8_t *mac)
Set the MAC address to use from the provided byte array (6 bytes).
int8_t step_to_accuracy_decimals(float step)
Derive accuracy in decimals from an increment step.
uint32_t random_uint32()
Return a random 32-bit unsigned integer.
const char * get_mac_address_pretty_into_buffer(std::span< char, MAC_ADDRESS_PRETTY_BUFFER_SIZE > buf)
Get the device MAC address into the given buffer, in colon-separated uppercase hex notation.
void IRAM_ATTR HOT delay_microseconds_safe(uint32_t us)
Delay for the given amount of microseconds, possibly yielding to other processes during the wait.
std::string str_upper_case(const std::string &str)
Convert the string to upper case.
std::string format_hex_pretty(const uint8_t *data, size_t length, char separator, bool show_length)
Format a byte array in pretty-printed, human-readable hex format.
constexpr size_t format_hex_size(size_t byte_count)
Calculate buffer size needed for format_hex_to: "XXXXXXXX...\0" = bytes * 2 + 1.
bool str_equals_case_insensitive(const std::string &a, const std::string &b)
Compare strings for equality in case-insensitive manner.
std::string str_until(const char *str, char ch)
Extract the part of the string until either the first occurrence of the specified character,...
bool str_endswith_ignore_case(const char *str, size_t str_len, const char *suffix, size_t suffix_len)
Case-insensitive check if string ends with suffix (no heap allocation).
constexpr ESPHOME_ALWAYS_INLINE ReturnT micros_to_millis(uint64_t us)
Convert a 64-bit microsecond count to milliseconds without calling __udivdi3 (software 64-bit divide,...
char * str_sanitize_to(char *buffer, size_t buffer_size, const char *str)
Sanitize a string to buffer, keeping only alphanumerics, dashes, and underscores.
char * int8_to_str(char *buf, int8_t val)
Write int8 value to buffer without modulo operations.
std::string format_mac_address_pretty(const uint8_t *mac)
size_t value_accuracy_with_uom_to_buf(std::span< char, VALUE_ACCURACY_MAX_LEN > buf, float value, int8_t accuracy_decimals, StringRef unit_of_measurement)
Format value with accuracy and UOM to buffer, returns chars written (excluding null)
constexpr size_t format_hex_pretty_size(size_t byte_count)
Calculate buffer size needed for format_hex_pretty_to with separator: "XX:XX:...:XX\0".
std::string base64_encode(const std::vector< uint8_t > &buf)
constexpr uint32_t FNV1_PRIME
FNV-1 32-bit prime.
constexpr T encode_value(const uint8_t *bytes)
Encode a value from its constituent bytes (from most to least significant) in an array with length si...
void hsv_to_rgb(int hue, float saturation, float value, float &red, float &green, float &blue)
Convert hue (0-360), saturation (0-1) and value (0-1) to red, green and blue (all 0-1).
void get_mac_address_into_buffer(std::span< char, MAC_ADDRESS_BUFFER_SIZE > buf)
Get the device MAC address into the given buffer, in lowercase hex notation.
uint16_t crc16be(const uint8_t *data, uint16_t len, uint16_t crc, uint16_t poly, bool refin, bool refout)
constexpr uint32_t encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4)
Encode a 32-bit value given four bytes in most to least significant byte order.
uint8_t crc8(const uint8_t *data, uint8_t len, uint8_t crc, uint8_t poly, bool msb_first)
Calculate a CRC-8 checksum of data with size len.
constexpr float celsius_to_fahrenheit(float value)
Convert degrees Celsius to degrees Fahrenheit.
std::string str_sprintf(const char *fmt,...)
size_t size_t const char va_start(args, fmt)
constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit value given the most and least significant byte.
void get_mac_address_raw(uint8_t *mac)
Get the device MAC address as raw bytes, written into the provided byte array (6 bytes).
size_t size_t const char * fmt
constexpr uint8_t parse_hex_char(char c)
bool str_startswith(const std::string &str, const std::string &start)
Check whether a string starts with a value.
constexpr std::array< uint8_t, sizeof(T)> decode_value(T val)
Decode a value into its constituent bytes (from most to least significant).
std::string get_mac_address()
Get the device MAC address as a string, in lowercase hex notation.
constexpr size_t format_bin_size(size_t byte_count)
Calculate buffer size needed for format_bin_to: "01234567...\0" = bytes * 8 + 1.
struct ESPDEPRECATED("Use std::index_sequence instead. Removed in 2026.6.0", "2025.12.0") seq
To bit_cast(const From &src)
Convert data between types, without aliasing issues or undefined behaviour.
constexpr char to_snake_case_char(char c)
Convert a single char to snake_case: lowercase and space to underscore.
constexpr float fahrenheit_to_celsius(float value)
Convert degrees Fahrenheit to degrees Celsius.
uint8_t reverse_bits(uint8_t x)
Reverse the order of 8 bits.
char * format_hex_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length)
Format byte array as lowercase hex to buffer (base implementation).
std::string str_snake_case(const std::string &str)
Convert the string to snake case (lowercase with underscores).
float lerp(float completion, float start, float end)=delete
constexpr size_t format_hex_pretty_uint16_size(size_t count)
Calculate buffer size needed for format_hex_pretty_to with uint16_t data: "XXXX:XXXX:....
T remap(U value, U min, U max, T min_out, T max_out)
Remap value from the range (min, max) to (min_out, max_out).
bool str_endswith(const std::string &str, const std::string &end)
Check whether a string ends with a value.
constexpr uint32_t fnv1a_hash(const char *str)
Calculate a FNV-1a hash of str.
std::string size_t std::string size_t buf_append_printf_p(char *buf, size_t size, size_t pos, PGM_P fmt,...)
Safely append formatted string to buffer, returning new position (capped at size).
size_t base64_decode(const std::string &encoded_string, uint8_t *buf, size_t buf_len)
ParseOnOffState
Return values for parse_on_off().
float pow10_int(int8_t exp)
Compute 10^exp using iterative multiplication/division.
std::string make_name_with_suffix(const char *name, size_t name_len, char sep, const char *suffix_ptr, size_t suffix_len)
Optimized string concatenation: name + separator + suffix (const char* overload) Uses a fixed stack b...
char * format_bin_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length)
Format byte array as binary string to buffer.
char * format_mac_addr_upper(const uint8_t *mac, char *output)
Format MAC address as XX:XX:XX:XX:XX:XX (uppercase, colon separators)
std::string str_truncate(const std::string &str, size_t length)
Truncate a string to a specific length.