-
Notifications
You must be signed in to change notification settings - Fork 0
storage
lib/NVS_STORE/ wraps Preferences with a recursive mutex (httpd task and
main-loop task call it concurrently). Each accessor opens/closes the namespace
per call. On first boot (nvsInit absent) it seeds the default station list
and RSS feeds.
| Key | Type | Default | Meaning |
|---|---|---|---|
nvsInit |
bool | — | first-boot seed marker |
st_count |
int | seeded | number of stations |
st_def |
int | seeded | how many leading stations are built-in (non-removable via dashboard) |
st<N>_n / st<N>_u
|
string | seeded | station N name / URL (N = 0…19, name ≤31 chars, URL ≤127) |
rss_count, rss<N>_u
|
int, string | 1 feed (VRT NWS) | RSS feeds (max 10, URL ≤127) |
pb_st |
int | 0 | last station index |
pb_play |
bool | false | was playing at last save |
pb_vol |
float | 1.0 | last driver volume |
ntp_srv |
string | pool.ntp.org |
NTP server |
tz |
string | CET-1CEST,M3.5.0,M10.5.0/3 |
POSIX timezone |
set_motors |
bool | false | motors master gate |
led_mode |
uchar | 0 (off) | LED subsystem mode: 0=off, 1=auto, 2=manual (NvsStore::loadLedMode/saveLedMode) |
set_led_fx |
int | 0 | selected LED effect index — an independent selector, not a master gate |
set_accel_wk |
bool | false | tap-to-wake |
mot_pwm_mul |
float | 1.0 | motor PWM calibration multiplier (0.70–1.30) |
led_fx_br |
uchar | 100 | LED effect brightness %, stored as the actual 30–100 value (UI slider is 0–100) |
led_eye_dim |
uchar | 0 | eye-pixel (0/1) dim offset %, subtracted from led_fx_br for the eyes only |
boot_mode |
uchar | 0 (STREAM) | 0 = Web Radio, 1 = Web Server |
bl_always_on |
bool | false | backlight never times out |
mood_snd_en |
bool | false | mood engine may trigger sound clips |
al_led_fx |
int | 11 (Matrix) | LED effect while the alarm rings |
al_dance_mv |
int | 5 (Twist) | dance move while the alarm rings |
al_aud_en |
bool | true | alarm plays audio |
al_station |
int | 0 | station index the alarm streams (falls back to backup clip if unavailable) |
al_backup_snd |
int | 2 (Calling) | local backup sound clip if streaming fails |
col0…col4
|
18-byte blob | zeros | saved LED color slots (6× r,g,b) |
wx_cache |
blob | — | WebFetcher's last weather + location + age |
rss_count/rss<N>_ustorage is live code with no live consumer:NvsStorestill seeds one feed on first boot (nvs_store.cpp:57-66) and implementsloadRssFeeds/saveRssFeeds/addRssFeed/removeRssFeed, but the dashboard'srss_add/rss_removehandlers are commented out (web_dashboard_idf.cpp:510-517) and the RSS-feed load block inmain.cppis commented out too (main.cpp:590-598) — nothing in the running firmware currently reads or writes these keys.
Not in NVS at all — alarm on/off and alarm hour/minute live in the PCF8523
RTC chip itself (TimeManager::setAlarm/getAlarm/isAlarmEnabled), not
NVS — they survive power loss because the RTC is battery-backed, same as the
clock.
Deliberately RAM-only (reset every boot, by design):
-
dance_move— a motor move must never resume after a power cycle. -
power_off_min/power_off_start— the explicit power-off countdown.
The GEM menu's "LED Mode" item (MenuElement::_cbLedMode,
menu_element.cpp:645-652) and the web dashboard's led_mode command
(WebDashboardIdf::_h_cmd, web_dashboard_idf.cpp:360-367) both write the
same Blackboard::led_mode field and persist it via NvsStore::saveLedMode()
— there is no separate "manual control" flag. The dashboard's
<select id="ledMode"> (data/www/app.js's sendLedMode()) just posts
{cmd:"led_mode", value: 0|1|2} for off/auto/manual, the same enum the menu
uses, and both surfaces read the persisted value back on load/open.
Every settings item in the LCD menu (lib/GUI_Menu/menu_element.cpp), with
where its value actually lives:
| Page | Item | Backed by |
|---|---|---|
| Settings | Acc WK | NVS set_accel_wk
|
| Settings | Backlight | NVS bl_always_on
|
| Settings | Boot in | NVS boot_mode (reboot to apply) |
| Settings | WiFi Setup / Show IP / Test / Forget WiFi | actions, no state |
| Effects | Mot En | NVS set_motors
|
| Effects | PWM x | NVS mot_pwm_mul
|
| Effects | Dance |
RAM-only (dance_move) |
| Mood | Audio | NVS mood_snd_en
|
| Mood | LED Mode | NVS led_mode
|
| Mood | Effect | NVS set_led_fx
|
| Mood | Brightness | NVS led_fx_br
|
| Mood | Eye Dim | NVS led_eye_dim
|
| Alarm | Enable | RTC (PCF8523), not NVS |
| Alarm | LED | NVS al_led_fx
|
| Alarm | Move | NVS al_dance_mv
|
| Alarm | Sound | NVS al_aud_en
|
| Alarm | Station | NVS al_station
|
| Alarm | Backup | NVS al_backup_snd
|
| Alarm → Set Alarm | Hour / Minute | RTC, written on Apply |
| Power | Timer |
RAM-only (power_off_min/power_off_start) |
| Power | Restart / Shut Down | actions, no state |
| Time | Hour/Min/Sec/Day/Month/Year | RTC, written on Apply |
| Games | (per registered game) | action, no state |
- Playback state is saved with a 500 ms debounce in
loop()(NVS commits stall both cores and starve the audio task) and force-flushed before shutdown. -
saveStations/saveRssFeedsremove orphaned keys when the list shrinks. -
loadBlob()only fills the buffer when the stored blob length matches exactly, so PODs can be reinterpreted safely across firmware changes.
MNM Hits, MNM, Radio 1, Radio 2, Studio Brussel, Q-music, Q-Foute Radio, Q-Allstars, Vivacité Bruxelles, La Première, WDR4, France Bleu — all plain MP3 icecast streams (the MultiDecoder currently only registers MP3, see Audio).
Partition table: ESP32_4MB_1APP.csv (single app + SPIFFS). Image source is
the data/ directory (pio run -t uploadfs, or enable the
upload_fs_before_flash.py extra script to do it automatically before each
flash).
| Path | Used by |
|---|---|
/www/index.html, /www/app.js, /www/style.css
|
web dashboard static assets |
/jokes/jokes.bin |
joke-of-the-day text read by lib/GUI_Jokes/jokes_element.cpp (JOKES_PATH), generated by patches/apply_patches.py's generate_jokes_bin()
|
Notes:
- Mood-sound clips are not read from SPIFFS at all — they're compiled
directly into the firmware binary.
lib/CAT_AUDIO/audio_driver.cpp:5-18includes one header per clip (angry.h,purr.h,hissing.h, …), each holding a baked-indata_<name>_mp3[]byte array; theSoundenum (audio_driver.h:11-26) indexes into them — 14 members:Angry,Bored,Calling,Confused,CoolOpera,CoolWobble,Cute,Hissing,InnerAngry,Purr,Snore,SoftAngry,Trilling,Wink. Thedata/directory currently has zero.mp3files. - Mood sounds are available by default:
setup()allocatesaudioMgrand wires it intoMoodManagerwhenever boot mode is STREAM, the default (main.cpp:573-574,582) — it's only left null in WEB mode. Availability is gated solely by themood_snd_enNVS toggle (default false), not by whether anAudioDriver/AudioManagerexists. -
data_old/is an old, unflashed asset set — an olderwww/plus many individually-numbered mood mp3s (angry_1.mp3,angry_2.mp3,bored_2.mp3, …). -
data_sounds/holds 14 mp3s (angry.mp3,bored.mp3,calling.mp3,confused.mp3,cool_opera.mp3,cool_wobble.mp3,cute.mp3,hissing.mp3,inner_angry.mp3,purr.mp3,snore.mp3,soft_angry.mp3,trilling.mp3,wink.mp3) matching the compiled-inSoundenum 1:1 — these look like the source files theCAT_AUDIOheaders were generated from, not something flashed as SPIFFS. -
.gitignorestill lists adata2/entry, but no such directory exists in the repo. -
setup()lists all SPIFFS files on serial at boot — handy to verify what is actually on the device.
setup() reads NVS once and publishes into the blackboard (main.cpp:508-562):
led_mode+led_effect, led_effect_brightness, led_eye_dim, accel wake,
mood sounds enabled, backlight-always-on, alarm LED/dance/audio/station/backup
sound, and motors gate + PWM multiplier. There's no separate "mood LED"
restore — that field doesn't exist; led_mode covers it. From then on the
blackboard is the live copy; NVS is only written on change (see
Data Broker).