24#include <esp_heap_caps.h>
28#include <freertos/FreeRTOS.h>
29#include <freertos/semphr.h>
30#elif defined(USE_LIBRETINY)
35#define HOT __attribute__((hot))
36#define ESPDEPRECATED(msg, when) __attribute__((deprecated(msg)))
37#define ESPHOME_ALWAYS_INLINE __attribute__((always_inline))
38#define PACKED __attribute__((packed))
42#if __cplusplus >= 201402L
43#define constexpr14 constexpr
45#define constexpr14 inline
58#if _GLIBCXX_RELEASE >= 8
65std::string
to_string(
unsigned long value);
66std::string
to_string(
unsigned long long value);
73#if _GLIBCXX_RELEASE >= 6
74using std::is_trivially_copyable;
83#if __cpp_lib_make_unique >= 201304
84using std::make_unique;
86template<
typename T,
typename... Args> std::unique_ptr<T>
make_unique(Args &&...args) {
87 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
92#if __cplusplus >= 201402L
93using std::enable_if_t;
95template<
bool B,
class T =
void>
using enable_if_t =
typename std::enable_if<B, T>::type;
99#if __cpp_lib_clamp >= 201603
102template<
typename T,
typename Compare>
constexpr const T &
clamp(
const T &v,
const T &lo,
const T &hi, Compare comp) {
103 return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
105template<
typename T>
constexpr const T &
clamp(
const T &v,
const T &lo,
const T &hi) {
106 return clamp(v, lo, hi, std::less<T>{});
111#if __cpp_lib_is_invocable >= 201703
112using std::is_invocable;
116 template<
class U>
static auto test(U *p) ->
decltype((*p)(std::declval<Args>()...), void(), std::true_type());
117 template<
class U>
static auto test(...) ->
decltype(std::false_type());
123#if __cpp_lib_bit_cast >= 201806
128 typename To,
typename From,
133 memcpy(&dst, &src,
sizeof(To));
141 for (
size_t i = 0; i <
sizeof(T); i++)
142 reinterpret_cast<uint8_t *
>(&
m)[i] =
reinterpret_cast<uint8_t *
>(&n)[
sizeof(T) - 1 - i];
145template<> constexpr14 uint8_t
byteswap(uint8_t n) {
return n; }
146template<> constexpr14 uint16_t
byteswap(uint16_t n) {
return __builtin_bswap16(n); }
147template<> constexpr14 uint32_t
byteswap(uint32_t n) {
return __builtin_bswap32(n); }
148template<> constexpr14 uint64_t
byteswap(uint64_t n) {
return __builtin_bswap64(n); }
149template<> constexpr14 int8_t
byteswap(int8_t n) {
return n; }
150template<> constexpr14 int16_t
byteswap(int16_t n) {
return __builtin_bswap16(n); }
151template<> constexpr14 int32_t
byteswap(int32_t n) {
return __builtin_bswap32(n); }
152template<> constexpr14 int64_t
byteswap(int64_t n) {
return __builtin_bswap64(n); }
160float lerp(
float completion,
float start,
float end);
163template<
typename T,
typename U> T
remap(U value, U min, U max, T min_out, T max_out) {
164 return (value - min) * (max_out - min_out) / (max - min) + min_out;
168uint8_t
crc8(
const uint8_t *data, uint8_t
len);
171uint16_t
crc16(
const uint8_t *data, uint16_t
len, uint16_t crc = 0xffff, uint16_t reverse_poly = 0xa001,
172 bool refin =
false,
bool refout =
false);
173uint16_t
crc16be(
const uint8_t *data, uint16_t
len, uint16_t crc = 0, uint16_t poly = 0x1021,
bool refin =
false,
174 bool refout =
false);
177uint32_t
fnv1_hash(
const std::string &str);
193 return (
static_cast<uint16_t
>(msb) << 8) | (
static_cast<uint16_t
>(lsb));
196constexpr uint32_t
encode_uint24(uint8_t byte1, uint8_t byte2, uint8_t byte3) {
197 return (
static_cast<uint32_t
>(byte1) << 16) | (
static_cast<uint32_t
>(byte2) << 8) | (
static_cast<uint32_t
>(byte3));
200constexpr uint32_t
encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4) {
201 return (
static_cast<uint32_t
>(byte1) << 24) | (
static_cast<uint32_t
>(byte2) << 16) |
202 (
static_cast<uint32_t
>(byte3) << 8) | (
static_cast<uint32_t
>(byte4));
206template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
209 for (
size_t i = 0; i <
sizeof(T); i++) {
216template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
217constexpr14 T
encode_value(
const std::array<uint8_t,
sizeof(T)> bytes) {
221template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
223 std::array<uint8_t,
sizeof(T)> ret{};
224 for (
size_t i =
sizeof(T); i > 0; i--) {
225 ret[i - 1] =
val & 0xFF;
233 x = ((
x & 0xAA) >> 1) | ((
x & 0x55) << 1);
234 x = ((
x & 0xCC) >> 2) | ((
x & 0x33) << 2);
235 x = ((
x & 0xF0) >> 4) | ((
x & 0x0F) << 4);
244 return (
reverse_bits(
static_cast<uint16_t
>(
x & 0xFFFF)) << 16) |
250#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
259#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
275bool str_startswith(
const std::string &str,
const std::string &start);
287std::string
str_until(
const char *str,
char ch);
289std::string
str_until(
const std::string &str,
char ch);
313template<typename T,
enable_if_t<(std::is_integral<T>::value && std::is_unsigned<T>::value),
int> = 0>
316 unsigned long value = ::strtoul(str, &
end, 10);
317 if (
end == str || *
end !=
'\0' || value > std::numeric_limits<T>::max())
322template<
typename T, enable_if_t<(std::is_
integral<T>::value && std::is_
unsigned<T>::value),
int> = 0>
327template<
typename T, enable_if_t<(std::is_
integral<T>::value && std::is_
signed<T>::value),
int> = 0>
330 signed long value = ::strtol(str, &
end, 10);
331 if (
end == str || *
end !=
'\0' || value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max())
336template<
typename T, enable_if_t<(std::is_
integral<T>::value && std::is_
signed<T>::value),
int> = 0>
341template<
typename T, enable_if_t<(std::is_same<T,
float>::value),
int> = 0> optional<T>
parse_number(
const char *str) {
343 float value = ::strtof(str, &
end);
344 if (
end == str || *
end !=
'\0' || value == HUGE_VALF)
349template<
typename T, enable_if_t<(std::is_same<T,
float>::value),
int> = 0>
365size_t parse_hex(
const char *str,
size_t len, uint8_t *data,
size_t count);
367inline bool parse_hex(
const char *str, uint8_t *data,
size_t count) {
368 return parse_hex(str, strlen(str), data, count) == 2 * count;
371inline bool parse_hex(
const std::string &str, uint8_t *data,
size_t count) {
372 return parse_hex(str.c_str(), str.length(), data, count) == 2 * count;
375inline bool parse_hex(
const char *str, std::vector<uint8_t> &data,
size_t count) {
377 return parse_hex(str, strlen(str), data.data(), count) == 2 * count;
380inline bool parse_hex(
const std::string &str, std::vector<uint8_t> &data,
size_t count) {
382 return parse_hex(str.c_str(), str.length(), data.data(), count) == 2 * count;
389template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
392 if (
len > 2 *
sizeof(T) ||
parse_hex(str,
len,
reinterpret_cast<uint8_t *
>(&
val),
sizeof(T)) == 0)
401template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
optional<T> parse_hex(
const std::string &str) {
408std::string
format_hex(
const std::vector<uint8_t> &data);
410template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0> std::string
format_hex(T
val) {
412 return format_hex(
reinterpret_cast<uint8_t *
>(&
val),
sizeof(T));
414template<std::
size_t N> std::string
format_hex(
const std::array<uint8_t, N> &data) {
435template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0> std::string
format_bin(T
val) {
437 return format_bin(
reinterpret_cast<uint8_t *
>(&
val),
sizeof(T));
456std::string
base64_encode(
const uint8_t *buf,
size_t buf_len);
459std::vector<uint8_t>
base64_decode(
const std::string &encoded_string);
460size_t base64_decode(std::string
const &encoded_string, uint8_t *buf,
size_t buf_len);
473void rgb_to_hsv(
float red,
float green,
float blue,
int &hue,
float &saturation,
float &value);
475void hsv_to_rgb(
int hue,
float saturation,
float value,
float &red,
float &green,
float &blue);
501 void add(std::function<
void(Ts...)> &&callback) { this->callbacks_.push_back(std::move(callback)); }
505 for (
auto &cb : this->callbacks_)
508 size_t size()
const {
return this->callbacks_.size(); }
574#if defined(USE_ESP32) || defined(USE_LIBRETINY)
575 SemaphoreHandle_t handle_;
621#if defined(USE_ESP8266) || defined(USE_RP2040)
700 this->flags_ = flags;
707 size_t size = n * manual_size;
711 ptr =
static_cast<T *
>(heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT));
714 ptr =
static_cast<T *
>(heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT));
718 ptr =
static_cast<T *
>(malloc(size));
726 size_t size = n *
sizeof(T);
730 ptr =
static_cast<T *
>(heap_caps_realloc(p, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT));
733 ptr =
static_cast<T *
>(heap_caps_realloc(p, size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT));
737 ptr =
static_cast<T *
>(realloc(p, size));
751 return ESP.getFreeHeap();
752#elif defined(USE_ESP32)
754 this->flags_ &
ALLOC_INTERNAL ? heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL) : 0;
756 this->flags_ &
ALLOC_EXTERNAL ? heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM) : 0;
757 return max_internal + max_external;
758#elif defined(USE_RP2040)
759 return ::rp2040.getFreeHeap();
760#elif defined(USE_LIBRETINY)
761 return lt_heap_get_free();
772 return ESP.getMaxFreeBlockSize();
773#elif defined(USE_ESP32)
775 this->flags_ &
ALLOC_INTERNAL ? heap_caps_get_largest_free_block(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL) : 0;
777 this->flags_ &
ALLOC_EXTERNAL ? heap_caps_get_largest_free_block(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM) : 0;
778 return std::max(max_internal, max_external);
799template<typename T, enable_if_t<!std::is_pointer<T>::value,
int> = 0> T
id(T value) {
return value; }
804template<typename T, enable_if_t<std::is_pointer<T *>::value,
int> = 0> T &
id(T *value) {
return *value; }
811ESPDEPRECATED(
"hexencode() is deprecated, use format_hex_pretty() instead.",
"2022.1")
815ESPDEPRECATED(
"hexencode() is deprecated, use format_hex_pretty() instead.",
"2022.1")
816std::
string hexencode(const T &data) {
817 return hexencode(data.data(), data.size());
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.
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 whether this is a duplicate.
bool has_value() const
Returns whether this deduplicator has processed any items so far.
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.
Helper class that wraps a mutex with a RAII-style API.
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.
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)
struct @67::@68 __attribute__
Providing packet encoding functions for exchanging data with a remote host.
constexpr14 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...
constexpr14 T convert_little_endian(T val)
Convert a value between host byte order and little endian (least significant byte first) order.
uint32_t fnv1_hash(const std::string &str)
Calculate a FNV-1 hash of str.
bool random_bytes(uint8_t *data, size_t len)
Generate len number of random bytes.
uint8_t crc8(const uint8_t *data, uint8_t len)
Calculate a CRC-8 checksum of data with size len using the CRC-8-Dallas/Maxim polynomial.
ESPDEPRECATED("Use Color::BLACK instead of COLOR_BLACK", "v1.21") extern const Color COLOR_BLACK
float random_float()
Return a random float between 0 and 1.
float gamma_uncorrect(float value, float gamma)
Reverts gamma correction of gamma to value.
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.
std::string value_accuracy_to_string(float value, int8_t accuracy_decimals)
Create a string from a value and an accuracy in decimals.
float gamma_correct(float value, float gamma)
Applies gamma correction of gamma to value.
bool mac_address_is_valid(const uint8_t *mac)
Check if the MAC address is not all zeros or all ones.
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.
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.
std::string str_sanitize(const std::string &str)
Sanitizes the input string by removing all characters but alphanumerics, dashes and underscores.
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.
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.
std::unique_ptr< T > make_unique(Args &&...args)
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.
constexpr14 T convert_big_endian(T val)
Convert a value between host byte order and big endian (most significant byte first) order.
uint32_t random_uint32()
Return a random 32-bit unsigned integer.
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.
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,...
typename std::enable_if< B, T >::type enable_if_t
std::string base64_encode(const std::vector< uint8_t > &buf)
constexpr14 std::array< uint8_t, sizeof(T)> decode_value(T val)
Decode a value into its constituent bytes (from most to least significant).
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).
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.
std::string to_string(int value)
constexpr float celsius_to_fahrenheit(float value)
Convert degrees Celsius to degrees Fahrenheit.
std::string str_sprintf(const char *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).
bool str_startswith(const std::string &str, const std::string &start)
Check whether a string starts with a value.
std::string get_mac_address()
Get the device MAC address as a string, in lowercase hex notation.
To bit_cast(const From &src)
Convert data between types, without aliasing issues or undefined behaviour.
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.
std::string str_snake_case(const std::string &str)
Convert the string to snake case (lowercase with underscores).
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.
float lerp(float completion, float start, float end)
Linearly interpolate between start and end by completion (between 0 and 1).
T id(T value)
Helper function to make id(var) known from lambdas work in custom components.
size_t base64_decode(const std::string &encoded_string, uint8_t *buf, size_t buf_len)
ParseOnOffState
Return values for parse_on_off().
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
std::string format_hex_pretty(const uint8_t *data, size_t length)
Format the byte array data of length len in pretty-printed, human-readable hex.
std::string str_truncate(const std::string &str, size_t length)
Truncate a string to a specific length.
static constexpr auto value
static auto test(...) -> decltype(std::false_type())
static auto test(U *p) -> decltype((*p)(std::declval< Args >()...), void(), std::true_type())