From a8b259b526e2fbbb47f78d4279c88606ff949e29 Mon Sep 17 00:00:00 2001 From: Torsten Stauder Date: Fri, 26 Feb 2021 23:09:36 +0100 Subject: [PATCH] Added fileseek (not yet working), bugfix #94, restart via webgui --- README.md | 3 +- changelog.md | 1 + html/management.html | 4 +-- src/HTMLmanagement.h | 4 +-- src/logmessages.h | 1 + src/logmessages_EN.h | 1 + src/main.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++-- src/settings.h | 3 +- src/values.h | 7 +++++ 9 files changed, 85 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2661089..ebb2781 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,14 @@ * As the creator of TonUINO claims it's trademark right, my project has been renamed to ESPuino. I'm totally respecting this and have to admit that I've been not aware of that. However, I instantly renamed everything and hopefully I didn't forget any parts. Since my repository has moved, please make sure (at least if you're using git) to change the URL of your local repository. An explanation was kindly [written by user](https://github.com/biologist79/ESPuino/issues/81). * Please note: inline with the renaming of the project, MQTT-topics were changed as well as they've been including the old name. Please make sure to change your local MQTT-configuration as well. Sorry to [those](https://github.com/biologist79/ESPuino/issues/83) that spent time on this to point out. * EN: I've set up a primarily German-speaking community with much documentation. Also an international corner for non-German-speakers is available at https://forum.espuino.de. Github-Login can be used there but it's not necessary. -* DE: Ich habe ein primär deutschsprachiges Forum aufgesetzt, welches ich mit reichlich Doku versehen habe. Würde mich freuen, euch dort zu sehen: https://forum.espuino.de. Ihr könnt euch dort mit eurem Github-Login einloggen, jedoch auch "normal" anmelden. +* DE: Ich habe ein primär deutschsprachiges Forum aufgesetzt, welches ich mit reichlich Doku versehen habe. Würde mich freuen, euch dort zu sehen: https://forum.espuino.de. Ihr könnt euch dort mit eurem Github-Login einloggen, jedoch auch "normal" anmelden. Dokumenation findet ihr insbesondere hier: https://forum.espuino.de/c/dokumentation/anleitungen/10 ## Changelog Moved to [another location](changelog.md) as it became to prominent here. Only last three events are kept: * 25.02.2020: Added support for dynamic button-layout. Rotary-encoder is now optional and up to five buttons can be used. * 25.02.2020: Actions can be freely assigned to buttons (multi-button(s), single-button(s) (short), single-button(s) (long)) * 25.02.2020: Added support for webcontrol: basic control (volume, play/pause, next, previous, first, last track) can now be controlled via webgui. * 25.02.2020: Added support for .m4a and .wav-files. +* 26.02.2020: Shutdown via webgui is now available. Thanks @QDaniel for the idea + basic implementation (first three features named above)! ## Known bugs * Some webstreams don't run. Guess it's a combination of saturated connection-pool and lack of heap-memory. Works probably better if ESP32-WROVER (e.g. Lolin D32 pro) is used, as this chip has PSRAM. Advice: Don't enable modules (e.g. MQTT) if you don't need them as this could save memory (and trouble). diff --git a/changelog.md b/changelog.md index 1e6e5fa..12a4303 100644 --- a/changelog.md +++ b/changelog.md @@ -30,3 +30,4 @@ * 25.02.2020: Actions can be freely assigned to buttons (multi-button, single-button (short), single-button (long)) * 25.02.2020: Added support for webcontrol: basic control (volume, play/pause, next, previous, first, last track) can now be controlled via webgui. * 25.02.2020: Added support for .m4a and .wav-files. +* 26.02.2020: Shutdown via webgui is now available. diff --git a/html/management.html b/html/management.html index 81fbd6d..19ffd46 100644 --- a/html/management.html +++ b/html/management.html @@ -133,8 +133,8 @@ width="35" height="35" class="d-inline-block align-top" alt=""/> ESPuino - - Neustart + Neustart + Ausschalten
diff --git a/src/HTMLmanagement.h b/src/HTMLmanagement.h index 9093b9a..5fbafc0 100644 --- a/src/HTMLmanagement.h +++ b/src/HTMLmanagement.h @@ -133,8 +133,8 @@ static const char management_HTML[] PROGMEM = "\ width=\"35\" height=\"35\" class=\"d-inline-block align-top\" alt=\"\"/>\ ESPuino\ \ -\ - Neustart\ + Neustart\ + Ausschalten\ \ \
\ diff --git a/src/logmessages.h b/src/logmessages.h index dd066e0..f16a358 100644 --- a/src/logmessages.h +++ b/src/logmessages.h @@ -164,6 +164,7 @@ static const char sdMountedMmc1BitMode[] PROGMEM = "Versuche SD-Karte wird im SD static const char sdMountedSpiMode[] PROGMEM = "Versuche SD-Karte wird im SPI-Modus zu mounten..."; static const char backupRecoveryWebsite[] PROGMEM = "

