Browse Source

Added fileseek (not yet working), bugfix #94, restart via webgui

master
Torsten Stauder 4 years ago
parent
commit
a8b259b526
  1. 3
      README.md
  2. 1
      changelog.md
  3. 4
      html/management.html
  4. 4
      src/HTMLmanagement.h
  5. 1
      src/logmessages.h
  6. 1
      src/logmessages_EN.h
  7. 70
      src/main.cpp
  8. 3
      src/settings.h
  9. 7
      src/values.h

3
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).

1
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.

4
html/management.html

@ -133,8 +133,8 @@
width="35" height="35" class="d-inline-block align-top" alt=""/>
ESPuino
</a>
<a class="reboot float-right nav-link" href="/restart"><i class="fas fa-power-off"></i> Neustart</a>
<a class="reboot float-right nav-link" href="/restart"><i class="fas fa-redo"></i> Neustart</a>
<a class="reboot float-right nav-link" href="/shutdown"><i class="fas fa-power-off"></i> Ausschalten</a>
</div>
</nav>
<br/>

4
src/HTMLmanagement.h

@ -133,8 +133,8 @@ static const char management_HTML[] PROGMEM = "<!DOCTYPE html>\
width=\"35\" height=\"35\" class=\"d-inline-block align-top\" alt=\"\"/>\
ESPuino\
</a>\
\
<a class=\"reboot float-right nav-link\" href=\"/restart\"><i class=\"fas fa-power-off\"></i> Neustart</a>\
<a class=\"reboot float-right nav-link\" href=\"/restart\"><i class=\"fas fa-redo\"></i> Neustart</a>\
<a class=\"reboot float-right nav-link\" href=\"/shutdown\"><i class=\"fas fa-power-off\"></i> Ausschalten</a>\
</div>\
</nav>\
<br/>\

1
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 = "<p>Das Backup-File wird eingespielt...<br />Zur letzten Seite <a href=\"javascript:history.back()\">zur&uuml;ckkehren</a>.</p>";
static const char restartWebsite[] PROGMEM = "<p>Der ESPuino wird neu gestartet...<br />Zur letzten Seite <a href=\"javascript:history.back()\">zur&uuml;ckkehren</a>.</p>";
static const char shutdownWebsite[] PROGMEM = "<p>Der ESPuino wird ausgeschaltet...</p>";
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";

1
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 = "<p>Backup-file is being applied...<br />Back to <a href=\"javascript:history.back()\">last page</a>.</p>";
static const char restartWebsite[] PROGMEM = "<p>ESPuino is being restarted...<br />Back to <a href=\"javascript:history.back()\">last page</a>.</p>";
static const char shutdownWebsite[] PROGMEM = "<p>Der ESPuino is being shutdown...</p>";
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";

70
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
// #<file/folder>#<startPlayPositionInBytes>#<playmode>#<trackNumberToStartWith>

3
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

7
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
Loading…
Cancel
Save