v0.9.561
This commit is contained in:
@@ -234,6 +234,14 @@ Work is in progress...
|
||||
|
||||
---
|
||||
## Version history
|
||||
### 0.9.561
|
||||
**!!! a [full update](#update-over-web-interface) with Sketch data upload is required !!!**\
|
||||
or-> just upload `yoRadio/data/www/script.js.gz` to Webboard Uploader http://radioipaddr/webboard\
|
||||
After updating please clear browser cache.
|
||||
- fixed error when switching to SD Card mode
|
||||
- fixed issue causing random reboots
|
||||
- fixed preview playback bug in Playlist Editor
|
||||
|
||||
### 0.9.555
|
||||
- fixed error "assert failed: udp_new_ip_type /IDF/components/lwip/lwip/src/core/udp.c:1278 (Required to lock TCPIP core functionality!)"\
|
||||
part #2
|
||||
|
||||
Binary file not shown.
@@ -1225,12 +1225,14 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t
|
||||
void AsyncWebSocket::_cleanBuffers()
|
||||
{
|
||||
AsyncWebLockGuard l(_lock);
|
||||
|
||||
for(AsyncWebSocketMessageBuffer * c: _buffers){
|
||||
while (_buffers.remove_first([](AsyncWebSocketMessageBuffer* b) {
|
||||
return b && b->canDelete();
|
||||
}));
|
||||
/*for(AsyncWebSocketMessageBuffer * c: _buffers){
|
||||
if(c && c->canDelete()){
|
||||
_buffers.remove(c);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
AsyncWebSocket::AsyncWebSocketClientLinkedList AsyncWebSocket::getClients() const {
|
||||
|
||||
@@ -86,9 +86,8 @@ class AsyncWebSocketMessageBuffer {
|
||||
private:
|
||||
uint8_t * _data;
|
||||
size_t _len;
|
||||
bool _lock;
|
||||
volatile bool _lock;
|
||||
uint32_t _count;
|
||||
|
||||
public:
|
||||
AsyncWebSocketMessageBuffer();
|
||||
AsyncWebSocketMessageBuffer(size_t size);
|
||||
|
||||
@@ -1717,7 +1717,6 @@ void Audio::setConnectionTimeout(uint16_t timeout_ms, uint16_t timeout_ms_ssl){
|
||||
void Audio::connectTask(void* pvParams) {
|
||||
ConnectParams* params = static_cast<ConnectParams*>(pvParams);
|
||||
Audio* self = params->instance;
|
||||
bool res = true;
|
||||
if(self->_client){
|
||||
self->_connectionResult = self->_client->connect(params->hostwoext, params->port/*, self->m_f_ssl ? self->m_timeout_ms_ssl : self->m_timeout_ms*/);
|
||||
}else{
|
||||
|
||||
@@ -175,8 +175,10 @@ void Config::changeMode(int newmode){
|
||||
if(getMode()==PM_SDCARD){
|
||||
if(pir) player.sendCommand({PR_STOP, 0});
|
||||
display.putRequest(NEWMODE, SDCHANGE);
|
||||
#ifdef NETSERVER_LOOP1
|
||||
while(display.mode()!=SDCHANGE)
|
||||
delay(10);
|
||||
#endif
|
||||
delay(50);
|
||||
}
|
||||
if(getMode()==PM_WEB) {
|
||||
@@ -222,6 +224,11 @@ bool Config::spiffsCleanup(){
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Config::waitConnection(){
|
||||
while(!player.connproc) vTaskDelay(50);
|
||||
vTaskDelay(500);
|
||||
}
|
||||
|
||||
char * Config::ipToStr(IPAddress ip){
|
||||
snprintf(ipBuf, 16, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
|
||||
return ipBuf;
|
||||
|
||||
@@ -280,6 +280,7 @@ class Config {
|
||||
#endif
|
||||
void resetSystem(const char *val, uint8_t clientId);
|
||||
bool spiffsCleanup();
|
||||
void waitConnection();
|
||||
char * ipToStr(IPAddress ip);
|
||||
bool prepareForPlaying(uint16_t stationId);
|
||||
void configPostPlaying(uint16_t stationId);
|
||||
|
||||
@@ -22,6 +22,16 @@ Nextion nextion;
|
||||
#ifndef DSP_TASK_CORE_ID
|
||||
#define DSP_TASK_CORE_ID 0
|
||||
#endif
|
||||
#ifndef DSP_TASK_DELAY
|
||||
#define DSP_TASK_DELAY pdMS_TO_TICKS(10) // cap for 50 fps
|
||||
#endif
|
||||
|
||||
#define DSP_QUEUE_TICKS 0
|
||||
|
||||
#ifndef DSQ_SEND_DELAY
|
||||
//#define DSQ_SEND_DELAY portMAX_DELAY
|
||||
#define DSQ_SEND_DELAY pdMS_TO_TICKS(200)
|
||||
#endif
|
||||
|
||||
QueueHandle_t displayQueue;
|
||||
|
||||
@@ -29,17 +39,20 @@ static void loopDspTask(void * pvParameters){
|
||||
while(true){
|
||||
#ifndef DUMMYDISPLAY
|
||||
if(displayQueue==NULL) break;
|
||||
netserver.loop();
|
||||
if(timekeeper.loop0())
|
||||
if(timekeeper.loop0()){
|
||||
display.loop();
|
||||
// will NOT delay here, would use message dequeue timeout instead
|
||||
//vTaskDelay(DSP_TASK_DELAY);
|
||||
#else
|
||||
#ifndef NETSERVER_LOOP1
|
||||
netserver.loop();
|
||||
timekeeper.loop0();
|
||||
vTaskDelay(10);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
timekeeper.loop0();
|
||||
#ifndef NETSERVER_LOOP1
|
||||
netserver.loop();
|
||||
#endif
|
||||
#endif
|
||||
vTaskDelay(DSP_TASK_DELAY);
|
||||
}
|
||||
vTaskDelete( NULL );
|
||||
}
|
||||
|
||||
@@ -53,18 +66,6 @@ DspCore dsp;
|
||||
|
||||
Page *pages[] = { new Page(), new Page(), new Page(), new Page() };
|
||||
|
||||
#ifndef DSQ_SEND_DELAY
|
||||
//#define DSQ_SEND_DELAY portMAX_DELAY
|
||||
#define DSQ_SEND_DELAY pdMS_TO_TICKS(200)
|
||||
#endif
|
||||
|
||||
#ifndef DSP_TASK_DELAY
|
||||
#define DSP_TASK_DELAY pdMS_TO_TICKS(20) // cap for 50 fps
|
||||
#endif
|
||||
|
||||
// will use DSP_QUEUE_TICKS as delay interval for display task runner when there are no msgs in a queue to process
|
||||
#define DSP_QUEUE_TICKS DSP_TASK_DELAY
|
||||
|
||||
#if !((DSP_MODEL==DSP_ST7735 && DTYPE==INITR_BLACKTAB) || DSP_MODEL==DSP_ST7789 || DSP_MODEL==DSP_ST7796 || DSP_MODEL==DSP_ILI9488 || DSP_MODEL==DSP_ILI9486 || DSP_MODEL==DSP_ILI9341 || DSP_MODEL==DSP_ILI9225)
|
||||
#undef BITRATE_FULL
|
||||
#define BITRATE_FULL false
|
||||
@@ -397,7 +398,7 @@ void Display::loop() {
|
||||
_bootScreen();
|
||||
return;
|
||||
}
|
||||
if(displayQueue==NULL) return;
|
||||
if(displayQueue==NULL || _locked) return;
|
||||
_pager.loop();
|
||||
#ifdef USE_NEXTION
|
||||
nextion.loop();
|
||||
|
||||
@@ -37,6 +37,8 @@ class Display {
|
||||
void wakeup();
|
||||
void setContrast();
|
||||
void printPLitem(uint8_t pos, const char* item);
|
||||
void lock() { _locked=true; }
|
||||
void unlock() { _locked=false; }
|
||||
private:
|
||||
ScrollWidget _meta, _title1, _plcurrent;
|
||||
ScrollWidget *_weather;
|
||||
@@ -52,6 +54,7 @@ class Display {
|
||||
ClockWidget _clock;
|
||||
Page *_boot;
|
||||
TextWidget *_bootstring, *_volip, *_voltxt, *_rssi, *_bitrate;
|
||||
bool _locked = false;
|
||||
uint8_t _bootStep;
|
||||
void _time(bool redraw = false);
|
||||
void _apScreen();
|
||||
|
||||
@@ -12,7 +12,7 @@ TimerHandle_t mqttReconnectTimer;
|
||||
char topic[100], status[BUFLEN+50];
|
||||
|
||||
void connectToMqtt() {
|
||||
while(!player.connproc) vTaskDelay(50);
|
||||
//config.waitConnection();
|
||||
mqttClient.connect();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "commandhandler.h"
|
||||
#include "timekeeper.h"
|
||||
#include <Update.h>
|
||||
#include <ESPmDNS.h>
|
||||
|
||||
//#include <Ticker.h>
|
||||
|
||||
#ifdef USE_SD
|
||||
@@ -21,7 +21,12 @@
|
||||
#define MIN_MALLOC 24112
|
||||
#endif
|
||||
#ifndef NSQ_SEND_DELAY
|
||||
#define NSQ_SEND_DELAY pdMS_TO_TICKS(100) //portMAX_DELAY?
|
||||
//#define NSQ_SEND_DELAY portMAX_DELAY
|
||||
#define NSQ_SEND_DELAY pdMS_TO_TICKS(300)
|
||||
#endif
|
||||
#ifndef NS_QUEUE_TICKS
|
||||
//#define NS_QUEUE_TICKS pdMS_TO_TICKS(2)
|
||||
#define NS_QUEUE_TICKS 0
|
||||
#endif
|
||||
|
||||
//#define CORS_DEBUG //Enable CORS policy: 'Access-Control-Allow-Origin' (for testing)
|
||||
@@ -72,8 +77,8 @@ bool NetServer::begin(bool quiet) {
|
||||
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Headers"), F("content-type"));
|
||||
#endif
|
||||
webserver.begin();
|
||||
if(strlen(config.store.mdnsname)>0)
|
||||
MDNS.begin(config.store.mdnsname);
|
||||
//if(strlen(config.store.mdnsname)>0)
|
||||
// MDNS.begin(config.store.mdnsname);
|
||||
websocket.onEvent(onWsEvent);
|
||||
webserver.addHandler(&websocket);
|
||||
if(!quiet) Serial.println("done");
|
||||
@@ -93,10 +98,12 @@ size_t NetServer::chunkedHtmlPageCallback(uint8_t* buffer, size_t maxLen, size_t
|
||||
size_t needread = filesize - index;
|
||||
if (!needread) {
|
||||
requiredfile.close();
|
||||
display.unlock();
|
||||
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);
|
||||
//netserver.loop();
|
||||
requiredfile.seek(index, SeekSet);
|
||||
requiredfile.read(buffer, canread);
|
||||
index += canread;
|
||||
@@ -108,6 +115,9 @@ void NetServer::chunkedHtmlPage(const String& contentType, AsyncWebServerRequest
|
||||
memset(chunkedPathBuffer, 0, sizeof(chunkedPathBuffer));
|
||||
strlcpy(chunkedPathBuffer, path, sizeof(chunkedPathBuffer)-1);
|
||||
AsyncWebServerResponse *response;
|
||||
#ifndef NETSERVER_LOOP1
|
||||
display.lock();
|
||||
#endif
|
||||
response = request->beginChunkedResponse(contentType, chunkedHtmlPageCallback);
|
||||
response->addHeader("Cache-Control","max-age=31536000");
|
||||
request->send(response);
|
||||
@@ -124,10 +134,6 @@ void NetServer::chunkedHtmlPage(const String& contentType, AsyncWebServerRequest
|
||||
#define SHOW_WEATHER false
|
||||
#endif
|
||||
|
||||
#ifndef NS_QUEUE_TICKS
|
||||
#define NS_QUEUE_TICKS 2
|
||||
#endif
|
||||
|
||||
const char *getFormat(BitrateFormat _format) {
|
||||
switch (_format) {
|
||||
case BF_MP3: return "MP3";
|
||||
@@ -308,13 +314,14 @@ void NetServer::loop() {
|
||||
delay(100);
|
||||
ESP.restart();
|
||||
}
|
||||
processQueue();
|
||||
websocket.cleanupClients();
|
||||
switch (importRequest) {
|
||||
case IMPL: importPlaylist(); importRequest = IMDONE; break;
|
||||
case IMWIFI: config.saveWifi(); importRequest = IMDONE; break;
|
||||
default: break;
|
||||
}
|
||||
processQueue();
|
||||
//processQueue();
|
||||
}
|
||||
|
||||
#if IR_PIN!=255
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "player.h"
|
||||
#include "mqtt.h"
|
||||
#include "timekeeper.h"
|
||||
#include <ESPmDNS.h>
|
||||
|
||||
#ifndef WIFI_ATTEMPTS
|
||||
#define WIFI_ATTEMPTS 16
|
||||
@@ -154,6 +155,8 @@ void MyNetwork::setWifiParams(){
|
||||
WiFi.onEvent(WiFiReconnected, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_GOT_IP);
|
||||
WiFi.onEvent(WiFiLostConnection, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
|
||||
//config.setTimeConf(); //??
|
||||
if(strlen(config.store.mdnsname)>0)
|
||||
MDNS.begin(config.store.mdnsname);
|
||||
}
|
||||
|
||||
void MyNetwork::requestTimeSync(bool withTelnetOutput, uint8_t clientId) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef options_h
|
||||
#define options_h
|
||||
|
||||
#define YOVERSION "0.9.555"
|
||||
#define YOVERSION "0.9.561"
|
||||
|
||||
/*******************************************************
|
||||
DO NOT EDIT THIS FILE.
|
||||
|
||||
@@ -206,6 +206,7 @@ void TimeKeeper::_upSDPos(){
|
||||
|
||||
void TimeKeeper::timeTask(){
|
||||
static uint8_t tsFailCnt = 0;
|
||||
config.waitConnection();
|
||||
if(getLocalTime(&network.timeinfo)){
|
||||
tsFailCnt = 0;
|
||||
forceTimeSync = false;
|
||||
@@ -226,8 +227,8 @@ void TimeKeeper::timeTask(){
|
||||
}
|
||||
}
|
||||
void TimeKeeper::weatherTask(){
|
||||
if(!weatherBuf || strlen(config.store.weatherkey)==0 || !config.store.showweather) return;
|
||||
forceWeather = false;
|
||||
if(!weatherBuf || strlen(config.store.weatherkey)==0 || !config.store.showweather) return;
|
||||
_getWeather();
|
||||
}
|
||||
|
||||
@@ -328,7 +329,7 @@ bool _getWeather() {
|
||||
}
|
||||
}, NULL); // <-- client->onData
|
||||
}, NULL); // <-- weatherClient->onConnect
|
||||
while(!player.connproc) vTaskDelay(50);
|
||||
config.waitConnection();
|
||||
if(!weatherClient->connect(host, 80)){
|
||||
Serial.println("##WEATHER###: connection failed");
|
||||
AsyncClient * client = weatherClient;
|
||||
|
||||
@@ -99,7 +99,6 @@ void setup() {
|
||||
if (config.getMode()==PM_SDCARD) player.initHeaders(config.station.url);
|
||||
player.lockOutput=false;
|
||||
if (config.store.smartstart == 1) {
|
||||
delay(250);
|
||||
player.sendCommand({PR_PLAY, config.lastStation()});
|
||||
}
|
||||
pm.on_end_setup();
|
||||
@@ -115,7 +114,9 @@ void loop() {
|
||||
#endif
|
||||
}
|
||||
loopControls();
|
||||
//netserver.loop();
|
||||
#ifdef NETSERVER_LOOP1
|
||||
netserver.loop();
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "core/audiohandlers.h"
|
||||
|
||||
Reference in New Issue
Block a user