RFC: Migration zu neuer Weboberfläche

Der PR ist ja schin länger offen und wurde durch die Review geschickt, Danke an @SZenglein !
Einige Kleinigkeiten habe ich noch korrigiert, z.B.wird jetzt auch die WLAN-Liste beim Laden der Webseite über das Websocket gefüllt, konsistent zum Laden der Einstellungen.

Habe Alles getestet soweit es geht & würde das die nächsten Tage in den DEV-Branch übernehmen…

2 „Gefällt mir“

Als letztes habe ich mir den „/info“ Endpunkt vorgeknöpft um die Trennung von Frontend/Backend weiter voranzutreiben.
Dazu liefert „/info“ jetzt nur noch die Werte als Application/JSON zurück und die Ausgabe/Formatierung wird im dann Frontend gemacht.
Damit verschiebt sich auch die Sprachumschaltung konsequent ins Frontend. Analog zum /settings Endpunkt kann man sich alle Informationen zurückgeben lassen oder nur einen einzelnen Bereich wie „battery“ oder „memory“ z.B. mit dem Aufruf http://espuino.local/info?section=battery

Wer möchte kann hier nochmal drüberschauen:

So sieht das /info-JSON dann aus:

{
   "software":{
      "version":"Software-revision: 20230804-1",
      "git":"Git-revision: 5f09f28-dirty",
      "arduino":"2.0.9",
      "idf":"v4.4.4"
   },
   "hardware":{
      "model":"ESP32-D0WD-V3",
      "revision":3,
      "freq":240
   },
   "memory":{
      "freeHeap":74144,
      "largestFreeBlock":3407860,
      "freePSRam":3478599
   },
   "wifi":{
      "ip":"192.168.1.55",
      "rssi":-67
   },
   "audio":{
      "playtimeTotal":35106000,
      "playtimeSinceStart":462000
   },
   "battery":{
      "currVoltage":3.938959122,
      "chargeLevel":77.03112793
   }
}

Das Infofenster bleibt nach der Änderung nahezu gleich:

2 „Gefällt mir“

Ist geplant dass über so einen Endpoint auch den Inhalt der backup.txt auszulesen um die im Frontend zu bearbeiten? Ich weiß, dass das schonmal irgendwo angesprochen wurde ich weiß nur nicht mehr in welchem Thread.

Es ist bereits möglich, Dateien von der SD-Karte zu laden und schreiben, daher kannst du das manuell ja schon. Ein Editor für die backup.txt direkt im Frontend ist wohl eher nicht geplant.

Ich überlegte das selbst hinzuzufügen. Die Frage zielte eher dahin ob eine Schnittstelle zum auslesen der RFIDs geplant ist. Dann müsste es nur im Frontend integriert werden.

Das war wohl dieser Thread:

Die Backup.txt kann man mit rechter Maustaste „Download“ oder diesem Befehl laden:
http://espuino.local/explorerdownload?path=/backup.txt

Die kann dann mit einem Texteditor bearbeitet und evt. wieder eingespielt werden.
@chrischan Zu welchem Zweck willst Du eine extra RFID-Bearbeitung in der Weboberfläche einbauen?
Weil das manuelle Triggern von Aktionen ist ja jetzt schon möglich.

1 „Gefällt mir“

Um evtl vorhandene Relikte entfernen zu können. Ich habe eine Box die mein Patenkind bekommt. Damit auch dessen Eltern das machen können ohne die Frustrationsgrenze zu suchen. Ich weiß nicht wie speicherintensiv lange Zuordnungslisten bei der Verarbeitung von aufgelegten Karten ist. Mein Gedanke war es nicht unnötig lang werden zu lassen.

Mit dem letzten Commit ist der „/restart“ & „/shutdown“ Endpunkt nun von GET auf POST geändert. Die bestehenden Endpunkte sollten nun einheitlich sein…

