You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9763436
Browse filesBrowse the repository at this point in the historyBrowse files
feat: auto-backup the full config to the sync server
Upload the same full backup the web "export" button produces (settings +
RFID assignments + per-path EQ rules + listening statistics, never any
passwords) to a server straight from the device — no browser needed.
- new Backup module: streams the backup to SD entry-by-entry first (so a
large RFID list fits in the limited heap), then POSTs the file to the
configured URL, reusing the file-sync credentials and sending the device
hostname in X-ESPuino-Host
- daily auto-backup (once the clock is set + WiFi is up), plus manual run
- Backup settings section in the Sync tab (URL + once-a-day toggle); a
"Back up now" button with live status; DE/EN/FR locales
- bindable command 189 and MQTT topic "backup" (HA button + status sensor)
- companion server/backup.php stores backups per device and prunes old ones
- /backupupload GET/POST endpoints + OpenAPI spec; GitHub-Pages demo mock
- README entry
Verified on device: a real upload produced valid JSON (13 settings
sections, 14 RFID tags, EQ rules, 365-day stats) with all passwords
stripped, accepted with HTTP 200.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -150,6 +150,7 @@ neon logo that doubles as the SVG favicon ([`7be5254`](../../commit/7be5254)):
150
150
|**Now-playing metadata**: parses ID3 title/artist/album + embedded cover (with a folder `cover.jpg`/`folder.jpg` fallback); an info dialog shows the full detail (codec / sample-rate / bitrate / channels, path, play mode, RFID tag) via `GET /currenttrack`; artist/album are also published to MQTT + Home Assistant |[`ce3116c`](../../commit/ce3116c) · [`fda14a3`](../../commit/fda14a3) · [`4123db6`](../../commit/4123db6) · [`5cb0b8b`](../../commit/5cb0b8b)|
151
151
|**Listening statistics**: per-day listening time (today / yesterday / 7 d / 30 d) in a 365-day NVS ring buffer, plus a most-played-cards top list — shown in the info dialog (`GET /info`, `GET /topcards`). The info dialog also draws a **30-day bar chart** (inline SVG, themed, no chart lib) and offers a **CSV export** of the full daily series (`GET /stats.csv`, `date,seconds`) |[`af6c8d3`](../../commit/af6c8d3) · [`c2e7d44`](../../commit/c2e7d44)|
152
152
|**Full backup**: export/import all settings + RFID assignments + per-path EQ rules + listening stats as one JSON file; passwords are only included when explicitly ticked, so a shared backup doesn't leak credentials |[`4c90ff4`](../../commit/4c90ff4) · [`646ec5c`](../../commit/646ec5c)|
153
+
|**Auto-backup to the sync server**: upload that same full backup (settings + RFID assignments + EQ rules + listening stats, **never** passwords) to a server straight from the device — no browser needed. A **Backup** section in the Sync settings tab takes the server URL (reusing the file-sync credentials) and a **once-a-day automatic** toggle; the file is streamed to SD entry-by-entry first (so a large RFID list fits in the limited heap) and then POSTed to the server, where the companion [`server/backup.php`](server/backup.php) stores it per-device and prunes old ones. The stored JSON drops straight back into the web interface's *import backup*. Run it from the Sync tab, command **189** or MQTT `backup` (Home Assistant button + status sensor included) |[`b134e7d`](../../commit/b134e7d)|
153
154
|**Home Assistant MQTT discovery**: auto-registers all entities under one HA device — track/status/firmware/WiFi/battery sensors, volume & LED-brightness numbers, lock & ambient-light switches, equalizer select, transport/update/shutdown buttons |[`db73db1`](../../commit/db73db1)|
154
155
| **Apple HomeKit + Siri** (`HOMEKIT_ENABLE`, via [HomeSpan](https://github.com/HomeSpan/HomeSpan)): pair the player straight into the Home app as a bridge with named tiles — **Playback** (play/pause + battery), **Volume** (brightness dimmer) and **Button-lock** — all controllable by Siri and usable in automations. State is mirrored back, so changes from buttons/RFID show up on the iPhone. Each device generates its **own random pairing code** on first boot (persisted in NVS) instead of a shared hard-coded one, so multiple ESPuinos — and everyone running this firmware — stay distinct and private. A dedicated **HomeKit settings section** shows the scannable pairing **QR code** + that setup code, a "reset pairing" button and an **on/off switch** to disable HomeKit entirely (HomeSpan then never starts, so it costs nothing at boot). HomeSpan now also comes up **lazily after boot** instead of inside `setup()`, so its multi-second start-up no longer stalls the boot LED. Pairs over the existing WiFi (no MFi chip needed); the HAP server runs on its own port and the poll task is pinned to core 0 so it never disturbs the audio pipeline on core 1 | [`6387563`](../../commit/6387563) |
155
156
|**Control tab**: Repeat / Sleep-Timer (live countdown) / Night-Mode / button-lock / FTP start-stop and a Bluetooth-mode picker (Normal / Speaker / Headphones) right in the control tab; mobile-optimised (full-width louder/quieter buttons instead of the fiddly slider) |[`88a742c`](../../commit/88a742c) · [`520815a`](../../commit/520815a) · [`d57f24a`](../../commit/d57f24a) · [`aef1765`](../../commit/aef1765)|
Copy file name to clipboardExpand all lines: html/locales/de.json
+12Lines changed: 12 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -549,6 +549,18 @@
549
549
"peerHostPlaceholder": "IP oder Hostname",
550
550
"peerHostRequired": "Bitte IP/Hostname angeben",
551
551
"noPeers": "Noch keine Peers."
552
+
},
553
+
"backup": {
554
+
"title": "Auto-Backup auf Server",
555
+
"desc": "Lädt ein vollständiges Konfigurations-Backup (Einstellungen, RFID-Zuordnungen, EQ-Regeln und Hörstatistik) auf einen Server – dasselbe Backup wie beim Export-Knopf, also per Import wiederherstellbar. Passwörter sind nie enthalten. Verwendet Benutzername/Passwort aus dem Datei-Sync-Abschnitt oben.",
Copy file name to clipboardExpand all lines: html/locales/en.json
+12Lines changed: 12 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -549,6 +549,18 @@
549
549
"peerHostPlaceholder": "IP or hostname",
550
550
"peerHostRequired": "Please enter an IP/hostname",
551
551
"noPeers": "No peers yet."
552
+
},
553
+
"backup": {
554
+
"title": "Auto-backup to server",
555
+
"desc": "Uploads a full configuration backup (settings, RFID assignments, EQ rules and listening statistics) to a server – the same backup the export button produces, so it can be restored via import. Passwords are never included. Uses the username/password from the file-sync section above.",
Copy file name to clipboardExpand all lines: html/locales/fr.json
+12Lines changed: 12 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -542,6 +542,18 @@
542
542
"peerHostPlaceholder": "IP ou nom d'hôte",
543
543
"peerHostRequired": "Veuillez saisir une IP/nom d'hôte",
544
544
"noPeers": "Aucun pair pour le moment."
545
+
},
546
+
"backup": {
547
+
"title": "Sauvegarde auto vers le serveur",
548
+
"desc": "Téléverse une sauvegarde complète de la configuration (réglages, affectations RFID, règles d'égaliseur et statistiques d'écoute) vers un serveur – la même sauvegarde que le bouton d'export, donc restaurable via l'import. Les mots de passe ne sont jamais inclus. Utilise l'identifiant/mot de passe de la section de synchronisation de fichiers ci-dessus.",
0 commit comments