nodeRED Dashboard

Hallo Community!

Ich bin gerade dabei für mich ein Dashboard für den ESPuino in nodeRED zu basteln und wollte mal kurz vorstellen was es so macht. Es ist noch in der „early alpha“ Phase und das Ergebnis von zwei Abenden gebastel. Des Weiteren wollte ich mal gucken ob daran interesse besteht so etwas zu veröffentlichen. Ich kann mir vorstellen, dass einige von euch einen Raspberry Pi zu hause laufen haben und vielleicht auch nodeRED für die Automatisierung verwenden. Voraussetzung sind hier nodeRED, MQTT und das nodeRED_ui

Also das frontend ist die normale NodeRED UI welche ich mit etwas css und html aufgepeppt habe. Die Icons sind eine Mischung aus FontAwesome, Angular-, und Material-Design-icons (werden alle von nodeRED unterstützt)

Das ist ein Screenshot vom Webbrowser. Auf dem Handy sind die drei Gruppen dann untereinander.

Zu den Elementen:
Das erste Panel kann zusammengeklappt werden (Dreieck oben rechts)
Status wird über den MQTT Status angezeigt, die IP auch. Wenn man auf die IP klickt/tippt gelangt man zum Webinterface von Thorsten. Das orange Logo rechts von der IP zeigt den Playmode als Icon an.

Der „Aus-Knopf“ schaltet zuerst den Neopixel auf 0 brightness und dann schickt er den ESP nach kurzem delay in den DeepSleep. Ich hatte nämlich das Problem, dass die vier weißen LEDs (oder manchmal auch nur 3) angeblieben sind wenn ich ihn schlafen geschickt habe.
Bluetooth schaltet besagtes ein (kein toggle → siehe Limitationen)
Das schloss sperrt und entsperrt die physikalischen Knöpfe / Drehencoder am ESP
Track Zeigt den laufenden Titel (Nummer) und Anzahl Gesamt Titel im Ordner an (musste ich mit regex aus der payload des State/ESPuino/Track string extrahieren (leider kein json :{} :wink:)) Wenn webradio gespielt wird, zeigt er das an, anstatt einen Track.
Der Mond schaltet die LEDs auf 2 runter und wird dann gelb wenn man drauf drückt. Wird auch gelb wenn man die LEDs selbst auf <2 stellt
Die Gauges (die Halbbögen) zeigen die LED Helligkeit und die Lautstärke an und die Schieberegler verstellen beides.

Play controls

Die oberste Reihe ist wohl selbsterklärend.
Emulate ist ein dropdown wo man Tags auswählen kann die dann virtuell an den RFID leser gehalten werden
Das gleiche gilt für das Webradio dropdown (hier habe ich einfach 12 stellige fake tags verwendet, damit ich nicht für alles eine Karte benutzen muss. Wenn man sowieso Karten für die Funktionen oder Ordner oder Radiosender hat, kann man natürlich auch die eintragen)
Tag: 555555555555 zeigt den zuletzt präsentierten RFID Tag an.

Favourites

Favourites basiert auf dem gleichen Prinzip. Hier kann man (Vorerst nur im backend) die IDs von den beliebtesten Hörbüchern, Radiosendern, Funktionen einfügen

Und so sieht es hinter den Kulissen aus:

Es basiert größtenteils (eigentlich zu 100%) auf MQTT. Vielleicht schreibt Thorsten ja noch einmal eine Doku zu den HTTP Requests, dann könnte man das auch sehr gut darüber steuern.

Daher gibt es zur Zeit noch Limitationen in Bezug auf das was man einstellen und verändern kann. Aber alles was man mit MQTT ändern und abfragen kann kann man auch mit diesem Dashboard anzeigen bzw. steuern.

Eine Sache zum Beispiel ist, dass man Bluetooth nur einschalten kann (über Emulation eines RFID Tags, welches ich vorher in der WEB UI zugeordnet habe), aber nicht wieder aus. Das liegt daran, dass der ESP im BLE Modus nicht mehr über das Wifi erreichbar ist (möglich wäre es auf dem ESP generell beides parallel laufen zu lassen), aber wenn ich Thorsten richtig verstanden habe stehen nicht genug Ressourcen zur Verfügung)

Eine weitere Limitation sind meine Programmierkenntnisse :sweat_smile: Die bestehen größtenteils aus dem was ich in der Uni mal gelernt habe, einem Bisschen selbst beigebrachtem (aus der Zeit als PHP4 gerade modern war) und viel gegoogle und copy und paste von stackoverflow et al.

Also, falls Jemand das benutzen möchte, kann ich das gerne als Open Source Projekt einrichten bzw. hier zur Verfügung stellen.

Beste grüße,
haukino

Torsten bitte :joy:
Cool, gefällt mir. Ein paar Punkte möchte ich aufgreifen:

