ESPHome 2025.5.2
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
globals_component.h
Go to the documentation of this file.
1#pragma once
2
6#include <cstring>
7
8namespace esphome {
9namespace globals {
10
11template<typename T> class GlobalsComponent : public Component {
12 public:
13 using value_type = T;
14 explicit GlobalsComponent() = default;
15 explicit GlobalsComponent(T initial_value) : value_(initial_value) {}
16 explicit GlobalsComponent(std::array<typename std::remove_extent<T>::type, std::extent<T>::value> initial_value) {
17 memcpy(this->value_, initial_value.data(), sizeof(T));
18 }
19
20 T &value() { return this->value_; }
21 void setup() override {}
22
23 protected:
24 T value_{};
25};
26
27template<typename T> class RestoringGlobalsComponent : public Component {
28 public:
29 using value_type = T;
30 explicit RestoringGlobalsComponent() = default;
31 explicit RestoringGlobalsComponent(T initial_value) : value_(initial_value) {}
33 std::array<typename std::remove_extent<T>::type, std::extent<T>::value> initial_value) {
34 memcpy(this->value_, initial_value.data(), sizeof(T));
35 }
36
37 T &value() { return this->value_; }
38
39 void setup() override {
40 this->rtc_ = global_preferences->make_preference<T>(1944399030U ^ this->name_hash_);
41 this->rtc_.load(&this->value_);
42 memcpy(&this->prev_value_, &this->value_, sizeof(T));
43 }
44
45 float get_setup_priority() const override { return setup_priority::HARDWARE; }
46
47 void loop() override { store_value_(); }
48
49 void on_shutdown() override { store_value_(); }
50
51 void set_name_hash(uint32_t name_hash) { this->name_hash_ = name_hash; }
52
53 protected:
54 void store_value_() {
55 int diff = memcmp(&this->value_, &this->prev_value_, sizeof(T));
56 if (diff != 0) {
57 this->rtc_.save(&this->value_);
58 memcpy(&this->prev_value_, &this->value_, sizeof(T));
59 }
60 }
61
62 T value_{};
64 uint32_t name_hash_{};
66};
67
68// Use with string or subclasses of strings
69template<typename T, uint8_t SZ> class RestoringGlobalStringComponent : public Component {
70 public:
71 using value_type = T;
72 explicit RestoringGlobalStringComponent() = default;
73 explicit RestoringGlobalStringComponent(T initial_value) { this->value_ = initial_value; }
75 std::array<typename std::remove_extent<T>::type, std::extent<T>::value> initial_value) {
76 memcpy(this->value_, initial_value.data(), sizeof(T));
77 }
78
79 T &value() { return this->value_; }
80
81 void setup() override {
82 char temp[SZ];
83 this->rtc_ = global_preferences->make_preference<uint8_t[SZ]>(1944399030U ^ this->name_hash_);
84 bool hasdata = this->rtc_.load(&temp);
85 if (hasdata) {
86 this->value_.assign(temp + 1, temp[0]);
87 }
88 this->prev_value_.assign(this->value_);
89 }
90
91 float get_setup_priority() const override { return setup_priority::HARDWARE; }
92
93 void loop() override { store_value_(); }
94
95 void on_shutdown() override { store_value_(); }
96
97 void set_name_hash(uint32_t name_hash) { this->name_hash_ = name_hash; }
98
99 protected:
101 int diff = this->value_.compare(this->prev_value_);
102 if (diff != 0) {
103 // Make it into a length prefixed thing
104 unsigned char temp[SZ];
105
106 // If string is bigger than the allocation, do not save it.
107 // We don't need to waste ram setting prev_value either.
108 int size = this->value_.size();
109 // Less than, not less than or equal, SZ includes the length byte.
110 if (size < SZ) {
111 memcpy(temp + 1, this->value_.c_str(), size);
112 // SZ should be pre checked at the schema level, it can't go past the char range.
113 temp[0] = ((unsigned char) size);
114 this->rtc_.save(&temp);
115 this->prev_value_.assign(this->value_);
116 }
117 }
118 }
119
122 uint32_t name_hash_{};
124};
125
126template<class C, typename... Ts> class GlobalVarSetAction : public Action<Ts...> {
127 public:
128 explicit GlobalVarSetAction(C *parent) : parent_(parent) {}
129
130 using T = typename C::value_type;
131
133
134 void play(Ts... x) override { this->parent_->value() = this->value_.value(x...); }
135
136 protected:
138};
139
140template<typename T> T &id(GlobalsComponent<T> *value) { return value->value(); }
141template<typename T> T &id(RestoringGlobalsComponent<T> *value) { return value->value(); }
142template<typename T, uint8_t SZ> T &id(RestoringGlobalStringComponent<T, SZ> *value) { return value->value(); }
143
144} // namespace globals
145} // namespace esphome
bool save(const T *src)
Definition preferences.h:21
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
GlobalsComponent(std::array< typename std::remove_extent< T >::type, std::extent< T >::value > initial_value)
RestoringGlobalStringComponent(std::array< typename std::remove_extent< T >::type, std::extent< T >::value > initial_value)
RestoringGlobalsComponent(std::array< typename std::remove_extent< T >::type, std::extent< T >::value > initial_value)
T & id(GlobalsComponent< T > *value)
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition component.cpp:18
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
ESPPreferences * global_preferences
uint16_t x
Definition tt21100.cpp:5