14 #include <esp_heap_caps.h> 17 #if defined(USE_ESP32) 18 #include <freertos/FreeRTOS.h> 19 #include <freertos/semphr.h> 22 #define HOT __attribute__((hot)) 23 #define ESPDEPRECATED(msg, when) __attribute__((deprecated(msg))) 24 #define ALWAYS_INLINE __attribute__((always_inline)) 25 #define PACKED __attribute__((packed)) 29 #if __cplusplus >= 201402L 30 #define constexpr14 constexpr 32 #define constexpr14 inline // constexpr implies inline 45 #if _GLIBCXX_RELEASE >= 8 52 std::string
to_string(
unsigned long value);
53 std::string
to_string(
unsigned long long value);
60 #if _GLIBCXX_RELEASE >= 6 61 using std::is_trivially_copyable;
70 #if __cpp_lib_make_unique >= 201304 73 template<
typename T,
typename... Args> std::unique_ptr<T>
make_unique(Args &&...args) {
74 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
79 #if __cplusplus >= 201402L 86 #if __cpp_lib_clamp >= 201603 89 template<
typename T,
typename Compare> constexpr
const T &
clamp(
const T &v,
const T &lo,
const T &hi, Compare comp) {
90 return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
92 template<
typename T> constexpr
const T &
clamp(
const T &v,
const T &lo,
const T &hi) {
93 return clamp(v, lo, hi, std::less<T>{});
98 #if __cpp_lib_is_invocable >= 201703 99 using std::is_invocable;
103 template<
class U>
static auto test(U *p) -> decltype((*p)(std::declval<Args>()...),
void(), std::true_type());
104 template<
class U>
static auto test(...) -> decltype(std::false_type());
105 static constexpr
auto value = decltype(test<T>(
nullptr))::value;
110 #if __cpp_lib_bit_cast >= 201806 115 typename To,
typename From,
120 memcpy(&dst, &src,
sizeof(To));
128 for (
size_t i = 0; i <
sizeof(T); i++)
129 reinterpret_cast<uint8_t *>(&m)[i] =
reinterpret_cast<uint8_t *
>(&n)[
sizeof(T) - 1 - i];
132 template<> constexpr14 uint8_t
byteswap(uint8_t n) {
return n; }
133 template<> constexpr14 uint16_t
byteswap(uint16_t n) {
return __builtin_bswap16(n); }
134 template<> constexpr14 uint32_t
byteswap(uint32_t n) {
return __builtin_bswap32(n); }
135 template<> constexpr14 uint64_t
byteswap(uint64_t n) {
return __builtin_bswap64(n); }
136 template<> constexpr14 int8_t
byteswap(int8_t n) {
return n; }
137 template<> constexpr14 int16_t
byteswap(int16_t n) {
return __builtin_bswap16(n); }
138 template<> constexpr14 int32_t
byteswap(int32_t n) {
return __builtin_bswap32(n); }
139 template<> constexpr14 int64_t
byteswap(int64_t n) {
return __builtin_bswap64(n); }
147 float lerp(
float completion,
float start,
float end);
150 template<
typename T,
typename U> T
remap(U value, U min, U max, T min_out, T max_out) {
151 return (value - min) * (max_out - min_out) / (max - min) + min_out;
155 uint8_t
crc8(uint8_t *data, uint8_t
len);
158 uint16_t
crc16(
const uint8_t *data, uint16_t len, uint16_t
crc = 0xffff, uint16_t reverse_poly = 0xa001,
159 bool refin =
false,
bool refout =
false);
160 uint16_t
crc16be(
const uint8_t *data, uint16_t len, uint16_t
crc = 0, uint16_t poly = 0x1021,
bool refin =
false,
161 bool refout =
false);
164 uint32_t
fnv1_hash(
const std::string &str);
180 return (static_cast<uint16_t>(msb) << 8) | (
static_cast<uint16_t
>(lsb));
183 constexpr uint32_t
encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4) {
184 return (static_cast<uint32_t>(byte1) << 24) | (
static_cast<uint32_t
>(byte2) << 16) |
185 (
static_cast<uint32_t
>(byte3) << 8) | (
static_cast<uint32_t
>(byte4));
188 constexpr uint32_t
encode_uint24(uint8_t byte1, uint8_t byte2, uint8_t byte3) {
189 return ((static_cast<uint32_t>(byte1) << 16) | (static_cast<uint32_t>(byte2) << 8) | (static_cast<uint32_t>(byte3)));
193 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
196 for (
size_t i = 0; i <
sizeof(T); i++) {
203 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
205 return encode_value<T>(
bytes.data());
208 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
210 std::array<uint8_t, sizeof(T)> ret{};
211 for (
size_t i =
sizeof(T); i > 0; i--) {
212 ret[i - 1] = val & 0xFF;
220 x = ((x & 0xAA) >> 1) | ((x & 0x55) << 1);
221 x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2);
222 x = ((x & 0xF0) >> 4) | ((x & 0x0F) << 4);
231 return (
reverse_bits(static_cast<uint16_t>(x & 0xFFFF)) << 16) |
232 reverse_bits(static_cast<uint16_t>((x >> 16) & 0xFFFF));
237 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 246 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 262 bool str_startswith(
const std::string &str,
const std::string &start);
264 bool str_endswith(
const std::string &str,
const std::string &end);
274 std::string
str_until(
const char *str,
char ch);
276 std::string
str_until(
const std::string &str,
char ch);
300 template<typename T, enable_if_t<(
std::is_integral<T>::value &&
std::is_unsigned<T>::value),
int> = 0>
303 unsigned long value = ::strtoul(str, &end, 10);
304 if (end == str || *end !=
'\0' || value > std::numeric_limits<T>::max())
309 template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_unsigned<T>::value),
int> = 0>
311 return parse_number<T>(str.c_str());
314 template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_signed<T>::value),
int> = 0>
317 signed long value = ::strtol(str, &end, 10);
318 if (end == str || *end !=
'\0' || value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max())
323 template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_signed<T>::value),
int> = 0>
325 return parse_number<T>(str.c_str());
328 template<typename T, enable_if_t<(std::is_same<T, float>::value),
int> = 0>
optional<T> parse_number(
const char *str) {
330 float value = ::strtof(str, &end);
331 if (end == str || *end !=
'\0' || value == HUGE_VALF)
336 template<typename T, enable_if_t<(std::is_same<T, float>::value),
int> = 0>
338 return parse_number<T>(str.c_str());
352 size_t parse_hex(
const char *str,
size_t len, uint8_t *data,
size_t count);
354 inline bool parse_hex(
const char *str, uint8_t *data,
size_t count) {
355 return parse_hex(str, strlen(str), data, count) == 2 * count;
358 inline bool parse_hex(
const std::string &str, uint8_t *data,
size_t count) {
359 return parse_hex(str.c_str(), str.length(), data, count) == 2 * count;
362 inline bool parse_hex(
const char *str, std::vector<uint8_t> &data,
size_t count) {
364 return parse_hex(str, strlen(str), data.data(), count) == 2 * count;
367 inline bool parse_hex(
const std::string &str, std::vector<uint8_t> &data,
size_t count) {
369 return parse_hex(str.c_str(), str.length(), data.data(), count) == 2 * count;
376 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
379 if (len > 2 *
sizeof(T) ||
parse_hex(str, len, reinterpret_cast<uint8_t *>(&val),
sizeof(T)) == 0)
384 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
optional<T> parse_hex(
const char *str) {
385 return parse_hex<T>(str, strlen(str));
388 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
optional<T> parse_hex(
const std::string &str) {
389 return parse_hex<T>(str.c_str(), str.length());
393 std::string
format_hex(
const uint8_t *data,
size_t length);
395 std::string
format_hex(
const std::vector<uint8_t> &data);
397 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0> std::string
format_hex(T
val) {
399 return format_hex(reinterpret_cast<uint8_t *>(&val),
sizeof(T));
401 template<std::
size_t N> std::string
format_hex(
const std::array<uint8_t, N> &data) {
446 void rgb_to_hsv(
float red,
float green,
float blue,
int &hue,
float &saturation,
float &value);
448 void hsv_to_rgb(
int hue,
float saturation,
float value,
float &red,
float &green,
float &blue);
474 void add(std::function<
void(Ts...)> &&callback) { this->callbacks_.push_back(std::move(callback)); }
478 for (
auto &
cb : this->callbacks_)
481 size_t size()
const {
return this->callbacks_.size(); }
495 if (this->has_value_) {
496 if (this->last_value_ == value)
499 this->has_value_ =
true;
500 this->last_value_ = value;
507 bool has_value_{
false};
546 #if defined(USE_ESP32) 547 SemaphoreHandle_t handle_;
590 #if defined(USE_ESP8266) || defined(USE_RP2040) 608 static bool is_high_frequency();
611 bool started_{
false};
648 REFUSE_INTERNAL = 1 << 0,
649 ALLOW_FAILURE = 1 << 1,
657 size_t size = n *
sizeof(T);
660 ptr =
static_cast<T *
>(heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT));
662 if (ptr ==
nullptr && (this->flags_ & Flags::REFUSE_INTERNAL) == 0)
663 ptr = static_cast<T *>(malloc(size));
664 if (ptr ==
nullptr && (this->flags_ & Flags::ALLOW_FAILURE) == 0)
686 template<typename T, enable_if_t<!std::is_pointer<T>::value,
int> = 0> T
id(T value) {
return value; }
691 template<typename T, enable_if_t<std::is_pointer<T *>::value,
int> = 0> T &
id(T *value) {
return *value; }
698 ESPDEPRECATED(
"hexencode() is deprecated, use format_hex_pretty() instead.",
"2022.1")
699 inline
std::
string hexencode(const uint8_t *data, uint32_t len) {
return format_hex_pretty(data, len); }
702 ESPDEPRECATED(
"hexencode() is deprecated, use format_hex_pretty() instead.",
"2022.1")
703 std::string hexencode(
const T &data) {
704 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.
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.
constexpr ExternalRAMAllocator(const ExternalRAMAllocator< U > &other)
std::string str_until(const char *str, char ch)
Extract the part of the string until either the first occurrence of the specified character...
uint8_t crc8(uint8_t *data, uint8_t len)
Calculate a CRC-8 checksum of data with size len.
Helper class to request loop() to be called as fast as possible.
typename std::enable_if< B, T >::type enable_if_t
An STL allocator that uses SPI RAM.
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(const std::string &val)
Convert the value to a string (added as extra overload so that to_string() can be used on all stringi...
void deallocate(T *p, size_t n)
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.
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.
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.
ExternalRAMAllocator(Flags flags)
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.
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).
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)
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.
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,...)
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.