ESPHome  1.15.1
helpers.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <string>
4 #include <functional>
5 #include <vector>
6 #include <memory>
7 #include <type_traits>
8 
10 #include "esphome/core/esphal.h"
11 
12 #ifdef CLANG_TIDY
13 #undef ICACHE_RAM_ATTR
14 #define ICACHE_RAM_ATTR
15 #undef ICACHE_RODATA_ATTR
16 #define ICACHE_RODATA_ATTR
17 #endif
18 
19 #define HOT __attribute__((hot))
20 #define ESPDEPRECATED(msg) __attribute__((deprecated(msg)))
21 #define ALWAYS_INLINE __attribute__((always_inline))
22 #define PACKED __attribute__((packed))
23 
24 namespace esphome {
25 
27 extern const char *HOSTNAME_CHARACTER_ALLOWLIST;
28 
30 std::string get_mac_address();
31 
32 std::string get_mac_address_pretty();
33 
34 std::string to_string(const std::string &val);
35 std::string to_string(int val);
36 std::string to_string(long val);
37 std::string to_string(long long val);
38 std::string to_string(unsigned val);
39 std::string to_string(unsigned long val);
40 std::string to_string(unsigned long long val);
41 std::string to_string(float val);
42 std::string to_string(double val);
43 std::string to_string(long double val);
44 optional<float> parse_float(const std::string &str);
45 
47 std::string sanitize_hostname(const std::string &hostname);
48 
50 std::string truncate_string(const std::string &s, size_t length);
51 
53 std::string to_lowercase_underscore(std::string s);
54 
56 bool str_equals_case_insensitive(const std::string &a, const std::string &b);
57 bool str_startswith(const std::string &full, const std::string &start);
58 bool str_endswith(const std::string &full, const std::string &ending);
59 
61  public:
62  void start();
63  void stop();
64 
65  static bool is_high_frequency();
66 
67  protected:
68  bool started_{false};
69 };
70 
78 float clamp(float val, float min, float max);
79 
88 float lerp(float completion, float start, float end);
89 
91 template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args &&... args) {
92  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
93 }
94 
96 uint32_t random_uint32();
97 
102 double random_double();
103 
105 float random_float();
106 
107 void fast_random_set_seed(uint32_t seed);
108 uint32_t fast_random_32();
109 uint16_t fast_random_16();
110 uint8_t fast_random_8();
111 
113 float gamma_correct(float value, float gamma);
114 
116 std::string value_accuracy_to_string(float value, int8_t accuracy_decimals);
117 
119 std::string uint64_to_string(uint64_t num);
120 
122 std::string uint32_to_string(uint32_t num);
123 
125 std::string sanitize_string_allowlist(const std::string &s, const std::string &allowlist);
126 
127 uint8_t reverse_bits_8(uint8_t x);
128 uint16_t reverse_bits_16(uint16_t x);
129 uint32_t reverse_bits_32(uint32_t x);
130 
132 uint16_t encode_uint16(uint8_t msb, uint8_t lsb);
134 std::array<uint8_t, 2> decode_uint16(uint16_t value);
135 
136 /***
137  * An interrupt helper class.
138  *
139  * This behaves like std::lock_guard. As long as the value is visible in the current stack, all interrupts
140  * (including flash reads) will be disabled.
141  *
142  * Please note all functions called when the interrupt lock must be marked ICACHE_RAM_ATTR (loading code into
143  * instruction cache is done via interrupts; disabling interrupts prevents data not already in cache from being
144  * pulled from flash).
145  *
146  * Example:
147  *
148  * ```cpp
149  * // interrupts are enabled
150  * {
151  * InterruptLock lock;
152  * // do something
153  * // interrupts are disabled
154  * }
155  * // interrupts are enabled
156  * ```
157  */
159  public:
160  InterruptLock();
161  ~InterruptLock();
162 
163  protected:
164 #ifdef ARDUINO_ARCH_ESP8266
165  uint32_t xt_state_;
166 #endif
167 };
168 
170 uint8_t crc8(uint8_t *data, uint8_t len);
171 
177 };
178 
179 ParseOnOffState parse_on_off(const char *str, const char *on = nullptr, const char *off = nullptr);
180 
181 // Encode raw data to a human-readable string (for debugging)
182 std::string hexencode(const uint8_t *data, uint32_t len);
183 template<typename T> std::string hexencode(const T &data) { return hexencode(data.data(), data.size()); }
184 
185 // https://stackoverflow.com/questions/7858817/unpacking-a-tuple-to-call-a-matching-function-pointer/7858971#7858971
186 template<int...> struct seq {}; // NOLINT
187 template<int N, int... S> struct gens : gens<N - 1, N - 1, S...> {}; // NOLINT
188 template<int... S> struct gens<0, S...> { using type = seq<S...>; }; // NOLINT
189 
190 template<bool B, class T = void> using enable_if_t = typename std::enable_if<B, T>::type;
191 
192 template<typename T, enable_if_t<!std::is_pointer<T>::value, int> = 0> T id(T value) { return value; }
193 template<typename T, enable_if_t<std::is_pointer<T *>::value, int> = 0> T &id(T *value) { return *value; }
194 
195 template<typename... X> class CallbackManager;
196 
201 template<typename... Ts> class CallbackManager<void(Ts...)> {
202  public:
204  void add(std::function<void(Ts...)> &&callback) { this->callbacks_.push_back(std::move(callback)); }
205 
207  void call(Ts... args) {
208  for (auto &cb : this->callbacks_)
209  cb(args...);
210  }
211 
212  protected:
213  std::vector<std::function<void(Ts...)>> callbacks_;
214 };
215 
216 // https://stackoverflow.com/a/37161919/8924614
217 template<class T, class... Args>
218 struct is_callable // NOLINT
219 {
220  template<class U> static auto test(U *p) -> decltype((*p)(std::declval<Args>()...), void(), std::true_type());
221 
222  template<class U> static auto test(...) -> decltype(std::false_type());
223 
224  static constexpr auto value = decltype(test<T>(nullptr))::value; // NOLINT
225 };
226 
227 template<typename T, typename... X> class TemplatableValue {
228  public:
229  TemplatableValue() : type_(EMPTY) {}
230 
231  template<typename F, enable_if_t<!is_callable<F, X...>::value, int> = 0>
232  TemplatableValue(F value) : type_(VALUE), value_(value) {}
233 
234  template<typename F, enable_if_t<is_callable<F, X...>::value, int> = 0>
235  TemplatableValue(F f) : type_(LAMBDA), f_(f) {}
236 
237  bool has_value() { return this->type_ != EMPTY; }
238 
239  T value(X... x) {
240  if (this->type_ == LAMBDA) {
241  return this->f_(x...);
242  }
243  // return value also when empty
244  return this->value_;
245  }
246 
248  if (!this->has_value()) {
249  return {};
250  }
251  return this->value(x...);
252  }
253 
254  T value_or(X... x, T default_value) {
255  if (!this->has_value()) {
256  return default_value;
257  }
258  return this->value(x...);
259  }
260 
261  protected:
262  enum {
266  } type_;
267 
269  std::function<T(X...)> f_;
270 };
271 
272 template<typename... X> class TemplatableStringValue : public TemplatableValue<std::string, X...> {
273  public:
275 
276  template<typename F, enable_if_t<!is_callable<F, X...>::value, int> = 0>
277  TemplatableStringValue(F value) : TemplatableValue<std::string, X...>(value) {}
278 
279  template<typename F, enable_if_t<is_callable<F, X...>::value, int> = 0>
281  : TemplatableValue<std::string, X...>([f](X... x) -> std::string { return to_string(f(x...)); }) {}
282 };
283 
284 void delay_microseconds_accurate(uint32_t usec);
285 
286 template<typename T> class Deduplicator {
287  public:
288  bool next(T value) {
289  if (this->has_value_) {
290  if (this->last_value_ == value)
291  return false;
292  }
293  this->has_value_ = true;
294  this->last_value_ = value;
295  return true;
296  }
297  bool has_value() const { return this->has_value_; }
298 
299  protected:
300  bool has_value_{false};
301  T last_value_{};
302 };
303 
304 template<typename T> class Parented {
305  public:
306  Parented() {}
307  Parented(T *parent) : parent_(parent) {}
308 
309  T *get_parent() const { return parent_; }
310  void set_parent(T *parent) { parent_ = parent; }
311 
312  protected:
313  T *parent_{nullptr};
314 };
315 
316 uint32_t fnv1_hash(const std::string &str);
317 
318 } // namespace esphome
uint16_t fast_random_16()
Definition: helpers.cpp:65
uint32_t reverse_bits_32(uint32_t x)
std::string value_accuracy_to_string(float value, int8_t accuracy_decimals)
Create a string from a value and an accuracy in decimals.
Definition: helpers.cpp:107
const char * HOSTNAME_CHARACTER_ALLOWLIST
The characters that are allowed in a hostname.
Definition: helpers.cpp:157
bool next(T value)
Definition: helpers.h:288
std::unique_ptr< T > make_unique(Args &&... args)
std::make_unique
Definition: helpers.h:91
uint8_t reverse_bits_8(uint8_t x)
Definition: helpers.cpp:186
uint32_t random_uint32()
Return a random 32 bit unsigned integer.
Definition: helpers.cpp:46
T value_or(X... x, T default_value)
Definition: helpers.h:254
uint8_t crc8(uint8_t *data, uint8_t len)
Calculate a crc8 of data with the provided data length.
Definition: helpers.cpp:159
void fast_random_set_seed(uint32_t seed)
Definition: helpers.cpp:60
typename std::enable_if< B, T >::type enable_if_t
Definition: helpers.h:190
uint8_t fast_random_8()
Definition: helpers.cpp:69
std::string to_string(const std::string &val)
Definition: helpers.cpp:196
std::string sanitize_string_allowlist(const std::string &s, const std::string &allowlist)
Sanitizes the input string with the allowlist.
Definition: helpers.cpp:88
std::string truncate_string(const std::string &s, size_t length)
Truncate a string to a specific length.
Definition: helpers.cpp:101
STL namespace.
T id(T value)
Definition: helpers.h:192
std::vector< std::function< void(Ts...)> > callbacks_
Definition: helpers.h:213
float lerp(float completion, float start, float end)
Linearly interpolate between end start and end by completion.
Definition: helpers.cpp:288
uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit unsigned integer given a most and least-significant byte.
Definition: helpers.cpp:295
float clamp(float val, float min, float max)
Clamp the value between min and max.
Definition: helpers.cpp:281
void set_parent(T *parent)
Definition: helpers.h:310
std::string uint32_to_string(uint32_t num)
Convert a uint32_t to a hex string.
Definition: helpers.cpp:120
void delay_microseconds_accurate(uint32_t usec)
Definition: helpers.cpp:174
void call(Ts... args)
Call all callbacks in this manager.
Definition: helpers.h:207
uint16_t reverse_bits_16(uint16_t x)
Definition: helpers.cpp:193
ParseOnOffState
Definition: helpers.h:172
float gamma_correct(float value, float gamma)
Applies gamma correction with the provided gamma to value.
Definition: helpers.cpp:74
std::string sanitize_hostname(const std::string &hostname)
Sanitize the hostname by removing characters that are not in the allowlist and truncating it to 63 ch...
Definition: helpers.cpp:96
bool str_startswith(const std::string &full, const std::string &start)
Definition: helpers.cpp:290
std::string get_mac_address()
Gets the MAC address as a string, this can be used as way to identify this ESP.
Definition: helpers.cpp:18
std::string hexencode(const uint8_t *data, uint32_t len)
Definition: helpers.cpp:302
uint8_t type
bool has_value() const
Definition: helpers.h:297
std::function< T(X...)> f_
Definition: helpers.h:269
uint32_t fast_random_32()
Definition: helpers.cpp:61
Parented(T *parent)
Definition: helpers.h:307
T * get_parent() const
Definition: helpers.h:309
ParseOnOffState parse_on_off(const char *str, const char *on, const char *off)
Definition: helpers.cpp:142
optional< T > optional_value(X... x)
Definition: helpers.h:247
uint32_t fnv1_hash(const std::string &str)
Definition: helpers.cpp:249
std::array< uint8_t, 2 > decode_uint16(uint16_t value)
Decode a 16-bit unsigned integer into an array of two values: most significant byte, least significant byte.
Definition: helpers.cpp:296
std::string to_lowercase_underscore(std::string s)
Convert the string to lowercase_underscore.
Definition: helpers.cpp:82
Definition: a4988.cpp:4
double random_double()
Returns a random double between 0 and 1.
Definition: helpers.cpp:54
std::string get_mac_address_pretty()
Definition: helpers.cpp:31
void add(std::function< void(Ts...)> &&callback)
Add a callback to the internal callback list.
Definition: helpers.h:204
bool str_endswith(const std::string &full, const std::string &ending)
Definition: helpers.cpp:291
optional< float > parse_float(const std::string &str)
Definition: helpers.cpp:242
std::string uint64_to_string(uint64_t num)
Convert a uint64_t to a hex string.
Definition: helpers.cpp:114
float random_float()
Returns a random float between 0 and 1. Essentially just casts random_double() to a float...
Definition: helpers.cpp:56
bool str_equals_case_insensitive(const std::string &a, const std::string &b)
Compare string a to string b (ignoring case) and return whether they are equal.
Definition: helpers.cpp:257