Das Backup-File wird eingespielt...
Zur letzten Seite zurückkehren.

"; static const char restartWebsite[] PROGMEM = "

Der ESPuino wird neu gestartet...
Zur letzten Seite zurückkehren.

"; +static const char shutdownWebsite[] PROGMEM = "

Der ESPuino wird ausgeschaltet...

"; static const char mqttMsgReceived[] PROGMEM = "MQTT-Nachricht empfangen"; static const char trackPausedAtPos[] PROGMEM = "Titel pausiert bei Position"; static const char freeHeapWithoutFtp[] PROGMEM = "Freier Heap-Speicher vor FTP-Instanzierung"; diff --git a/src/logmessages_EN.h b/src/logmessages_EN.h index 3e38611..77f311a 100644 --- a/src/logmessages_EN.h +++ b/src/logmessages_EN.h @@ -163,6 +163,7 @@ static const char notADirectory[] PROGMEM = "Not a directory"; static const char sdMountedMmc1BitMode[] PROGMEM = "SD card mounted in SPI-mode configured..."; static const char backupRecoveryWebsite[] PROGMEM = "

Backup-file is being applied...
Back to last page.

"; static const char restartWebsite[] PROGMEM = "

ESPuino is being restarted...
Back to last page.

"; +static const char shutdownWebsite[] PROGMEM = "

Der ESPuino is being shutdown...

