ESPHome 2026.5.0-dev
Loading...
Searching...
No Matches
preferences.cpp
Go to the documentation of this file.
1#ifdef USE_ZEPHYR
2#ifdef CONFIG_SETTINGS
3
4#include <zephyr/kernel.h>
5#include "preferences.h"
6#include "esphome/core/log.h"
7#include <zephyr/settings/settings.h>
8#include <cinttypes>
9#include <cstring>
10
11namespace esphome::zephyr {
12
13static const char *const TAG = "preferences";
14
15bool ZephyrPreferenceBackend::save(const uint8_t *data, size_t len) {
16 this->data.resize(len);
17 std::memcpy(this->data.data(), data, len);
18 ESP_LOGVV(TAG, "save key: %" PRIu32 ", len: %zu", this->type_, len);
19 return true;
20}
21
22bool ZephyrPreferenceBackend::load(uint8_t *data, size_t len) {
23 if (len != this->data.size()) {
24 char key_buf[KEY_BUFFER_SIZE];
25 this->format_key(key_buf, sizeof(key_buf));
26 ESP_LOGE(TAG, "size of setting key %s changed, from: %zu, to: %zu", key_buf, this->data.size(), len);
27 return false;
28 }
29 std::memcpy(data, this->data.data(), len);
30 ESP_LOGVV(TAG, "load key: %" PRIu32 ", len: %zu", this->type_, len);
31 return true;
32}
33
35 int err = settings_subsys_init();
36 if (err) {
37 ESP_LOGE(TAG, "Failed to initialize settings subsystem, err: %d", err);
38 return;
39 }
40
41 static struct settings_handler settings_cb = {
42 .name = ESPHOME_SETTINGS_KEY,
43 .h_set = load_setting,
44 .h_export = export_settings,
45 };
46
47 err = settings_register(&settings_cb);
48 if (err) {
49 ESP_LOGE(TAG, "setting_register failed, err, %d", err);
50 return;
51 }
52
53 err = settings_load_subtree(ESPHOME_SETTINGS_KEY);
54 if (err) {
55 ESP_LOGE(TAG, "Cannot load settings, err: %d", err);
56 return;
57 }
58 ESP_LOGD(TAG, "Loaded %zu settings.", this->backends_.size());
59}
60
62 for (auto *backend : this->backends_) {
63 if (backend->get_type() == type) {
64 return ESPPreferenceObject(backend);
65 }
66 }
67 auto *pref = new ZephyrPreferenceBackend(type); // NOLINT(cppcoreguidelines-owning-memory)
68 char key_buf[KEY_BUFFER_SIZE];
69 pref->format_key(key_buf, sizeof(key_buf));
70 ESP_LOGD(TAG, "Add new setting %s.", key_buf);
71 this->backends_.push_back(pref);
72 return ESPPreferenceObject(pref);
73}
74
76 ESP_LOGD(TAG, "Save settings");
77 int err = settings_save();
78 if (err) {
79 ESP_LOGE(TAG, "Cannot save settings, err: %d", err);
80 return false;
81 }
82 return true;
83}
84
86 ESP_LOGD(TAG, "Reset settings");
87 for (auto *backend : this->backends_) {
88 // save empty delete data
89 backend->data.clear();
90 }
91 this->sync();
92 return true;
93}
94
95int ZephyrPreferences::load_setting(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg) {
96 auto type = parse_hex<uint32_t>(name);
97 if (!type.has_value()) {
98 std::string full_name(ESPHOME_SETTINGS_KEY);
99 full_name += "/";
100 full_name += name;
101 // Delete unusable keys. Otherwise it will stay in flash forever.
102 settings_delete(full_name.c_str());
103 return 1;
104 }
105 std::vector<uint8_t> data(len);
106 int err = read_cb(cb_arg, data.data(), len);
107
108 ESP_LOGD(TAG, "load setting, name: %s(%" PRIu32 "), len %zu, err %d", name, *type, len, err);
109 auto *pref = new ZephyrPreferenceBackend(*type, std::move(data)); // NOLINT(cppcoreguidelines-owning-memory)
110 get_preferences()->backends_.push_back(pref);
111 return 0;
112}
113
114int ZephyrPreferences::export_settings(int (*cb)(const char *name, const void *value, size_t val_len)) {
115 for (auto *backend : get_preferences()->backends_) {
116 char name[KEY_BUFFER_SIZE];
117 backend->format_key(name, sizeof(name));
118 int err = cb(name, backend->data.data(), backend->data.size());
119 ESP_LOGD(TAG, "save in flash, name %s, len %zu, err %d", name, backend->data.size(), err);
120 }
121 return 0;
122}
123
124static ZephyrPreferences s_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
125
126ZephyrPreferences *get_preferences() { return &s_preferences; }
127
129 global_preferences = &s_preferences;
130 s_preferences.open();
131}
132
133} // namespace esphome::zephyr
134
135namespace esphome {
136ESPPreferences *global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
137} // namespace esphome
138
139#endif
140#endif
bool load(uint8_t *data, size_t len)
void format_key(char *buf, size_t size) const
bool save(const uint8_t *data, size_t len)
ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)
Definition preferences.h:15
static int load_setting(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg)
std::vector< ZephyrPreferenceBackend * > backends_
Definition preferences.h:23
static int export_settings(int(*cb)(const char *name, const void *value, size_t val_len))
uint16_t type
const char *const TAG
Definition spi.cpp:7
ZephyrPreferences * get_preferences()
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
Preferences ESPPreferences
Definition preferences.h:42
std::string size_t len
Definition helpers.h:1045
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.
Definition helpers.cpp:333
ESPPreferences * global_preferences
static void uint32_t
uint16_t length
Definition tt21100.cpp:0