14 #include <esp_heap_caps.h> 17 #if defined(USE_ESP32) 18 #include <freertos/FreeRTOS.h> 19 #include <freertos/semphr.h> 20 #elif defined(USE_LIBRETINY) 25 #define HOT __attribute__((hot)) 26 #define ESPDEPRECATED(msg, when) __attribute__((deprecated(msg))) 27 #define ALWAYS_INLINE __attribute__((always_inline)) 28 #define PACKED __attribute__((packed)) 32 #if __cplusplus >= 201402L 33 #define constexpr14 constexpr 35 #define constexpr14 inline // constexpr implies inline 48 #if _GLIBCXX_RELEASE >= 8 55 std::string
to_string(
unsigned long value);
56 std::string
to_string(
unsigned long long value);
63 #if _GLIBCXX_RELEASE >= 6 64 using std::is_trivially_copyable;
73 #if __cpp_lib_make_unique >= 201304 76 template<
typename T,
typename... Args> std::unique_ptr<T>
make_unique(Args &&...args) {
77 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
82 #if __cplusplus >= 201402L 89 #if __cpp_lib_clamp >= 201603 92 template<
typename T,
typename Compare> constexpr
const T &
clamp(
const T &v,
const T &lo,
const T &hi, Compare comp) {
93 return comp(v, lo) ? lo : comp(hi, v) ? hi : v;
95 template<
typename T> constexpr
const T &
clamp(
const T &v,
const T &lo,
const T &hi) {
96 return clamp(v, lo, hi, std::less<T>{});
101 #if __cpp_lib_is_invocable >= 201703 102 using std::is_invocable;
106 template<
class U>
static auto test(U *p) -> decltype((*p)(std::declval<Args>()...),
void(), std::true_type());
107 template<
class U>
static auto test(...) -> decltype(std::false_type());
108 static constexpr
auto value = decltype(test<T>(
nullptr))::value;
113 #if __cpp_lib_bit_cast >= 201806 118 typename To,
typename From,
123 memcpy(&dst, &src,
sizeof(To));
131 for (
size_t i = 0; i <
sizeof(T); i++)
132 reinterpret_cast<uint8_t *>(&m)[i] =
reinterpret_cast<uint8_t *
>(&n)[
sizeof(T) - 1 - i];
135 template<> constexpr14 uint8_t
byteswap(uint8_t n) {
return n; }
136 template<> constexpr14 uint16_t
byteswap(uint16_t n) {
return __builtin_bswap16(n); }
137 template<> constexpr14 uint32_t
byteswap(uint32_t n) {
return __builtin_bswap32(n); }
138 template<> constexpr14 uint64_t
byteswap(uint64_t n) {
return __builtin_bswap64(n); }
139 template<> constexpr14 int8_t
byteswap(int8_t n) {
return n; }
140 template<> constexpr14 int16_t
byteswap(int16_t n) {
return __builtin_bswap16(n); }
141 template<> constexpr14 int32_t
byteswap(int32_t n) {
return __builtin_bswap32(n); }
142 template<> constexpr14 int64_t
byteswap(int64_t n) {
return __builtin_bswap64(n); }
150 float lerp(
float completion,
float start,
float end);
153 template<
typename T,
typename U> T
remap(U value, U min, U max, T min_out, T max_out) {
154 return (value - min) * (max_out - min_out) / (max - min) + min_out;
158 uint8_t
crc8(uint8_t *data, uint8_t
len);
161 uint16_t
crc16(
const uint8_t *data, uint16_t len, uint16_t
crc = 0xffff, uint16_t reverse_poly = 0xa001,
162 bool refin =
false,
bool refout =
false);
163 uint16_t
crc16be(
const uint8_t *data, uint16_t len, uint16_t
crc = 0, uint16_t poly = 0x1021,
bool refin =
false,
164 bool refout =
false);
167 uint32_t
fnv1_hash(
const std::string &str);
183 return (static_cast<uint16_t>(msb) << 8) | (
static_cast<uint16_t
>(lsb));
186 constexpr uint32_t
encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4) {
187 return (static_cast<uint32_t>(byte1) << 24) | (
static_cast<uint32_t
>(byte2) << 16) |
188 (
static_cast<uint32_t
>(byte3) << 8) | (
static_cast<uint32_t
>(byte4));
191 constexpr uint32_t
encode_uint24(uint8_t byte1, uint8_t byte2, uint8_t byte3) {
192 return ((static_cast<uint32_t>(byte1) << 16) | (static_cast<uint32_t>(byte2) << 8) | (static_cast<uint32_t>(byte3)));
196 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
199 for (
size_t i = 0; i <
sizeof(T); i++) {
206 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
208 return encode_value<T>(
bytes.data());
211 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
213 std::array<uint8_t, sizeof(T)> ret{};
214 for (
size_t i =
sizeof(T); i > 0; i--) {
215 ret[i - 1] = val & 0xFF;
223 x = ((x & 0xAA) >> 1) | ((x & 0x55) << 1);
224 x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2);
225 x = ((x & 0xF0) >> 4) | ((x & 0x0F) << 4);
234 return (
reverse_bits(static_cast<uint16_t>(x & 0xFFFF)) << 16) |
235 reverse_bits(static_cast<uint16_t>((x >> 16) & 0xFFFF));
240 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 249 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 265 bool str_startswith(
const std::string &str,
const std::string &start);
267 bool str_endswith(
const std::string &str,
const std::string &end);
277 std::string
str_until(
const char *str,
char ch);
279 std::string
str_until(
const std::string &str,
char ch);
303 template<typename T, enable_if_t<(
std::is_integral<T>::value &&
std::is_unsigned<T>::value),
int> = 0>
306 unsigned long value = ::strtoul(str, &end, 10);
307 if (end == str || *end !=
'\0' || value > std::numeric_limits<T>::max())
312 template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_unsigned<T>::value),
int> = 0>
314 return parse_number<T>(str.c_str());
317 template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_signed<T>::value),
int> = 0>
320 signed long value = ::strtol(str, &end, 10);
321 if (end == str || *end !=
'\0' || value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max())
326 template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_signed<T>::value),
int> = 0>
328 return parse_number<T>(str.c_str());
331 template<typename T, enable_if_t<(std::is_same<T, float>::value),
int> = 0>
optional<T> parse_number(
const char *str) {
333 float value = ::strtof(str, &end);
334 if (end == str || *end !=
'\0' || value == HUGE_VALF)
339 template<typename T, enable_if_t<(std::is_same<T, float>::value),
int> = 0>
341 return parse_number<T>(str.c_str());
355 size_t parse_hex(
const char *str,
size_t len, uint8_t *data,
size_t count);
357 inline bool parse_hex(
const char *str, uint8_t *data,
size_t count) {
358 return parse_hex(str, strlen(str), data, count) == 2 * count;
361 inline bool parse_hex(
const std::string &str, uint8_t *data,
size_t count) {
362 return parse_hex(str.c_str(), str.length(), data, count) == 2 * count;
365 inline bool parse_hex(
const char *str, std::vector<uint8_t> &data,
size_t count) {
367 return parse_hex(str, strlen(str), data.data(), count) == 2 * count;
370 inline bool parse_hex(
const std::string &str, std::vector<uint8_t> &data,
size_t count) {
372 return parse_hex(str.c_str(), str.length(), data.data(), count) == 2 * count;
379 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
382 if (len > 2 *
sizeof(T) ||
parse_hex(str, len, reinterpret_cast<uint8_t *>(&val),
sizeof(T)) == 0)
387 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
optional<T> parse_hex(
const char *str) {
388 return parse_hex<T>(str, strlen(str));
391 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0>
optional<T> parse_hex(
const std::string &str) {
392 return parse_hex<T>(str.c_str(), str.length());
396 std::string
format_hex(
const uint8_t *data,
size_t length);
398 std::string
format_hex(
const std::vector<uint8_t> &data);
400 template<typename T, enable_if_t<std::is_unsigned<T>::value,
int> = 0> std::string
format_hex(T
val) {
402 return format_hex(reinterpret_cast<uint8_t *>(&val),
sizeof(T));
404 template<std::
size_t N> std::string
format_hex(
const std::array<uint8_t, N> &data) {
449 void rgb_to_hsv(
float red,
float green,
float blue,
int &hue,
float &saturation,
float &value);
451 void hsv_to_rgb(
int hue,
float saturation,
float value,
float &red,
float &green,
float &blue);
477 void add(std::function<
void(Ts...)> &&callback) { this->callbacks_.push_back(std::move(callback)); }
481 for (
auto &
cb : this->callbacks_)
484 size_t size()
const {
return this->callbacks_.size(); }
498 if (this->has_value_) {
499 if (this->last_value_ == value)
502 this->has_value_ =
true;
503 this->last_value_ = value;
510 bool has_value_{
false};
549 #if defined(USE_ESP32) || defined(USE_LIBRETINY) 550 SemaphoreHandle_t handle_;
593 #if defined(USE_ESP8266) || defined(USE_RP2040) 611 static bool is_high_frequency();
614 bool started_{
false};
651 REFUSE_INTERNAL = 1 << 0,
652 ALLOW_FAILURE = 1 << 1,
660 size_t size = n *
sizeof(T);
663 ptr =
static_cast<T *
>(heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT));
665 if (ptr ==
nullptr && (this->flags_ & Flags::REFUSE_INTERNAL) == 0)
666 ptr = static_cast<T *>(malloc(size));
667 if (ptr ==
nullptr && (this->flags_ & Flags::ALLOW_FAILURE) == 0)
689 template<typename T, enable_if_t<!std::is_pointer<T>::value,
int> = 0> T
id(T value) {
return value; }
694 template<typename T, enable_if_t<std::is_pointer<T *>::value,
int> = 0> T &
id(T *value) {
return *value; }
701 ESPDEPRECATED(
"hexencode() is deprecated, use format_hex_pretty() instead.",
"2022.1")
702 inline
std::
string hexencode(const uint8_t *data, uint32_t len) {
return format_hex_pretty(data, len); }
705 ESPDEPRECATED(
"hexencode() is deprecated, use format_hex_pretty() instead.",
"2022.1")
706 std::string hexencode(
const T &data) {
707 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.
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,...)
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.