"; static const char mqttMsgReceived[] PROGMEM = "MQTT-message received"; static const char trackPausedAtPos[] PROGMEM = "Track paused at position"; static const char freeHeapWithoutFtp[] PROGMEM = "Free heap before FTP-allocation"; diff --git a/src/main.cpp b/src/main.cpp index 204a494..a57ea78 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -124,6 +124,8 @@ typedef struct { // Bit field bool trackFinished: 1; // If current track is finished bool playlistFinished: 1; // If whole playlist is finished uint8_t playUntilTrackNumber: 6; // Number of tracks to play after which uC goes to sleep + uint8_t currentSeekmode: 2; // If seekmode is active and if yes: forward or backwards? + uint8_t lastSeekmode: 2; // Helper to determine if seekmode was changed } playProps; playProps playProperties; @@ -456,7 +458,7 @@ void IRAM_ATTR onTimer() { recoverLastRfid = false; String lastRfidPlayed = prefsSettings.getString("lastRfid", "-1"); if (!lastRfidPlayed.compareTo("-1")) { - loggerNl(serialDebug,((char *) FPSTR(unableToRestoreLastRfidFromNVS), LOGLEVEL_INFO); + loggerNl(serialDebug,(char *) FPSTR(unableToRestoreLastRfidFromNVS), LOGLEVEL_INFO); } else { char *lastRfid = strdup(lastRfidPlayed.c_str()); xQueueSend(rfidCardQueue, &lastRfid, 0); @@ -1376,6 +1378,8 @@ void playAudio(void *parameter) { playProperties.trackFinished = false; if (playProperties.playMode == NO_PLAYLIST) { playProperties.playlistFinished = true; + //playProperties.currentSeekmode = SEEK_NORMAL; + //playProperties.lastSeekmode = SEEK_NORMAL; continue; } if (playProperties.saveLastPlayPosition) { // Don't save for AUDIOBOOK_LOOP because not necessary @@ -1681,6 +1685,27 @@ void playAudio(void *parameter) { } } + if (playProperties.currentSeekmode != playProperties.lastSeekmode) { + Serial.println(F("Seekmode has changed!")); // Todo + bool seekmodeChangeSuccessful = false; + if (playProperties.currentSeekmode == SEEK_NORMAL) { + seekmodeChangeSuccessful = audio.audioFileSeek(1); + } else if (playProperties.currentSeekmode == SEEK_FORWARDS) { + seekmodeChangeSuccessful = audio.audioFileSeek(4); + } else if (playProperties.currentSeekmode == SEEK_BACKWARDS) { + seekmodeChangeSuccessful = audio.audioFileSeek(-4); + } + + if (seekmodeChangeSuccessful) { + playProperties.lastSeekmode = playProperties.currentSeekmode; + } else { + playProperties.currentSeekmode = playProperties.lastSeekmode; + #ifdef NEOPIXEL_ENABLE + showLedError = true; + #endif + } + } + // Calculate relative position in file (for neopixel) for SD-card-mode #ifdef NEOPIXEL_ENABLE if (!playProperties.playlistFinished && playProperties.playMode != WEBSTREAM) { @@ -3088,6 +3113,28 @@ void doCmdAction(const uint16_t mod) { gotoSleep = true; break; } + case CMD_SEEK_FORWARDS: { + Serial.println(F("Seek forwards")); // todo + if (playProperties.currentSeekmode == SEEK_FORWARDS) { + playProperties.currentSeekmode = SEEK_NORMAL; + } else { + playProperties.currentSeekmode = SEEK_FORWARDS; + } + Serial.println(playProperties.currentSeekmode); + Serial.println(playProperties.lastSeekmode); + break; + } + case CMD_SEEK_BACKWARDS: { + Serial.println(F("Seek backwards")); // todo + if (playProperties.currentSeekmode == SEEK_BACKWARDS) { + playProperties.currentSeekmode = SEEK_NORMAL; + } else { + playProperties.currentSeekmode = SEEK_BACKWARDS; + } + Serial.println(playProperties.currentSeekmode); + Serial.println(playProperties.lastSeekmode); + break; + } default: { snprintf(logBuf, serialLoglength, "%s %d !", (char *) FPSTR(modificatorDoesNotExist), mod); loggerNl(serialDebug, logBuf, LOGLEVEL_ERROR); @@ -3201,14 +3248,23 @@ void accessPointStart(const char *SSID, IPAddress ip, IPAddress netmask) { wServer.on("/restart", HTTP_GET, [] (AsyncWebServerRequest *request) { #if (LANGUAGE == 1) - request->send(200, "text/html", "ESP wird neu gestartet..."); + request->send(200, "text/html", "ESPuino wird neu gestartet..."); #else - request->send(200, "text/html", "ESP is being restarted..."); + request->send(200, "text/html", "ESPuino is being restarted..."); #endif Serial.flush(); ESP.restart(); }); + wServer.on("/shutdown", HTTP_GET, [] (AsyncWebServerRequest *request) { + #if (LANGUAGE == 1) + request->send(200, "text/html", "ESPuino wird ausgeschaltet..."); + #else + request->send(200, "text/html", "ESPuino is being shutdown..."); + #endif + gotoSleep = true; + }); + // allow cors for local debug DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); wServer.begin(); @@ -3754,6 +3810,12 @@ void webserverStart(void) { ESP.restart(); }); + // ESP-shutdown + wServer.on("/shutdown", HTTP_GET, [] (AsyncWebServerRequest *request) { + request->send_P(200, "text/html", shutdownWebsite); + gotoSleep = true; + }); + // Fileexplorer (realtime) wServer.on("/explorer", HTTP_GET, explorerHandleListRequest); @@ -4352,6 +4414,8 @@ void setup() { playProperties.pausePlay = false; playProperties.trackFinished = NULL; playProperties.playlistFinished = true; + playProperties.currentSeekmode = SEEK_NORMAL; + playProperties.lastSeekmode = SEEK_NORMAL; // Examples for serialized RFID-actions that are stored in NVS // #### diff --git a/src/settings.h b/src/settings.h index 80662a5..ad91c4b 100644 --- a/src/settings.h +++ b/src/settings.h @@ -55,7 +55,8 @@ //################## BUTTON-Layout ################################## -/* Please note the following numbers as you need to know them in order to define actions for buttons. +/* German documentation: https://forum.espuino.de/t/das-dynamische-button-layout/224 + Please note the following numbers as you need to know them in order to define actions for buttons. Even if you don't use all of them, their numbers won't change 0: NEXT_BUTTON 1: PREVIOUS_BUTTON diff --git a/src/values.h b/src/values.h index 3e05894..213ea17 100644 --- a/src/values.h +++ b/src/values.h @@ -55,6 +55,8 @@ #define CMD_VOLUMEDOWN 177 // Command: lower volume by 1 #define CMD_MEASUREBATTERY 178 // Command: Measure battery-voltage #define CMD_SLEEPMODE 179 // Command: Go to deepsleep + #define CMD_SEEK_FORWARDS 180 // Command: fast forward => don't use, has no effect currently! + #define CMD_SEEK_BACKWARDS 181 // Command: wind back => don't use, has no effect currently! // Repeat-Modes #define NO_REPEAT 0 // No repeat @@ -62,4 +64,9 @@ #define PLAYLIST 2 // Repeat whole playlist (infinite loop) #define TRACK_N_PLAYLIST 3 // Repeat both (infinite loop) + // Seek-modes + #define SEEK_NORMAL 0 // Normal play + #define SEEK_FORWARDS 1 // Seek forwards + #define SEEK_BACKWARDS 2 // Seek backwards + #endif \ No newline at end of file