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 7b8e303
Browse filesBrowse the repository at this point in the historyBrowse files
feat: RFID learn via explorer context menu (scan-after-select) + document virtual cards
After reverting the misguided web-generate/-trigger approach, implement the
intuitive learn flow the way the existing feature is meant to be used:
- Context menu 'RFID anlernen' -> pick a play mode -> the NEXT card laid on the
reader is assigned to that path (armRfidLearn/completeRfidLearn, 60s timeout).
Works with physical cards and the existing virtual cards (CMD_VIRTUAL_RFID_CARD_*
-> ids 900000000001..010) alike; no tab switch / submit. Remove-assignment entry
kept. i18n de/en/fr.
- README: new 'Virtual RFID cards' section documenting the existing (upstream)
CMD_VIRTUAL_RFID_CARD_* mechanism and how to learn cards from the file browser.
Verified on the test device via Playwright: arm learn -> fire CMD_VIRTUAL_RFID_CARD_01
(lays 900000000001) -> assignment saved with correct path/mode + badge -> cleaned up,
no console errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+23-1Lines changed: 23 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -135,7 +135,7 @@ neon logo that doubles as the SVG favicon ([`7be5254`](../../commit/7be5254)):
135
135
| **HTTP file sync**: pull audio files from a web server (e.g. nginx) onto the SD card. A new **Sync** settings sub-tab takes a manifest URL plus optional HTTP Basic Auth (user/password); the device fetches a JSON manifest (`{"files":[{"path","size"},…]}`) and downloads every listed file that is missing locally or differs in size, streaming each in small chunks straight to SD. Additive only (never deletes), runs in a background task, and shows live progress including the file currently being downloaded plus a stop button to cancel a running sync. The **Sync** settings sub-tab holds the config (manifest URL + Basic Auth) and documents the manifest format/nginx setup; the actual run button and live progress live in the **Tools** tab, with a shortcut button in the Sync sub-tab that jumps there. If audio is playing when a sync starts, playback is paused for the SD-writing phase and resumes automatically when the sync finishes; pressing play (or skipping a track) cancels the running sync and resumes playback immediately. Any button press (or triggered command) also aborts a running sync — toggleable in the Sync settings sub-tab (default on). Reloading the web UI reconnects to a sync still running in the background instead of showing an idle state. A stalled download (connection open but no data for 20 s) is aborted and marked failed so one bad/slow file can't hang the whole sync. While a sync runs the NeoPixel indicator LEDs light solid blue (a single transmission while the LED task is paused, so there is no repeated refresh to starve WiFi/TLS). A running sync also keeps the device awake: since the sync runs in a background task and pauses playback, it no longer refreshes the activity timer on its own, so the inactivity timeout / sleep-timer is suppressed while a sync is in progress — preventing the device from going to deep-sleep mid-transfer (which would tear down the SD card and abort the sync); the timer resumes normally once the sync finishes | [`ac24bbc`](../../commit/ac24bbc) |
136
136
|**Fully offline web interface**: all third-party libraries (jQuery, jQuery-UI, Bootstrap JS/CSS, jstree + themes, bootstrap-slider, Font Awesome + webfonts, i18next) and the Orbitron/Rajdhani/Share Tech Mono fonts are now vendored and served gzipped from the device instead of public CDNs. This fixes the ~2-minute first-load hang with empty (untranslated) text after a cold boot/flash, and makes the management UI work without any internet access (incl. AP mode). `processHtml.py` embeds the assets into flash (build size grows accordingly) and now derives unique header symbol names from the full asset path. The libs are concatenated into a single JS and a single CSS bundle (`tools/bundle_assets.py`) so the page makes only a handful of requests — many parallel requests to the ESP32's async web server made some browsers (Safari/Chrome) stall for minutes while Firefox coped |[`c618191`](../../commit/c618191)|
137
137
|**M3U playlist builder**: a "Create playlist" button in the Files tab opens a two-pane builder — browse the SD card on the left, an ordered (drag-to-reorder) track list on the right — to assemble an `.m3u` from SD files, whole folders, and webradio URLs (which `LOCAL_M3U` plays interchangeably). Saving writes `/Playlists/<name>.m3u` via a new `POST /playlist` endpoint; the file can then be assigned to an RFID tag with play mode 11. i18n de/en/fr |[`af041fc`](../../commit/af041fc)|
138
-
|**File browser: assignment badges + context-menu RFID learn**: in the Files-tab tree each row is badged (right-aligned, after the name) when that exact path has an **RFID tag** assigned (tag icon) and/or a **per-path EQ rule** (sliders icon), so you can see at a glance what is mapped where. The explorer **context menu**now also learns/removes RFID assignments directly: place a card (its id fills the field), then right-click a file/folder → **RFID** → pick a play mode to assign it to that card on the spot (no tab switch / submit), or **remove** an existing assignment. Mirrors the existing EQ-profile submenu. Badges refresh when a folder is (re)opened and live after assigning/removing. i18n de/en/fr |[`PENDING`](../../commit/PENDING)|
138
+
|**File browser: assignment badges + context-menu RFID learn (scan-after-select)**: in the Files-tab tree each row is badged (right-aligned, after the name) when that exact path has an **RFID tag** assigned (tag icon) and/or a **per-path EQ rule** (sliders icon), so you can see at a glance what is mapped where. The explorer **context menu** learns/removes RFID assignments directly: right-click a file/folder → **RFID anlernen** → pick a play mode, then **lay the card** — the next scanned card is assigned to that path (no tab switch / submit); or **remove** an existing assignment. Mirrors the existing EQ-profile submenu. Works with physical cards and the [virtual cards](#virtual-rfid-cards) (`CMD_VIRTUAL_RFID_CARD_*`) alike. Badges refresh when a folder is (re)opened and live after assigning/removing. i18n de/en/fr |[`PENDING`](../../commit/PENDING)|
139
139
|**OpenAPI/Swagger spec updated**: the bundled `REST_API.yaml` (served at `/swagger.html`) now documents all fork-added endpoints (`/sync`, `/syncstop`, `/playlist`, `/githubupdate`, `/version`, `/login`, `/logout`, `/security`, `/eqrule(s)`, `/activeequalizer`, `/bluetooth*`, `/sdclean`) and declares the security schemes (`X-API-Key` header / `apikey` query param, or the `ESPUINO_SESSION` login cookie) so the Swagger "Authorize" button works. The web-interface footer links to the Swagger UI (`/swagger.html`) |[`f8298d9`](../../commit/f8298d9)|
140
140
141
141
#### Feature highlights
@@ -200,6 +200,28 @@ neon logo that doubles as the SVG favicon ([`7be5254`](../../commit/7be5254)):
200
200
| Support for a 6th button |[`b116151`](../../commit/b116151)|
201
201
| OLED display support (SH1106/SSD1306 128×64 over I2C): boot splash, idle screen with IP + READY, now-playing title (up to 3 lines, scrolling) with battery/time/wifi status bar, and a volume bar |[`8ce8104`](../../commit/8ce8104)|
202
202
203
+
### Virtual RFID cards
204
+
205
+
This is an existing ESPuino feature (not a fork addition) that is easy to miss, so it is documented
206
+
here for clarity. Action-to-button assignment in general works as described in the upstream
207
+
*"dynamic button layout"* documentation.
208
+
209
+
**Normal card.** A physical RFID card has a fixed, pre-programmed number. When the card is placed on
210
+
the reader the ESP32 reads that number (it is also pushed into the web interface). You then *learn*
211
+
the card — i.e. you link its number to an action. The next time the card is placed, the ESP32 looks
212
+
up that mapping in its flash and runs the matching action.
213
+
214
+
**Virtual card.** You bind a button press (short or long) or a two-button combination to an action
215
+
in `settings.h` as usual — but the actions `CMD_VIRTUAL_RFID_CARD_01` … `CMD_VIRTUAL_RFID_CARD_10`
216
+
are special: they *simulate placing a card*. Running `CMD_VIRTUAL_RFID_CARD_01` is exactly the same
217
+
as placing a physical card with the number `900000000001` (…`_10` → `900000000010`). You learn that
218
+
number in the web interface like any normal card, and pressing the bound button then has the same
219
+
effect as placing that card. The fixed ids live in [`src/values.h`](src/values.h) and are enqueued
220
+
in [`src/Cmd.cpp`](src/Cmd.cpp). MQTT can lay the same ids via the `rfid` command topic.
221
+
222
+
> Tip: to learn a (physical or virtual) card to a file/folder, right-click it in the file browser →
223
+
> **RFID anlernen** → pick a play mode, then lay the card (or press the button bound to its virtual id).
0 commit comments