#include "settings.h" #include "sdkconfig.h" #include "esp_log.h" #include "nvs.h" #include "nvs_flash.h" #include #include static const char *TAG = "settings"; static nvs_handle_t nvs; settings_t settings; static cam_info_t favs[FAV_SLOTS]; static bool fav_used[FAV_SLOTS]; static void slot_key(int slot, char *key) { snprintf(key, 8, "fav%d", slot); } void settings_init(void) { 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(); } ESP_ERROR_CHECK(err); ESP_ERROR_CHECK(nvs_open("widget", NVS_READWRITE, &nvs)); settings = (settings_t){ .interval_s = CONFIG_WIDGET_INTERVAL_S, .lcd_brightness = CONFIG_WIDGET_LCD_BRIGHTNESS, .led_brightness = CONFIG_WIDGET_LED_BRIGHTNESS, #if CONFIG_WIDGET_LISTING_RATING .listing = LISTING_RATING, #elif CONFIG_WIDGET_LISTING_NEW .listing = LISTING_NEW, #else .listing = LISTING_MIXED, #endif .source = SOURCE_RANDOM, .caption = 1, }; settings_t stored; size_t len = sizeof stored; if (nvs_get_blob(nvs, "settings", &stored, &len) == ESP_OK && len == sizeof stored) { settings = stored; if (settings.interval_s < 5 || settings.interval_s > 300) settings.interval_s = CONFIG_WIDGET_INTERVAL_S; if (settings.lcd_brightness > 100) settings.lcd_brightness = 100; if (settings.listing > LISTING_NEW) settings.listing = LISTING_MIXED; if (settings.source > SOURCE_FAVORITES) settings.source = SOURCE_RANDOM; } for (int i = 0; i < FAV_SLOTS; i++) { char key[8]; slot_key(i, key); len = sizeof favs[i]; fav_used[i] = nvs_get_blob(nvs, key, &favs[i], &len) == ESP_OK && len == sizeof favs[i] && favs[i].url[0]; } ESP_LOGI(TAG, "interval %us, lcd %u%%, ring %u, listing %u, source %u, %d favourites", settings.interval_s, settings.lcd_brightness, settings.led_brightness, settings.listing, settings.source, fav_count()); } void settings_save(void) { if (nvs_set_blob(nvs, "settings", &settings, sizeof settings) != ESP_OK || nvs_commit(nvs) != ESP_OK) ESP_LOGW(TAG, "save failed"); } void settings_request_portal(void) { nvs_set_u8(nvs, "portal", 1); nvs_commit(nvs); } bool settings_take_portal_request(void) { uint8_t v = 0; if (nvs_get_u8(nvs, "portal", &v) != ESP_OK || !v) return false; nvs_erase_key(nvs, "portal"); nvs_commit(nvs); return true; } const cam_info_t *fav_get(int slot) { return (slot >= 0 && slot < FAV_SLOTS && fav_used[slot]) ? &favs[slot] : NULL; } void fav_set(int slot, const cam_info_t *cam) { if (slot < 0 || slot >= FAV_SLOTS) return; char key[8]; slot_key(slot, key); favs[slot] = *cam; fav_used[slot] = true; if (nvs_set_blob(nvs, key, &favs[slot], sizeof favs[slot]) != ESP_OK || nvs_commit(nvs) != ESP_OK) ESP_LOGW(TAG, "favourite %d not saved", slot); } void fav_clear(int slot) { if (slot < 0 || slot >= FAV_SLOTS) return; char key[8]; slot_key(slot, key); fav_used[slot] = false; nvs_erase_key(nvs, key); nvs_commit(nvs); } int fav_find(const cam_info_t *cam) { for (int i = 0; i < FAV_SLOTS; i++) if (fav_used[i] && favs[i].id == cam->id && !strcmp(favs[i].url, cam->url)) return i; return -1; } int fav_count(void) { int n = 0; for (int i = 0; i < FAV_SLOTS; i++) n += fav_used[i]; return n; }