From 6fee1a61d22591c94ecc86681e236932623dd6e4 Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Sun, 8 Jan 2023 16:28:39 +0100 Subject: [PATCH 01/15] feature tts as playmode and button-action --- html/management_DE.html | 61 ++++++++++++++++++++++++++++++++++++- html/management_EN.html | 61 ++++++++++++++++++++++++++++++++++++- src/AudioPlayer.cpp | 66 ++++++++++++++++++++++++++++++++++++++--- src/AudioPlayer.h | 1 + src/Cmd.cpp | 16 ++++++++++ src/Web.cpp | 2 ++ src/values.h | 2 ++ 7 files changed, 203 insertions(+), 6 deletions(-) diff --git a/html/management_DE.html b/html/management_DE.html index 1c76da63..d144df66 100644 --- a/html/management_DE.html +++ b/html/management_DE.html @@ -228,6 +228,39 @@ Aktueller Titel
+
+ Command Control + + +
+ @@ -318,6 +352,7 @@ + @@ -464,6 +499,18 @@
+
+
+ Custom Text + + + +
+ Bitte Custom-Text eintragen. +
+
+
+
@@ -1209,7 +1256,8 @@ vWarning: document.getElementById('warningLowVoltage').value, vIndLow: document.getElementById('voltageIndicatorLow').value, vIndHi: document.getElementById('voltageIndicatorHigh').value, - vInt: document.getElementById('voltageCheckInterval').value + vInt: document.getElementById('voltageCheckInterval').value, + vCustText: document.getElementById('customText').value } }; var myJSON = JSON.stringify(myObj); @@ -1310,6 +1358,17 @@ var myJSON = JSON.stringify(myObj); socket.send(myJSON); } + + function executeCommand() { + var myObj = { + "controls": { + action: document.getElementById('commandId').value + } + }; + var myJSON = JSON.stringify(myObj); + socket.send(myJSON); + } + function sendVolume(vol) { var myObj = { "controls": { diff --git a/html/management_EN.html b/html/management_EN.html index 8670019b..e3d80205 100644 --- a/html/management_EN.html +++ b/html/management_EN.html @@ -228,6 +228,39 @@ Current track
+
+ Command Control + + +
+ @@ -317,6 +351,7 @@ + @@ -463,6 +498,18 @@
+
+
+ Custom Text + + + +
+ Please enter custom-text. +
+
+
+
@@ -1208,7 +1255,8 @@ vWarning: document.getElementById('warningLowVoltage').value, vIndLow: document.getElementById('voltageIndicatorLow').value, vIndHi: document.getElementById('voltageIndicatorHigh').value, - vInt: document.getElementById('voltageCheckInterval').value + vInt: document.getElementById('voltageCheckInterval').value, + vCustText: document.getElementById('customText').value } }; var myJSON = JSON.stringify(myObj); @@ -1309,6 +1357,17 @@ var myJSON = JSON.stringify(myObj); socket.send(myJSON); } + + function executeCommand() { + var myObj = { + "controls": { + action: document.getElementById('commandId').value + } + }; + var myJSON = JSON.stringify(myObj); + socket.send(myJSON); + } + function sendVolume(vol) { var myObj = { "controls": { diff --git a/src/AudioPlayer.cpp b/src/AudioPlayer.cpp index 3429a7a5..2bf6d161 100644 --- a/src/AudioPlayer.cpp +++ b/src/AudioPlayer.cpp @@ -43,6 +43,7 @@ static uint8_t AudioPlayer_InitVolume = AUDIOPLAYER_VOLUME_INIT; static void AudioPlayer_Task(void *parameter); static void AudioPlayer_HeadphoneVolumeManager(void); static char **AudioPlayer_ReturnPlaylistFromWebstream(const char *_webUrl); +static char **AutioPlayer_ReturnPlaylistFromTextToSpeech(const char *_textToInsert); static int AudioPlayer_ArrSortHelper(const void *a, const void *b); static void AudioPlayer_SortPlaylist(const char **arr, int n); static void AudioPlayer_SortPlaylist(char *str[], const uint32_t count); @@ -624,6 +625,12 @@ void AudioPlayer_Task(void *parameter) { if (gPlayProperties.playMode == WEBSTREAM || (gPlayProperties.playMode == LOCAL_M3U && gPlayProperties.isWebstream)) { // Webstream audioReturnCode = audio->connecttohost(*(gPlayProperties.playlist + gPlayProperties.currentTrackNumber)); gPlayProperties.playlistFinished = false; + } else if (gPlayProperties.playMode == TEXT_TO_SPEECH) { + audioReturnCode = true; // is handled later + gPlayProperties.tellCustomText = true; + gPlayProperties.currentSpeechActive = true; + gPlayProperties.lastSpeechActive = true; + gPlayProperties.playlistFinished = false; } else if (gPlayProperties.playMode != WEBSTREAM && !gPlayProperties.isWebstream) { // Files from SD if (!gFSystem.exists(*(gPlayProperties.playlist + gPlayProperties.currentTrackNumber))) { // Check first if file/folder exists @@ -657,6 +664,8 @@ void AudioPlayer_Task(void *parameter) { } else { Audio_setTitle("Webradio"); } + } else if (gPlayProperties.tellCustomText) { + Audio_setTitle("Text To Speech"); } else { if (gPlayProperties.numberOfTracks > 1) { Audio_setTitle("(%u/%u): %s", gPlayProperties.currentTrackNumber+1, gPlayProperties.numberOfTracks, *(gPlayProperties.playlist + gPlayProperties.currentTrackNumber)); @@ -719,10 +728,32 @@ void AudioPlayer_Task(void *parameter) { } } + // Handle custom text + if (gPlayProperties.tellCustomText) { + gPlayProperties.tellCustomText = false; + bool speechOk; + String customText = ""; + if (gPlayProperties.playMode == TEXT_TO_SPEECH){ + customText = *(gPlayProperties.playlist); + } else { + customText = gPrefsSettings.getString("customText", ""); + } + #if (LANGUAGE == DE) + speechOk = audio->connecttospeech(customText.c_str(), "de"); + #else + speechOk = audio->connecttospeech(customText.c_str(), "en"); + #endif + if (!speechOk) { + System_IndicateError(); + } + } + // If speech is over, go back to predefined state if (!gPlayProperties.currentSpeechActive && gPlayProperties.lastSpeechActive) { gPlayProperties.lastSpeechActive = false; - if (gPlayProperties.playMode != NO_PLAYLIST) { + if (gPlayProperties.playMode == TEXT_TO_SPEECH) { + gPlayProperties.playMode = NO_PLAYLIST; + } else if (gPlayProperties.playMode != NO_PLAYLIST) { xQueueSend(gRfidCardQueue, gPlayProperties.playRfidTag, 0); // Re-inject previous RFID-ID in order to continue playback } } @@ -835,7 +866,11 @@ void AudioPlayer_TrackQueueDispatcher(const char *_itemToPlay, const uint32_t _l gPlayProperties.currentTrackNumber = _trackLastPlayed; char **musicFiles; - if (_playMode != WEBSTREAM) { + if (_playMode == WEBSTREAM) { + musicFiles = AudioPlayer_ReturnPlaylistFromWebstream(filename); + } else if (_playMode == TEXT_TO_SPEECH) { + musicFiles = AutioPlayer_ReturnPlaylistFromTextToSpeech(filename); // no modification needed + } else { if (_playMode == RANDOM_SUBDIRECTORY_OF_DIRECTORY) { filename = SdCard_pickRandomSubdirectory(filename); // *filename (input): target-directory // *filename (output): random subdirectory if (filename == NULL) { // If error occured while extracting random subdirectory @@ -846,8 +881,6 @@ void AudioPlayer_TrackQueueDispatcher(const char *_itemToPlay, const uint32_t _l } else { musicFiles = SdCard_ReturnPlaylist(filename, _playMode); } - } else { - musicFiles = AudioPlayer_ReturnPlaylistFromWebstream(filename); } // Catch if error occured (e.g. file not found) @@ -857,6 +890,7 @@ void AudioPlayer_TrackQueueDispatcher(const char *_itemToPlay, const uint32_t _l if (gPlayProperties.playMode != NO_PLAYLIST) { AudioPlayer_TrackControlToQueueSender(STOP); } + free(filename); return; } @@ -978,6 +1012,18 @@ void AudioPlayer_TrackQueueDispatcher(const char *_itemToPlay, const uint32_t _l break; } + case TEXT_TO_SPEECH: { // This is also always just one "track" + Log_Println((char *) FPSTR(modeWebstream), LOGLEVEL_NOTICE); + if (Wlan_IsConnected()) { + xQueueSend(gTrackQueue, &(musicFiles), 0); + } else { + Log_Println((char *) FPSTR(webstreamNotAvailable), LOGLEVEL_ERROR); + System_IndicateError(); + gPlayProperties.playMode = NO_PLAYLIST; + } + break; + } + case LOCAL_M3U: { // Can be one or multiple SD-files or webradio-stations; or a mix of both Log_Println((char *) FPSTR(modeWebstreamM3u), LOGLEVEL_NOTICE); xQueueSend(gTrackQueue, &(musicFiles), 0); @@ -1053,6 +1099,18 @@ char **AudioPlayer_ReturnPlaylistFromWebstream(const char *_webUrl) { return ++url; } +// Adds Text To Speech to playlist; same like SdCard_ReturnPlaylist() but always only one entry +char **AutioPlayer_ReturnPlaylistFromTextToSpeech(const char *_textToInsert) { + char *textToInsert = x_strdup(_textToInsert); + static char **playlist; + playlist = (char **)x_malloc(sizeof(char *) * 2); + playlist[0] = x_strdup("1"); // Number of files is always 1 in url-mode + playlist[1] = x_strdup(textToInsert); + + free(textToInsert); + return ++playlist; +} + // Adds new control-command to control-queue void AudioPlayer_TrackControlToQueueSender(const uint8_t trackCommand) { xQueueSend(gTrackControlQueue, &trackCommand, 0); diff --git a/src/AudioPlayer.h b/src/AudioPlayer.h index f990a957..985c5b11 100644 --- a/src/AudioPlayer.h +++ b/src/AudioPlayer.h @@ -24,6 +24,7 @@ typedef struct { // Bit field bool currentPlayMono: 1; // true if mono; false if stereo bool isWebstream: 1; // Indicates if track currenty played is a webstream bool tellIpAddress: 1; // If true current IP-address is spoken + bool tellCustomText: 1; // If true current IP-address is spoken bool currentSpeechActive: 1; // If speech-play is active bool lastSpeechActive: 1; // If speech-play was active size_t coverFilePos; // current cover file position diff --git a/src/Cmd.cpp b/src/Cmd.cpp index d06e1869..74bb0b1f 100644 --- a/src/Cmd.cpp +++ b/src/Cmd.cpp @@ -288,6 +288,22 @@ void Cmd_Action(const uint16_t mod) { break; } + case CMD_TELL_CUSTOM_TEXT: { + if (Wlan_IsConnected()) { + if (!gPlayProperties.pausePlay) { + AudioPlayer_TrackControlToQueueSender(PAUSEPLAY); + } + gPlayProperties.tellCustomText = true; + gPlayProperties.currentSpeechActive = true; + gPlayProperties.lastSpeechActive = true; + System_IndicateOk(); + } else { + Log_Println(unableToTellIpAddress, LOGLEVEL_ERROR); + System_IndicateError(); + } + break; + } + case CMD_PLAYPAUSE: { if (OPMODE_NORMAL == System_GetOperationMode()) { AudioPlayer_TrackControlToQueueSender(PAUSEPLAY); diff --git a/src/Web.cpp b/src/Web.cpp index 062feaa7..00b736b9 100644 --- a/src/Web.cpp +++ b/src/Web.cpp @@ -448,6 +448,7 @@ bool processJsonRequest(char *_serialJson) { float vIndLow = doc["general"]["vIndLow"].as(); float vIndHi = doc["general"]["vIndHi"].as(); uint8_t vInt = doc["general"]["vInt"].as(); + const char *_customText = object["general"]["vCustText"]; gPrefsSettings.putUInt("initVolume", iVol); gPrefsSettings.putUInt("maxVolumeSp", mVolSpeaker); @@ -459,6 +460,7 @@ bool processJsonRequest(char *_serialJson) { gPrefsSettings.putFloat("vIndicatorLow", vIndLow); gPrefsSettings.putFloat("vIndicatorHigh", vIndHi); gPrefsSettings.putUInt("vCheckIntv", vInt); + gPrefsSettings.putString("customText", _customText); // Check if settings were written successfully if (gPrefsSettings.getUInt("initVolume", 0) != iVol || diff --git a/src/values.h b/src/values.h index c5b653f4..5569c4c5 100644 --- a/src/values.h +++ b/src/values.h @@ -28,6 +28,7 @@ #define ALL_TRACKS_OF_DIR_RANDOM_LOOP 9 // Play all files of a directory (randomized) in infinite-loop #define RANDOM_SUBDIRECTORY_OF_DIRECTORY 13 // Picks a random subdirectory from a given directory and do ALL_TRACKS_OF_DIR_SORTED #define WEBSTREAM 8 // Play webradio-stream +#define TEXT_TO_SPEECH 14 // Play Text To Speech #define LOCAL_M3U 11 // Plays items (webstream or files) with addresses/paths from a local m3u-file #define BUSY 10 // Used if playlist is created @@ -50,6 +51,7 @@ #define CMD_TOGGLE_BLUETOOTH_SOURCE_MODE 141 // Toggles Normal/Bluetooth source Mode #define CMD_ENABLE_FTP_SERVER 150 // Enables FTP-server #define CMD_TELL_IP_ADDRESS 151 // Command: ESPuino announces its IP-address via speech +#define CMD_TELL_CUSTOM_TEXT 152 // Command: ESPuino announces its IP-address via speech #define CMD_PLAYPAUSE 170 // Command: play/pause #define CMD_PREVTRACK 171 // Command: previous track From db08969a7ce3a5efaa090064da8fe25667b62d0d Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Sun, 8 Jan 2023 20:48:30 +0100 Subject: [PATCH 02/15] fix English translation --- html/management_EN.html | 55 +++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/html/management_EN.html b/html/management_EN.html index e3d80205..ce539d8c 100644 --- a/html/management_EN.html +++ b/html/management_EN.html @@ -230,33 +230,33 @@
Command Control - + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -350,6 +350,7 @@ + From 7077626f2b116281202aa6cfe75950cdd44d431d Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Sun, 8 Jan 2023 20:56:32 +0100 Subject: [PATCH 03/15] some cleanup on the website --- html/management_DE.html | 12 ++++++------ html/management_EN.html | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/html/management_DE.html b/html/management_DE.html index d144df66..fd24988d 100644 --- a/html/management_DE.html +++ b/html/management_DE.html @@ -229,9 +229,9 @@
- Command Control + Befehls Steuerung + +
- Bitte Custom-Text eintragen. + Bitte Text eintragen.
diff --git a/html/management_EN.html b/html/management_EN.html index ce539d8c..3bef447c 100644 --- a/html/management_EN.html +++ b/html/management_EN.html @@ -231,7 +231,7 @@
Command Control
Please enter custom-text. From 5ac8e09dc02bb2b13998ef64e53217a6fcc44b14 Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Sun, 8 Jan 2023 21:01:41 +0100 Subject: [PATCH 04/15] english translation review --- html/management_EN.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/html/management_EN.html b/html/management_EN.html index 3bef447c..0c2161ca 100644 --- a/html/management_EN.html +++ b/html/management_EN.html @@ -233,7 +233,7 @@ - + @@ -347,10 +347,10 @@ - + - + From 72856e36fedc968854132b975722f40348091530 Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Thu, 9 Feb 2023 21:12:49 +0100 Subject: [PATCH 05/15] removed web-stuff and start to add them again. --- html/locales/de.json | 3 ++- html/locales/en.json | 3 ++- html/management.html | 1 + src/values.h | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/html/locales/de.json b/html/locales/de.json index 4f4839fa..15a5a6b6 100644 --- a/html/locales/de.json +++ b/html/locales/de.json @@ -103,7 +103,8 @@ "Alle Titel eines Verzeichnis (zufällig, Endlosschleife)", "Alle Titel aus einem zufälligen Unterverzeichnis (sortiert)", "Webradio", - "Liste (Dateien von SD und/oder Webstreams) aus lokaler .m3u-Datei" + "Liste (Dateien von SD und/oder Webstreams) aus lokaler .m3u-Datei", + "Gesprochener Text" ] }, "mod": { diff --git a/html/locales/en.json b/html/locales/en.json index 89e9317e..3c4b00f6 100644 --- a/html/locales/en.json +++ b/html/locales/en.json @@ -103,7 +103,8 @@ "All tracks of a directory (random, loop)", "All tracks of a random subdirectory (sorted alph.)", "Webradio", - "List (files from SD and/or webstreams) from local .m3u-File" + "List (files from SD and/or webstreams) from local .m3u-File", + "Text To Speech" ] }, "mod": { diff --git a/html/management.html b/html/management.html index 2b4ec524..0af9c66b 100644 --- a/html/management.html +++ b/html/management.html @@ -305,6 +305,7 @@ +
diff --git a/src/values.h b/src/values.h index 5569c4c5..43ef980a 100644 --- a/src/values.h +++ b/src/values.h @@ -51,7 +51,7 @@ #define CMD_TOGGLE_BLUETOOTH_SOURCE_MODE 141 // Toggles Normal/Bluetooth source Mode #define CMD_ENABLE_FTP_SERVER 150 // Enables FTP-server #define CMD_TELL_IP_ADDRESS 151 // Command: ESPuino announces its IP-address via speech -#define CMD_TELL_CUSTOM_TEXT 152 // Command: ESPuino announces its IP-address via speech +#define CMD_TELL_CUSTOM_TEXT 152 // Command: ESPuino announces a predefined text #define CMD_PLAYPAUSE 170 // Command: play/pause #define CMD_PREVTRACK 171 // Command: previous track From fb64bb9fadc4d0de7b6abca7b38f2d01da929bbb Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Thu, 9 Feb 2023 21:29:30 +0100 Subject: [PATCH 06/15] try to add command-selection --- html/locales/de.json | 3 ++- html/locales/en.json | 3 ++- html/management.html | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/html/locales/de.json b/html/locales/de.json index 15a5a6b6..d4bbbbab 100644 --- a/html/locales/de.json +++ b/html/locales/de.json @@ -50,7 +50,8 @@ "volume": "Lautstärke", "voldown": "Leiser", "volup": "Lauter", - "current": "Aktueller Titel" + "current": "Aktueller Titel", + "command": "Befehl Ausführen" }, "files": { "title": "Dateien", diff --git a/html/locales/en.json b/html/locales/en.json index 3c4b00f6..cdeedc89 100644 --- a/html/locales/en.json +++ b/html/locales/en.json @@ -50,7 +50,8 @@ "volume": "Volume", "voldown": "Volume Down", "volup": "Volume Up", - "current": "Current track" + "current": "Current track", + "command": "Excecute Command" }, "files": { "title": "Files", diff --git a/html/management.html b/html/management.html index 0af9c66b..23870355 100644 --- a/html/management.html +++ b/html/management.html @@ -237,6 +237,39 @@
+
+
+ +
+ + +
+
From 80af63db9092fb24bdf5a3ed581579e57f4e60a2 Mon Sep 17 00:00:00 2001 From: laszloh Date: Mon, 13 Feb 2023 18:39:46 +0100 Subject: [PATCH 09/15] bugfix: UTF8 encoding & missing translation Make python explicitely use utf8 as file encoding. Add missing translation of file upload progress bar. --- html/locales/de.json | 10 ++++- html/locales/en.json | 10 ++++- html/management.html | 91 +++++++++++++++++++++----------------------- processHtml.py | 12 +++--- 4 files changed, 66 insertions(+), 57 deletions(-) diff --git a/html/locales/de.json b/html/locales/de.json index 4f4839fa..333ffbea 100644 --- a/html/locales/de.json +++ b/html/locales/de.json @@ -76,8 +76,14 @@ "desc": "Upload starten", "selectFolder": "Wähle den Ordner für den Upload!", "selectFile": "Wähle eine Datei zum Hochladen!", - "success": "Upload erfolgreich", - "error": "Upload fehlgeschlagen" + "success": "Upload erfolgreich ({{elapsed}}, {{speed}} KB/s)", + "error": "Upload fehlgeschlagen", + "timeCalc": "Verbleibende Zeit wird berechnet..", + "minutes_one": "Minute", + "minutes_other": "Minuten", + "seconds": "Sekunden", + "fewSec": "wenige", + "progress": "{{percent}}% ({{speed}} KB/s), {{remaining.value}} {{remaining.unit}} verbleibend.." }, "rfid": { "title": "RFID-Zuweisungen", diff --git a/html/locales/en.json b/html/locales/en.json index 89e9317e..c39a3d49 100644 --- a/html/locales/en.json +++ b/html/locales/en.json @@ -76,8 +76,14 @@ "desc": "Start Upload", "selectFolder": "Please select the upload location!", "selectFile": "Please select files to upload!", - "success": "Upload success", - "error": "Upload error" + "success": "Upload successfull ({{elapsed}}, {{speed}} KB/s)", + "error": "Upload error", + "timeCalc": "Remaining time is being calculated..", + "minutes_one": "minute", + "minutes_other": "minutes", + "seconds": "seconds", + "fewSec": "few", + "progress": "{{percent}}% ({{speed}} KB/s), {{remaining.value}} {{remaining.unit}} remaining.." }, "rfid": { "title": "RFID-Assignments", diff --git a/html/management.html b/html/management.html index 5bcb51b1..008ea1ad 100644 --- a/html/management.html +++ b/html/management.html @@ -775,6 +775,8 @@ console.log("Parent path: " + path); } + const startTime = new Date().getTime(); + let bytesTotal = 0; $.ajax({ url: '/explorer?path=' + path, type: 'POST', @@ -782,63 +784,58 @@ contentType: false, processData:false, xhr: function() { - var lastNow = new Date().getTime(); - startTime = new Date().getTime(); - var lastKBytes = 0; - bytesTotal = 0; var xhr = new window.XMLHttpRequest(); xhr.upload.addEventListener("progress", function(evt) { if (evt.lengthComputable) { - var now = new Date().getTime(); + const now = new Date().getTime(); + const percent = parseInt(evt.loaded * 100 / evt.total); + const elapsed = (now - startTime) / 1000; bytesTotal = evt.total; - var percentComplete = evt.loaded / evt.total; - percentComplete = parseInt(percentComplete * 100); - kbytes = evt.loaded / 1024; - var uploadedkBytes = kbytes - lastKBytes; - var elapsed = (now - lastNow) / 1000; - elapsed_total = (now - startTime) / 1000; - var kbps = elapsed ? uploadedkBytes / elapsed : 0; - lastKBytes = kbytes; - lastNow = now; - - var seconds_elapsed = (now - startTime) / 1000; - var bytes_per_second = seconds_elapsed ? evt.loaded / seconds_elapsed : 0; - var Kbytes_per_second = bytes_per_second / 1024; - var remaining_bytes = evt.total - evt.loaded; - var seconds_remaining = seconds_elapsed ? (remaining_bytes / bytes_per_second) : 'is being calculated..' ; - - var percent = percentComplete + '%'; - console.log("Percent: " + percent + ", " + Kbytes_per_second.toFixed(2) + " KB/s"); - var progressText = percent; - if (seconds_remaining > 60) { - progressText = progressText + ", " + (seconds_remaining / 60).toFixed(0) + " mins. remaining.."; - } else - if (seconds_remaining <= 0) { - progressText = progressText + " (" + Kbytes_per_second.toFixed(2) + " KB/s)"; - } else - if (seconds_remaining < 2) { - progressText = progressText + ", few secs. remaining.."; - } else { - progressText = progressText + ", " + seconds_remaining.toFixed(0) + " secs. remaining.."; + + let progressText = i18next.t("files.upload.timeCalc"); + if(elapsed){ + const bps = evt.loaded / elapsed; + const kbps = bps / 1024; + const remaining = Math.round((evt.total - evt.loaded) / bps); + + const data = { + percent: percent, + remaining: { + unit: (remaining>60) ? i18next.t("files.upload.minutes", {count: Math.round(remaining/60)}) : i18next.t("files.upload.seconds"), + value: (remaining>60) ? Math.round(remaining/60) : ((remaining > 2) ? remaining : i18next.t("files.upload.fewSec")) + }, + speed: kbps.toFixed(2) + } + progressText = i18next.t("files.upload.progress", data); + console.log("Percent: " + percent + "%% " + kbps.toFixed(2) + " KB/s"); } - $("#explorerUploadProgress").css('width', percent).text(progressText); + $("#explorerUploadProgress").css('width', percent+"%").text(progressText); } }, false); return xhr; }, success: function(data, textStatus, jqXHR) { - var now = new Date().getTime(); - var elapsed_time = (now - startTime); - var seconds_elapsed = elapsed_time / 1000; - var bytes_per_second = seconds_elapsed ? bytesTotal / seconds_elapsed : 0; - var Kbytes_per_second = bytes_per_second / 1024 ; - var minutes = Math.floor(seconds_elapsed / 60); - var seconds = seconds_elapsed - (minutes * 60); - var timeText = minutes.toString().padStart(2, '0') + ':' + seconds.toFixed(0).toString().padStart(2, '0'); - console.log("Upload success (" + timeText + ", " + Kbytes_per_second.toFixed(2) + " KB/s): " + textStatus); - var progressText = i18next.t("files.upload.success") +" (" + timeText + ", " + Kbytes_per_second.toFixed(2) + " KB/s)."; + const now = new Date().getTime(); + const elapsed = (now - startTime) / 1000; + + let transData = { + elapsed: "00:00", + speed: "0,00" + }; + if(elapsed){ + const bps = bytesTotal / elapsed; + const kbps = bps / 1024; + + const date = new Date(null); + date.setSeconds(elapsed); + const timeText = date.toISOString().substr(11, 8); + + transData = { elapsed: timeText, speed: kbps.toFixed(2) }; + } + console.log("Upload success (" + transData.elapsed + ", " + transData.speed + " KB/s): " + textStatus); + const progressText = i18next.t("files.upload.success", transData); $("#explorerUploadProgress").text(progressText); document.getElementById('uploaded_file').value = ''; document.getElementById('uploaded_file_text').innerHTML = ''; @@ -853,8 +850,8 @@ }, error: function(request, status, error) { console.log("Upload ERROR!"); - $("#explorerUploadProgress").text(i18next.t("files.upload.error") +" :" + status); - toastr.error(i18next.t("files.upload.error") + status); + $("#explorerUploadProgress").text(i18next.t("files.upload.error") +": " + status); + toastr.error(i18next.t("files.upload.error") + ": " + status); } }); }); diff --git a/processHtml.py b/processHtml.py index 26608691..e8db5640 100644 --- a/processHtml.py +++ b/processHtml.py @@ -58,12 +58,12 @@ def _escape_html(data): def _process_header_file(cls, html_path, header_path): parser = Parser({}, True) parser.update_runtime_options(True, True, True) - with html_path.open("r") as html_file: + with html_path.open(mode="r", encoding="utf-8") as html_file: content = html_file.read() content = parser.minify(content, "html") # minify content as html content = cls._escape_html(content) - with header_path.open("w") as header_file: + with header_path.open(mode="w", encoding="utf-8") as header_file: header_file.write( f"static const char {html_path.name.split('.')[0]}_HTML[] PROGMEM = \"" ) @@ -75,18 +75,18 @@ def _process_header_file(cls, html_path, header_path): def _process_binary_file(cls, binary_path, header_path, info): # minify json files explicitly if binary_path.suffix == "json": - with binary_path.open("r") as f: + with binary_path.open(mode="r", encoding="utf-8") as f: jsonObj = json.load(f) content = json.dumps(jsonObj, separators=(',', ':')) # use everything else as is else: - with binary_path.open("r") as f: + with binary_path.open(mode="r", encoding="utf-8") as f: content = f.read() # compress content data = gzip.compress(content.encode()) - with header_path.open("a") as header_file: + with header_path.open(mode="a", encoding="utf-8") as header_file: varName = binary_path.name.split('.')[0] header_file.write( f"static const uint8_t {varName}_BIN[] PROGMEM = {{\n " @@ -126,7 +126,7 @@ def process(cls): info = cls._process_binary_file(HTML_DIR / binary_file, binary_header, info) fileList.append(info) - with binary_header.open("a") as f: + with binary_header.open(mode="a", encoding="utf-8") as f: f.write("""using RouteRegistrationHandler = std::function; class WWWData { From cede2249c6ecc0d42aaa62d833d6d8669c9fc3fc Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Tue, 14 Feb 2023 06:30:11 +0100 Subject: [PATCH 10/15] execute modification works again --- html/locales/de.json | 3 ++- html/locales/en.json | 3 ++- html/management.html | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/html/locales/de.json b/html/locales/de.json index 58847be6..5e616882 100644 --- a/html/locales/de.json +++ b/html/locales/de.json @@ -2,6 +2,7 @@ "submit": "Absenden", "restart": "Neustart", "reset": "Reset", + "execute": "Ausführen", "title": "ESPuino-Konfiguration", "shutdown": "Ausschalten", "log": "Log", @@ -51,7 +52,7 @@ "voldown": "Leiser", "volup": "Lauter", "current": "Aktueller Titel", - "command": "Befehl Ausführen" + "command": "Modifikation Ausführen" }, "files": { "title": "Dateien", diff --git a/html/locales/en.json b/html/locales/en.json index 3f8ae1f2..998558e2 100644 --- a/html/locales/en.json +++ b/html/locales/en.json @@ -2,6 +2,7 @@ "submit": "Submit", "restart": "Restart", "reset": "Reset", + "execute": "Execute", "title": "ESPuino-Settings", "shutdown": "Shutdown", "log": "Log", @@ -51,7 +52,7 @@ "voldown": "Volume Down", "volup": "Volume Up", "current": "Current track", - "command": "Excecute Command" + "command": "Excecute Modification" }, "files": { "title": "Files", diff --git a/html/management.html b/html/management.html index 302258f7..3ac6649f 100644 --- a/html/management.html +++ b/html/management.html @@ -270,6 +270,8 @@ +
+ From 31368020a1320ed6fafc56da90b601f9b17d5589 Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Tue, 14 Feb 2023 06:52:07 +0100 Subject: [PATCH 11/15] prepare for custom-text --- html/locales/de.json | 6 ++++++ html/locales/en.json | 9 ++++++++- html/management.html | 14 +++++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/html/locales/de.json b/html/locales/de.json index 5e616882..f782a936 100644 --- a/html/locales/de.json +++ b/html/locales/de.json @@ -210,6 +210,12 @@ "lowCritical": "Eine LED leuchtet bei dieser Spannung", "high": "Alle LEDs leuchten bei dieser Spannung", "measureInterval": "Zeitabstand der Messung (in Minuten)" + }, + "customtext": { + "title": "Benutzerdefinierte Ansage", + "desc": "Benuterdefinierte Ansage des ESPUINO", + "textLabel": "Text der Ansage", + "textDefault": "Dies ist der ESPUINO von Torsten" } }, "tools": { diff --git a/html/locales/en.json b/html/locales/en.json index 998558e2..bf694620 100644 --- a/html/locales/en.json +++ b/html/locales/en.json @@ -209,7 +209,14 @@ "lowCritical": "Lowest voltage, that is indicated by one LED", "high": "Voltage, that is indicated by all LEDs", "measureInterval": "Interval between measurements (in minutes)" - } + }, + "customtext": { + "title": "User defined speech", + "desc": "User defined speech of the ESPUINO", + "textLabel": "Text of speech", + "textDefault": "This is the ESPUINO of Torsten" + } + }, "tools": { "nvserase": { diff --git a/html/management.html b/html/management.html index 3ac6649f..c4c2577d 100644 --- a/html/management.html +++ b/html/management.html @@ -538,7 +538,19 @@ -
+
+ +
+
+ +
+
+ + +
+
+
  From 857fe257d05b2d8009cda06427f03ae18d337d6f Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Tue, 14 Feb 2023 16:02:20 +0100 Subject: [PATCH 12/15] add custom-text again --- html/management.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/html/management.html b/html/management.html index 7cbf0caa..6c0aa7db 100644 --- a/html/management.html +++ b/html/management.html @@ -1293,7 +1293,8 @@ vWarning: document.getElementById('warningLowVoltage').value, vIndLow: document.getElementById('voltageIndicatorLow').value, vIndHi: document.getElementById('voltageIndicatorHigh').value, - vInt: document.getElementById('voltageCheckInterval').value + vInt: document.getElementById('voltageCheckInterval').value, + vCustText: document.getElementById('customText').value } }; var myJSON = JSON.stringify(myObj); From abd804ec5a10cba07dc98496e25704663b79166c Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Tue, 14 Feb 2023 17:13:02 +0100 Subject: [PATCH 13/15] don't require text anymore --- html/management.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/management.html b/html/management.html index 6c0aa7db..bd49bba2 100644 --- a/html/management.html +++ b/html/management.html @@ -547,7 +547,7 @@
