diff --git a/README.md b/README.md
index f9f703b..b743641 100644
--- a/README.md
+++ b/README.md
@@ -317,6 +317,24 @@ Work is in progress...
---
## Version history
+#### v0.7.490
+**!!! a [full update](#update-over-web-interface) with Sketch data upload is required. After updating please press CTRL+F5 in browser !!!** \
+**Please backup playlist.csv and wifi.csv before updating.**
+- fixed playlist break down when saving it
+- fixed bug with cropped song titles on single line displays (GC9106, ST7735mini, N5110 etc.)
+- netserver - optimization and refactoring
+- web interface optimization
+- the AUDIOBUFFER_MULTIPLIER parameter is deprecated. New parameter AUDIOBUFFER_MULTIPLIER2. If everything works fine, then it is better not to touch it.
+- new setting VS_PATCH_ENABLE (see PS)
+- fixing other bugs
+
+_**PS:** A bug was found with the lack of sound on some (not all) green VS1053 boards.
+If there is no sound, you need to assign in myoptions_
+```
+#define VS_PATCH_ENABLE false
+```
+_On red boards and normally working green boards, nothing else needs to be done._
+
#### v0.7.414
- fixed non latin long titles of songs error
diff --git a/yoRadio/audiohandlers.ino b/yoRadio/audiohandlers.ino
index 18139c4..74bff8e 100644
--- a/yoRadio/audiohandlers.ino
+++ b/yoRadio/audiohandlers.ino
@@ -15,7 +15,7 @@ void audio_info(const char *info) {
player.mode = STOPPED;
player.stopInfo();
}
- if (strstr(info, "not supported") != NULL){
+ if (strstr(info, "not supported") != NULL || strstr(info, "Account already in use") != NULL){
config.setTitle(info);
netserver.requestOnChange(TITLE, 0);
player.setOutputPins(false);
@@ -47,20 +47,32 @@ bool printable(const char *info) {
}
void audio_showstation(const char *info) {
+ DBGVB("[%s] info = %s", __func__, info);
if (strlen(info) > 0) {
bool p = printable(info);
- config.setTitle(p?info:"*****");
+ config.setTitle(p?info:config.station.name);
netserver.requestOnChange(TITLE, 0);
}
}
void audio_showstreamtitle(const char *info) {
+ DBGVB("[%s] info = %s", __func__, info);
+ if (strstr(info, "Account already in use") != NULL){
+ config.setTitle(info);
+ netserver.requestOnChange(TITLE, 0);
+ player.setOutputPins(false);
+ player.setDefaults();
+ if (player_on_stop_play) player_on_stop_play();
+ player.mode = STOPPED;
+ player.stopInfo();
+ return;
+ }
if (strlen(info) > 0) {
bool p = printable(info);
#ifdef DEBUG_TITLES
config.setTitle(DEBUG_TITLES);
#else
- config.setTitle(p?info:"*****");
+ config.setTitle(p?info:config.station.name);
#endif
netserver.requestOnChange(TITLE, 0);
}
diff --git a/yoRadio/config.cpp b/yoRadio/config.cpp
index ea8ace8..74c8d60 100644
--- a/yoRadio/config.cpp
+++ b/yoRadio/config.cpp
@@ -443,7 +443,7 @@ bool Config::parseSsid(const char* line, char* ssid, char* pass) {
return true;
}
-bool Config::saveWifi(const char* post) {
+bool Config::saveWifiFromNextion(const char* post){
File file = SPIFFS.open(SSIDS_PATH, "w");
if (!file) {
return false;
@@ -455,6 +455,14 @@ bool Config::saveWifi(const char* post) {
}
}
+bool Config::saveWifi() {
+ if (!SPIFFS.exists(TMP_PATH)) return false;
+ SPIFFS.remove(SSIDS_PATH);
+ SPIFFS.rename(TMP_PATH, SSIDS_PATH);
+ ESP.restart();
+ return true;
+}
+
bool Config::initNetwork() {
File file = SPIFFS.open(SSIDS_PATH, "r");
if (!file || file.isDirectory()) {
diff --git a/yoRadio/config.h b/yoRadio/config.h
index 4c3e599..b046946 100644
--- a/yoRadio/config.h
+++ b/yoRadio/config.h
@@ -147,7 +147,8 @@ class Config {
bool parseSsid(const char* line, char* ssid, char* pass);
void loadStation(uint16_t station);
bool initNetwork();
- bool saveWifi(const char* post);
+ bool saveWifi();
+ bool saveWifiFromNextion(const char* post);
void setSmartStart(byte ss);
void initPlaylist();
void indexPlaylist();
diff --git a/yoRadio/data/www/script.js.gz b/yoRadio/data/www/script.js.gz
index ba3ea9f..aa35f08 100644
Binary files a/yoRadio/data/www/script.js.gz and b/yoRadio/data/www/script.js.gz differ
diff --git a/yoRadio/data/www/settings.html b/yoRadio/data/www/settings.html
index cbc32e1..2a381f3 100644
--- a/yoRadio/data/www/settings.html
+++ b/yoRadio/data/www/settings.html
@@ -177,6 +177,7 @@
diff --git a/yoRadio/display.cpp b/yoRadio/display.cpp
index ef16f8b..5b0f940 100644
--- a/yoRadio/display.cpp
+++ b/yoRadio/display.cpp
@@ -580,7 +580,7 @@ char *split(char *str, const char *delim) {
}
void Display::title() {
- DBGVB("call of %s(), config.station.title=%s", __func__, config.station.title);
+ DBGVB("[%s] config.station.title = %s", __func__, config.station.title);
if (strlen(config.station.title) > 0) {
char tmpbuf[strlen(config.station.title)+1];
strlcpy(tmpbuf, config.station.title, strlen(config.station.title)+1);
@@ -589,7 +589,7 @@ void Display::title() {
title1.setText(dsp.utf8Rus(tmpbuf, true));
title2.setText(dsp.utf8Rus(stitle, true));
}else{
- title1.setText(dsp.utf8Rus(tmpbuf, true));
+ title1.setText(dsp.utf8Rus(config.station.title, true));
title2.setText(dsp.utf8Rus("", true));
}
#ifdef USE_NEXTION
diff --git a/yoRadio/netserver.cpp b/yoRadio/netserver.cpp
index 9520921..8b38b18 100644
--- a/yoRadio/netserver.cpp
+++ b/yoRadio/netserver.cpp
@@ -25,123 +25,41 @@ AsyncUDP udp;
String processor(const String& var);
void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
+void handleUpdate(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
+void handleHTTPArgs(AsyncWebServerRequest * request);
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len);
-void handleHTTPPost(AsyncWebServerRequest * request);
bool shouldReboot = false;
+#ifdef MQTT_HOST
+Ticker mqttplaylistticker;
+bool mqttplaylistblock = false;
+void mqttplaylistSend() {
+ mqttplaylistblock = true;
+ mqttplaylistticker.detach();
+ mqttPublishPlaylist();
+ mqttplaylistblock = false;
+}
+#endif
-char* updateError(){
+char* updateError() {
static char ret[140] = {0};
sprintf(ret, "Update failed with error (%d)
%s", (int)Update.getError(), Update.errorString());
return ret;
}
-void NetServer::takeMallocDog(){
- int mcb = heap_caps_get_free_size(MALLOC_CAP_8BIT);
- int mci = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
- (void)mci;
- DBGVB("MALLOC_CAP_8BIT=%d, MALLOC_CAP_INTERNAL=%d", mcb, mci);
- resumePlay = mcb < MIN_MALLOC;
- if (resumePlay) {
- player.toggle();
- vTaskDelay(150);
- xSemaphoreTake(player.playmutex, portMAX_DELAY);
- }
-}
-
-void NetServer::giveMallocDog(){
- if (resumePlay) {
- resumePlay = false;
- vTaskDelay(150);
- xSemaphoreGive(player.playmutex);
- player.toggle();
- }
-}
-
bool NetServer::begin() {
- importRequest = false;
+ importRequest = IMDONE;
irRecordEnable = false;
- webserver.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
- if (network.status == CONNECTED) {
- netserver.htmlPath = PINDEX;
- netserver.chunkedHtmlPage(String(), request);
- }else{
- netserver.htmlPath = PSETTINGS;
- netserver.chunkedHtmlPage(String(), request);
- }
- });
-
+ webserver.on("/", HTTP_ANY, handleHTTPArgs);
+ webserver.on(PLAYLIST_PATH, HTTP_GET, handleHTTPArgs);
+ webserver.on(INDEX_PATH, HTTP_GET, handleHTTPArgs);
+ webserver.on(SSIDS_PATH, HTTP_GET, handleHTTPArgs);
+ webserver.on("/upload", HTTP_POST, beginUpload, handleUpload);
+ webserver.on("/update", HTTP_GET, handleHTTPArgs);
+ webserver.on("/update", HTTP_POST, beginUpdate, handleUpdate);
+ webserver.on("/settings", HTTP_GET, handleHTTPArgs);
+ if (IR_PIN != 255) webserver.on("/ir", HTTP_GET, handleHTTPArgs);
webserver.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=31536000");
-
- webserver.on("/", HTTP_POST, [](AsyncWebServerRequest * request) {
- handleHTTPPost(request);
- });
- webserver.on(PLAYLIST_PATH, HTTP_GET, [](AsyncWebServerRequest * request) {
- netserver.takeMallocDog();
- request->send(SPIFFS, PLAYLIST_PATH, "application/octet-stream");
- netserver.giveMallocDog();
- DBGVB("PLAYLIST_PATH client ip=%s", request->client()->remoteIP().toString().c_str());
- /*netserver.htmlPath = PPLAYLIST; // TODO
- netserver.chunkedHtmlPage("application/octet-stream", request);
- netserver.giveMallocDog();*/
- });
- webserver.on(INDEX_PATH, HTTP_GET, [](AsyncWebServerRequest * request) {
- request->send(SPIFFS, INDEX_PATH, "application/octet-stream");
- });
- webserver.on(SSIDS_PATH, HTTP_GET, [](AsyncWebServerRequest * request) {
- netserver.htmlPath = PSSIDS;
- netserver.chunkedHtmlPage("application/octet-stream", request);
- });
- webserver.on("/upload", HTTP_POST, [](AsyncWebServerRequest * request) {
- //request->send(200);
-
- }, handleUpload);
- webserver.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
- netserver.htmlPath = PUPDATE;
- netserver.chunkedHtmlPage(String(), request);
- });
- webserver.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){
- netserver.htmlPath = PSETTINGS;
- netserver.chunkedHtmlPage(String(), request);
- });
-
-#if IR_PIN!=255
- webserver.on("/ir", HTTP_GET, [](AsyncWebServerRequest *request){
- netserver.htmlPath = PIR;
- netserver.chunkedHtmlPage(String(), request);
- });
-#endif
- webserver.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){
- shouldReboot = !Update.hasError();
- AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", shouldReboot?"OK": updateError());
- response->addHeader("Connection", "close");
- request->send(response);
- },[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
- if(!index){
- int target = (request->getParam("updatetarget", true)->value() == "spiffs") ? U_SPIFFS : U_FLASH;
- Serial.printf("Update Start: %s\n", filename.c_str());
- player.mode = STOPPED;
- display.putRequest({NEWMODE, UPDATING});
- if(!Update.begin(UPDATE_SIZE_UNKNOWN, target)){
- Update.printError(Serial);
- request->send(200, "text/html", updateError());
- }
- }
- if(!Update.hasError()){
- if(Update.write(data, len) != len){
- Update.printError(Serial);
- request->send(200, "text/html", updateError());
- }
- }
- if(final){
- if(Update.end(true)){
- Serial.printf("Update Success: %uB\n", index+len);
- } else {
- Update.printError(Serial);
- request->send(200, "text/html", updateError());
- }
- }
- });
#ifdef CORS_DEBUG
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Origin"), F("*"));
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Headers"), F("content-type"));
@@ -160,504 +78,439 @@ bool NetServer::begin() {
return true;
}
-void NetServer::chunkedHtmlPage(const String& contentType, AsyncWebServerRequest *request){
- max = heap_caps_get_free_size(MALLOC_CAP_8BIT) / 32;
- htmlpos = 0;
- theend = false;
- DBGVB("chunkedHtmlPage client ip=%s", request->client()->remoteIP().toString().c_str());
- AsyncWebServerResponse *response = request->beginChunkedResponse(contentType, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
- if(netserver.theend) return 0;
- File htmlpage;
- switch(netserver.htmlPath){
- case PINDEX: {
- htmlpage = SPIFFS.open("/www/index.html", "r");
- break;
- }
- case PSETTINGS: {
- htmlpage = SPIFFS.open("/www/settings.html", "r");
- break;
- }
- case PUPDATE: {
- htmlpage = SPIFFS.open("/www/update.html", "r");
- break;
- }
- case PIR: {
- htmlpage = SPIFFS.open("/www/ir.html", "r");
- break;
- }
- case PPLAYLIST: {
- htmlpage = SPIFFS.open(PLAYLIST_PATH, "r");
- DBGVB("SPIFFS.open(PLAYLIST_PATH)");
- break;
- }
- case PSSIDS: {
- htmlpage = SPIFFS.open(SSIDS_PATH, "r");
- break;
- }
- default: {
- return 0;
- break;
- }
- }
- if(!htmlpage) return 0;
- uint32_t htmlpagesize = htmlpage.size();
- uint32_t len = htmlpagesize - netserver.htmlpos;
- if (len > maxLen) len = maxLen;
- if (len > netserver.max) len = netserver.max;
- if (len + netserver.htmlpos > htmlpagesize) {
- netserver.theend = true;
- len = htmlpagesize - netserver.htmlpos;
- }
- if (len > 0) {
- DBGVB("seek to %d in %s and read %d bytes", netserver.htmlpos, htmlpage.name(), len);
- htmlpage.seek(netserver.htmlpos, SeekSet);
- htmlpage.read(buffer, len);
- netserver.htmlpos = netserver.htmlpos + len;
- }
- if(htmlpage) htmlpage.close();
- return len;
- }, processor); // AsyncWebServerResponse
+void NetServer::beginUpdate(AsyncWebServerRequest *request) {
+ shouldReboot = !Update.hasError();
+ AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", shouldReboot ? "OK" : updateError());
+ response->addHeader("Connection", "close");
request->send(response);
}
+void handleUpdate(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
+ if (!index) {
+ int target = (request->getParam("updatetarget", true)->value() == "spiffs") ? U_SPIFFS : U_FLASH;
+ Serial.printf("Update Start: %s\n", filename.c_str());
+ player.mode = STOPPED;
+ display.putRequest({NEWMODE, UPDATING});
+ if (!Update.begin(UPDATE_SIZE_UNKNOWN, target)) {
+ Update.printError(Serial);
+ request->send(200, "text/html", updateError());
+ }
+ }
+ if (!Update.hasError()) {
+ if (Update.write(data, len) != len) {
+ Update.printError(Serial);
+ request->send(200, "text/html", updateError());
+ }
+ }
+ if (final) {
+ if (Update.end(true)) {
+ Serial.printf("Update Success: %uB\n", index + len);
+ } else {
+ Update.printError(Serial);
+ request->send(200, "text/html", updateError());
+ }
+ }
+}
+
+void NetServer::beginUpload(AsyncWebServerRequest *request) {
+ if (request->hasParam("plfile", true, true)) {
+ netserver.importRequest = IMPL;
+ request->send(200);
+ } else if (request->hasParam("wifile", true, true)) {
+ netserver.importRequest = IMWIFI;
+ request->send(200);
+ } else {
+ request->send(404);
+ }
+}
+
+size_t NetServer::chunkedHtmlPageCallback(uint8_t* buffer, size_t maxLen, size_t index){
+ File requiredfile = SPIFFS.open(netserver.chunkedPathBuffer, "r");
+ if (!requiredfile) return 0;
+ size_t filesize = requiredfile.size();
+ size_t needread = filesize - index;
+ if (!needread) return 0;
+ size_t canread = (needread > maxLen) ? maxLen : needread;
+ DBGVB("[%s] seek to %d in %s and read %d bytes with maxLen=%d", __func__, index, netserver.chunkedPathBuffer, canread, maxLen);
+ requiredfile.seek(index, SeekSet);
+ requiredfile.read(buffer, canread);
+ index += canread;
+ if (requiredfile) requiredfile.close();
+ return canread;
+}
+
+void NetServer::chunkedHtmlPage(const String& contentType, AsyncWebServerRequest *request, const char * path, bool gzip) {
+ memset(chunkedPathBuffer, 0, sizeof(chunkedPathBuffer));
+ strlcpy(chunkedPathBuffer, path, sizeof(chunkedPathBuffer)-1);
+ PLOW();
+ AsyncWebServerResponse *response = request->beginChunkedResponse(contentType, chunkedHtmlPageCallback, processor);
+ xSemaphoreTake(player.playmutex, portMAX_DELAY);
+ request->send(response);
+ xSemaphoreGive(player.playmutex); PHIG();
+}
+/*
+void NetServer::chunkedHtmlPage(const String& contentType, AsyncWebServerRequest *request, const char * path, bool gzip) {
+ static char pathbuffer[40] = { 0 };
+ strlcpy(pathbuffer, path, 39);
+ PLOW();
+ AsyncWebServerResponse *response = request->beginChunkedResponse(contentType, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
+ File requiredfile = SPIFFS.open(pathbuffer, "r");
+ if (!requiredfile) return 0;
+ size_t filesize = requiredfile.size();
+ size_t needread = filesize - index;
+ if (!needread) return 0;
+ size_t canread = (needread > maxLen) ? maxLen : needread;
+ DBGVB("[%s] seek to %d in %s and read %d bytes with maxLen=%d", __func__, index, pathbuffer, canread, maxLen);
+ requiredfile.seek(index, SeekSet);
+ requiredfile.read(buffer, canread);
+ index += canread;
+ if (requiredfile) requiredfile.close();
+ return canread;
+ }, processor); // AsyncWebServerResponse
+
+ xSemaphoreTake(player.playmutex, portMAX_DELAY);
+ request->send(response);
+ xSemaphoreGive(player.playmutex);
+ PHIG();
+}
+ */
void NetServer::loop() {
- if(shouldReboot){
+ if (shouldReboot) {
Serial.println("Rebooting...");
delay(100);
ESP.restart();
}
websocket.cleanupClients();
- if (playlistrequest > 0) {
- requestOnChange(PLAYLIST, playlistrequest);
- playlistrequest = 0;
- }
- if (importRequest) {
- if (importPlaylist()) {
- requestOnChange(PLAYLIST, 0);
- }
- importRequest = false;
- }
- if (rssi < 255) {
- requestOnChange(NRSSI, 0);
+ //if (playlistrequest > 0) { requestOnChange(PLAYLIST, playlistrequest); playlistrequest = 0; } /* Cleanup this */
+ switch (importRequest) {
+ case IMPL: importPlaylist(); importRequest = IMDONE; break;
+ case IMWIFI: config.saveWifi(); importRequest = IMDONE; break;
+ default: break;
}
+ if (rssi < 255) requestOnChange(NRSSI, 0);
}
+
#if IR_PIN!=255
void NetServer::irToWs(const char* protocol, uint64_t irvalue) {
char buf[BUFLEN] = { 0 };
sprintf (buf, "{\"ircode\": %llu, \"protocol\": \"%s\"}", irvalue, protocol);
websocket.textAll(buf);
}
-void NetServer::irValsToWs(){
- if(!irRecordEnable) return;
+void NetServer::irValsToWs() {
+ if (!irRecordEnable) return;
char buf[BUFLEN] = { 0 };
sprintf (buf, "{\"irvals\": [%llu, %llu, %llu]}", config.ircodes.irVals[config.irindex][0], config.ircodes.irVals[config.irindex][1], config.ircodes.irVals[config.irindex][2]);
websocket.textAll(buf);
}
#endif
+
void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t clientId) {
AwsFrameInfo *info = (AwsFrameInfo*)arg;
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
data[len] = 0;
char cmd[65], val[65];
if (config.parseWsCommand((const char*)data, cmd, val, 65)) {
- if (strcmp(cmd, "getmode") == 0) {
- requestOnChange(GETMODE,clientId);
- return;
- }
- if (strcmp(cmd, "getindex") == 0) {
- requestOnChange(GETINDEX,clientId);
- return;
- }
- if (strcmp(cmd, "getsystem") == 0) {
- requestOnChange(GETSYSTEM,clientId);
- return;
- }
- if (strcmp(cmd, "getscreen") == 0) {
- requestOnChange(GETSCREEN,clientId);
- return;
- }
- if (strcmp(cmd, "gettimezone") == 0) {
- requestOnChange(GETTIMEZONE,clientId);
- return;
- }
- if (strcmp(cmd, "getcontrols") == 0) {
- requestOnChange(GETCONTROLS,clientId);
- return;
- }
- if (strcmp(cmd, "getweather") == 0) {
- requestOnChange(GETWEATHER,clientId);
- return;
- }
- if (strcmp(cmd, "getactive") == 0) {
- requestOnChange(GETACTIVE,clientId);
- return;
- }
-
+ if (strcmp(cmd, "getmode") == 0 ) { requestOnChange(GETMODE, clientId); return; }
+ if (strcmp(cmd, "getindex") == 0 ) { requestOnChange(GETINDEX, clientId); return; }
+ if (strcmp(cmd, "getsystem") == 0 ) { requestOnChange(GETSYSTEM, clientId); return; }
+ if (strcmp(cmd, "getscreen") == 0 ) { requestOnChange(GETSCREEN, clientId); return; }
+ if (strcmp(cmd, "gettimezone") == 0 ) { requestOnChange(GETTIMEZONE, clientId); return; }
+ if (strcmp(cmd, "getcontrols") == 0 ) { requestOnChange(GETCONTROLS, clientId); return; }
+ if (strcmp(cmd, "getweather") == 0 ) { requestOnChange(GETWEATHER, clientId); return; }
+ if (strcmp(cmd, "getactive") == 0 ) { requestOnChange(GETACTIVE, clientId); return; }
if (strcmp(cmd, "smartstart") == 0) {
- byte valb=atoi(val);
- config.store.smartstart=valb==1?1:2;
- if(!player.isRunning() && config.store.smartstart==1) config.store.smartstart=0;
+ byte valb = atoi(val);
+ config.store.smartstart = valb == 1 ? 1 : 2;
+ if (!player.isRunning() && config.store.smartstart == 1) config.store.smartstart = 0;
config.save();
return;
}
if (strcmp(cmd, "audioinfo") == 0) {
- byte valb=atoi(val);
- config.store.audioinfo=valb;
+ byte valb = atoi(val);
+ config.store.audioinfo = valb;
config.save();
- display.putRequest({NEWMODE, CLEAR});
- display.putRequest({NEWMODE, PLAYER});
+ display.putRequest({NEWMODE, CLEAR}); display.putRequest({NEWMODE, PLAYER});
return;
}
if (strcmp(cmd, "vumeter") == 0) {
- byte valb=atoi(val);
- config.store.vumeter=valb;
+ byte valb = atoi(val);
+ config.store.vumeter = valb;
config.save();
- display.putRequest({NEWMODE, CLEAR});
- display.putRequest({NEWMODE, PLAYER});
+ display.putRequest({NEWMODE, CLEAR}); display.putRequest({NEWMODE, PLAYER});
return;
}
if (strcmp(cmd, "softap") == 0) {
- byte valb=atoi(val);
- config.store.softapdelay=valb;
+ byte valb = atoi(val);
+ config.store.softapdelay = valb;
config.save();
return;
}
if (strcmp(cmd, "invertdisplay") == 0) {
- byte valb=atoi(val);
- config.store.invertdisplay=valb;
+ byte valb = atoi(val);
+ config.store.invertdisplay = valb;
config.save();
display.invert();
return;
}
if (strcmp(cmd, "numplaylist") == 0) {
- byte valb=atoi(val);
- config.store.numplaylist=valb;
+ byte valb = atoi(val);
+ config.store.numplaylist = valb;
config.save();
- display.putRequest({NEWMODE, CLEAR});
- display.putRequest({NEWMODE, PLAYER});
+ display.putRequest({NEWMODE, CLEAR}); display.putRequest({NEWMODE, PLAYER});
return;
}
-
if (strcmp(cmd, "fliptouch") == 0) {
- byte valb=atoi(val);
- config.store.fliptouch=valb==1;
+ byte valb = atoi(val);
+ config.store.fliptouch = valb == 1;
config.save();
flipTS();
return;
}
if (strcmp(cmd, "dbgtouch") == 0) {
- byte valb=atoi(val);
- config.store.dbgtouch=valb==1;
+ byte valb = atoi(val);
+ config.store.dbgtouch = valb == 1;
config.save();
return;
}
if (strcmp(cmd, "flipscreen") == 0) {
- byte valb=atoi(val);
- config.store.flipscreen=valb;
+ byte valb = atoi(val);
+ config.store.flipscreen = valb;
config.save();
display.flip();
- display.putRequest({NEWMODE, CLEAR});
- display.putRequest({NEWMODE, PLAYER});
+ display.putRequest({NEWMODE, CLEAR}); display.putRequest({NEWMODE, PLAYER});
return;
}
if (strcmp(cmd, "brightness") == 0) {
- byte valb=atoi(val);
- if(!config.store.dspon) requestOnChange(DSPON, 0);
- config.store.brightness=valb;
- //display.setContrast();
+ byte valb = atoi(val);
+ if (!config.store.dspon) requestOnChange(DSPON, 0);
+ config.store.brightness = valb;
config.setBrightness(true);
return;
}
if (strcmp(cmd, "screenon") == 0) {
- byte valb=atoi(val);
- //config.store.dspon=valb==1;
- //config.setBrightness(true);
- config.setDspOn(valb==1);
+ byte valb = atoi(val);
+ config.setDspOn(valb == 1);
return;
}
if (strcmp(cmd, "contrast") == 0) {
- byte valb=atoi(val);
- config.store.contrast=valb;
+ byte valb = atoi(val);
+ config.store.contrast = valb;
config.save();
display.setContrast();
return;
}
if (strcmp(cmd, "tzh") == 0) {
- int vali=atoi(val);
- config.store.tzHour=vali;
+ int vali = atoi(val);
+ config.store.tzHour = vali;
return;
}
if (strcmp(cmd, "tzm") == 0) {
- int vali=atoi(val);
- config.store.tzMin=vali;
+ int vali = atoi(val);
+ config.store.tzMin = vali;
return;
}
if (strcmp(cmd, "sntp2") == 0) {
- strlcpy(config.store.sntp2,val, 35);
+ strlcpy(config.store.sntp2, val, 35);
return;
}
if (strcmp(cmd, "sntp1") == 0) {
- strlcpy(config.store.sntp1,val, 35);
- bool tzdone=false;
- if(strlen(config.store.sntp1)>0 && strlen(config.store.sntp2)>0){
+ strlcpy(config.store.sntp1, val, 35);
+ bool tzdone = false;
+ if (strlen(config.store.sntp1) > 0 && strlen(config.store.sntp2) > 0) {
configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1, config.store.sntp2);
- tzdone=true;
- }else if(strlen(config.store.sntp1)>0){
+ tzdone = true;
+ } else if (strlen(config.store.sntp1) > 0) {
configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1);
- tzdone=true;
+ tzdone = true;
}
- if(tzdone){
+ if (tzdone) {
network.requestTimeSync(true);
config.save();
}
return;
}
-
if (strcmp(cmd, "volsteps") == 0) {
- uint8_t valb=atoi(val);
- config.store.volsteps=valb;
+ uint8_t valb = atoi(val);
+ config.store.volsteps = valb;
config.save();
return;
}
if (strcmp(cmd, "encacceleration") == 0) {
- uint16_t valb=atoi(val);
+ uint16_t valb = atoi(val);
setEncAcceleration(valb);
- config.store.encacc=valb;
+ config.store.encacc = valb;
config.save();
return;
}
if (strcmp(cmd, "irtlp") == 0) {
- uint8_t valb=atoi(val);
+ uint8_t valb = atoi(val);
setIRTolerance(valb);
return;
}
if (strcmp(cmd, "showweather") == 0) {
- uint8_t valb=atoi(val);
- config.store.showweather=valb==1;
+ uint8_t valb = atoi(val);
+ config.store.showweather = valb == 1;
config.save();
display.showWeather();
#ifdef USE_NEXTION
nextion.startWeather();
#endif
- display.putRequest({NEWMODE, CLEAR});
- display.putRequest({NEWMODE, PLAYER});
+ display.putRequest({NEWMODE, CLEAR}); display.putRequest({NEWMODE, PLAYER});
return;
}
if (strcmp(cmd, "lat") == 0) {
- strlcpy(config.store.weatherlat,val, 10);
+ strlcpy(config.store.weatherlat, val, 10);
return;
}
if (strcmp(cmd, "lon") == 0) {
- strlcpy(config.store.weatherlon,val, 10);
+ strlcpy(config.store.weatherlon, val, 10);
return;
}
if (strcmp(cmd, "key") == 0) {
- strlcpy(config.store.weatherkey,val, 64);
+ strlcpy(config.store.weatherkey, val, 64);
config.save();
display.showWeather();
#ifdef USE_NEXTION
nextion.startWeather();
#endif
- display.putRequest({NEWMODE, CLEAR});
- display.putRequest({NEWMODE, PLAYER});
+ display.putRequest({NEWMODE, CLEAR}); display.putRequest({NEWMODE, PLAYER});
return;
}
/* RESETS */
if (strcmp(cmd, "reset") == 0) {
if (strcmp(val, "system") == 0) {
- config.store.smartstart=2;
- config.store.audioinfo=false;
- config.store.vumeter=false;
- config.store.softapdelay=0;
+ config.store.smartstart = 2;
+ config.store.audioinfo = false;
+ config.store.vumeter = false;
+ config.store.softapdelay = 0;
config.save();
- display.putRequest({NEWMODE, CLEAR});
- display.putRequest({NEWMODE, PLAYER});
- requestOnChange(GETSYSTEM,clientId);
+ display.putRequest({NEWMODE, CLEAR}); display.putRequest({NEWMODE, PLAYER});
+ requestOnChange(GETSYSTEM, clientId);
return;
}
if (strcmp(val, "screen") == 0) {
- config.store.flipscreen=false;
+ config.store.flipscreen = false;
display.flip();
- config.store.invertdisplay=false;
+ config.store.invertdisplay = false;
display.invert();
- config.store.dspon=true;
- config.store.brightness=100;
+ config.store.dspon = true;
+ config.store.brightness = 100;
config.setBrightness(false);
- config.store.contrast=55;
+ config.store.contrast = 55;
display.setContrast();
- config.store.numplaylist=false;
+ config.store.numplaylist = false;
config.save();
- display.putRequest({NEWMODE, CLEAR});
- display.putRequest({NEWMODE, PLAYER});
- requestOnChange(GETSCREEN,clientId);
+ display.putRequest({NEWMODE, CLEAR}); display.putRequest({NEWMODE, PLAYER});
+ requestOnChange(GETSCREEN, clientId);
return;
}
if (strcmp(val, "timezone") == 0) {
- config.store.tzHour=3;
- config.store.tzMin=0;
- strlcpy(config.store.sntp1,"pool.ntp.org", 35);
- strlcpy(config.store.sntp2,"0.ru.pool.ntp.org", 35);
+ config.store.tzHour = 3;
+ config.store.tzMin = 0;
+ strlcpy(config.store.sntp1, "pool.ntp.org", 35);
+ strlcpy(config.store.sntp2, "0.ru.pool.ntp.org", 35);
config.save();
configTime(config.store.tzHour * 3600 + config.store.tzMin * 60, config.getTimezoneOffset(), config.store.sntp1, config.store.sntp2);
network.requestTimeSync(true);
- requestOnChange(GETTIMEZONE,clientId);
+ requestOnChange(GETTIMEZONE, clientId);
return;
}
if (strcmp(val, "weather") == 0) {
- config.store.showweather=0;
- strlcpy(config.store.weatherlat,"55.7512", 10);
- strlcpy(config.store.weatherlon,"37.6184", 10);
- strlcpy(config.store.weatherkey,"", 64);
+ config.store.showweather = 0;
+ strlcpy(config.store.weatherlat, "55.7512", 10);
+ strlcpy(config.store.weatherlon, "37.6184", 10);
+ strlcpy(config.store.weatherkey, "", 64);
config.save();
display.showWeather();
#ifdef USE_NEXTION
nextion.startWeather();
#endif
- display.putRequest({NEWMODE, CLEAR});
- display.putRequest({NEWMODE, PLAYER});
- requestOnChange(GETWEATHER,clientId);
+ display.putRequest({NEWMODE, CLEAR}); display.putRequest({NEWMODE, PLAYER});
+ requestOnChange(GETWEATHER, clientId);
return;
}
if (strcmp(val, "controls") == 0) {
- config.store.volsteps=1;
- config.store.fliptouch=false;
- config.store.dbgtouch=false;
+ config.store.volsteps = 1;
+ config.store.fliptouch = false;
+ config.store.dbgtouch = false;
setEncAcceleration(200);
setIRTolerance(40);
- requestOnChange(GETCONTROLS,clientId);
+ requestOnChange(GETCONTROLS, clientId);
return;
}
- } /* RESETS */
+ } /* EOF RESETS */
if (strcmp(cmd, "volume") == 0) {
byte v = atoi(val);
player.setVol(v, false);
}
-
- /* REMOVE FROM POST
- * if (request->hasParam("trebble", true)) {
- AsyncWebParameter* pt = request->getParam("trebble", true);
- AsyncWebParameter* pm = request->getParam("middle", true);
- AsyncWebParameter* pb = request->getParam("bass", true);
- int t = atoi(pt->value().c_str());
- int m = atoi(pm->value().c_str());
- int b = atoi(pb->value().c_str());
- //setTone(int8_t gainLowPass, int8_t gainBandPass, int8_t gainHighPass)
- player.setTone(b, m, t);
- config.setTone(b, m, t);
- netserver.requestOnChange(EQUALIZER, 0);
- request->send(200);
- return;
- }
- if (request->hasParam("ballance", true)) {
- AsyncWebParameter* p = request->getParam("ballance", true);
- int b = atoi(p->value().c_str());
- player.setBalance(b);
- config.setBalance(b);
- netserver.requestOnChange(BALANCE, 0);
- request->send(200);
- return;
- }
- */
if (strcmp(cmd, "balance") == 0) {
- int8_t valb=atoi(val);
+ int8_t valb = atoi(val);
player.setBalance(valb);
config.setBalance(valb);
netserver.requestOnChange(BALANCE, 0);
return;
}
if (strcmp(cmd, "treble") == 0) {
- int8_t valb=atoi(val);
+ int8_t valb = atoi(val);
player.setTone(config.store.bass, config.store.middle, valb);
config.setTone(config.store.bass, config.store.middle, valb);
netserver.requestOnChange(EQUALIZER, 0);
return;
}
if (strcmp(cmd, "middle") == 0) {
- int8_t valb=atoi(val);
+ int8_t valb = atoi(val);
player.setTone(config.store.bass, valb, config.store.trebble);
config.setTone(config.store.bass, valb, config.store.trebble);
netserver.requestOnChange(EQUALIZER, 0);
return;
}
if (strcmp(cmd, "bass") == 0) {
- int8_t valb=atoi(val);
+ int8_t valb = atoi(val);
player.setTone(valb, config.store.middle, config.store.trebble);
config.setTone(valb, config.store.middle, config.store.trebble);
netserver.requestOnChange(EQUALIZER, 0);
return;
}
if (strcmp(cmd, "submitplaylist") == 0) {
- if(player.isRunning()){
- player.toggle();
- while (player.isRunning()) {
- vTaskDelay(10);
- }
- vTaskDelay(50);
- resumePlay=true;
- }
+ // xSemaphoreTake(player.playmutex, portMAX_DELAY);
return;
}
if (strcmp(cmd, "submitplaylistdone") == 0) {
- if(resumePlay){
- vTaskDelay(100);
- player.toggle();
- resumePlay=false;
- }
#ifdef MQTT_HOST
- mqttPublishPlaylist();
+ //mqttPublishPlaylist();
+ mqttplaylistticker.attach(5, mqttplaylistSend);
#endif
+ // xSemaphoreGive(player.playmutex);
+ if (player.isRunning()) {
+ player.request.station = config.store.lastStation;
+ player.request.doSave = false;
+ }
return;
}
#if IR_PIN!=255
if (strcmp(cmd, "irbtn") == 0) {
- config.irindex=atoi(val);
- irRecordEnable=(config.irindex>=0);
- config.irchck=0;
+ config.irindex = atoi(val);
+ irRecordEnable = (config.irindex >= 0);
+ config.irchck = 0;
irValsToWs();
- if(config.irindex<0) config.saveIR();
+ if (config.irindex < 0) config.saveIR();
}
if (strcmp(cmd, "chkid") == 0) {
- config.irchck=atoi(val);
+ config.irchck = atoi(val);
}
if (strcmp(cmd, "irclr") == 0) {
byte cl = atoi(val);
- config.ircodes.irVals[config.irindex][cl]=0;
+ config.ircodes.irVals[config.irindex][cl] = 0;
}
#endif
}
}
}
-void NetServer::setRSSI(int val) {
- rssi = val;
- //requestOnChange(NRSSI, 0);
-}
-
void NetServer::getPlaylist(uint8_t clientId) {
char buf[160] = {0};
sprintf(buf, "{\"file\": \"http://%s%s\"}", WiFi.localIP().toString().c_str(), PLAYLIST_PATH);
- if (clientId == 0) {
- websocket.textAll(buf);
- } else {
- websocket.text(clientId, buf);
- }
- if (resumePlay) {
- resumePlay = false;
- player.toggle();
- }
-}
-
-bool NetServer::savePlaylist(const char* post) {
- File file = SPIFFS.open(PLAYLIST_PATH, "w");
- if (!file) {
- return false;
- } else {
- file.print(post);
- file.close();
- vTaskDelay(150);
- netserver.requestOnChange(PLAYLISTSAVED, 0);
- return true;
- }
+ if (clientId == 0) { websocket.textAll(buf); } else { websocket.text(clientId, buf); }
}
bool NetServer::importPlaylist() {
@@ -708,180 +561,71 @@ bool NetServer::importPlaylist() {
void NetServer::requestOnChange(requestType_e request, uint8_t clientId) {
char buf[BUFLEN * 2] = { 0 };
switch (request) {
- case PLAYLIST: {
- getPlaylist(clientId);
- break;
- }
- case PLAYLISTSAVED: {
- config.indexPlaylist();
- config.initPlaylist();
- getPlaylist(clientId);
-/*#ifdef MQTT_HOST
- mqttPublishPlaylist();
-#endif*/
- break;
- }
+ case PLAYLIST: getPlaylist(clientId); break;
+ case PLAYLISTSAVED: config.indexPlaylist(); config.initPlaylist(); getPlaylist(clientId); break;
case GETACTIVE: {
bool dbgact = false;
- String act="\"group_wifi\",";
+ String act = "\"group_wifi\",";
if (network.status == CONNECTED) {
- act+="\"group_system\",";
- if(BRIGHTNESS_PIN!=255 || DSP_FLIPPED==1 || DSP_MODEL==DSP_NOKIA5110 || dbgact){
- act+="\"group_display\",";
- }
+ act += "\"group_system\",";
+ if (BRIGHTNESS_PIN != 255 || DSP_FLIPPED == 1 || DSP_MODEL == DSP_NOKIA5110 || dbgact) act += "\"group_display\",";
#ifdef USE_NEXTION
- act+="\"group_nextion\",";
- if (WEATHER_READY==0 || dbgact){
- act+="\"group_weather\",";
- }
+ act += "\"group_nextion\",";
+ if (WEATHER_READY == 0 || dbgact) act += "\"group_weather\",";
#endif
#if defined(LCD_I2C) || DSP_OLED
- act+="\"group_oled\",";
+ act += "\"group_oled\",";
#endif
- if(VU_READY==1 || dbgact){
- act+="\"group_vu\",";
- }
- if(BRIGHTNESS_PIN!=255 || dbgact){
- act+="\"group_brightness\",";
- }
- if(DSP_FLIPPED==1 || dbgact){
- act+="\"group_tft\",";
- }
- if(TS_CS!=255 || dbgact){
- act+="\"group_touch\",";
- }
- if(DSP_MODEL==DSP_NOKIA5110){
- act+="\"group_nokia\",";
- }
- if(DSP_MODEL!=DSP_DUMMY || dbgact){
- act+="\"group_timezone\",";
-
- }
- if (WEATHER_READY==1 || dbgact){
- act+="\"group_weather\",";
- }
- act+="\"group_controls\",";
- if(ENC_BTNL!=255 || ENC2_BTNL!=255 || dbgact){
- act+="\"group_encoder\",";
- }
- if(IR_PIN!=255 || dbgact){
- act+="\"group_ir\",";
- }
+ if (VU_READY == 1 || dbgact) act += "\"group_vu\",";
+ if (BRIGHTNESS_PIN != 255 || dbgact) act += "\"group_brightness\",";
+ if (DSP_FLIPPED == 1 || dbgact) act += "\"group_tft\",";
+ if (TS_CS != 255 || dbgact) act += "\"group_touch\",";
+ if (DSP_MODEL == DSP_NOKIA5110) act += "\"group_nokia\",";
+ if (DSP_MODEL != DSP_DUMMY || dbgact) act += "\"group_timezone\",";
+ if (WEATHER_READY == 1 || dbgact) act += "\"group_weather\",";
+ act += "\"group_controls\",";
+ if (ENC_BTNL != 255 || ENC2_BTNL != 255 || dbgact) act += "\"group_encoder\",";
+ if (IR_PIN != 255 || dbgact) act += "\"group_ir\",";
}
- act = act.substring(0, act.length()-1);
+ act = act.substring(0, act.length() - 1);
sprintf (buf, "{\"act\":[%s]}", act.c_str());
break;
- }
- case GETMODE: {
- sprintf (buf, "{\"pmode\":\"%s\"}", network.status == CONNECTED?"player":"ap");
- break;
- }
- case GETINDEX: {
- requestOnChange(STATION, clientId);
- requestOnChange(TITLE, clientId);
- requestOnChange(VOLUME, clientId);
- requestOnChange(EQUALIZER, clientId);
- requestOnChange(BALANCE, clientId);
- requestOnChange(BITRATE, clientId);
- requestOnChange(MODE, clientId);
- //playlistrequest = clientId; /* Cleanup this */
- return;
- break;
- }
- case GETSYSTEM: {
- sprintf (buf, "{\"sst\":%d,\"aif\":%d,\"vu\":%d,\"softr\":%d}", config.store.smartstart!=2, config.store.audioinfo, config.store.vumeter, config.store.softapdelay);
- break;
- }
- case GETSCREEN: {
- sprintf (buf, "{\"flip\":%d,\"inv\":%d,\"nump\":%d,\"tsf\":%d,\"tsd\":%d,\"dspon\":%d,\"br\":%d,\"con\":%d}", config.store.flipscreen, config.store.invertdisplay, config.store.numplaylist, config.store.fliptouch, config.store.dbgtouch, config.store.dspon, config.store.brightness, config.store.contrast);
- break;
- }
- case GETTIMEZONE: {
- sprintf (buf, "{\"tzh\":%d,\"tzm\":%d,\"sntp1\":\"%s\",\"sntp2\":\"%s\"}", config.store.tzHour, config.store.tzMin, config.store.sntp1, config.store.sntp2);
- break;
- }
- case GETWEATHER: {
- sprintf (buf, "{\"wen\":%d,\"wlat\":\"%s\",\"wlon\":\"%s\",\"wkey\":\"%s\"}", config.store.showweather, config.store.weatherlat, config.store.weatherlon, config.store.weatherkey);
- break;
- }
- case GETCONTROLS: {
- sprintf (buf, "{\"vols\":%d,\"enca\":%d,\"irtl\":%d}", config.store.volsteps, config.store.encacc, config.store.irtlp);
- break;
- }
- case DSPON: {
- sprintf (buf, "{\"dspontrue\":%d}", 1);
- break;
- }
- case STATION: {
- sprintf (buf, "{\"nameset\": \"%s\"}", config.station.name);
- requestOnChange(ITEM, clientId);
- break;
- }
- case ITEM: {
- sprintf (buf, "{\"current\": %d}", config.store.lastStation);
- break;
- }
- case TITLE: {
- sprintf (buf, "{\"meta\": \"%s\"}", config.station.title);
- if (player.requestToStart) {
- telnet.info();
- player.requestToStart = false;
- } else {
- telnet.printf("##CLI.META#: %s\n> ", config.station.title);
- }
- break;
- }
- case VOLUME: {
- sprintf (buf, "{\"vol\": %d}", config.store.volume);
-#ifdef MQTT_HOST
- if (clientId == 0) mqttPublishVolume();
-#endif
- break;
- }
- case NRSSI: {
- sprintf (buf, "{\"rssi\": %d}", rssi);
- rssi = 255;
- break;
- }
- case BITRATE: {
- sprintf (buf, "{\"bitrate\": %d}", config.station.bitrate);
- break;
- }
- case MODE: {
- sprintf (buf, "{\"mode\": \"%s\"}", player.mode == PLAYING ? "playing" : "stopped");
- break;
- }
- case EQUALIZER: {
- sprintf (buf, "{\"bass\": %d, \"middle\": %d, \"trebble\": %d}", config.store.bass, config.store.middle, config.store.trebble);
- break;
- }
- case BALANCE: {
- sprintf (buf, "{\"balance\": %d}", config.store.balance);
- break;
}
+ case GETMODE: sprintf (buf, "{\"pmode\":\"%s\"}", network.status == CONNECTED ? "player" : "ap"); break;
+ case GETINDEX: requestOnChange(STATION, clientId); requestOnChange(TITLE, clientId); requestOnChange(VOLUME, clientId); requestOnChange(EQUALIZER, clientId); requestOnChange(BALANCE, clientId); requestOnChange(BITRATE, clientId); requestOnChange(MODE, clientId); return; break;
+ case GETSYSTEM: sprintf (buf, "{\"sst\":%d,\"aif\":%d,\"vu\":%d,\"softr\":%d}", config.store.smartstart != 2, config.store.audioinfo, config.store.vumeter, config.store.softapdelay); break;
+ case GETSCREEN: sprintf (buf, "{\"flip\":%d,\"inv\":%d,\"nump\":%d,\"tsf\":%d,\"tsd\":%d,\"dspon\":%d,\"br\":%d,\"con\":%d}", config.store.flipscreen, config.store.invertdisplay, config.store.numplaylist, config.store.fliptouch, config.store.dbgtouch, config.store.dspon, config.store.brightness, config.store.contrast); break;
+ case GETTIMEZONE: sprintf (buf, "{\"tzh\":%d,\"tzm\":%d,\"sntp1\":\"%s\",\"sntp2\":\"%s\"}", config.store.tzHour, config.store.tzMin, config.store.sntp1, config.store.sntp2); break;
+ case GETWEATHER: sprintf (buf, "{\"wen\":%d,\"wlat\":\"%s\",\"wlon\":\"%s\",\"wkey\":\"%s\"}", config.store.showweather, config.store.weatherlat, config.store.weatherlon, config.store.weatherkey); break;
+ case GETCONTROLS: sprintf (buf, "{\"vols\":%d,\"enca\":%d,\"irtl\":%d}", config.store.volsteps, config.store.encacc, config.store.irtlp); break;
+ case DSPON: sprintf (buf, "{\"dspontrue\":%d}", 1); break;
+ case STATION: sprintf (buf, "{\"nameset\": \"%s\"}", config.station.name); requestOnChange(ITEM, clientId); break;
+ case ITEM: sprintf (buf, "{\"current\": %d}", config.store.lastStation); break;
+ case TITLE: sprintf (buf, "{\"meta\": \"%s\"}", config.station.title); if (player.requestToStart) { telnet.info(); player.requestToStart = false; } else { telnet.printf("##CLI.META#: %s\n> ", config.station.title); } break;
+ case VOLUME: sprintf (buf, "{\"vol\": %d}", config.store.volume); break;
+ case NRSSI: sprintf (buf, "{\"rssi\": %d}", rssi); rssi = 255; break;
+ case BITRATE: sprintf (buf, "{\"bitrate\": %d}", config.station.bitrate); break;
+ case MODE: sprintf (buf, "{\"mode\": \"%s\"}", player.mode == PLAYING ? "playing" : "stopped"); break;
+ case EQUALIZER: sprintf (buf, "{\"bass\": %d, \"middle\": %d, \"trebble\": %d}", config.store.bass, config.store.middle, config.store.trebble); DBGVB("[%s] %s", __func__, buf); break;
+ case BALANCE: sprintf (buf, "{\"balance\": %d}", config.store.balance); break;
}
if (strlen(buf) > 0) {
- if (clientId == 0) {
- websocket.textAll(buf);
+ if (clientId == 0) { websocket.textAll(buf); }else{ websocket.text(clientId, buf); }
#ifdef MQTT_HOST
- if (request == STATION || request == ITEM || request == TITLE || request == MODE) mqttPublishStatus();
+ if (clientId == 0 && (request == STATION || request == ITEM || request == TITLE || request == MODE)) mqttPublishStatus();
+ if (clientId == 0 && request == VOLUME) mqttPublishVolume();
#endif
- } else {
- websocket.text(clientId, buf);
- }
}
}
String processor(const String& var) { // %Templates%
- if (var == "VERSION") {
- return VERSION;
- }
+ if (var == "VERSION") return VERSION;
return String();
}
void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
if (!index) {
- netserver.takeMallocDog();
+ PLOW();
request->_tempFile = SPIFFS.open(TMP_PATH , "w");
}
if (len) {
@@ -890,130 +634,97 @@ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index,
}
if (final) {
request->_tempFile.close();
- netserver.importRequest = true;
- request->send(200);
+ PHIG();
}
}
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
switch (type) {
- case WS_EVT_CONNECT:
- if(config.store.audioinfo) Serial.printf("[WEBSOCKET] client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
- /*netserver.requestOnChange(STATION, client->id());
- netserver.requestOnChange(TITLE, client->id());
- netserver.requestOnChange(VOLUME, client->id());
- netserver.requestOnChange(EQUALIZER, client->id());
- netserver.requestOnChange(BALANCE, client->id());
- netserver.requestOnChange(BITRATE, client->id());
- netserver.requestOnChange(MODE, client->id());
- netserver.playlistrequest = client->id();*/
-
- break;
- case WS_EVT_DISCONNECT:
- if(config.store.audioinfo) Serial.printf("[WEBSOCKET] client #%u disconnected\n", client->id());
- break;
- case WS_EVT_DATA:
- netserver.onWsMessage(arg, data, len, client->id());
- break;
+ case WS_EVT_CONNECT: if (config.store.audioinfo) Serial.printf("[WEBSOCKET] client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str()); break;
+ case WS_EVT_DISCONNECT: if (config.store.audioinfo) Serial.printf("[WEBSOCKET] client #%u disconnected\n", client->id()); break;
+ case WS_EVT_DATA: netserver.onWsMessage(arg, data, len, client->id()); break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
}
}
-void handleHTTPPost(AsyncWebServerRequest * request) {
- if (request->hasParam("wifisettings", true)) {
- AsyncWebParameter* p = request->getParam("wifisettings", true);
- if (p->value() != "") {
- config.saveWifi(p->value().c_str());
+void handleHTTPArgs(AsyncWebServerRequest * request) {
+ if (request->method() == HTTP_GET) {
+ DBGVB("[%s] client ip=%s request of %s", __func__, request->client()->remoteIP().toString().c_str(), request->url().c_str());
+ if (strcmp(request->url().c_str(), PLAYLIST_PATH) == 0 || strcmp(request->url().c_str(), SSIDS_PATH) == 0 || strcmp(request->url().c_str(), INDEX_PATH) == 0 || strcmp(request->url().c_str(), TMP_PATH) == 0) {
+#ifdef MQTT_HOST
+ if (strcmp(request->url().c_str(), PLAYLIST_PATH) == 0) while (mqttplaylistblock) vTaskDelay(5);
+#endif
+ netserver.chunkedHtmlPage("application/octet-stream", request, request->url().c_str());
+ return;
+ }
+ if (strcmp(request->url().c_str(), "/") == 0 && request->params() == 0) {
+ netserver.chunkedHtmlPage(String(), request, network.status == CONNECTED ? "/www/index.html" : "/www/settings.html");
+ return;
+ }
+ if (strcmp(request->url().c_str(), "/update") == 0 || strcmp(request->url().c_str(), "/settings") == 0 || strcmp(request->url().c_str(), "/ir") == 0) {
+ char buf[40] = { 0 };
+ sprintf(buf, "/www%s.html", request->url().c_str());
+ netserver.chunkedHtmlPage(String(), request, buf);
+ return;
}
- request->send(200);
- return;
- }
- if (request->hasParam("playlist", true)) {
- AsyncWebParameter* p = request->getParam("playlist", true);
- netserver.savePlaylist(p->value().c_str());
- request->send(200);
- return;
- }
- if (network.status != CONNECTED) {
- request->send(404);
- return;
- }
- if (request->hasParam("start", true)) {
- player.request.station = config.store.lastStation;
- request->send(200);
- return;
- }
- if (request->hasParam("stop", true)) {
- player.mode = STOPPED;
- //display.title("[stopped]");
- config.setTitle("[stopped]");
- request->send(200);
- return;
- }
- if (request->hasParam("prev", true)) {
- player.prev();
- request->send(200);
- return;
- }
- if (request->hasParam("next", true)) {
- player.next();
- request->send(200);
- return;
- }
- if (request->hasParam("volm", true)) {
- player.stepVol(false);
- request->send(200);
- return;
- }
- if (request->hasParam("volp", true)) {
- player.stepVol(true);
- request->send(200);
- return;
- }
- if (request->hasParam("vol", true)) {
- AsyncWebParameter* p = request->getParam("vol", true);
- int v = atoi(p->value().c_str());
- if (v < 0) v = 0;
- if (v > 254) v = 254;
- player.setVol(v, false);
- request->send(200);
- return;
- }
- if (request->hasParam("trebble", true)) {
- AsyncWebParameter* pt = request->getParam("trebble", true);
- AsyncWebParameter* pm = request->getParam("middle", true);
- AsyncWebParameter* pb = request->getParam("bass", true);
- int t = atoi(pt->value().c_str());
- int m = atoi(pm->value().c_str());
- int b = atoi(pb->value().c_str());
- //setTone(int8_t gainLowPass, int8_t gainBandPass, int8_t gainHighPass)
- player.setTone(b, m, t);
- config.setTone(b, m, t);
- netserver.requestOnChange(EQUALIZER, 0);
- request->send(200);
- return;
- }
- if (request->hasParam("ballance", true)) {
- AsyncWebParameter* p = request->getParam("ballance", true);
- int b = atoi(p->value().c_str());
- player.setBalance(b);
- config.setBalance(b);
- netserver.requestOnChange(BALANCE, 0);
- request->send(200);
- return;
- }
- if (request->hasParam("playstation", true)) {
- AsyncWebParameter* p = request->getParam("playstation", true);
- int id = atoi(p->value().c_str());
- if (id < 1) id = 1;
- if (id > config.store.countStation) id = config.store.countStation;
- player.request.station = id;
- player.request.doSave = true;
- request->send(200);
- return;
}
+ if (network.status == CONNECTED) {
+ if (request->hasArg("start")) player.request.station = config.store.lastStation;
+ if (request->hasArg("stop")) {
+ player.mode = STOPPED;
+ config.setTitle("[stopped]");
+ }
+ if (request->hasArg("prev")) player.prev();
+ if (request->hasArg("next")) player.next();
+ if (request->hasArg("volm")) player.stepVol(false);
+ if (request->hasArg("volp")) player.stepVol(true);
- request->send(404);
+ if (request->hasArg("trebble") && request->hasArg("middle") && request->hasArg("bass")) {
+ AsyncWebParameter* pt = request->getParam("trebble", request->method() == HTTP_POST);
+ AsyncWebParameter* pm = request->getParam("middle", request->method() == HTTP_POST);
+ AsyncWebParameter* pb = request->getParam("bass", request->method() == HTTP_POST);
+ int t = atoi(pt->value().c_str());
+ int m = atoi(pm->value().c_str());
+ int b = atoi(pb->value().c_str());
+ player.setTone(b, m, t);
+ config.setTone(b, m, t);
+ netserver.requestOnChange(EQUALIZER, 0);
+ }
+ if (request->hasArg("ballance")) {
+ AsyncWebParameter* p = request->getParam("ballance", request->method() == HTTP_POST);
+ int b = atoi(p->value().c_str());
+ player.setBalance(b);
+ config.setBalance(b);
+ netserver.requestOnChange(BALANCE, 0);
+ }
+ if (request->hasArg("playstation") || request->hasArg("play")) {
+ AsyncWebParameter* p = request->getParam(request->hasArg("playstation") ? "playstation" : "play", request->method() == HTTP_POST);
+ int id = atoi(p->value().c_str());
+ if (id < 1) id = 1;
+ if (id > config.store.countStation) id = config.store.countStation;
+ player.request.station = id;
+ player.request.doSave = true;
+ DBGVB("[%s] play=%d", __func__, id);
+ }
+ if (request->hasArg("vol")) {
+ AsyncWebParameter* p = request->getParam("vol", request->method() == HTTP_POST);
+ int v = atoi(p->value().c_str());
+ if (v < 0) v = 0;
+ if (v > 254) v = 254;
+ config.store.volume = v;
+ player.setVol(v, false);
+ DBGVB("[%s] vol=%d", __func__, v);
+ }
+ if (request->params() > 0) {
+ request->send(200);
+ return;
+ }
+ } else {
+ if (request->params() > 0) {
+ request->send(404);
+ return;
+ }
+ }
}
diff --git a/yoRadio/netserver.h b/yoRadio/netserver.h
index 437e599..914faf6 100644
--- a/yoRadio/netserver.h
+++ b/yoRadio/netserver.h
@@ -6,38 +6,38 @@
#include "AsyncUDP.h"
enum requestType_e : uint8_t { PLAYLIST=1, STATION=2, ITEM=3, TITLE=4, VOLUME=5, NRSSI=6, BITRATE=7, MODE=8, EQUALIZER=9, BALANCE=10, PLAYLISTSAVED=11, GETMODE=12, GETINDEX=13, GETACTIVE=14, GETSYSTEM=15, GETSCREEN=16, GETTIMEZONE=17, GETWEATHER=18, GETCONTROLS=19, DSPON=20 };
-enum htmlPath_e : uint8_t { PINDEX=1, PSETTINGS=2, PUPDATE=3, PIR=4, PPLAYLIST=5, PSSIDS=6 };
+enum import_e : uint8_t { IMDONE=0, IMPL=1, IMWIFI=2 };
+
+#define PLOW() //player.setBufsize(1600*2, -1); vTaskDelay(150)
+#define PHIG() //vTaskDelay(150); player.setBufsize(1600*AUDIOBUFFER_MULTIPLIER2, -1)
class NetServer {
public:
- uint8_t playlistrequest; // ClientId want the playlist
- bool importRequest;
+ //uint8_t playlistrequest; // ClientId want the playlist/* Cleanup this */
+ import_e importRequest;
bool resumePlay;
- htmlPath_e htmlPath;
+ char chunkedPathBuffer[40];
public:
NetServer() {};
bool begin();
void loop();
void requestOnChange(requestType_e request, uint8_t clientId);
- void setRSSI(int val);
+ void setRSSI(int val) { rssi = val; };
+ void chunkedHtmlPage(const String& contentType, AsyncWebServerRequest *request, const char * path, bool gzip = false);
void onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t clientId);
- bool savePlaylist(const char* post);
- void takeMallocDog();
- void giveMallocDog();
- uint32_t max, htmlpos;
- bool theend;
#if IR_PIN!=255
bool irRecordEnable;
void irToWs(const char* protocol, uint64_t irvalue);
- void irValsToWs();
- void chunkedHtmlPage(const String& contentType, AsyncWebServerRequest *request);
+ void irValsToWs();
#endif
private:
requestType_e request;
int rssi;
-
void getPlaylist(uint8_t clientId);
bool importPlaylist();
+ static size_t chunkedHtmlPageCallback(uint8_t* buffer, size_t maxLen, size_t index);
+ static void beginUpload(AsyncWebServerRequest *request);
+ static void beginUpdate(AsyncWebServerRequest *request);
};
extern NetServer netserver;
diff --git a/yoRadio/options.h b/yoRadio/options.h
index a216f1f..63d0fc6 100644
--- a/yoRadio/options.h
+++ b/yoRadio/options.h
@@ -1,7 +1,7 @@
#ifndef options_h
#define options_h
-#define VERSION "0.7.414"
+#define VERSION "0.7.490"
/*******************************************************
DO NOT EDIT THIS FILE.
diff --git a/yoRadio/player.cpp b/yoRadio/player.cpp
index f200d01..40810b8 100644
--- a/yoRadio/player.cpp
+++ b/yoRadio/player.cpp
@@ -61,7 +61,10 @@ void Player::stopInfo() {
void Player::loop() {
if (mode == PLAYING) {
+ xSemaphoreTake(playmutex, portMAX_DELAY);
Audio::loop();
+ xSemaphoreGive(playmutex);
+ vTaskDelay(2);
} else {
if (isRunning()) {
//digitalWrite(LED_BUILTIN, LOW);
@@ -71,7 +74,6 @@ void Player::loop() {
//stopSong();
setDefaults();
stopInfo();
- xSemaphoreGive(playmutex);
if (player_on_stop_play) player_on_stop_play();
}
}
@@ -112,8 +114,6 @@ void Player::setOutputPins(bool isPlaying) {
void Player::play(uint16_t stationId) {
//stopSong();
- xSemaphoreGive(playmutex);
- xSemaphoreTake(playmutex, portMAX_DELAY);
setDefaults();
setOutputPins(false);
config.setTitle("[connecting]");
diff --git a/yoRadio/src/audioI2S/AudioEx.h b/yoRadio/src/audioI2S/AudioEx.h
index 6236d31..5d6ab3f 100644
--- a/yoRadio/src/audioI2S/AudioEx.h
+++ b/yoRadio/src/audioI2S/AudioEx.h
@@ -32,8 +32,8 @@
#include
#endif // SDFATFS_USED
-#ifndef AUDIOBUFFER_MULTIPLIER
-#define AUDIOBUFFER_MULTIPLIER 12
+#ifndef AUDIOBUFFER_MULTIPLIER2
+#define AUDIOBUFFER_MULTIPLIER2 8
#endif
#ifdef SDFATFS_USED
@@ -140,7 +140,7 @@ public:
protected:
size_t m_buffSizePSRAM = 300000; // most webstreams limit the advance to 100...300Kbytes
//size_t m_buffSizeRAM = 1600 * 5;
- size_t m_buffSizeRAM = 1600 * AUDIOBUFFER_MULTIPLIER;
+ size_t m_buffSizeRAM = 1600 * AUDIOBUFFER_MULTIPLIER2;
size_t m_buffSize = 0;
size_t m_freeSpace = 0;
size_t m_writeSpace = 0;
diff --git a/yoRadio/src/audioVS1053/audioVS1053Ex.cpp b/yoRadio/src/audioVS1053/audioVS1053Ex.cpp
index 52fb031..f9ff3ef 100644
--- a/yoRadio/src/audioVS1053/audioVS1053Ex.cpp
+++ b/yoRadio/src/audioVS1053/audioVS1053Ex.cpp
@@ -7,7 +7,9 @@
* Updated on: Aug 15.2022
* Author: Wolle
*/
-
+#ifndef VS_PATCH_ENABLE
+#define VS_PATCH_ENABLE true
+#endif
#include "audioVS1053Ex.h"
//---------------------------------------------------------------------------------------------------------------------
@@ -325,7 +327,7 @@ void Audio::begin(){
setVUmeter();
m_endFillByte = wram_read(0x1E06) & 0xFF;
// printDetails("After last clocksetting \n");
- loadUserCode(); // load in VS1053B if you want to play flac
+ if(VS_PATCH_ENABLE) loadUserCode(); // load in VS1053B if you want to play flac
startSong();
}
//---------------------------------------------------------------------------------------------------------------------
@@ -1613,6 +1615,7 @@ void Audio::setDefaults(){
* \n The VU meter takes about 0.2MHz of processing power with 48 kHz samplerate.
*/
void Audio::setVUmeter() {
+ if(!VS_PATCH_ENABLE) return;
uint16_t MP3Status = read_register(SCI_STATUS);
if(MP3Status==0) {
Serial.println("VS1053 Error: Unable to write SCI_STATUS");
@@ -1636,6 +1639,7 @@ void Audio::setVUmeter() {
* \warning This feature is only available with patches that support VU meter.
*/
void Audio::getVUlevel() {
+ if(!VS_PATCH_ENABLE) return;
if(!_vuInitalized) return;
int16_t reg = read_register(SCI_AICTRL3);
uint8_t rl = map((uint8_t)reg, 85, 92, 0, 255);
diff --git a/yoRadio/src/audioVS1053/audioVS1053Ex.h b/yoRadio/src/audioVS1053/audioVS1053Ex.h
index d9b17c5..b7020ba 100644
--- a/yoRadio/src/audioVS1053/audioVS1053Ex.h
+++ b/yoRadio/src/audioVS1053/audioVS1053Ex.h
@@ -9,8 +9,8 @@
#ifndef _vs1053_ext
#define _vs1053_ext
-#ifndef AUDIOBUFFER_MULTIPLIER
-#define AUDIOBUFFER_MULTIPLIER 12
+#ifndef AUDIOBUFFER_MULTIPLIER2
+#define AUDIOBUFFER_MULTIPLIER2 10
#endif
#define VS1053VOLM 128 // 128 or 96 only
@@ -97,7 +97,7 @@ public:
protected:
const size_t m_buffSizePSRAM = 300000; // most webstreams limit the advance to 100...300Kbytes
//const size_t m_buffSizeRAM = 1600 * 10;
- const size_t m_buffSizeRAM = 1600 * AUDIOBUFFER_MULTIPLIER;
+ const size_t m_buffSizeRAM = 1600 * AUDIOBUFFER_MULTIPLIER2;
size_t m_buffSize = 0;
size_t m_freeSpace = 0;
size_t m_writeSpace = 0;
diff --git a/yoRadio/src/displays/nextion.cpp b/yoRadio/src/displays/nextion.cpp
index 5d55817..e4beb6c 100644
--- a/yoRadio/src/displays/nextion.cpp
+++ b/yoRadio/src/displays/nextion.cpp
@@ -353,7 +353,7 @@ void Nextion::loop() {
wifisettings+=(String(scanBuf)+"\n");
}
if (sscanf(rxbuf, "wifidone=%d", &scanDigit) == 1){
- config.saveWifi(wifisettings.c_str());
+ config.saveWifiFromNextion(wifisettings.c_str());
}
}
}