mirror of https://github.com/e2002/yoradio.git
Compare commits
4 Commits
c2c1908f96
...
e4175e8a8e
| Author | SHA1 | Date |
|---|---|---|
|
|
e4175e8a8e | |
|
|
98c005d5e0 | |
|
|
e339e820fc | |
|
|
c7eb9cc700 |
10
README.md
10
README.md
|
|
@ -234,6 +234,16 @@ Work is in progress...
|
|||
|
||||
---
|
||||
## Version history
|
||||
### 0.9.420
|
||||
**!!! a [full update](#update-over-web-interface) with Sketch data upload is required. After updating please press CTRL+F5 in browser !!!**
|
||||
- added screensaver mode during playback, configurable via the web interface, pull request[#129](https://github.com/e2002/yoradio/pull/129)
|
||||
- added blank screen mode to screensaver, configurable via the web interface, pull request[#129](https://github.com/e2002/yoradio/pull/129)
|
||||
Thanks to @trip5 for the amazing code!
|
||||
- speeding up indexing of SD cards (advice - don't put all files in one folder)
|
||||
- i don't remember (honestly) why the AsyncTCP server worked on the same core with the player, now it works on the same core with the display
|
||||
`#define CONFIG_ASYNC_TCP_RUNNING_CORE 0`
|
||||
- bug fixes
|
||||
|
||||
### v0.9.412
|
||||
**!!! a [full update](#update-over-web-interface) with Sketch data upload is required. After updating please press CTRL+F5 in browser !!!**
|
||||
- added mDNS support, configurable via the web interface, pull[#125](https://github.com/e2002/yoradio/pull/125)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -78,12 +78,30 @@
|
|||
<div class="row-title"><span>screensaver</span></div>
|
||||
<div class="flex-row group group_tft group_oled group_nextion hidden" style="margin-top:20px;">
|
||||
<div class="inputwrap">
|
||||
<span class="inputtitle">screensaver enabled</span>
|
||||
<span class="inputtitle">while not playing</span>
|
||||
<div class="checkbox off nous" id="screensaverenabled" style="padding-top:16px;"></div>
|
||||
</div>
|
||||
<div class="inputwrap">
|
||||
<span class="inputtitle">screensaver timeout (sec)</span>
|
||||
<input type="number" id="screensavertimeout" class="textinput inputchange" name="screensavertimeout" value="" maxlength="3" min="0" max="65520" />
|
||||
<span class="inputtitle">blank screen</span>
|
||||
<div class="checkbox off nous" id="screensaverblank"></div>
|
||||
</div>
|
||||
<div class="inputwrap">
|
||||
<span class="inputtitle">timeout (sec)</span>
|
||||
<input type="number" id="screensavertimeout" class="textinput inputchange" name="screensavertimeout" value="" maxlength="3" min="5" max="65520" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-row group group_tft group_oled group_nextion hidden">
|
||||
<div class="inputwrap">
|
||||
<span class="inputtitle">while playing</span>
|
||||
<div class="checkbox off nous" id="screensaverplayingenabled"></div>
|
||||
</div>
|
||||
<div class="inputwrap">
|
||||
<span class="inputtitle">blank screen</span>
|
||||
<div class="checkbox off nous" id="screensaverplayingblank"></div>
|
||||
</div>
|
||||
<div class="inputwrap">
|
||||
<span class="inputtitle">timeout (min)</span>
|
||||
<input type="number" id="screensaverplayingtimeout" class="textinput inputchange" name="screensaverplayingtimeout" value="" maxlength="3" min="1" max="1080" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ extern "C" {
|
|||
|
||||
//If core is not defined, then we are running in Arduino or PIO
|
||||
#ifndef CONFIG_ASYNC_TCP_RUNNING_CORE
|
||||
#define CONFIG_ASYNC_TCP_RUNNING_CORE 1 //any available core (-1)
|
||||
#define CONFIG_ASYNC_TCP_RUNNING_CORE 0 //any available core (-1)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ASYNC_TCP_USE_WDT
|
||||
|
|
@ -43,7 +43,7 @@ extern "C" {
|
|||
#define XTASK_MEM_SIZE 6144 // 8192 / 2
|
||||
#endif
|
||||
#ifndef XTASK_PRIOTITY
|
||||
#define XTASK_PRIOTITY 3 //3
|
||||
#define XTASK_PRIOTITY 5 //3
|
||||
#endif
|
||||
#ifndef ATCP_TASK_DELAY
|
||||
#define ATCP_TASK_DELAY 2
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST, UPDATING, INFO, SETTINGS, TIMEZONE, WIFI, CLEAR, SLEEPING, SDCHANGE, SCREENSAVER };
|
||||
enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST, UPDATING, INFO, SETTINGS, TIMEZONE, WIFI, CLEAR, SLEEPING, SDCHANGE, SCREENSAVER, SCREENBLANK };
|
||||
enum pages_e : uint8_t { PG_PLAYER=0, PG_DIALOG=1, PG_PLAYLIST=2, PG_SCREENSAVER=3 };
|
||||
|
||||
enum displayRequestType_e { BOOTSTRING, NEWMODE, CLOCK, NEWTITLE, NEWSTATION, NEXTSTATION, DRAWPLAYLIST, DRAWVOL, DBITRATE, AUDIOINFO, SHOWVUMETER, DSPRSSI, SHOWWEATHER, NEWWEATHER, PSTOP, PSTART, DSP_START, WAITFORSD, SDFILEINDEX, NEWIP, NOPE };
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ void Config::init() {
|
|||
EEPROM.begin(EEPROM_SIZE);
|
||||
sdResumePos = 0;
|
||||
screensaverTicks = 0;
|
||||
screensaverPlayingTicks = 0;
|
||||
isScreensaver = false;
|
||||
bootInfo();
|
||||
#if RTCSUPPORTED
|
||||
|
|
@ -97,6 +98,12 @@ void Config::_setupVersion(){
|
|||
saveValue(store.mdnsname, buf, MDNS_LENGTH);
|
||||
saveValue(&store.skipPlaylistUpDown, false);
|
||||
break;
|
||||
case 3:
|
||||
saveValue(&store.screensaverBlank, false);
|
||||
saveValue(&store.screensaverPlayingEnabled, false);
|
||||
saveValue(&store.screensaverPlayingTimeout, (uint16_t)5);
|
||||
saveValue(&store.screensaverPlayingBlank, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -353,6 +360,8 @@ void Config::setDefaults() {
|
|||
store.screensaverTimeout = 20;
|
||||
snprintf(store.mdnsname, MDNS_LENGTH, "yoradio-%x", getChipId());
|
||||
store.skipPlaylistUpDown = false;
|
||||
store.screensaverPlayingEnabled = false;
|
||||
store.screensaverPlayingTimeout = 5;
|
||||
eepromWrite(EEPROM_START, store);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
|
||||
#define ESP_ARDUINO_3 1
|
||||
#endif
|
||||
#define CONFIG_VERSION 3
|
||||
#define CONFIG_VERSION 4
|
||||
|
||||
enum playMode_e : uint8_t { PM_WEB=0, PM_SDCARD=1 };
|
||||
enum BitrateFormat { BF_UNCNOWN, BF_MP3, BF_AAC, BF_FLAC, BF_OGG, BF_WAV };
|
||||
|
|
@ -136,6 +136,10 @@ struct config_t
|
|||
bool rotate90;
|
||||
bool screensaverEnabled;
|
||||
uint16_t screensaverTimeout;
|
||||
bool screensaverBlank;
|
||||
bool screensaverPlayingEnabled;
|
||||
uint16_t screensaverPlayingTimeout;
|
||||
bool screensaverPlayingBlank;
|
||||
char mdnsname[24];
|
||||
bool skipPlaylistUpDown;
|
||||
};
|
||||
|
|
@ -181,6 +185,7 @@ class Config {
|
|||
bool emptyFS;
|
||||
uint16_t vuThreshold;
|
||||
uint16_t screensaverTicks;
|
||||
uint16_t screensaverPlayingTicks;
|
||||
bool isScreensaver;
|
||||
public:
|
||||
Config() {};
|
||||
|
|
|
|||
|
|
@ -284,11 +284,13 @@ void Display::_swichMode(displayMode_e newmode) {
|
|||
_pager.setPage( pages[PG_PLAYER]);
|
||||
pm.on_display_player();
|
||||
}
|
||||
if (newmode == SCREENSAVER) {
|
||||
if (newmode == SCREENSAVER || newmode == SCREENBLANK) {
|
||||
config.isScreensaver = true;
|
||||
_pager.setPage( pages[PG_SCREENSAVER]);
|
||||
if (newmode == SCREENBLANK) dsp.clearClock();
|
||||
}else{
|
||||
config.screensaverTicks=SCREENSAVERSTARTUPDELAY;
|
||||
config.screensaverPlayingTicks=SCREENSAVERSTARTUPDELAY;
|
||||
config.isScreensaver = false;
|
||||
}
|
||||
if (newmode == VOL) {
|
||||
|
|
@ -532,8 +534,14 @@ void Display::_time(bool redraw) {
|
|||
config.setBrightness();
|
||||
}
|
||||
#endif
|
||||
if(config.isScreensaver && network.timeinfo.tm_sec % 60 == 0)
|
||||
_clock.moveTo({clockConf.left, random(TFT_FRAMEWDT+clockConf.textsize, (dsp.height()-TFT_FRAMEWDT*2)), 0});
|
||||
if(config.isScreensaver && network.timeinfo.tm_sec % 60 == 0){
|
||||
#ifdef GXCLOCKFONT
|
||||
uint16_t ft=static_cast<uint16_t>(random(TFT_FRAMEWDT, (dsp.height()-dsp.plItemHeight-TFT_FRAMEWDT*2-clockConf.textsize)));
|
||||
#else
|
||||
uint16_t ft=static_cast<uint16_t>(random(TFT_FRAMEWDT+clockConf.textsize, (dsp.height()-dsp.plItemHeight-TFT_FRAMEWDT*2)));
|
||||
#endif
|
||||
_clock.moveTo({clockConf.left, ft, 0});
|
||||
}
|
||||
_clock.draw();
|
||||
/*#ifdef USE_NEXTION
|
||||
nextion.printClock(network.timeinfo);
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ void NetServer::processQueue(){
|
|||
config.vuThreshold,
|
||||
config.store.mdnsname);
|
||||
break;
|
||||
case GETSCREEN: sprintf (wsbuf, "{\"flip\":%d,\"inv\":%d,\"nump\":%d,\"tsf\":%d,\"tsd\":%d,\"dspon\":%d,\"br\":%d,\"con\":%d,\"scre\":%d,\"scrt\":%d}",
|
||||
case GETSCREEN: sprintf (wsbuf, "{\"flip\":%d,\"inv\":%d,\"nump\":%d,\"tsf\":%d,\"tsd\":%d,\"dspon\":%d,\"br\":%d,\"con\":%d,\"scre\":%d,\"scrt\":%d,\"scrb\":%d,\"scrpe\":%d,\"scrpt\":%d,\"scrpb\":%d}",
|
||||
config.store.flipscreen,
|
||||
config.store.invertdisplay,
|
||||
config.store.numplaylist,
|
||||
|
|
@ -308,7 +308,11 @@ void NetServer::processQueue(){
|
|||
config.store.brightness,
|
||||
config.store.contrast,
|
||||
config.store.screensaverEnabled,
|
||||
config.store.screensaverTimeout);
|
||||
config.store.screensaverTimeout,
|
||||
config.store.screensaverBlank,
|
||||
config.store.screensaverPlayingEnabled,
|
||||
config.store.screensaverPlayingTimeout,
|
||||
config.store.screensaverPlayingBlank);
|
||||
break;
|
||||
case GETTIMEZONE: sprintf (wsbuf, "{\"tzh\":%d,\"tzm\":%d,\"sntp1\":\"%s\",\"sntp2\":\"%s\"}",
|
||||
config.store.tzHour,
|
||||
|
|
@ -507,13 +511,46 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client
|
|||
}
|
||||
if (strcmp(cmd, "screensavertimeout") == 0) {
|
||||
uint16_t valb = atoi(val);
|
||||
valb = constrain(valb,0,65520);
|
||||
valb = constrain(valb,5,65520);
|
||||
config.saveValue(&config.store.screensaverTimeout, valb);
|
||||
#ifndef DSP_LCD
|
||||
display.putRequest(NEWMODE, PLAYER);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd, "screensaverblank") == 0) {
|
||||
bool valb = static_cast<bool>(atoi(val));
|
||||
config.saveValue(&config.store.screensaverBlank, valb);
|
||||
#ifndef DSP_LCD
|
||||
display.putRequest(NEWMODE, PLAYER);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd, "screensaverplayingenabled") == 0) {
|
||||
bool valb = static_cast<bool>(atoi(val));
|
||||
config.saveValue(&config.store.screensaverPlayingEnabled, valb);
|
||||
#ifndef DSP_LCD
|
||||
display.putRequest(NEWMODE, PLAYER);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd, "screensaverplayingtimeout") == 0) {
|
||||
uint16_t valb = atoi(val);
|
||||
valb = constrain(valb,1,1080);
|
||||
config.saveValue(&config.store.screensaverPlayingTimeout, valb);
|
||||
#ifndef DSP_LCD
|
||||
display.putRequest(NEWMODE, PLAYER);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd, "screensaverplayingblank") == 0) {
|
||||
bool valb = static_cast<bool>(atoi(val));
|
||||
config.saveValue(&config.store.screensaverPlayingBlank, valb);
|
||||
#ifndef DSP_LCD
|
||||
display.putRequest(NEWMODE, PLAYER);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd, "tzh") == 0) {
|
||||
int8_t vali = atoi(val);
|
||||
config.saveValue(&config.store.tzHour, vali);
|
||||
|
|
@ -613,6 +650,10 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client
|
|||
config.saveValue(&config.store.numplaylist, false);
|
||||
config.saveValue(&config.store.screensaverEnabled, false);
|
||||
config.saveValue(&config.store.screensaverTimeout, (uint16_t)20);
|
||||
config.saveValue(&config.store.screensaverBlank, false);
|
||||
config.saveValue(&config.store.screensaverPlayingEnabled, false);
|
||||
config.saveValue(&config.store.screensaverPlayingTimeout, (uint16_t)5);
|
||||
config.saveValue(&config.store.screensaverPlayingBlank, false);
|
||||
display.putRequest(NEWMODE, CLEAR); display.putRequest(NEWMODE, PLAYER);
|
||||
requestOnChange(GETSCREEN, clientId);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,24 @@ void ticks() {
|
|||
}
|
||||
#ifndef DSP_LCD
|
||||
if(config.store.screensaverEnabled && display.mode()==PLAYER && !player.isRunning()){
|
||||
if(config.screensaverTicks++ > config.store.screensaverTimeout+SCREENSAVERSTARTUPDELAY) display.putRequest(NEWMODE, SCREENSAVER);
|
||||
config.screensaverTicks++;
|
||||
if(config.screensaverTicks > config.store.screensaverTimeout+SCREENSAVERSTARTUPDELAY){
|
||||
if(config.store.screensaverBlank){
|
||||
display.putRequest(NEWMODE, SCREENBLANK);
|
||||
}else{
|
||||
display.putRequest(NEWMODE, SCREENSAVER);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(config.store.screensaverPlayingEnabled && display.mode()==PLAYER && player.isRunning()){
|
||||
config.screensaverPlayingTicks++;
|
||||
if(config.screensaverPlayingTicks > config.store.screensaverPlayingTimeout*60+SCREENSAVERSTARTUPDELAY){
|
||||
if(config.store.screensaverPlayingBlank){
|
||||
display.putRequest(NEWMODE, SCREENBLANK);
|
||||
}else{
|
||||
display.putRequest(NEWMODE, SCREENSAVER);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if RTCSUPPORTED
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef options_h
|
||||
#define options_h
|
||||
|
||||
#define YOVERSION "0.9.412"
|
||||
#define YOVERSION "0.9.420"
|
||||
|
||||
/*******************************************************
|
||||
DO NOT EDIT THIS FILE.
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ void Player::_play(uint16_t stationId) {
|
|||
config.vuThreshold = 0;
|
||||
//display.putRequest(PSTOP);
|
||||
config.screensaverTicks=SCREENSAVERSTARTUPDELAY;
|
||||
config.screensaverPlayingTicks=SCREENSAVERSTARTUPDELAY;
|
||||
if(config.getMode()!=PM_SDCARD) {
|
||||
display.putRequest(PSTOP);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,41 +60,50 @@ bool SDManager::_endsWith (const char* base, const char* str) {
|
|||
return (strncmp(p, str, slen) == 0);
|
||||
}
|
||||
|
||||
void SDManager::listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8_t levels){
|
||||
File root = sdman.open(dirname);
|
||||
if(!root){
|
||||
Serial.println("##[ERROR]#\tFailed to open directory");
|
||||
return;
|
||||
}
|
||||
if(!root.isDirectory()){
|
||||
Serial.println("##[ERROR]#\tNot a directory");
|
||||
return;
|
||||
}
|
||||
File file = root.openNextFile();
|
||||
uint32_t pos = 0;
|
||||
while(file){
|
||||
vTaskDelay(2);
|
||||
bool fid = file.isDirectory();
|
||||
const char * fp = file.path();
|
||||
const char * fn = file.name();
|
||||
if(fid){
|
||||
if(levels && !_checkNoMedia(fp)){
|
||||
listSD(plSDfile, plSDindex, fp, levels -1);
|
||||
}
|
||||
} else {
|
||||
if(_endsWith(strlwr((char*)fn), ".mp3") || _endsWith(fn, ".m4a") || _endsWith(fn, ".aac") || _endsWith(fn, ".wav") || _endsWith(fn, ".flac")){
|
||||
pos = plSDfile.position();
|
||||
plSDfile.print(fn); plSDfile.print("\t"); plSDfile.print(fp); plSDfile.print("\t"); plSDfile.println(0);
|
||||
plSDindex.write((uint8_t *) &pos, 4);
|
||||
Serial.print(".");
|
||||
if(display.mode()==SDCHANGE) display.putRequest(SDFILEINDEX, _sdFCount+1);
|
||||
_sdFCount++;
|
||||
if(_sdFCount%64==0) Serial.println();
|
||||
}
|
||||
void SDManager::listSD(File &plSDfile, File &plSDindex, const char* dirname, uint8_t levels) {
|
||||
File root = sdman.open(dirname);
|
||||
if (!root) {
|
||||
Serial.println("##[ERROR]#\tFailed to open directory");
|
||||
return;
|
||||
}
|
||||
if(file) file.close(); file = root.openNextFile();
|
||||
}
|
||||
if(root) root.close();
|
||||
if (!root.isDirectory()) {
|
||||
Serial.println("##[ERROR]#\tNot a directory");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t pos = 0;
|
||||
char* filePath;
|
||||
while (true) {
|
||||
vTaskDelay(2);
|
||||
bool isDir;
|
||||
String fileName = root.getNextFileName(&isDir);
|
||||
if (fileName.isEmpty()) break;
|
||||
filePath = (char*)malloc(fileName.length() + 1);
|
||||
if (filePath == NULL) {
|
||||
Serial.println("Memory allocation failed");
|
||||
break;
|
||||
}
|
||||
strcpy(filePath, fileName.c_str());
|
||||
const char* fn = strrchr(filePath, '/') + 1;
|
||||
if (isDir) {
|
||||
if (levels && !_checkNoMedia(filePath)) {
|
||||
listSD(plSDfile, plSDindex, filePath, levels - 1);
|
||||
}
|
||||
} else {
|
||||
if (_endsWith(strlwr((char*)fn), ".mp3") || _endsWith(fn, ".m4a") || _endsWith(fn, ".aac") ||
|
||||
_endsWith(fn, ".wav") || _endsWith(fn, ".flac")) {
|
||||
pos = plSDfile.position();
|
||||
plSDfile.printf("%s\t%s\t0\n", fn, filePath);
|
||||
plSDindex.write((uint8_t*)&pos, 4);
|
||||
Serial.print(".");
|
||||
if(display.mode()==SDCHANGE) display.putRequest(SDFILEINDEX, _sdFCount+1);
|
||||
_sdFCount++;
|
||||
if (_sdFCount % 64 == 0) Serial.println();
|
||||
}
|
||||
}
|
||||
free(filePath);
|
||||
}
|
||||
root.close();
|
||||
}
|
||||
|
||||
void SDManager::indexSDPlaylist() {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ void DspCore::drawPlaylist(uint16_t currentItem) {
|
|||
clear();
|
||||
config.fillPlMenu(currentItem - plCurrentPos, plTtemsCount);
|
||||
setCursor(0,1);
|
||||
write(byte(126));
|
||||
write(uint8_t(126));
|
||||
}
|
||||
|
||||
void DspCore::clearDsp(bool black) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#define CHARHEIGHT 8
|
||||
|
||||
#define DSP_OLED
|
||||
#define GXCLOCKFONT
|
||||
|
||||
typedef GFXcanvas1 Canvas;
|
||||
#include "widgets/widgets.h"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#define CHARHEIGHT 8
|
||||
|
||||
#define DSP_OLED
|
||||
#define GXCLOCKFONT
|
||||
|
||||
typedef GFXcanvas1 Canvas;
|
||||
#include "widgets/widgets.h"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#define CHARHEIGHT 8
|
||||
|
||||
#define DSP_OLED
|
||||
#define GXCLOCKFONT
|
||||
|
||||
typedef GFXcanvas1 Canvas;
|
||||
#include "widgets/widgets.h"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#define CHARHEIGHT 8
|
||||
|
||||
#define DSP_OLED
|
||||
#define GXCLOCKFONT
|
||||
|
||||
typedef GFXcanvas1 Canvas;
|
||||
#include "widgets/widgets.h"
|
||||
|
|
|
|||
Loading…
Reference in New Issue