+ data-i18n="[placeholder]general.customtext.textDefault" name="customText">
From 11497bf639c7f8d2f027e0ebc16fc9ff454a7325 Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Tue, 14 Feb 2023 20:23:21 +0100 Subject: [PATCH 14/15] fix assignment in webserver --- html/locales/en.json | 4 ++-- html/management.html | 41 ++++++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/html/locales/en.json b/html/locales/en.json index ae5c1633..4a52fff4 100644 --- a/html/locales/en.json +++ b/html/locales/en.json @@ -132,7 +132,8 @@ "Loop track", "Dimm LEDs (nightmode)", "Toggle WiFi", - "Toggle Bluetooth", + "Toggle Bluetooth Speeker", + "Toggle Bluetooth Headphones", "Enable FTP", "Remove assignment", "Toggle Play/Pause", @@ -222,7 +223,6 @@ "textLabel": "Text of speech", "textDefault": "This is the ESPUINO of Torsten" } - }, "tools": { "nvserase": { diff --git a/html/management.html b/html/management.html index bd49bba2..174300d5 100644 --- a/html/management.html +++ b/html/management.html @@ -258,16 +258,17 @@ - - - - - - - - - - + + + + + + + + + + +
@@ -362,15 +363,17 @@ - - - - - - - - - + + + + + + + + + + + From 5fdeb92626bd72f9bff9f3d95255003120abd1c9 Mon Sep 17 00:00:00 2001 From: Joe91 <1015.5@gmx.de> Date: Thu, 23 Feb 2023 20:33:59 +0100 Subject: [PATCH 15/15] fix merge issues --- html/locales/de.json | 2 +- html/locales/en.json | 2 +- html/management.html | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/html/locales/de.json b/html/locales/de.json index 91b7a265..909ee06e 100644 --- a/html/locales/de.json +++ b/html/locales/de.json @@ -112,7 +112,7 @@ "13":"Alle Titel aus einem zufälligen Unterverzeichnis (sortiert)", "8":"Webradio", "11":"Liste (Dateien von SD und/oder Webstreams) aus lokaler .m3u-Datei", - "13":"Gesprochener Text" + "14":"Gesprochener Text" } }, "mod": { diff --git a/html/locales/en.json b/html/locales/en.json index 19ddc99a..5482d35c 100644 --- a/html/locales/en.json +++ b/html/locales/en.json @@ -112,7 +112,7 @@ "13":"All tracks of a random subdirectory (sorted alph.)", "8":"Webradio", "11":"List (files from SD and/or webstreams) from local .m3u-File", - "13":"Text To Speech" + "14":"Text To Speech" } }, "mod": { diff --git a/html/management.html b/html/management.html index a6ae7768..64164087 100644 --- a/html/management.html +++ b/html/management.html @@ -240,7 +240,7 @@
-
+