a) Den Websocket habe ich bisher gar nicht groß als Schnittstelle gesehen, über die man auch von extern kommunizieren möchte. Bringt dir das denn einen großen Vorteil, dort irgendwelche Einstellungen machen zu können? Also um welche Einstellung konkret geht es dir? Also bei MQTT habe ich mir echt viel Arbeit gemacht, so dass man da von außen super viel parametrieren kann. Was hier kürzlich noch genannt wurde ist die Ausgabe des aktuellen Playmodus. Das werde ich noch einbauen.

b) Ob BT und WLAN nicht gleichzeitig gehen kann ich dir ehrlich gesagt gar nicht sagen. Ich habe die BT-Lib ich sage mal „angekarrt“ und sie hat auch funktioniert, aber final in meinen Code integriert haben das @Harry und @elmar-ops. Grundsätzlich muss man an der Stelle aber auch schauen, dass man mit dem Ram auskommt, den man hat und muss da sicher auch in Sachen Heap-Fragmentierung aufpassen. Ich selbst habe dazu keine Tests mehr gemacht, weil ich das einfach gar nicht mehr alles zeitlich schaffe :woman_shrugging:
c) Den Neopixel abdimmen zuvor ist ein guter Punkt. Ich habe den Effekt auch schon gesehen, wenn ich keine Mosfet-Abschaltung eingesetzt habe. Das werde ich in meinen Master mal inkludieren; ist ja ziemlich einfach und macht total Sinn.

Cool :+1:

Hey, Danke für das Feedback.

Über die Arbeit die du hier reingesteckt hast staune ich jedes Mal. Sollte auch gar nicht negativ gemeint sein. Es ist halt nur das möglich was über mqtt übermittelt bzw empfangen werden kann. Ich hatte schon mal bevor ich den ESP zum Audioplayer gebaut habe, mit der mqtt library rumgespielt, aber ich traue mir (noch) nicht zu, in deinem Code sowas einzubauen (z.b. id3 tags über mqtt als json objekt)

Ich hatte ausserdem gedacht, dass man damit dann auf das Filesystem zugreifen könnte. Ich dachte zuerst nur um alle die Dinge die in der WEB UI auch möglich sind einzustellen.
Dann hätte man ja in nodeRED quasi ALLE Möglichkeiten offen.

Zum Beispiel eine Liste der Webradiostations die man dort ablegen könnte.
Favoritenverwaltung
Integration über Telegram
etc.

Kann man NodeRed auch als Standaloneapplikation laufen lassen?
Ich hatte das bisher nur als integrtion mit IOBroker gesehen.

Wie sollten die id3 Tags als Json Objekt aussehen? Die wären ja nur bei mp3 da.
Beispiel:

{
  "Titel": "A Whiter Shade Of Pale",
  "Interpret": Doro,
  "Album": false,
  "Kommentar": null,
  "Datum": 1995,
  "Tracknummer": 2,
  "Genre": false
}

bräuchte man die alle oder reicht ein kleinerer Teil?
Wenn das über die Lib abgefragt werden kann, (hab da aber noch gar nicht reingesehen), sollte das kein großes Problem sein, das als MQTT-Topic zu schicken.

Wenn ihr mal in die main.cpp geht dann scrollt ihr mal gaaaanz nach unten. Da seht ihr Methoden, die von der Schreibaul-Lib aufgerufen werden. D.h. dort wird das Logging gemacht, das ihr in der Konsole seht. Anders ausgededrückt: Der ESPuino weiß von dem ganzen Output eigentlich gar nix, sondern das sind quasi einfach nur Wrapper-Methoden. D.h. der ESPuino ruft diese Methoden nicht selbst auf, sondern sie werden automatisch „aus dem Inneren“ aufgerufen.

Wenn ihr da MQTT drinhaben wollt, dann könnt ihr die Methoden einfach um MQTT erweitern. So dass ein Output x nicht nur im Serial-Logging landet, sondern auch in MQTT. Fertig :slight_smile: Ich weiß nur nicht, wie es mit richtig langen Strings aussieht.

Warum Wifi und Bluetooth gleichzeitig Probleme machen kann habe ich versucht hier zu beschreiben.
Prinzipiell läuft es parallel und vielleicht verbraucht MQTT nicht zu viele Resourcen. Leider kann ich das hier nicht ausprobieren.
@haukino: wenn du Bluetooth und MQTT gleichzeitig mal ausprobieren willst, dann pack mal den wifiManager() und das MQTT handling aus dem operationMode Abfrageblock in setup() und loop() raus.
Zu meiner Schande muss ich gestehen, dass ich noch keinen MQTT Broker habe, um das zu testen. Aber deine nodeRED Implementierung hat mir Lust darauf gemacht :slight_smile:

Eieiei, sorry :sweat_smile:

Das wäre cool, wenn man zumindest wieder aus dem BT Modus herauskäme. Denn wenn man im Bluetooth Modus ist, steuert man das ja sowieso über das Handy (Bzw den Sender). Mit A2DP-SRC sähe das natürlich wieder anders aus. Wäre auch interessant, da ich mit nodeRED meine Bluetooth Boxen (UE Boom) über den Raspberry direkt (mit rfcomm) anschalten kann.

