mirror of
https://github.com/esphome/esphome.git
synced 2024-11-10 01:07:45 +01:00
Store preferences in disk file on host platform (#6428)
Co-authored-by: H. Árkosi Róbert <robreg@zsurob.hu> Co-authored-by: clydeps <U5yx99dok9>
This commit is contained in:
parent
e87727aed3
commit
121bd84854
2 changed files with 116 additions and 12 deletions
|
@ -1,36 +1,87 @@
|
||||||
#ifdef USE_HOST
|
#ifdef USE_HOST
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
#include <cstring>
|
#include "esphome/core/application.h"
|
||||||
#include "esphome/core/preferences.h"
|
|
||||||
#include "esphome/core/helpers.h"
|
|
||||||
#include "esphome/core/log.h"
|
|
||||||
#include "esphome/core/defines.h"
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace host {
|
namespace host {
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
static const char *const TAG = "host.preferences";
|
static const char *const TAG = "host.preferences";
|
||||||
|
|
||||||
class HostPreferences : public ESPPreferences {
|
void HostPreferences::setup_() {
|
||||||
public:
|
if (this->setup_complete_)
|
||||||
ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash) override { return {}; }
|
return;
|
||||||
|
this->filename_.append(getenv("HOME"));
|
||||||
|
this->filename_.append("/.esphome");
|
||||||
|
this->filename_.append("/prefs");
|
||||||
|
fs::create_directories(this->filename_);
|
||||||
|
this->filename_.append("/");
|
||||||
|
this->filename_.append(App.get_name());
|
||||||
|
this->filename_.append(".prefs");
|
||||||
|
FILE *fp = fopen(this->filename_.c_str(), "rb");
|
||||||
|
if (fp != nullptr) {
|
||||||
|
while (!feof((fp))) {
|
||||||
|
uint32_t key;
|
||||||
|
uint8_t len;
|
||||||
|
if (fread(&key, sizeof(key), 1, fp) != 1)
|
||||||
|
break;
|
||||||
|
if (fread(&len, sizeof(len), 1, fp) != 1)
|
||||||
|
break;
|
||||||
|
uint8_t data[len];
|
||||||
|
if (fread(data, sizeof(uint8_t), len, fp) != len)
|
||||||
|
break;
|
||||||
|
std::vector vec(data, data + len);
|
||||||
|
this->data[key] = vec;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
this->setup_complete_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
ESPPreferenceObject make_preference(size_t length, uint32_t type) override { return {}; }
|
bool HostPreferences::sync() {
|
||||||
|
this->setup_();
|
||||||
|
FILE *fp = fopen(this->filename_.c_str(), "wb");
|
||||||
|
std::map<uint32_t, std::vector<uint8_t>>::iterator it;
|
||||||
|
|
||||||
bool sync() override { return true; }
|
for (it = this->data.begin(); it != this->data.end(); ++it) {
|
||||||
bool reset() override { return true; }
|
fwrite(&it->first, sizeof(uint32_t), 1, fp);
|
||||||
|
uint8_t len = it->second.size();
|
||||||
|
fwrite(&len, sizeof(len), 1, fp);
|
||||||
|
fwrite(it->second.data(), sizeof(uint8_t), it->second.size(), fp);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HostPreferences::reset() {
|
||||||
|
host_preferences->data.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESPPreferenceObject HostPreferences::make_preference(size_t length, uint32_t type, bool in_flash) {
|
||||||
|
auto backend = new HostPreferenceBackend(type);
|
||||||
|
return ESPPreferenceObject(backend);
|
||||||
};
|
};
|
||||||
|
|
||||||
void setup_preferences() {
|
void setup_preferences() {
|
||||||
auto *pref = new HostPreferences(); // NOLINT(cppcoreguidelines-owning-memory)
|
auto *pref = new HostPreferences(); // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
|
host_preferences = pref;
|
||||||
global_preferences = pref;
|
global_preferences = pref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HostPreferenceBackend::save(const uint8_t *data, size_t len) {
|
||||||
|
return host_preferences->save(this->key_, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HostPreferenceBackend::load(uint8_t *data, size_t len) { return host_preferences->load(this->key_, data, len); }
|
||||||
|
|
||||||
|
HostPreferences *host_preferences;
|
||||||
} // namespace host
|
} // namespace host
|
||||||
|
|
||||||
ESPPreferences *global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
ESPPreferences *global_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
|
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
#endif // USE_HOST
|
#endif // USE_HOST
|
||||||
|
|
|
@ -2,10 +2,63 @@
|
||||||
|
|
||||||
#ifdef USE_HOST
|
#ifdef USE_HOST
|
||||||
|
|
||||||
|
#include "esphome/core/preferences.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace host {
|
namespace host {
|
||||||
|
|
||||||
|
class HostPreferenceBackend : public ESPPreferenceBackend {
|
||||||
|
public:
|
||||||
|
explicit HostPreferenceBackend(uint32_t key) { this->key_ = key; }
|
||||||
|
|
||||||
|
bool save(const uint8_t *data, size_t len) override;
|
||||||
|
bool load(uint8_t *data, size_t len) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint32_t key_{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class HostPreferences : public ESPPreferences {
|
||||||
|
public:
|
||||||
|
bool sync() override;
|
||||||
|
bool reset() override;
|
||||||
|
|
||||||
|
ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash) override;
|
||||||
|
ESPPreferenceObject make_preference(size_t length, uint32_t type) override {
|
||||||
|
return make_preference(length, type, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool save(uint32_t key, const uint8_t *data, size_t len) {
|
||||||
|
if (len > 255)
|
||||||
|
return false;
|
||||||
|
this->setup_();
|
||||||
|
std::vector vec(data, data + len);
|
||||||
|
this->data[key] = vec;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool load(uint32_t key, uint8_t *data, size_t len) {
|
||||||
|
if (len > 255)
|
||||||
|
return false;
|
||||||
|
this->setup_();
|
||||||
|
if (this->data.count(key) == 0)
|
||||||
|
return false;
|
||||||
|
auto vec = this->data[key];
|
||||||
|
if (vec.size() != len)
|
||||||
|
return false;
|
||||||
|
memcpy(data, vec.data(), len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setup_();
|
||||||
|
bool setup_complete_{};
|
||||||
|
std::string filename_{};
|
||||||
|
std::map<uint32_t, std::vector<uint8_t>> data{};
|
||||||
|
};
|
||||||
void setup_preferences();
|
void setup_preferences();
|
||||||
|
extern HostPreferences *host_preferences; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
|
|
||||||
} // namespace host
|
} // namespace host
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
Loading…
Reference in a new issue