15 #include <esp_heap_caps.h> 18 #if defined(USE_ESP32) 19 #include <freertos/FreeRTOS.h> 20 #include <freertos/semphr.h> 21 #elif defined(USE_LIBRETINY) 26 #define HOT __attribute__((hot)) 27 #define ESPDEPRECATED(msg, when) __attribute__((deprecated(msg))) 28 #define ESPHOME_ALWAYS_INLINE __attribute__((always_inline)) 29 #define PACKED __attribute__((packed)) 33 #if __cplusplus >= 201402L 34 #define constexpr14 constexpr 36 #define constexpr14 inline // constexpr implies inline 49 #if _GLIBCXX_RELEASE >= 8 56 std::string
to_string(
unsigned long value);
57 std::string
to_string(
unsigned long long value);
64 #if _GLIBCXX_RELEASE >= 6 65 using std::is_trivially_copyable;
74 #if __cpp_lib_make_unique >= 201304 77 template<
typename T,
typename... Args> std::unique_ptr<T>
make_unique(Args &&...args) {
78 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
83 #if __cplusplus >= 201402L 90 #if __cpp_lib_clamp >= 201603 93 template<
typename T,
typename Compare> constexpr
const T &
clamp(
const T &v,
const T &lo,
const T &hi, Compare comp) {
94 return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
96 template<
typename T> constexpr
const T &
clamp(
const T &v,
const T &lo,
const T &hi) {
97 return clamp(v, lo, hi, std::less<T>{});
102 #if __cpp_lib_is_invocable >= 201703 103 using std::is_invocable;
107 template<
class U>
static auto test(U *p) -> decltype((*p)(std::declval<Args>()...),
void(), std::true_type());
108 template<
class U>
static auto test(...) -> decltype(std::false_type());
109 static constexpr
auto value = decltype(test<T>(
nullptr))::value;
114 #if __cpp_lib_bit_cast >= 201806 119 typename To,
typename From,
124 memcpy(&dst, &src,
sizeof(To));
132 for (
size_t i = 0; i <
sizeof(T); i++)
133 reinterpret_cast<uint8_t *>(&m)[i] =
reinterpret_cast<uint8_t *
>(&n)[
sizeof(T) - 1 - i];
136 template<> constexpr14 uint8_t
byteswap(uint8_t n) {
return n; }
137 template<> constexpr14 uint16_t
byteswap(uint16_t n) {
return __builtin_bswap16(n); }
138 template<> constexpr14 uint32_t
byteswap(uint32_t n) {
return __builtin_bswap32(n); }
139 template<> constexpr14 uint64_t
byteswap(uint64_t n) {
return __builtin_bswap64(n); }
140 template<> constexpr14 int8_t
byteswap(int8_t n) {
return n; }
141 template<> constexpr14 int16_t
byteswap(int16_t n) {
return __builtin_bswap16(n); }
142 template<> constexpr14 int32_t
byteswap(int32_t n) {
return __builtin_bswap32(n); }
143 template<> constexpr14 int64_t
byteswap(int64_t n) {
return __builtin_bswap64(n); }
151 float lerp(
float completion,
float start,
float end);
154 template<
typename T,
typename U> T
remap(U value, U min, U max, T min_out, T max_out) {
155 return (value - min) * (max_out - min_out) / (max - min) + min_out;
159 uint8_t
crc8(
const uint8_t *data, uint8_t
len);
162 uint16_t
crc16(
const uint8_t *data, uint16_t len, uint16_t
crc = 0xffff, uint16_t reverse_poly = 0xa001,
163 bool refin =
false,
bool refout =
false);
164 uint16_t
crc16be(
const uint8_t *data, uint16_t len, uint16_t
crc = 0, uint16_t poly = 0x1021,
bool refin =
false,
165 bool refout =
false);
168 uint32_t
fnv1_hash(
const std::string &str);
184 return (static_cast<uint16_t>(msb) << 8) | (
static_cast<uint16_t
>(lsb));
187 constexpr uint32_t
encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4) {
188 return (static_cast<uint32_t>(byte1) << 24) | (
static_cast<uint32_t
>(byte2) << 16) |
189 (
static_cast<uint32_t
>(byte3) << 8) | (
static_cast<uint32_t
>(byte4));
192 constexpr uint32_t
encode_uint24(uint8_t byte1, uint8_t byte2, uint8_t byte3) {
193 return ((static_cast<uint32_t>(byte1) << 16) | (static_cast<uint32_t>(byte2) << 8) | (static_cast<uint32_t>(byte3)));
197 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
200 for (
size_t i = 0; i <
sizeof(T); i++) {
207 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
209 return encode_value<T>(
bytes.data());
212 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
214 std::array<uint8_t, sizeof(T)> ret{};
215 for (
size_t i =
sizeof(T); i > 0; i--) {
216 ret[i - 1] = val & 0xFF;
224 x = ((x & 0xAA) >> 1) | ((x & 0x55) << 1);
225 x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2);
226 x = ((x & 0xF0) >> 4) | ((x & 0x0F) << 4);
235 return (
reverse_bits(static_cast<uint16_t>(x & 0xFFFF)) << 16) |
236 reverse_bits(static_cast<uint16_t>((x >> 16) & 0xFFFF));
241 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 250 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 266 bool str_startswith(
const std::string &str,
const std::string &start);
268 bool str_endswith(
const std::string &str,
const std::string &end);
278 std::string
str_until(
const char *str,
char ch);
280 std::string
str_until(
const std::string &str,
char ch);
304 template<typename T, enable_if_t<(
std::is_integral<T>::value &&
std::is_unsigned<T>::value),
int> = 0>
307 unsigned long value = ::strtoul(str, &end, 10);
308 if (end == str || *end !=
'\0' || value > std::numeric_limits<T>::max())
313 template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_unsigned<T>::value),
int> = 0>
315 return parse_number<T>(str.c_str());
318 template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_signed<T>::value),
int> = 0>
321 signed long value = ::strtol(str, &end, 10);
322 if (end == str || *end !=
'\0' || value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max())
327 template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_signed<T>::value),
int> = 0>
329 return parse_number<T>(str.c_str());
332 template<typename T, enable_if_t<(std::is_same<T, float>::value),
int> = 0>
optional<T> parse_number(
const char *str) {
334 float value = ::strtof(str, &end);
335 if (end == str || *end !=
'\0' || value == HUGE_VALF)
340 template<typename T, enable_if_t<(std::is_same<T, float>::value),
int> = 0>
342 return parse_number<T>(str.c_str());
356 size_t parse_hex(
const char *str,
size_t len, uint8_t *data,
size_t count);
358 inline bool parse_hex(
const char *str, uint8_t *data,
size_t count) {
359 return parse_hex(str, strlen(str), data, count) == 2 * count;
362 inline bool parse_hex(
const std::string &str, uint8_t *data,
size_t count) {
363 return parse_hex(str.c_str(), str.length(), data, count) == 2 * count;
366 inline bool parse_hex(
const char *str, std::vector<uint8_t> &data,
size_t count) {
368 return parse_hex(str, strlen(str), data.data(), count) == 2 * count;
371 inline bool parse_hex(
const std::string &str, std::vector<uint8_t> &data,
size_t count) {
373 return parse_hex(str.c_str(), str.length(), data.data(), count) == 2 * count;
380 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
383 if (len > 2 *
sizeof(T) ||
parse_hex(str, len, reinterpret_cast<uint8_t *>(&val),
sizeof(T)) == 0)
388 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
optional<T> parse_hex(
const char *str) {
389 return parse_hex<T>(str, strlen(str));
392 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
optional<T> parse_hex(
const std::string &str) {
393 return parse_hex<T>(str.c_str(), str.length());
397 std::string
format_hex(
const uint8_t *data,
size_t length);
399 std::string
format_hex(
const std::vector<uint8_t> &data);
401 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0> std::string
format_hex(T
val) {
403 return format_hex(reinterpret_cast<uint8_t *>(&val),
sizeof(T));
405 template<std::
size_t N> std::string
format_hex(
const std::array<uint8_t, N> &data) {
439 std::string
base64_encode(
const uint8_t *buf,
size_t buf_len);
442 std::vector<uint8_t>
base64_decode(
const std::string &encoded_string);
443 size_t base64_decode(std::string
const &encoded_string, uint8_t *buf,
size_t buf_len);
456 void rgb_to_hsv(
float red,
float green,
float blue,
int &hue,
float &saturation,
float &value);
458 void hsv_to_rgb(
int hue,
float saturation,
float value,
float &red,
float &green,
float &blue);
484 void add(std::function<
void(Ts...)> &&callback) { this->callbacks_.push_back(std::move(callback)); }
488 for (
auto &
cb : this->callbacks_)
491 size_t size()
const {
return this->callbacks_.size(); }
505 if (this->has_value_) {
506 if (this->last_value_ == value)
509 this->has_value_ =
true;
510 this->last_value_ = value;
517 bool has_value_{
false};
557 #if defined(USE_ESP32) || defined(USE_LIBRETINY) 558 SemaphoreHandle_t handle_;
603 #if defined(USE_ESP8266) || defined(USE_RP2040) 621 static bool is_high_frequency();
624 bool started_{
false};
672 ALLOC_EXTERNAL = 1 << 0,
673 ALLOC_INTERNAL = 1 << 1,
674 ALLOW_FAILURE = 1 << 2,
682 size_t size = n *
sizeof(T);
686 if ((this->flags_ & Flags::ALLOC_EXTERNAL) || ((this->flags_ & Flags::ALLOC_INTERNAL) == 0)) {
687 ptr =
static_cast<T *
>(heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT));
690 if (ptr ==
nullptr && ((this->flags_ & Flags::ALLOC_INTERNAL) || (this->flags_ & Flags::ALLOC_EXTERNAL) == 0)) {
691 ptr =
static_cast<T *
>(malloc(size));
695 ptr =
static_cast<T *
>(malloc(size));
705 uint8_t flags_{Flags::ALLOW_FAILURE};
719 template<typename T, enable_if_t<!std::is_pointer<T>::value,
int> = 0> T
id(T value) {
return value; }
724 template<typename T, enable_if_t<std::is_pointer<T *>::value,
int> = 0> T &
id(T *value) {
return *value; }
731 ESPDEPRECATED(
"hexencode() is deprecated, use format_hex_pretty() instead.",
"2022.1")
732 inline
std::
string hexencode(const uint8_t *data, uint32_t len) {
return format_hex_pretty(data, len); }
735 ESPDEPRECATED(
"hexencode() is deprecated, use format_hex_pretty() instead.",
"2022.1")
736 std::string hexencode(
const T &data) {
737 return hexencode(data.data(), data.size());
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)...
std::string str_snake_case(const std::string &str)
Convert the string to snake case (lowercase with underscores).
std::string str_truncate(const std::string &str, size_t length)
Truncate a string to a specific length.
uint16_t crc16be(const uint8_t *data, uint16_t len, uint16_t crc, uint16_t poly, bool refin, bool refout)
std::string value_accuracy_to_string(float value, int8_t accuracy_decimals)
Create a string from a value and an accuracy in decimals.
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.
bool has_custom_mac_address()
Check if a custom MAC address is set (ESP32 & variants)
std::string str_upper_case(const std::string &str)
Convert the string to upper case.
std::string format_hex(const uint8_t *data, size_t length)
Format the byte array data of length len in lowercased hex.
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.
bool next(T value)
Feeds the next item in the series to the deduplicator and returns whether this is a duplicate...
uint32_t random_uint32()
Return a random 32-bit unsigned integer.
std::string str_until(const char *str, char ch)
Extract the part of the string until either the first occurrence of the specified character...
Helper class to request loop() to be called as fast as possible.
typename std::enable_if< B, T >::type enable_if_t
constexpr RAMAllocator(const RAMAllocator< U > &other)
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.
size_t base64_decode(const std::string &encoded_string, uint8_t *buf, size_t buf_len)
std::string to_string(const std::string &val)
Convert the value to a string (added as extra overload so that to_string() can be used on all stringi...
T id(T value)
Helper function to make id(var) known from lambdas work in custom components.
std::vector< std::function< void(Ts...)> > callbacks_
float lerp(float completion, float start, float end)
Linearly interpolate between start and end by completion (between 0 and 1).
void set_parent(T *parent)
Set the parent of this object.
void delay_microseconds_safe(uint32_t us)
Delay for the given amount of microseconds, possibly yielding to other processes during the wait...
bool random_bytes(uint8_t *data, size_t len)
Generate len number of random bytes.
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...
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.
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
ParseOnOffState parse_on_off(const char *str, const char *on, const char *off)
Parse a string that contains either on, off or toggle.
void call(Ts... args)
Call all callbacks in this manager.
uint8_t reverse_bits(uint8_t x)
Reverse the order of 8 bits.
ParseOnOffState
Return values for parse_on_off().
float gamma_correct(float value, float gamma)
Applies gamma correction of gamma to value.
bool str_startswith(const std::string &str, const std::string &start)
Check whether a string starts with a value.
constexpr float celsius_to_fahrenheit(float value)
Convert degrees Celsius to degrees Fahrenheit.
std::string base64_encode(const std::vector< uint8_t > &buf)
ESPDEPRECATED("Use Color::BLACK instead of COLOR_BLACK", "v1.21") extern const Color COLOR_BLACK
optional< T > parse_number(const char *str)
Parse an unsigned decimal number from a null-terminated string.
uint8_t crc8(const uint8_t *data, uint8_t len)
Calculate a CRC-8 checksum of data with size len.
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 str_lower_case(const std::string &str)
Convert the string to lower case.
std::string str_sprintf(const char *fmt,...)
constexpr14 std::array< uint8_t, sizeof(T)> decode_value(T val)
Decode a value into its constituent bytes (from most to least significant).
constexpr14 T convert_big_endian(T val)
Convert a value between host byte order and big endian (most significant byte first) order...
std::string get_mac_address()
Get the device MAC address as a string, in lowercase hex notation.
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_value() const
Returns whether this deduplicator has processed any items so far.
bool str_endswith(const std::string &str, const std::string &end)
Check whether a string ends with a value.
constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit value given the most and least significant byte.
RAMAllocator(uint8_t flags)
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.
enum esphome::EntityCategory __attribute__
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).
void deallocate(T *p, size_t n)
T * get_parent() const
Get the parent of this object.
Helper class to disable interrupts.
std::string str_sanitize(const std::string &str)
Sanitizes the input string by removing all characters but alphanumerics, dashes and underscores...
std::string to_string(int value)
uint32_t fnv1_hash(const std::string &str)
Calculate a FNV-1 hash of str.
constexpr14 T byteswap(T n)
bool mac_address_is_valid(const uint8_t *mac)
Check if the MAC address is not all zeros or all ones.
To bit_cast(const From &src)
Convert data between types, without aliasing issues or undefined behaviour.
constexpr14 T convert_little_endian(T val)
Convert a value between host byte order and little endian (least significant byte first) order...
Helper class to deduplicate items in a series of values.
Implementation of SPI Controller mode.
void operator()(Ts... args)
Call all callbacks in this manager.
std::vector< uint8_t > bytes
std::unique_ptr< T > make_unique(Args &&...args)
std::string get_mac_address_pretty()
Get the device MAC address as a string, in colon-separated uppercase hex notation.
void add(std::function< void(Ts...)> &&callback)
Add a callback to the list.
constexpr float fahrenheit_to_celsius(float value)
Convert degrees Fahrenheit to degrees Celsius.
static uint8_t num_requests
std::string str_snprintf(const char *fmt, size_t len,...)
An STL allocator that uses SPI or internal RAM.
float random_float()
Return a random float between 0 and 1.
Helper class to easily give an object a parent of type T.
Helper class that wraps a mutex with a RAII-style API.
Mutex implementation, with API based on the unavailable std::mutex.
bool str_equals_case_insensitive(const std::string &a, const std::string &b)
Compare strings for equality in case-insensitive manner.
void get_mac_address_raw(uint8_t *mac)
Get the device MAC address as raw bytes, written into the provided byte array (6 bytes).
constexpr const T & clamp(const T &v, const T &lo, const T &hi)
float gamma_uncorrect(float value, float gamma)
Reverts gamma correction of gamma to value.