Public Access
Home Assistant: remove the Clock switch (its entity is deleted on connect), add an IP sensor and Mode / Off image dropdowns whose options follow the saved bitmaps. Remove the built-in "Nintendo border" bitmap. Off image: a bitmap (or blank) left on the dots when the display switches off. Nano: pause after each flip pulse and repeat pulses for changed dots, both stored in EEPROM (G/N commands). Refresh effects (E command): instant, sparkle, wipe, rain, from the middle out, diagonal, spiral, flip all then reveal, push and random, optionally only for small changes. Effects run in steps from loop() so serial input keeps flowing. Web UI: flip settings, refresh effect and test patterns under Settings; the System tab shows why the ESP32 last restarted. Settings records from versions 1 and 2 are migrated. Firmware 2.3.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
71 lines
1.8 KiB
C++
71 lines
1.8 KiB
C++
#include "system/settings_store.h"
|
|
|
|
#include <Preferences.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
|
|
static const char *NAMESPACE = "flipdot";
|
|
static const char *KEY = "settings";
|
|
// Increase when the Settings struct changes; old records are then ignored (defaults),
|
|
// unless OLD_VERSIONS says how to read them
|
|
static const uint16_t VERSION = 3;
|
|
|
|
// Older versions: fields were only added at the end, so the start of an old record has
|
|
// the same layout. New fields keep their defaults.
|
|
struct OldVersion
|
|
{
|
|
uint16_t version;
|
|
size_t fields; // bytes of Settings that version had
|
|
};
|
|
static const OldVersion OLD_VERSIONS[] = {
|
|
{1, offsetof(Settings, off_page)},
|
|
{2, offsetof(Settings, drive)},
|
|
};
|
|
|
|
struct StoredSettings
|
|
{
|
|
uint16_t version;
|
|
uint16_t size;
|
|
Settings settings;
|
|
};
|
|
|
|
void loadSettings(Settings &settings)
|
|
{
|
|
settings = Settings();
|
|
StoredSettings stored;
|
|
memset(&stored, 0, sizeof(stored));
|
|
Preferences prefs;
|
|
prefs.begin(NAMESPACE, true);
|
|
size_t read = prefs.getBytes(KEY, &stored, sizeof(stored));
|
|
prefs.end();
|
|
|
|
Settings loaded;
|
|
if (read == sizeof(stored) && stored.version == VERSION && stored.size == sizeof(Settings))
|
|
loaded = stored.settings;
|
|
else
|
|
{
|
|
const OldVersion *old = nullptr;
|
|
for (const OldVersion &o : OLD_VERSIONS)
|
|
if (o.version == stored.version)
|
|
old = &o;
|
|
if (!old || stored.size < old->fields || stored.size > sizeof(Settings) ||
|
|
read != offsetof(StoredSettings, settings) + stored.size)
|
|
return;
|
|
memcpy((void *)&loaded, &stored.settings, old->fields);
|
|
}
|
|
if (validateSettings(loaded) == nullptr)
|
|
settings = loaded;
|
|
}
|
|
|
|
void saveSettings(const Settings &settings)
|
|
{
|
|
StoredSettings stored;
|
|
stored.version = VERSION;
|
|
stored.size = sizeof(Settings);
|
|
stored.settings = settings;
|
|
Preferences prefs;
|
|
prefs.begin(NAMESPACE, false);
|
|
prefs.putBytes(KEY, &stored, sizeof(stored));
|
|
prefs.end();
|
|
}
|