checking persistence on desktop and esp32
Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
@@ -58,7 +58,15 @@ void Menu::setItemSize(const size_t size)
|
||||
for (size_t i = m_items.size() - 1; i < size; i++)
|
||||
{
|
||||
auto caption = std::string("Bereich ") + std::to_string(i + 1);
|
||||
addSelection(i + 1, caption, m_items.at(0).getValues(), 0);
|
||||
auto index = 0;
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
constexpr int key_length = 20;
|
||||
char key[key_length] = "";
|
||||
snprintf(key, key_length, "section_%zu", i + 1);
|
||||
index = m_options->persistenceManager->GetValue(key, index);
|
||||
}
|
||||
addSelection(i + 1, caption, m_items.at(0).getValues(), index);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
295
components/insa/src/common/PersistenceManager.cpp
Normal file
295
components/insa/src/common/PersistenceManager.cpp
Normal file
@@ -0,0 +1,295 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "common/PersistenceManager.h"
|
||||
#include <cstring>
|
||||
#include <esp_log.h>
|
||||
|
||||
static const char *TAG = "PersistenceManager";
|
||||
|
||||
PersistenceManager::PersistenceManager(const std::string &nvs_namespace)
|
||||
: namespace_(nvs_namespace), initialized_(false)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
PersistenceManager::~PersistenceManager()
|
||||
{
|
||||
Deinitialize();
|
||||
}
|
||||
|
||||
bool PersistenceManager::Initialize()
|
||||
{
|
||||
if (initialized_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initialize NVS
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
|
||||
{
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
err = nvs_flash_init();
|
||||
}
|
||||
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to initialize NVS flash: %s", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open NVS handle
|
||||
err = nvs_open(namespace_.c_str(), NVS_READWRITE, &nvs_handle_);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to open NVS handle: %s", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
initialized_ = true;
|
||||
ESP_LOGI(TAG, "PersistenceManager initialized with namespace: %s", namespace_.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void PersistenceManager::Deinitialize()
|
||||
{
|
||||
if (initialized_)
|
||||
{
|
||||
nvs_close(nvs_handle_);
|
||||
initialized_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PersistenceManager::EnsureInitialized() const
|
||||
{
|
||||
if (!initialized_)
|
||||
{
|
||||
ESP_LOGE(TAG, "PersistenceManager not initialized");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistenceManager::HasKey(const std::string &key) const
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return false;
|
||||
|
||||
size_t required_size = 0;
|
||||
esp_err_t err = nvs_get_blob(nvs_handle_, key.c_str(), nullptr, &required_size);
|
||||
return err == ESP_OK;
|
||||
}
|
||||
|
||||
void PersistenceManager::RemoveKey(const std::string &key)
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return;
|
||||
|
||||
esp_err_t err = nvs_erase_key(nvs_handle_, key.c_str());
|
||||
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to remove key '%s': %s", key.c_str(), esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
void PersistenceManager::Clear()
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return;
|
||||
|
||||
esp_err_t err = nvs_erase_all(nvs_handle_);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to clear all keys: %s", esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
size_t PersistenceManager::GetKeyCount() const
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return 0;
|
||||
|
||||
nvs_iterator_t it = nullptr;
|
||||
esp_err_t err = nvs_entry_find(NVS_DEFAULT_PART_NAME, namespace_.c_str(), NVS_TYPE_ANY, &it);
|
||||
|
||||
if (err != ESP_OK || it == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t count = 0;
|
||||
|
||||
while (it != nullptr)
|
||||
{
|
||||
count++;
|
||||
err = nvs_entry_next(&it);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nvs_release_iterator(it);
|
||||
return count;
|
||||
}
|
||||
|
||||
bool PersistenceManager::Save()
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return false;
|
||||
|
||||
esp_err_t err = nvs_commit(nvs_handle_);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to commit NVS: %s", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistenceManager::Load()
|
||||
{
|
||||
return EnsureInitialized();
|
||||
}
|
||||
|
||||
void PersistenceManager::SetValueImpl(const std::string &key, bool value)
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return;
|
||||
|
||||
uint8_t val = value ? 1 : 0;
|
||||
esp_err_t err = nvs_set_u8(nvs_handle_, key.c_str(), val);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to set bool key '%s': %s", key.c_str(), esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
void PersistenceManager::SetValueImpl(const std::string &key, int value)
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return;
|
||||
|
||||
esp_err_t err = nvs_set_i32(nvs_handle_, key.c_str(), value);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to set int key '%s': %s", key.c_str(), esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
void PersistenceManager::SetValueImpl(const std::string &key, float value)
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return;
|
||||
|
||||
esp_err_t err = nvs_set_blob(nvs_handle_, key.c_str(), &value, sizeof(float));
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to set float key '%s': %s", key.c_str(), esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
void PersistenceManager::SetValueImpl(const std::string &key, double value)
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return;
|
||||
|
||||
esp_err_t err = nvs_set_blob(nvs_handle_, key.c_str(), &value, sizeof(double));
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to set double key '%s': %s", key.c_str(), esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
void PersistenceManager::SetValueImpl(const std::string &key, const std::string &value)
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return;
|
||||
|
||||
esp_err_t err = nvs_set_str(nvs_handle_, key.c_str(), value.c_str());
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to set string key '%s': %s", key.c_str(), esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
bool PersistenceManager::GetValueImpl(const std::string &key, bool defaultValue) const
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return defaultValue;
|
||||
|
||||
uint8_t value;
|
||||
esp_err_t err = nvs_get_u8(nvs_handle_, key.c_str(), &value);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
int PersistenceManager::GetValueImpl(const std::string &key, int defaultValue) const
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return defaultValue;
|
||||
|
||||
int32_t value;
|
||||
esp_err_t err = nvs_get_i32(nvs_handle_, key.c_str(), &value);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
return static_cast<int>(value);
|
||||
}
|
||||
|
||||
float PersistenceManager::GetValueImpl(const std::string &key, float defaultValue) const
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return defaultValue;
|
||||
|
||||
float value;
|
||||
size_t required_size = sizeof(float);
|
||||
esp_err_t err = nvs_get_blob(nvs_handle_, key.c_str(), &value, &required_size);
|
||||
if (err != ESP_OK || required_size != sizeof(float))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
double PersistenceManager::GetValueImpl(const std::string &key, double defaultValue) const
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return defaultValue;
|
||||
|
||||
double value;
|
||||
size_t required_size = sizeof(double);
|
||||
esp_err_t err = nvs_get_blob(nvs_handle_, key.c_str(), &value, &required_size);
|
||||
if (err != ESP_OK || required_size != sizeof(double))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string PersistenceManager::GetValueImpl(const std::string &key, const std::string &defaultValue) const
|
||||
{
|
||||
if (!EnsureInitialized())
|
||||
return defaultValue;
|
||||
|
||||
size_t required_size = 0;
|
||||
esp_err_t err = nvs_get_str(nvs_handle_, key.c_str(), nullptr, &required_size);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
std::string value(required_size - 1, '\0'); // -1 for null terminator
|
||||
err = nvs_get_str(nvs_handle_, key.c_str(), value.data(), &required_size);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif // ESP32
|
@@ -8,21 +8,37 @@
|
||||
*/
|
||||
namespace LightMenuItem
|
||||
{
|
||||
constexpr uint8_t ACTIVATE = 0; ///< ID for the light activation toggle
|
||||
constexpr uint8_t MODE = 1; ///< ID for the light mode selection
|
||||
constexpr uint8_t LED_SETTINGS = 2; ///< ID for the LED settings menu item
|
||||
constexpr uint8_t ACTIVATE = 0; ///< ID for the light activation toggle
|
||||
constexpr uint8_t MODE = 1; ///< ID for the light mode selection
|
||||
constexpr uint8_t LED_SETTINGS = 2; ///< ID for the LED settings menu item
|
||||
} // namespace LightMenuItem
|
||||
|
||||
namespace LightMenuOptions
|
||||
{
|
||||
constexpr std::string LIGHT_ACTIVE = "light_active";
|
||||
constexpr std::string LIGHT_MODE = "light_mode";
|
||||
}
|
||||
|
||||
LightMenu::LightMenu(menu_options_t *options) : Menu(options), m_options(options)
|
||||
{
|
||||
// Add toggle for enabling/disabling the light system
|
||||
addToggle(LightMenuItem::ACTIVATE, "Einschalten", true);
|
||||
bool active = false;
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
active = m_options->persistenceManager->GetValue(LightMenuOptions::LIGHT_ACTIVE, active);
|
||||
}
|
||||
addToggle(LightMenuItem::ACTIVATE, "Einschalten", active);
|
||||
|
||||
// Create mode selection options (Day/Night modes)
|
||||
std::vector<std::string> values;
|
||||
values.emplace_back("Tag"); // Day mode
|
||||
values.emplace_back("Nacht"); // Night mode
|
||||
addSelection(LightMenuItem::MODE, "Modus", values, 0);
|
||||
values.emplace_back("Tag"); // Day mode
|
||||
values.emplace_back("Nacht"); // Night mode
|
||||
int mode_value = 0;
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
mode_value = m_options->persistenceManager->GetValue(LightMenuOptions::LIGHT_MODE, mode_value);
|
||||
}
|
||||
addSelection(LightMenuItem::MODE, "Modus", values, mode_value);
|
||||
|
||||
// Add menu item for accessing LED settings submenu
|
||||
addText(LightMenuItem::LED_SETTINGS, "Einstellungen");
|
||||
@@ -31,7 +47,7 @@ LightMenu::LightMenu(menu_options_t *options) : Menu(options), m_options(options
|
||||
void LightMenu::onButtonPressed(const MenuItem &menuItem, const ButtonType button)
|
||||
{
|
||||
std::shared_ptr<Widget> widget;
|
||||
|
||||
|
||||
// Handle different menu items based on their ID
|
||||
switch (menuItem.getId())
|
||||
{
|
||||
@@ -40,13 +56,28 @@ void LightMenu::onButtonPressed(const MenuItem &menuItem, const ButtonType butto
|
||||
if (button == ButtonType::SELECT)
|
||||
{
|
||||
toggle(menuItem);
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
const auto value = getItem(menuItem.getId()).getValue() == "1";
|
||||
m_options->persistenceManager->SetValue(LightMenuOptions::LIGHT_ACTIVE, value);
|
||||
m_options->persistenceManager->Save();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LightMenuItem::MODE: {
|
||||
// Switch between day/night modes using left/right buttons
|
||||
switchValue(menuItem, button);
|
||||
const auto item = switchValue(menuItem, button);
|
||||
if (button == ButtonType::LEFT || button == ButtonType::RIGHT)
|
||||
{
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
const auto value = getItem(item.getId()).getIndex();
|
||||
m_options->persistenceManager->SetValue(LightMenuOptions::LIGHT_MODE, value);
|
||||
m_options->persistenceManager->Save();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -9,6 +9,14 @@ namespace LightSettingsMenuItem
|
||||
constexpr uint8_t SECTION_COUNTER = 0; ///< ID for the section counter menu item
|
||||
}
|
||||
|
||||
std::string LightSettingsMenu::CreateKey(const int index)
|
||||
{
|
||||
constexpr int key_length = 20;
|
||||
char key[key_length] = "";
|
||||
snprintf(key, key_length, "section_%d", index);
|
||||
return key;
|
||||
}
|
||||
|
||||
LightSettingsMenu::LightSettingsMenu(menu_options_t *options) : Menu(options), m_options(options)
|
||||
{
|
||||
// Create values vector for section counts (1-99)
|
||||
@@ -19,7 +27,12 @@ LightSettingsMenu::LightSettingsMenu(menu_options_t *options) : Menu(options), m
|
||||
}
|
||||
|
||||
// Add section counter selection (allows choosing number of sections)
|
||||
addSelection(LightSettingsMenuItem::SECTION_COUNTER, "Sektionen", values, 7);
|
||||
auto value = 7;
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
value = m_options->persistenceManager->GetValue(CreateKey(0), value);
|
||||
}
|
||||
addSelection(LightSettingsMenuItem::SECTION_COUNTER, "Sektionen", values, value);
|
||||
|
||||
setItemSize(std::stoull(getItem(0).getValue()));
|
||||
}
|
||||
@@ -30,5 +43,15 @@ void LightSettingsMenu::onButtonPressed(const MenuItem &menuItem, const ButtonTy
|
||||
switchValue(menuItem, button);
|
||||
|
||||
// Update the section list size based on the section counter value
|
||||
setItemSize(std::stoull(getItem(0).getValue()));
|
||||
if (menuItem.getId() == 0)
|
||||
{
|
||||
setItemSize(std::stoull(getItem(0).getValue()));
|
||||
}
|
||||
|
||||
// Persist the changed section values if persistence is available
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
const auto value = getItem(menuItem.getId()).getIndex();
|
||||
m_options->persistenceManager->SetValue(CreateKey(menuItem.getId()), value);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user