Aus meiner Sicht sind die unterschiedlichen Startmethoden des Webservers im Accesspoint / Management Modus jetzt überflüssig. ich meine Web_Init() und webserverStart()
Die derzeit getrennten Accesspoint / Management Seiten könnten doch über die gleichen Methoden von webserverStart() laufen. Nur beim Ausliefern der Index.html Datei müsste man im Moment noch unterscheiden. Damit würde einiges an redundanten Code rausfliegen (Also komplett Web_Init()).
Was meint Ihr dazu?

Es fehlt noch komplett ein Endpunkt zum Lesen/Schreiben/Modifikation von RFID-Tags. Das wird bisher über das Websocket mit „rfidAssign“ und „rfidMod“ hier und hier gemacht. Gibt es Vorschläge wie man das zusätzlich mit HTTP-Endpunkt(en) umsetzt?

Wenn wir sowas haben könnte auch die bestehende Web-UI profitieren: Beim Auflegen einer bereits zugewiesenen Karte könnte die gespeicherte Zuweisung wieder angezeigt werden (URL & Modus bzw. Modifikation wird vorausgefüllt wie jetzt das RFID-Feld)

Eine Auflistung aller im NVS gespeicherten Tags scheint mit Arduino-Preferences gar nicht möglich?

Edit: Das wäre mein Vorschlag für die Vereinheitlichung vom accesspoint/management im Webserver:

Ich glaube, bei der Migration ist ein wenig was kaputt gegangen - zumindest wird bei mir im Dev-Branch die Option initBrightness bzw. nightBrightness zwar korrekt gespeichert und geladen - aber dann nicht verwendet, sondern immer nur der Default-Wert von 16.
Scheint mir auf den ersten Blick daran zu liegen, dass in der Web.cpp das ganze mit gPrefsSettings.putUInt()/gPrefsSettings.getUInt() gespeichert/geladen wird aber in der Led.cpp mit gPrefsSettings.getUChar() geladen wird.

2 „Gefällt mir“

@kkF Danke für Deinen Bugreport!
Das muss natürlich einheitlich sein, verstehe aber nicht ganz warum der Integer-Wert zuvor als UChar gespeichert wurde, UInt wäre doch logischer, also Fix in Led.cpp?

UChar braucht nur 1 Byte
Uint min. 2 wenn nicht sogar 4

grenzenlose Speicherverschwendung :wink:

2 „Gefällt mir“

Hab’s gefixt (mit UChar) kann es aber mit Hardware erst am Wochenende testen.

1 „Gefällt mir“

Es fehlt ja noch ein Endpunkt zum Lesen/Schreiben der RFID-Zuweisungen. Bislang können Zuweisungen nur über das Socket mit „rfidAssign“ und „rfidMod“ gesetzt werden.

Dazu habe ich mal einen neuen HTTP-Endpunkt /rfid implementiert & möchte das erstmal zur Diskussion stellen:

  • GET ohne Parameter liefert alle Zuweisungen als JSON-Array zurück.
  • GET/rfid/12345678 oder /rfid?id=12345678 liefert die Zuweisung eines einzelnen Tags zurück
  • POST mit JSON-Daten speichert eine neue Zuweisung im NVS
  • DELETE löscht eine Zuweisung im NVS
  • Abspiel- & Modifikationskarten laufen über den gleichen Endpunkt und unterscheiden sich nur durch „modId“/„playMode“

Hier mal JSON-Beispiele aus meinem schon lauffähigen Code:

[
    {
        "id": "003108198106",
        "modId": 130
    },
    {
        "id": "064170251048",
        "fileOrUrl": "/Rabe Socke - Alles gefunden",
        "playMode": 2,
        "lastPlayPos": 195721,
        "trackLastPlayed": 6
    },
    {
        "id": "086114072041",
        "fileOrUrl": "/2 kleine Wölfe",
        "playMode": 4,
        "lastPlayPos": 217348,
        "trackLastPlayed": 2
    },
    {
        "id": "121240148153",
        "modId": 152
    }
]