Könnte man den ESP auch per MQTT wieder aus dem DeepSleep holen, oder braucht man dafür einen physikalischen Button? Davon abgesehen schaltet meine Powerbank sowieso ab wegen zu wenig Stromverbrauch aber das ist ein anderes Thema um das ich mich noch kümmern muss.

Ja, kann man. So war es eigentlich auch gedacht als es entwickelt wurde. Es steht auf NodeJS und braucht den npm. Damit lassen sich auch die ganzen extra nodes installieren.

Title, Artist, Album würde mir sogar schon reichen. Die Track# kommt ja aus dem Ordner und muss nicht immer übereinstimmen mit den Id3 Tags denn manchmal lösche ich auch die Intros und Anfangslieder raus.
Aber mehr schadet sicher auch nicht. MQTT ist so ein schlankes Protokoll, da fallen ein paar mehr Daten bestimmt nicht ins Gewicht. Oder ist der ESP dann zu beschäftigt?

@Harry Ich hab zwar keine Ahnung ob ich das hinbekomme, aber ausprobieren kann ich es mal.
Man muss ja nicht gleich einen kompletten Server dafür einrichten. Es gibt auch einen Windows Service (Mosquitto) mit dem das läuft und dann als Klienten sind mosquitto_pub und mosquitto_sub dabei, die über die Kommandozeile ganz einfach zu bedienen sind. So habe ich auch angefangen.

Ist in anderer Form einfach möglich.
wie Torsten beschrieb gibt es einen Aufruf aus der Lib am Ende der Main.

void audio_id3data(const char *info) {  //id3 metadata
    snprintf(logBuf, serialLoglength, "id3data     : %s", info);
    loggerNl(serialDebug, logBuf, LOGLEVEL_INFO);

// die Zeilen einfügen 

#ifdef MQTT_ENABLE
    publishMqtt((char *)FPSTR(topicTrackID3State), logBuf, false);
#endif
}

und in settings.h

static const char topicTrackID3State[] PROGMEM = "State/ESPuino/ID3";

einfügen.
Unter dem topic kann dann
id3data : Media: DIG
id3data : Length (ms): 193018
id3data : Title: Tenderness
id3data : Artist: Steppenwolf
id3data : Album: 16 Greatest Hits
id3data : Track: 15
id3data : ContentType: (17)
empfangen werden.
Mehr Aufwand wäre den logBuf in einen json String zu wandeln.

Also wenn alle Werte einzeln rübergeschippert kommen, dann ist es ja garkein Problem und JSON dann garnicht notwendig. Es ging nur darum, dass bei dem Track alle drei Informationen in einem String waren die man mit regex ersteinmal auseinanderpfriemeln musste. Und fließend spreche ich auch kein regex :stuck_out_tongue_winking_eye: deswegen hat es schon etwas gedauert bis ich den richtigen $match hatte.

$match(msg.payload, /([\d]*)\/([\d]*)/ ,1).groups

Eigentlich ganz einfach … (wenn man weiß was man tut :smile:)

Build error

Ich glaube zwar nicht, dass das etwas damit zu tun hat, aber ich bekomme immer den folgenden Fehler beim builden:

src/main.cpp:4281:42: error: 'sdMountedSpiMode' was not declared in this scope
 loggerNl(serialDebug, (char *) FPSTR(sdMountedSpiMode), LOGLEVEL_NOTICE);

vor zwei Tagen ging noch alles einwandfrei :exploding_head:

Obiges hat sich geklärt.

Ich hab’s mal versucht mit dem code, @gmbo:

Aber auf dem topic State/ESPuino/ID3 empfange ich nur:

State/ESPuino/ID3 eof_mp3     : Brain_Trust.mp3

am Ende des Liedes.

OK, Wenn man’s richti macht funktioniert’s auch :man_facepalming:

hatte es unter der eof funktion eingetragen :roll_eyes:

Aber schön, dass es jetzt klappt.

Hab es gleich mal testweise auch für den webstream reingetan. Funktioniert wunderbar :grinning:

Es klappt ganz gut:

Über MQTT kommt:

geht durch nodeRED:

und landet im Dashboard:

Screenclip_3

Natürlich ist man darauf angewiesen, dass die Streams die Daten auch schicken. Bei meinen Tests habe ich zum Beispiel gefunden, dass Bremen 4 einfach nur „Bremen 4“ als streamtitle schickt.

Na das war doch mal eine Anpassung, die einfach zu bewerkstelligen war, oder? :smiley:
Hast du jetzt nur in audio_id3data() was reingeschrieben oder woanders auch? Frage nur, weil das könnte ich natürlich auch einfach in meinem Master-Branch bereitstellen.

ja nech…

erstmal nur unter:
// Some mp3-lib-stuff (slightly changed from default

Obwohl es dort auch nicht überall sinnvoll ist. Z.B. das EOF bei einem track bekommt man ja sowieso ausgegeben.