refactor persistence manager from cpp to c
Some checks failed
ESP-IDF Build / build (esp32c6, release-v5.4) (push) Failing after 4m12s
ESP-IDF Build / build (esp32c6, release-v5.5) (push) Failing after 4m17s
ESP-IDF Build / build (esp32s3, release-v5.4) (push) Failing after 3m49s
ESP-IDF Build / build (esp32s3, release-v5.5) (push) Failing after 4m0s
Some checks failed
ESP-IDF Build / build (esp32c6, release-v5.4) (push) Failing after 4m12s
ESP-IDF Build / build (esp32c6, release-v5.5) (push) Failing after 4m17s
ESP-IDF Build / build (esp32s3, release-v5.4) (push) Failing after 3m49s
ESP-IDF Build / build (esp32s3, release-v5.5) (push) Failing after 4m0s
Signed-off-by: Peter Siegmund <developer@mars3142.org>
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
|
||||
// Project-specific headers
|
||||
#include "common/Widget.h"
|
||||
#include "IPersistenceManager.h"
|
||||
#include "persistence_manager.h"
|
||||
#include "u8g2.h"
|
||||
|
||||
class MenuItem;
|
||||
@@ -28,7 +28,7 @@ class MenuItem;
|
||||
* @details This structure serves as a configuration container that provides menu widgets
|
||||
* with access to the display system, screen management functions, input
|
||||
* handling callbacks, and persistent storage.
|
||||
*
|
||||
*
|
||||
* @see Widget
|
||||
* @see ButtonType
|
||||
* @see IPersistenceManager
|
||||
@@ -61,14 +61,8 @@ typedef struct
|
||||
std::function<void(ButtonType button)> onButtonClicked;
|
||||
|
||||
/**
|
||||
* @brief Shared pointer to platform-independent persistence manager
|
||||
* @details This provides access to persistent key-value storage across different
|
||||
* platforms. The actual implementation (SDL3 or ESP32/NVS) is determined
|
||||
* at compile time based on the target platform.
|
||||
*
|
||||
* @note The persistence manager is shared across all menu widgets and maintains
|
||||
* its state throughout the application lifecycle.
|
||||
* @brief Zeiger auf C-Persistence-Manager-Instanz
|
||||
*/
|
||||
std::shared_ptr<IPersistenceManager> persistenceManager;
|
||||
persistence_manager_t *persistenceManager;
|
||||
|
||||
} menu_options_t;
|
||||
@@ -64,7 +64,7 @@ void Menu::setItemSize(const size_t size, int8_t startIndex)
|
||||
constexpr int key_length = 20;
|
||||
char key[key_length] = "";
|
||||
snprintf(key, key_length, "section_%zu", i + 1 - startIndex);
|
||||
index = m_options->persistenceManager->GetValue(key, index);
|
||||
index = persistence_manager_get_int(m_options->persistenceManager, key, index);
|
||||
}
|
||||
addSelection(i + 1, caption, m_items.at(0).getValues(), index);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "ui/ClockScreenSaver.h"
|
||||
#include "hal_esp32/PersistenceManager.h"
|
||||
#include "persistence_manager.h"
|
||||
#include "simulator.h"
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
@@ -38,8 +38,9 @@ void ClockScreenSaver::updateTextDimensions()
|
||||
|
||||
void ClockScreenSaver::getCurrentTimeString(char *buffer, size_t bufferSize) const
|
||||
{
|
||||
if (m_options && m_options->persistenceManager->GetValue("light_active", false) &&
|
||||
m_options->persistenceManager->GetValue("light_mode", 0) == 0)
|
||||
if (m_options && m_options->persistenceManager &&
|
||||
persistence_manager_get_bool(m_options->persistenceManager, "light_active", false) &&
|
||||
persistence_manager_get_int(m_options->persistenceManager, "light_mode", 0) == 0)
|
||||
{
|
||||
char *simulated_time = get_time();
|
||||
if (simulated_time != nullptr)
|
||||
|
||||
@@ -27,7 +27,7 @@ LightMenu::LightMenu(menu_options_t *options) : Menu(options), m_options(options
|
||||
bool active = false;
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
active = m_options->persistenceManager->GetValue(LightMenuOptions::LIGHT_ACTIVE, active);
|
||||
active = persistence_manager_get_bool(m_options->persistenceManager, LightMenuOptions::LIGHT_ACTIVE, active);
|
||||
}
|
||||
addToggle(LightMenuItem::ACTIVATE, "Einschalten", active);
|
||||
|
||||
@@ -39,7 +39,8 @@ LightMenu::LightMenu(menu_options_t *options) : Menu(options), m_options(options
|
||||
int mode_value = 0;
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
mode_value = m_options->persistenceManager->GetValue(LightMenuOptions::LIGHT_MODE, mode_value);
|
||||
mode_value =
|
||||
persistence_manager_get_int(m_options->persistenceManager, LightMenuOptions::LIGHT_MODE, mode_value);
|
||||
}
|
||||
addSelection(LightMenuItem::MODE, "Modus", items, mode_value);
|
||||
|
||||
@@ -50,7 +51,9 @@ LightMenu::LightMenu(menu_options_t *options) : Menu(options), m_options(options
|
||||
int variant_value = 3;
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
variant_value = m_options->persistenceManager->GetValue(LightMenuOptions::LIGHT_VARIANT, variant_value) - 1;
|
||||
variant_value =
|
||||
persistence_manager_get_int(m_options->persistenceManager, LightMenuOptions::LIGHT_VARIANT, variant_value) -
|
||||
1;
|
||||
}
|
||||
addSelection(LightMenuItem::VARIANT, "Variante", variants, variant_value);
|
||||
}
|
||||
@@ -70,7 +73,7 @@ void LightMenu::onButtonPressed(const MenuItem &menuItem, const ButtonType butto
|
||||
const auto value = getItem(menuItem.getId()).getValue() == "1";
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
m_options->persistenceManager->SetValue(LightMenuOptions::LIGHT_ACTIVE, value);
|
||||
persistence_manager_set_bool(m_options->persistenceManager, LightMenuOptions::LIGHT_ACTIVE, value);
|
||||
}
|
||||
|
||||
start_simulation();
|
||||
@@ -86,8 +89,8 @@ void LightMenu::onButtonPressed(const MenuItem &menuItem, const ButtonType butto
|
||||
const auto value = getItem(item.getId()).getIndex();
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
m_options->persistenceManager->SetValue(LightMenuOptions::LIGHT_MODE, value);
|
||||
m_options->persistenceManager->Save();
|
||||
persistence_manager_set_int(m_options->persistenceManager, LightMenuOptions::LIGHT_MODE, value);
|
||||
persistence_manager_save(m_options->persistenceManager);
|
||||
}
|
||||
|
||||
start_simulation();
|
||||
@@ -103,8 +106,8 @@ void LightMenu::onButtonPressed(const MenuItem &menuItem, const ButtonType butto
|
||||
const auto value = getItem(item.getId()).getIndex() + 1;
|
||||
if (m_options && m_options->persistenceManager)
|
||||
{
|
||||
m_options->persistenceManager->SetValue(LightMenuOptions::LIGHT_VARIANT, value);
|
||||
m_options->persistenceManager->Save();
|
||||
persistence_manager_set_int(m_options->persistenceManager, LightMenuOptions::LIGHT_VARIANT, value);
|
||||
persistence_manager_save(m_options->persistenceManager);
|
||||
}
|
||||
|
||||
start_simulation();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
idf_component_register(SRCS
|
||||
src/PersistenceManager.cpp
|
||||
src/persistence_manager.c
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES
|
||||
nvs_flash
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
/**
|
||||
* @interface IPersistenceManager
|
||||
* @brief Abstract interface for platform-independent persistence management
|
||||
* @details This interface defines the contract for key-value storage and retrieval
|
||||
* systems across different platforms (Desktop/SDL3 and ESP32).
|
||||
*/
|
||||
class IPersistenceManager
|
||||
{
|
||||
public:
|
||||
virtual ~IPersistenceManager() = default;
|
||||
|
||||
/**
|
||||
* @brief Template methods for type-safe setting and retrieving of values
|
||||
* @tparam T The type of value to set (must be one of: bool, int, float, double, std::string)
|
||||
* @param key The key to associate with the value
|
||||
* @param value The value to store
|
||||
*/
|
||||
template<typename T>
|
||||
void SetValue(const std::string& key, const T& value) {
|
||||
static_assert(std::is_same_v<T, bool> ||
|
||||
std::is_same_v<T, int> ||
|
||||
std::is_same_v<T, float> ||
|
||||
std::is_same_v<T, double> ||
|
||||
std::is_same_v<T, std::string>,
|
||||
"Unsupported type for IPersistenceManager");
|
||||
SetValueImpl(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Template method for type-safe retrieval of values
|
||||
* @tparam T The type of value to retrieve
|
||||
* @param key The key to look up
|
||||
* @param defaultValue The default value to return if the key is not found
|
||||
* @return The stored value or default value if the key doesn't exist
|
||||
*/
|
||||
template<typename T>
|
||||
[[nodiscard]] T GetValue(const std::string& key, const T& defaultValue = T{}) const {
|
||||
return GetValueImpl<T>(key, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Utility methods for key management
|
||||
*/
|
||||
[[nodiscard]] virtual bool HasKey(const std::string& key) const = 0; ///< Check if a key exists
|
||||
virtual void RemoveKey(const std::string& key) = 0; ///< Remove a key-value pair
|
||||
virtual void Clear() = 0; ///< Clear all stored data
|
||||
[[nodiscard]] virtual size_t GetKeyCount() const = 0; ///< Get the number of stored keys
|
||||
|
||||
/**
|
||||
* @brief Persistence operations
|
||||
*/
|
||||
virtual bool Save() = 0; ///< Save data to persistent storage
|
||||
virtual bool Load() = 0; ///< Load data from persistent storage
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Template-specific implementations that must be overridden by derived classes
|
||||
* @details These methods handle the actual storage and retrieval of different data types
|
||||
*/
|
||||
virtual void SetValueImpl(const std::string& key, bool value) = 0;
|
||||
virtual void SetValueImpl(const std::string& key, int value) = 0;
|
||||
virtual void SetValueImpl(const std::string& key, float value) = 0;
|
||||
virtual void SetValueImpl(const std::string& key, double value) = 0;
|
||||
virtual void SetValueImpl(const std::string& key, const std::string& value) = 0;
|
||||
|
||||
[[nodiscard]] virtual bool GetValueImpl(const std::string& key, bool defaultValue) const = 0;
|
||||
[[nodiscard]] virtual int GetValueImpl(const std::string& key, int defaultValue) const = 0;
|
||||
[[nodiscard]] virtual float GetValueImpl(const std::string& key, float defaultValue) const = 0;
|
||||
[[nodiscard]] virtual double GetValueImpl(const std::string& key, double defaultValue) const = 0;
|
||||
[[nodiscard]] virtual std::string GetValueImpl(const std::string& key, const std::string& defaultValue) const = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Template dispatch methods for type-safe value retrieval
|
||||
* @tparam T The type to retrieve
|
||||
* @param key The key to look up
|
||||
* @param defaultValue The default value to return
|
||||
* @return The retrieved value or default if not found
|
||||
*/
|
||||
template<typename T>
|
||||
[[nodiscard]] T GetValueImpl(const std::string& key, const T& defaultValue) const
|
||||
{
|
||||
if constexpr (std::is_same_v<T, bool>) {
|
||||
return GetValueImpl(key, static_cast<bool>(defaultValue));
|
||||
} else if constexpr (std::is_same_v<T, int>) {
|
||||
return GetValueImpl(key, static_cast<int>(defaultValue));
|
||||
} else if constexpr (std::is_same_v<T, float>) {
|
||||
return GetValueImpl(key, static_cast<float>(defaultValue));
|
||||
} else if constexpr (std::is_same_v<T, double>) {
|
||||
return GetValueImpl(key, static_cast<double>(defaultValue));
|
||||
} else if constexpr (std::is_same_v<T, std::string>) {
|
||||
return GetValueImpl(key, static_cast<const std::string&>(defaultValue));
|
||||
} else {
|
||||
static_assert(std::is_same_v<T, bool> ||
|
||||
std::is_same_v<T, int> ||
|
||||
std::is_same_v<T, float> ||
|
||||
std::is_same_v<T, double> ||
|
||||
std::is_same_v<T, std::string>,
|
||||
"Unsupported type for IPersistenceManager");
|
||||
return defaultValue; // This line will never be reached, but satisfies the compiler
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "IPersistenceManager.h"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <nvs.h>
|
||||
#include <nvs_flash.h>
|
||||
|
||||
/**
|
||||
* @class PersistenceManager
|
||||
* @brief ESP32-specific implementation using NVS (Non-Volatile Storage)
|
||||
* @details This implementation uses ESP32's NVS API for persistent storage
|
||||
* in flash memory, providing a platform-optimized solution for
|
||||
* embedded systems.
|
||||
*/
|
||||
class PersistenceManager final : public IPersistenceManager
|
||||
{
|
||||
private:
|
||||
nvs_handle_t nvs_handle_;
|
||||
std::string namespace_;
|
||||
bool initialized_;
|
||||
|
||||
public:
|
||||
explicit PersistenceManager(const std::string &nvs_namespace = "config");
|
||||
~PersistenceManager() override;
|
||||
|
||||
bool HasKey(const std::string &key) const override;
|
||||
void RemoveKey(const std::string &key) override;
|
||||
void Clear() override;
|
||||
size_t GetKeyCount() const override;
|
||||
|
||||
bool Save() override;
|
||||
bool Load() override;
|
||||
|
||||
bool Initialize();
|
||||
void Deinitialize();
|
||||
bool IsInitialized() const
|
||||
{
|
||||
return initialized_;
|
||||
}
|
||||
|
||||
protected:
|
||||
void SetValueImpl(const std::string &key, bool value) override;
|
||||
void SetValueImpl(const std::string &key, int value) override;
|
||||
void SetValueImpl(const std::string &key, float value) override;
|
||||
void SetValueImpl(const std::string &key, double value) override;
|
||||
void SetValueImpl(const std::string &key, const std::string &value) override;
|
||||
|
||||
bool GetValueImpl(const std::string &key, bool defaultValue) const override;
|
||||
int GetValueImpl(const std::string &key, int defaultValue) const override;
|
||||
float GetValueImpl(const std::string &key, float defaultValue) const override;
|
||||
double GetValueImpl(const std::string &key, double defaultValue) const override;
|
||||
std::string GetValueImpl(const std::string &key, const std::string &defaultValue) const override;
|
||||
|
||||
private:
|
||||
bool EnsureInitialized() const;
|
||||
};
|
||||
@@ -0,0 +1,200 @@
|
||||
#pragma once
|
||||
|
||||
#include <nvs.h>
|
||||
#include <nvs_flash.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Structure to manage persistent storage using NVS.
|
||||
*
|
||||
* This struct holds the NVS handle, namespace, and initialization state
|
||||
* for managing persistent key-value storage on the device.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** Handle to the NVS storage. */
|
||||
nvs_handle_t nvs_handle;
|
||||
/** Namespace used for NVS operations (max 15 chars + null terminator). */
|
||||
char nvs_namespace[16];
|
||||
/** Indicates if the persistence manager is initialized. */
|
||||
bool initialized;
|
||||
} persistence_manager_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the persistence manager with a given NVS namespace.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param nvs_namespace Namespace to use for NVS operations.
|
||||
*/
|
||||
void persistence_manager_init(persistence_manager_t *pm, const char *nvs_namespace);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the persistence manager and release resources.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
*/
|
||||
void persistence_manager_deinit(persistence_manager_t *pm);
|
||||
|
||||
/**
|
||||
* @brief Check if the persistence manager is initialized.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @return true if initialized, false otherwise.
|
||||
*/
|
||||
bool persistence_manager_is_initialized(const persistence_manager_t *pm);
|
||||
|
||||
/**
|
||||
* @brief Check if a key exists in the NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to check for existence.
|
||||
* @return true if the key exists, false otherwise.
|
||||
*/
|
||||
bool persistence_manager_has_key(const persistence_manager_t *pm, const char *key);
|
||||
|
||||
/**
|
||||
* @brief Remove a key from the NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to remove.
|
||||
*/
|
||||
void persistence_manager_remove_key(persistence_manager_t *pm, const char *key);
|
||||
|
||||
/**
|
||||
* @brief Clear all keys from the NVS storage in the current namespace.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
*/
|
||||
void persistence_manager_clear(persistence_manager_t *pm);
|
||||
|
||||
/**
|
||||
* @brief Get the number of keys stored in the current namespace.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @return Number of keys.
|
||||
*/
|
||||
size_t persistence_manager_get_key_count(const persistence_manager_t *pm);
|
||||
|
||||
/**
|
||||
* @brief Save all pending changes to NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @return true if successful, false otherwise.
|
||||
*/
|
||||
bool persistence_manager_save(persistence_manager_t *pm);
|
||||
|
||||
/**
|
||||
* @brief Load all data from NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @return true if successful, false otherwise.
|
||||
*/
|
||||
bool persistence_manager_load(persistence_manager_t *pm);
|
||||
|
||||
/**
|
||||
* @brief Set a boolean value for a key in NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to set.
|
||||
* @param value Boolean value to store.
|
||||
*/
|
||||
void persistence_manager_set_bool(persistence_manager_t *pm, const char *key, bool value);
|
||||
|
||||
/**
|
||||
* @brief Set an integer value for a key in NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to set.
|
||||
* @param value Integer value to store.
|
||||
*/
|
||||
void persistence_manager_set_int(persistence_manager_t *pm, const char *key, int32_t value);
|
||||
|
||||
/**
|
||||
* @brief Set a float value for a key in NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to set.
|
||||
* @param value Float value to store.
|
||||
*/
|
||||
void persistence_manager_set_float(persistence_manager_t *pm, const char *key, float value);
|
||||
|
||||
/**
|
||||
* @brief Set a double value for a key in NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to set.
|
||||
* @param value Double value to store.
|
||||
*/
|
||||
void persistence_manager_set_double(persistence_manager_t *pm, const char *key, double value);
|
||||
|
||||
/**
|
||||
* @brief Set a string value for a key in NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to set.
|
||||
* @param value String value to store.
|
||||
*/
|
||||
void persistence_manager_set_string(persistence_manager_t *pm, const char *key, const char *value);
|
||||
|
||||
/**
|
||||
* @brief Get a boolean value for a key from NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to retrieve.
|
||||
* @param default_value Value to return if key does not exist.
|
||||
* @return Boolean value.
|
||||
*/
|
||||
bool persistence_manager_get_bool(const persistence_manager_t *pm, const char *key, bool default_value);
|
||||
|
||||
/**
|
||||
* @brief Get an integer value for a key from NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to retrieve.
|
||||
* @param default_value Value to return if key does not exist.
|
||||
* @return Integer value.
|
||||
*/
|
||||
int32_t persistence_manager_get_int(const persistence_manager_t *pm, const char *key, int32_t default_value);
|
||||
|
||||
/**
|
||||
* @brief Get a float value for a key from NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to retrieve.
|
||||
* @param default_value Value to return if key does not exist.
|
||||
* @return Float value.
|
||||
*/
|
||||
float persistence_manager_get_float(const persistence_manager_t *pm, const char *key, float default_value);
|
||||
|
||||
/**
|
||||
* @brief Get a double value for a key from NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to retrieve.
|
||||
* @param default_value Value to return if key does not exist.
|
||||
* @return Double value.
|
||||
*/
|
||||
double persistence_manager_get_double(const persistence_manager_t *pm, const char *key, double default_value);
|
||||
|
||||
/**
|
||||
* @brief Get a string value for a key from NVS storage.
|
||||
*
|
||||
* @param pm Pointer to the persistence manager structure.
|
||||
* @param key Key to retrieve.
|
||||
* @param out_value Buffer to store the retrieved string.
|
||||
* @param max_len Maximum length of the output buffer.
|
||||
* @param default_value Value to use if key does not exist.
|
||||
*/
|
||||
void persistence_manager_get_string(const persistence_manager_t *pm, const char *key, char *out_value,
|
||||
size_t max_len, const char *default_value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,279 +0,0 @@
|
||||
#include "hal_esp32/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();
|
||||
Load();
|
||||
}
|
||||
|
||||
PersistenceManager::~PersistenceManager()
|
||||
{
|
||||
Deinitialize();
|
||||
}
|
||||
|
||||
bool PersistenceManager::Initialize()
|
||||
{
|
||||
if (initialized_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Open NVS handle
|
||||
esp_err_t 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;
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
#include "persistence_manager.h"
|
||||
#include <esp_log.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TAG "persistence_manager"
|
||||
|
||||
void persistence_manager_init(persistence_manager_t *pm, const char *nvs_namespace)
|
||||
{
|
||||
if (!pm)
|
||||
return;
|
||||
strncpy(pm->nvs_namespace, nvs_namespace ? nvs_namespace : "config", sizeof(pm->nvs_namespace) - 1);
|
||||
pm->nvs_namespace[sizeof(pm->nvs_namespace) - 1] = '\0';
|
||||
pm->initialized = false;
|
||||
esp_err_t err = nvs_open(pm->nvs_namespace, NVS_READWRITE, &pm->nvs_handle);
|
||||
if (err == ESP_OK)
|
||||
{
|
||||
pm->initialized = true;
|
||||
ESP_LOGI(TAG, "Initialized with namespace: %s", pm->nvs_namespace);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to open NVS handle: %s", esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
void persistence_manager_deinit(persistence_manager_t *pm)
|
||||
{
|
||||
if (pm && pm->initialized)
|
||||
{
|
||||
nvs_close(pm->nvs_handle);
|
||||
pm->initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool persistence_manager_is_initialized(const persistence_manager_t *pm)
|
||||
{
|
||||
return pm && pm->initialized;
|
||||
}
|
||||
|
||||
bool persistence_manager_has_key(const persistence_manager_t *pm, const char *key)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return false;
|
||||
size_t required_size = 0;
|
||||
esp_err_t err = nvs_get_blob(pm->nvs_handle, key, NULL, &required_size);
|
||||
return err == ESP_OK;
|
||||
}
|
||||
|
||||
void persistence_manager_remove_key(persistence_manager_t *pm, const char *key)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return;
|
||||
esp_err_t err = nvs_erase_key(pm->nvs_handle, key);
|
||||
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to remove key '%s': %s", key, esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
void persistence_manager_clear(persistence_manager_t *pm)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return;
|
||||
esp_err_t err = nvs_erase_all(pm->nvs_handle);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to clear all keys: %s", esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
size_t persistence_manager_get_key_count(const persistence_manager_t *pm)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return 0;
|
||||
nvs_iterator_t it = NULL;
|
||||
esp_err_t err = nvs_entry_find(NVS_DEFAULT_PART_NAME, pm->nvs_namespace, NVS_TYPE_ANY, &it);
|
||||
if (err != ESP_OK || it == NULL)
|
||||
return 0;
|
||||
size_t count = 0;
|
||||
while (it != NULL)
|
||||
{
|
||||
count++;
|
||||
err = nvs_entry_next(&it);
|
||||
if (err != ESP_OK)
|
||||
break;
|
||||
}
|
||||
nvs_release_iterator(it);
|
||||
return count;
|
||||
}
|
||||
|
||||
bool persistence_manager_save(persistence_manager_t *pm)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return false;
|
||||
esp_err_t err = nvs_commit(pm->nvs_handle);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to commit NVS: %s", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool persistence_manager_load(persistence_manager_t *pm)
|
||||
{
|
||||
return persistence_manager_is_initialized(pm);
|
||||
}
|
||||
|
||||
void persistence_manager_set_bool(persistence_manager_t *pm, const char *key, bool value)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return;
|
||||
uint8_t val = value ? 1 : 0;
|
||||
esp_err_t err = nvs_set_u8(pm->nvs_handle, key, val);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to set bool key '%s': %s", key, esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
void persistence_manager_set_int(persistence_manager_t *pm, const char *key, int32_t value)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return;
|
||||
esp_err_t err = nvs_set_i32(pm->nvs_handle, key, value);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to set int key '%s': %s", key, esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
void persistence_manager_set_float(persistence_manager_t *pm, const char *key, float value)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return;
|
||||
esp_err_t err = nvs_set_blob(pm->nvs_handle, key, &value, sizeof(float));
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to set float key '%s': %s", key, esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
void persistence_manager_set_double(persistence_manager_t *pm, const char *key, double value)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return;
|
||||
esp_err_t err = nvs_set_blob(pm->nvs_handle, key, &value, sizeof(double));
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to set double key '%s': %s", key, esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
void persistence_manager_set_string(persistence_manager_t *pm, const char *key, const char *value)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return;
|
||||
esp_err_t err = nvs_set_str(pm->nvs_handle, key, value);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Failed to set string key '%s': %s", key, esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
|
||||
bool persistence_manager_get_bool(const persistence_manager_t *pm, const char *key, bool default_value)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return default_value;
|
||||
uint8_t value;
|
||||
esp_err_t err = nvs_get_u8(pm->nvs_handle, key, &value);
|
||||
if (err != ESP_OK)
|
||||
return default_value;
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
int32_t persistence_manager_get_int(const persistence_manager_t *pm, const char *key, int32_t default_value)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return default_value;
|
||||
int32_t value;
|
||||
esp_err_t err = nvs_get_i32(pm->nvs_handle, key, &value);
|
||||
if (err != ESP_OK)
|
||||
return default_value;
|
||||
return value;
|
||||
}
|
||||
|
||||
float persistence_manager_get_float(const persistence_manager_t *pm, const char *key, float default_value)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return default_value;
|
||||
float value;
|
||||
size_t required_size = sizeof(float);
|
||||
esp_err_t err = nvs_get_blob(pm->nvs_handle, key, &value, &required_size);
|
||||
if (err != ESP_OK || required_size != sizeof(float))
|
||||
return default_value;
|
||||
return value;
|
||||
}
|
||||
|
||||
double persistence_manager_get_double(const persistence_manager_t *pm, const char *key, double default_value)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
return default_value;
|
||||
double value;
|
||||
size_t required_size = sizeof(double);
|
||||
esp_err_t err = nvs_get_blob(pm->nvs_handle, key, &value, &required_size);
|
||||
if (err != ESP_OK || required_size != sizeof(double))
|
||||
return default_value;
|
||||
return value;
|
||||
}
|
||||
|
||||
void persistence_manager_get_string(const persistence_manager_t *pm, const char *key, char *out_value, size_t max_len,
|
||||
const char *default_value)
|
||||
{
|
||||
if (!persistence_manager_is_initialized(pm))
|
||||
{
|
||||
strncpy(out_value, default_value, max_len - 1);
|
||||
out_value[max_len - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
size_t required_size = 0;
|
||||
esp_err_t err = nvs_get_str(pm->nvs_handle, key, NULL, &required_size);
|
||||
if (err != ESP_OK || required_size == 0 || required_size > max_len)
|
||||
{
|
||||
strncpy(out_value, default_value, max_len - 1);
|
||||
out_value[max_len - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
err = nvs_get_str(pm->nvs_handle, key, out_value, &required_size);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
strncpy(out_value, default_value, max_len - 1);
|
||||
out_value[max_len - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "simulator.h"
|
||||
|
||||
#include "color.h"
|
||||
#include "hal_esp32/PersistenceManager.h"
|
||||
#include "led_strip_ws2812.h"
|
||||
#include "persistence_manager.h"
|
||||
#include "storage.h"
|
||||
#include <esp_heap_caps.h>
|
||||
#include <esp_log.h>
|
||||
@@ -145,10 +145,12 @@ static void initialize_light_items(void)
|
||||
initialize_storage();
|
||||
|
||||
static char filename[30];
|
||||
auto persistence = PersistenceManager();
|
||||
int variant = persistence.GetValue("light_variant", 1);
|
||||
persistence_manager_t persistence;
|
||||
persistence_manager_init(&persistence, "config");
|
||||
int variant = persistence_manager_get_int(&persistence, "light_variant", 1);
|
||||
snprintf(filename, sizeof(filename), "/spiffs/schema_%02d.csv", variant);
|
||||
load_file(filename);
|
||||
persistence_manager_deinit(&persistence);
|
||||
|
||||
if (head == NULL)
|
||||
{
|
||||
@@ -398,25 +400,22 @@ void start_simulation(void)
|
||||
{
|
||||
stop_simulation_task();
|
||||
|
||||
auto persistence = PersistenceManager();
|
||||
if (persistence.GetValue("light_active", false))
|
||||
persistence_manager_t persistence;
|
||||
persistence_manager_init(&persistence, "config");
|
||||
if (persistence_manager_get_bool(&persistence, "light_active", false))
|
||||
{
|
||||
|
||||
int mode = persistence.GetValue("light_mode", 0);
|
||||
int mode = persistence_manager_get_int(&persistence, "light_mode", 0);
|
||||
switch (mode)
|
||||
{
|
||||
case 0: // Simulation mode
|
||||
start_simulation_task();
|
||||
break;
|
||||
|
||||
case 1: // Day mode
|
||||
start_simulate_day();
|
||||
break;
|
||||
|
||||
case 2: // Night mode
|
||||
start_simulate_night();
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGW(TAG, "Unknown light mode: %d", mode);
|
||||
break;
|
||||
@@ -426,4 +425,5 @@ void start_simulation(void)
|
||||
{
|
||||
led_strip_update(LED_STATE_OFF, rgb_t{});
|
||||
}
|
||||
persistence_manager_deinit(&persistence);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user