Einzelnes Tag lesen mit http://espuino.local/rfid?id=064170251048 oder http://espuino.local/rfid/064170251048 :

{
    "id": "064170251048",
    "fileOrUrl": "/Rabe Socke - Alles gefunden",
    "playMode": 2,
    "lastPlayPos": 195721,
    "trackLastPlayed": 6
}

Konkret könnten wir den neuen Endpunkt zum Auflisten und evt. auch Bearbeiten/Löschen der Zuweisungen in der bestehenden Weboberfläche verwenden.
Was meint Ihr dazu?

5 „Gefällt mir“

Gefällt mir gut. Ich überlege nur, ob’s sinniger wäre, sowas wie playMode oder modId zu übersetzen beim GET. Also dass man da die Strings stehen hat und nicht die Integer. Wobei wenn man das macht, dann muss man es in die andere Richtung vermutlich auch akzeptieren.

playMode (1-12) bzw. modID (>=100) sindt klar definiert und lassen sich schlanker als Integer übertragen. Für die Darstellung im Frontend wird dann natürlich der (lokalisierte) Bezeichner angezeigt, z.B. „Hörbuch endlos“. Die Sprache wird ja im Frontend eingestellt.

2 „Gefällt mir“

Die /rfid Erweiterung habe mal zur Review eingereicht:

Schaut mal drüber, Frontend wird nachgereicht, könnte dann etwa so aussehem:

Etwas Feinarbeit ist noch notwendig…

2 „Gefällt mir“

cool das das (bald) über eine API möglich ist, gefällt mir.

Mal gucken vlt. baue ich mal eine Desktop App die das dann alles aus der Ferne ändern kann (und backup machen und…)

Für die Auflistung der RFID-Tags (/rfid GET) hatte ich zunächst die vorhandene Funktion Web_DumpNvsToSd() verwendet. Also zunächst die Tags in Datei „_backup.txt“ speichern und von dort einlesen & als JSON zurückgeben.
Das war schnell gemacht aber hat auch Nachteile: Der SD-Schreib-/Lesezugriff kann zu kurzem Audioruckeln führen und wenn man keine SD-Karte verwendet klappte die Auflistung nicht.

Habe den PR korrigiert: Die Tags werden jetzt direkt aus dem NVS ins JSON geschrieben . Dazu wirft die Funktion listNVSKeys() für jeden NVS-Key/Tag ein Callback-Event. Im jeweiligen Callback wird dann entweder in die Datei oder ins JSON-Array geschrieben.

3 „Gefällt mir“

Hast du dir Gedanken um die Speichergröße des JSON gemacht, wenn sehr viele RFID zugewiesen sind? Eventuell kann man die Eintrage streamen, statt erst alles in ein großes Array zu schreiben. AsyncWebServer bietet da glaube ich was in der Richtung.

Das mischen von nvs funktionen und preferences finde ich verwirrend, aber geht wohl nicht anders.

@SZenglein Du hast in beiden Punkten absolut recht:
Die Anzahl der gespeicherten Karten kann nicht genau vorhergesagt werden, es können auch über 100 sein. Wenn man von durchschnittlich 128 Bytes ausgeht, ist bei 80 Einträgen Schluss. Ein Streaming des JSON wäre schön. Das könnte in unserem Fall machbar sein, eventuell auch für die Verzeichnisauflistung. Wenn in einem Verzeichnis sehr viele Dateien / Ordner oder auch lange Dateinamen sind, könnte es auch hier zu einem Absturz kommen. Das habe ich zu dem Thema gefunden:

Wg. Mischung von NVS Funktion in web.cpp. Habe die vorhandene Funktion nur um ein Callback erweitert aber stimme zu das die dort eigentlich nicht reingehört. Verschieben nach z.B. nach… Tja wohin?