ESPHome 2026.8.0-dev
Loading...
Searching...
No Matches
preferences.cpp
Go to the documentation of this file.
1#ifdef USE_HOST
2
3#include <filesystem>
4#include <fstream>
5#include "preferences.h"
7#include "esphome/core/log.h"
8
9namespace esphome::host {
10namespace fs = std::filesystem;
11
12static const char *const TAG = "preferences";
13
15 if (this->setup_complete_)
16 return;
17 const char *prefdir = getenv("ESPHOME_PREFDIR");
18 std::string pref_path;
19 if (prefdir != nullptr) {
20 pref_path = prefdir;
21 } else {
22 const char *home = getenv("HOME");
23 if (home == nullptr) {
24 ESP_LOGE(TAG, "ESPHOME_PREFDIR and HOME environment variables not set, unable to save preferences");
25 return;
26 }
27 pref_path = std::string(home) + "/.esphome/prefs";
28 }
29 std::error_code ec;
30 fs::create_directories(pref_path, ec);
31 if (ec) {
32 ESP_LOGE(TAG, "Failed to create preferences directory: %s (%s)", pref_path.c_str(), ec.message().c_str());
33 return;
34 }
35 this->filename_ = pref_path;
36 this->filename_.append("/");
37 this->filename_.append(App.get_name());
38 this->filename_.append(".prefs");
39 FILE *fp = fopen(this->filename_.c_str(), "rb");
40 if (fp != nullptr) {
41 while (!feof(fp)) {
42 uint32_t key;
43 uint8_t len;
44 if (fread(&key, sizeof(key), 1, fp) != 1)
45 break;
46 if (fread(&len, sizeof(len), 1, fp) != 1)
47 break;
48 uint8_t data[len];
49 if (fread(data, sizeof(uint8_t), len, fp) != len)
50 break;
51 std::vector vec(data, data + len);
52 this->data_[key] = vec;
53 }
54 fclose(fp);
55 }
56 this->setup_complete_ = true;
57}
58
60 this->setup_();
61 if (this->filename_.empty()) {
62 ESP_LOGE(TAG, "Preferences filename not set, unable to save preferences");
63 return false;
64 }
65 FILE *fp = fopen(this->filename_.c_str(), "wb");
66 if (fp == nullptr) {
67 ESP_LOGE(TAG, "Failed to open preferences file for writing: %s", this->filename_.c_str());
68 return false;
69 }
70
71 for (auto &it : this->data_) {
72 fwrite(&it.first, sizeof(uint32_t), 1, fp);
73 uint8_t len = it.second.size();
74 fwrite(&len, sizeof(len), 1, fp);
75 fwrite(it.second.data(), sizeof(uint8_t), it.second.size(), fp);
76 }
77 fclose(fp);
78 return true;
79}
80
82 host_preferences->data_.clear();
83 return true;
84}
85
87 auto *backend = new HostPreferenceBackend(type);
88 return ESPPreferenceObject(backend);
89};
90
91static HostPreferences s_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
92
93HostPreferences *get_preferences() { return &s_preferences; }
94
96 host_preferences = &s_preferences;
97 global_preferences = &s_preferences;
98}
99
100bool HostPreferenceBackend::save(const uint8_t *data, size_t len) const {
101 return host_preferences->save(this->key_, data, len);
102}
103
104bool HostPreferenceBackend::load(uint8_t *data, size_t len) const {
105 return host_preferences->load(this->key_, data, len);
106}
107
108HostPreferences *host_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
109
110} // namespace esphome::host
111
112namespace esphome {
113ESPPreferences *global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
114} // namespace esphome
115
116#endif // USE_HOST
const StringRef & get_name() const
Get the name of this Application set by pre_setup().
bool load(uint8_t *data, size_t len) const
bool save(const uint8_t *data, size_t len) const
bool load(uint32_t key, uint8_t *data, size_t len)
Definition preferences.h:30
std::map< uint32_t, std::vector< uint8_t > > data_
Definition preferences.h:48
bool save(uint32_t key, const uint8_t *data, size_t len)
Definition preferences.h:21
ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)
uint16_t type
HostPreferences * get_preferences()
void setup_preferences()
HostPreferences * host_preferences
const void size_t len
Definition hal.h:64
ESPPreferences * global_preferences
Application App
Global storage of Application pointer - only one Application can exist.
static void uint32_t
uint16_t length
Definition tt21100.cpp:0