#include "settings_store.h" #include "display.h" #include "motion_gesture.h" #include "esp_log.h" #include "nvs.h" #include "nvs_flash.h" static const char *TAG = "settings_store"; static const char *SETTINGS_NAMESPACE = "settings"; static const settings_data_t SETTINGS_DEFAULTS = { .notification_enabled = false, .brightness_pct = 70, .volume_pct = 50, .mute = false, .shake_nav_enabled = true, .shake_sensitivity = SHAKE_SENS_MED, }; static settings_data_t s_data; static void load_key_u8(nvs_handle_t handle, const char *key, uint8_t *out, uint8_t default_val) { uint8_t val = default_val; if (nvs_get_u8(handle, key, &val) != ESP_OK) { val = default_val; } *out = val; } void settings_store_load(void) { s_data = SETTINGS_DEFAULTS; nvs_handle_t handle; esp_err_t err = nvs_open(SETTINGS_NAMESPACE, NVS_READONLY, &handle); if (err != ESP_OK) { ESP_LOGI(TAG, "No saved settings, using defaults"); return; } uint8_t val; load_key_u8(handle, "notif", &val, SETTINGS_DEFAULTS.notification_enabled); s_data.notification_enabled = val != 0; load_key_u8(handle, "bright", &s_data.brightness_pct, SETTINGS_DEFAULTS.brightness_pct); load_key_u8(handle, "vol", &s_data.volume_pct, SETTINGS_DEFAULTS.volume_pct); load_key_u8(handle, "mute", &val, SETTINGS_DEFAULTS.mute); s_data.mute = val != 0; load_key_u8(handle, "shake_en", &val, SETTINGS_DEFAULTS.shake_nav_enabled); s_data.shake_nav_enabled = val != 0; load_key_u8(handle, "shake_sens", &val, SETTINGS_DEFAULTS.shake_sensitivity); s_data.shake_sensitivity = (shake_sensitivity_t)val; nvs_close(handle); ESP_LOGI(TAG, "Settings loaded (bright=%u vol=%u)", s_data.brightness_pct, s_data.volume_pct); } const settings_data_t *settings_store_get(void) { return &s_data; } void settings_store_update(const settings_data_t *data) { s_data = *data; } esp_err_t settings_store_commit(void) { nvs_handle_t handle; esp_err_t err = nvs_open(SETTINGS_NAMESPACE, NVS_READWRITE, &handle); if (err != ESP_OK) { ESP_LOGE(TAG, "nvs_open failed: %s", esp_err_to_name(err)); return err; } err = nvs_set_u8(handle, "notif", s_data.notification_enabled ? 1 : 0); if (err == ESP_OK) { err = nvs_set_u8(handle, "bright", s_data.brightness_pct); } if (err == ESP_OK) { err = nvs_set_u8(handle, "vol", s_data.volume_pct); } if (err == ESP_OK) { err = nvs_set_u8(handle, "mute", s_data.mute ? 1 : 0); } if (err == ESP_OK) { err = nvs_set_u8(handle, "shake_en", s_data.shake_nav_enabled ? 1 : 0); } if (err == ESP_OK) { err = nvs_set_u8(handle, "shake_sens", (uint8_t)s_data.shake_sensitivity); } if (err == ESP_OK) { err = nvs_commit(handle); } nvs_close(handle); if (err != ESP_OK) { ESP_LOGE(TAG, "commit failed: %s", esp_err_to_name(err)); } return err; } esp_err_t settings_store_factory_reset(void) { nvs_handle_t handle; esp_err_t err = nvs_open(SETTINGS_NAMESPACE, NVS_READWRITE, &handle); if (err == ESP_OK) { err = nvs_erase_all(handle); if (err == ESP_OK) { err = nvs_commit(handle); } nvs_close(handle); } s_data = SETTINGS_DEFAULTS; esp_err_t commit_err = settings_store_commit(); if (err != ESP_OK) { return err; } return commit_err; } void settings_store_apply(void) { uint16_t duty = (uint16_t)((s_data.brightness_pct * 1023U) / 100U); display_backlight_set_brightness(duty); motion_gesture_set_enabled(s_data.shake_nav_enabled); motion_gesture_set_sensitivity(s_data.shake_sensitivity); }