v0.9.200
This commit is contained in:
@@ -144,7 +144,7 @@ class yoradioDevice(MediaPlayerEntity):
|
||||
if js['on']==1:
|
||||
self._state = STATE_PLAYING if js['status']==1 else STATE_IDLE
|
||||
else:
|
||||
self._state = STATE_OFF
|
||||
self._state = STATE_PLAYING if js['status']==1 else STATE_OFF
|
||||
self._current_source = str(js['station']) + '. ' + js['name']
|
||||
try:
|
||||
self.async_schedule_update_ha_state()
|
||||
|
||||
13
README.md
13
README.md
@@ -226,6 +226,19 @@ Work is in progress...
|
||||
|
||||
---
|
||||
## Version history
|
||||
#### v0.9.200
|
||||
**!!! a [full update](#update-over-web-interface) with Sketch data upload is required. After updating please press CTRL+F5 in browser !!!**
|
||||
- implementation of WEB/SD mode switching without reboot
|
||||
- replacement of SD cards without turning off the power
|
||||
- switching WEB / SD from the web interface. full update required, including SPIFFS Data
|
||||
- fixing the Home Assistant integration behavior logic
|
||||
- SD_HSPI parameter now works. Pins HSPI - 13(MOSI) 12(MISO) 14(CLK)
|
||||
- new parameter SD_SPIPINS. ```#define SD_SPIPINS sck, miso, mosi```
|
||||
- sck, miso, mosi - any available pins. Used for "TTGO Tm Music Album" boards ```#define SD_SPIPINS 14, 2, 15```
|
||||
- fixed a bug with garbage appearing on display ILI9225
|
||||
- the slider for moving along the SD track is temporarily not working.
|
||||
- bug fixes
|
||||
|
||||
#### v0.9.180
|
||||
- OneButton library moved to the project
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<title>ёRadio - Player</title>
|
||||
<style> </style>
|
||||
</head>
|
||||
<body class="%MODE%">
|
||||
<body class="modeweb">
|
||||
<div class="content">
|
||||
<div class="logo"></div>
|
||||
<div id="navbar">
|
||||
@@ -57,12 +57,13 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div id="volnav">
|
||||
<div id="modeline"><span id="modeweb" class="modeitem" data-name="web">Web</span><span id="modesd" data-name="sd" class="modeitem">SD</span></div>
|
||||
<input type="range" id="volrange" class="slider" name="volume" data-slaveid="volinfo" min="0" max="254" value="0">
|
||||
</div>
|
||||
<div id="sdnav" class="hidden">
|
||||
<div id="sdposvals">
|
||||
<div id="sdposvalscurrent">0:00</div>
|
||||
<div id="snuffle" class="playerbytton active" data-name="snuffle"></div>
|
||||
<div id="snuffle" class="playerbytton active" data-name="snuffle"><span></span></div>
|
||||
<div id="sdposvalsend">0:00</div>
|
||||
</div>
|
||||
<input type="range" id="sdpos" class="slider" name="sdpos" min="0" max="100" value="0">
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -65,6 +65,7 @@ const char const_DlgLost[] PROGMEM = "* LOST *";
|
||||
const char const_DlgUpdate[] PROGMEM = "* UPDATING *";
|
||||
const char const_DlgNextion[] PROGMEM = "* NEXTION *";
|
||||
const char const_getWeather[] PROGMEM = "";
|
||||
const char const_waitForSD[] PROGMEM = "WAIT FOR SD";
|
||||
|
||||
const char apNameTxt[] PROGMEM = "AP NAME";
|
||||
const char apPassTxt[] PROGMEM = "PASSWORD";
|
||||
|
||||
@@ -65,6 +65,7 @@ const char const_DlgLost[] PROGMEM = "ОТКЛЮЧЕНО";
|
||||
const char const_DlgUpdate[] PROGMEM = "ОБНОВЛЕНИЕ";
|
||||
const char const_DlgNextion[] PROGMEM = "NEXTION";
|
||||
const char const_getWeather[] PROGMEM = "";
|
||||
const char const_waitForSD[] PROGMEM = "ОЖИДАНИЕ SD";
|
||||
|
||||
const char apNameTxt[] PROGMEM = "ТОЧКА ДОСТУПА";
|
||||
const char apPassTxt[] PROGMEM = "ПАРОЛЬ";
|
||||
|
||||
@@ -201,6 +201,9 @@ static void _async_service_task(void *pvParameters){
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if ATCP_TASK_DELAY>0
|
||||
vTaskDelay(ATCP_TASK_DELAY);
|
||||
#endif
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
_async_service_task_handle = NULL;
|
||||
@@ -218,7 +221,7 @@ static bool _start_async_task(){
|
||||
return false;
|
||||
}
|
||||
if(!_async_service_task_handle){
|
||||
xTaskCreateUniversal(_async_service_task, "async_tcp", XTASK_MEM_SIZE, NULL, 3, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE);
|
||||
xTaskCreateUniversal(_async_service_task, "async_tcp", XTASK_MEM_SIZE, NULL, XTASK_PRIOTITY, &_async_service_task_handle, CONFIG_ASYNC_TCP_RUNNING_CORE);
|
||||
if(!_async_service_task_handle){
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -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 0 //any available core (-1)
|
||||
#define CONFIG_ASYNC_TCP_RUNNING_CORE 1 //any available core (-1)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ASYNC_TCP_USE_WDT
|
||||
@@ -40,7 +40,13 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef XTASK_MEM_SIZE
|
||||
#define XTASK_MEM_SIZE 8192 / 2
|
||||
#define XTASK_MEM_SIZE 6144 // 8192 / 2
|
||||
#endif
|
||||
#ifndef XTASK_PRIOTITY
|
||||
#define XTASK_PRIOTITY 3 //3
|
||||
#endif
|
||||
#ifndef ATCP_TASK_DELAY
|
||||
#define ATCP_TASK_DELAY 2
|
||||
#endif
|
||||
|
||||
#ifndef XQUEUE_SIZE
|
||||
|
||||
@@ -711,14 +711,14 @@ bool Audio::connecttoFS(fs::FS &fs, const char* path, uint32_t resumeFilePos) {
|
||||
m_file_size = audiofile.size();//TEST loop
|
||||
cardLock(false);
|
||||
char* afn = NULL; // audioFileName
|
||||
cardLock(true);
|
||||
//cardLock(true);
|
||||
#ifdef SDFATFS_USED
|
||||
audiofile.getName(chbuf, sizeof(chbuf));
|
||||
afn = strdup(chbuf);
|
||||
#else
|
||||
afn = strdup(audiofile.name());
|
||||
#endif
|
||||
cardLock(false);
|
||||
//cardLock(false);
|
||||
uint8_t dotPos = lastIndexOf(afn, ".");
|
||||
for(uint8_t i = dotPos + 1; i < strlen(afn); i++){
|
||||
afn[i] = toLowerCase(afn[i]);
|
||||
@@ -1553,7 +1553,8 @@ int Audio::read_ID3_Header(uint8_t *data, size_t len) {
|
||||
AUDIO_INFO("file has no mp3 tag, skip metadata");
|
||||
m_audioDataSize = m_contentlength;
|
||||
AUDIO_INFO("Audio-Length: %u", m_audioDataSize);
|
||||
if(audio_progress) audio_progress(295903, m_audioDataSize);
|
||||
//if(audio_progress) audio_progress(295903, m_audioDataSize);
|
||||
if(audio_progress) audio_progress(0, m_audioDataSize);
|
||||
return -1; // error, no ID3 signature found
|
||||
}
|
||||
ID3version = *(data + 3);
|
||||
@@ -3034,14 +3035,14 @@ void Audio::processLocalFile() {
|
||||
} //TEST loop
|
||||
f_stream = false;
|
||||
m_streamType = ST_NONE;
|
||||
cardLock(true);
|
||||
//cardLock(true);
|
||||
#ifdef SDFATFS_USED
|
||||
audiofile.getName(chbuf, sizeof(chbuf));
|
||||
char *afn =strdup(chbuf);
|
||||
#else
|
||||
char *afn =strdup(audiofile.name()); // store temporary the name
|
||||
#endif
|
||||
cardLock(false);
|
||||
//cardLock(false);
|
||||
stopSong();
|
||||
if(m_codec == CODEC_MP3) MP3Decoder_FreeBuffers();
|
||||
if(m_codec == CODEC_AAC) AACDecoder_FreeBuffers();
|
||||
@@ -4399,9 +4400,9 @@ bool Audio::setPinout(uint8_t BCLK, uint8_t LRC, uint8_t DOUT, int8_t DIN, int8_
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
uint32_t Audio::getFileSize() {
|
||||
if(!audiofile) return 0;
|
||||
cardLock(true);
|
||||
//cardLock(true);
|
||||
uint32_t s = audiofile.size();
|
||||
cardLock(false);
|
||||
//cardLock(false);
|
||||
return s;
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -152,6 +152,7 @@ Audio::Audio(uint8_t _cs_pin, uint8_t _dcs_pin, uint8_t _dreq_pin, uint8_t spi,
|
||||
m_endFillByte=0;
|
||||
curvol=50;
|
||||
m_LFcount=0;
|
||||
mutex_pl = xSemaphoreCreateMutex();
|
||||
}
|
||||
Audio::~Audio(){
|
||||
// destructor
|
||||
@@ -302,7 +303,7 @@ void Audio::begin(){
|
||||
pinMode(dreq_pin, INPUT); // DREQ is an input
|
||||
pinMode(cs_pin, OUTPUT); // The SCI and SDI signals
|
||||
pinMode(dcs_pin, OUTPUT);
|
||||
mutex_pl = xSemaphoreCreateMutex();
|
||||
//mutex_pl = xSemaphoreCreateMutex();
|
||||
DCS_HIGH();
|
||||
CS_HIGH();
|
||||
delay(170);
|
||||
@@ -743,9 +744,9 @@ void Audio::processLocalFile() {
|
||||
|
||||
f_stream = false;
|
||||
m_f_localfile = false;
|
||||
cardLock(true);
|
||||
//cardLock(true);
|
||||
char *afn =strdup(audiofile.name()); // store temporary the name
|
||||
cardLock(false);
|
||||
//cardLock(false);
|
||||
stopSong();
|
||||
sprintf(chbuf, "End of file \"%s\"", afn);
|
||||
if(audio_info) audio_info(chbuf);
|
||||
@@ -2153,7 +2154,8 @@ int Audio::read_MP3_Header(uint8_t *data, size_t len) {
|
||||
if(audio_info) audio_info("file has no mp3 tag, skip metadata");
|
||||
m_audioDataSize = m_contentlength;
|
||||
sprintf(chbuf, "Audio-Length: %u", m_audioDataSize);
|
||||
if(audio_progress) audio_progress(295903, m_audioDataSize);
|
||||
//if(audio_progress) audio_progress(295903, m_audioDataSize);
|
||||
if(audio_progress) audio_progress(0, m_audioDataSize);
|
||||
if(audio_info) audio_info(chbuf);
|
||||
return -1; // error, no ID3 signature found
|
||||
}
|
||||
@@ -2482,9 +2484,9 @@ void Audio::showID3Tag(const char* tag, const char* value){
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
uint32_t Audio::getFileSize(){
|
||||
if (!audiofile) return 0;
|
||||
cardLock(true);
|
||||
//cardLock(true);
|
||||
uint32_t s = audiofile.size();
|
||||
cardLock(false);
|
||||
//cardLock(false);
|
||||
return s;
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -7,9 +7,14 @@
|
||||
|
||||
Config config;
|
||||
|
||||
#if DSP_HSPI || TS_HSPI || VS_HSPI || SD_HSPI
|
||||
#if DSP_HSPI || TS_HSPI || VS_HSPI
|
||||
SPIClass SPI2(HSPI);
|
||||
#endif
|
||||
#if defined(SD_SPIPINS) || SD_HSPI
|
||||
SPIClass SDSPI(HSPI);
|
||||
#endif
|
||||
#define SDL() if(player.mutex_pl!=NULL) player.cardLock(true)
|
||||
#define SDU() vTaskDelay(2); if(player.mutex_pl!=NULL) player.cardLock(false)
|
||||
|
||||
void u8fix(char *src){
|
||||
char last = src[strlen(src)-1];
|
||||
@@ -32,6 +37,13 @@ void Config::init() {
|
||||
emptyFS = true;
|
||||
#if IR_PIN!=255
|
||||
irindex=-1;
|
||||
#endif
|
||||
#if defined(SD_SPIPINS) || SD_HSPI
|
||||
#if !defined(SD_SPIPINS)
|
||||
SDSPI.begin();
|
||||
#else
|
||||
SDSPI.begin(SD_SPIPINS); // SCK, MISO, MOSI
|
||||
#endif
|
||||
#endif
|
||||
eepromRead(EEPROM_START, store);
|
||||
if (store.config_set != 4262) setDefaults();
|
||||
@@ -50,25 +62,112 @@ void Config::init() {
|
||||
emptyFS = _isFSempty();
|
||||
if(emptyFS) BOOTLOG("SPIFFS is empty!");
|
||||
ssidsCount = 0;
|
||||
sdResumePos = 0;
|
||||
if(SDC_CS!=255){
|
||||
if(!SD.begin(SDC_CS)){
|
||||
store.play_mode=PM_WEB;
|
||||
Serial.println("##[ERROR]#\tCard Mount Failed");
|
||||
_cardStatus = CS_NONE;
|
||||
mountSDbusy = false;
|
||||
if(SDC_CS!=255) randomSeed(analogRead(SDC_CS));
|
||||
backupSDStation = 0;
|
||||
//checkSD();
|
||||
_bootDone=false;
|
||||
bootInfo();
|
||||
}
|
||||
|
||||
bool Config::_sdCardIsConnected() {
|
||||
if(SD.sectorSize()<1) return false;
|
||||
SDL();
|
||||
uint8_t buff[SD.sectorSize()] = { 0 };
|
||||
bool bread = SD.readRAW(buff, 1);
|
||||
if(SD.sectorSize()>0 && !bread) SD.end();
|
||||
SDU();
|
||||
return bread;
|
||||
}
|
||||
|
||||
bool Config::_sdBegin(){
|
||||
bool out;
|
||||
SDL();
|
||||
#if defined(SD_SPIPINS) || SD_HSPI
|
||||
out = SD.begin(SDC_CS, SDSPI);
|
||||
#else
|
||||
out = SD.begin(SDC_CS);
|
||||
#endif
|
||||
SDU();
|
||||
return out;
|
||||
}
|
||||
|
||||
void Config::checkSD(){
|
||||
if(SDC_CS==255) return;
|
||||
mountSDbusy = true;
|
||||
cardStatus_e prevCardStatus = _cardStatus;
|
||||
if(_sdCardIsConnected()){
|
||||
if(_cardStatus==CS_NONE || _cardStatus==CS_PRESENT || _cardStatus==CS_EJECTED) {
|
||||
_cardStatus=CS_PRESENT;
|
||||
}else{
|
||||
if(store.play_mode==PM_SDCARD) initSDPlaylist();
|
||||
_cardStatus=CS_MOUNTED;
|
||||
}
|
||||
if(_cardStatus==CS_PRESENT && store.play_mode==PM_WEB && SD_AUTOPLAY && prevCardStatus==CS_EJECTED) config.changeMode(PM_SDCARD);
|
||||
}else{
|
||||
if(_cardStatus==CS_MOUNTED || _cardStatus==CS_PRESENT || _cardStatus==CS_EJECTED){
|
||||
if(_cardStatus!=CS_EJECTED && store.play_mode==PM_SDCARD && SD_AUTOPLAY) config.changeMode(PM_WEB);
|
||||
_cardStatus=CS_EJECTED;
|
||||
}
|
||||
backupSDStation = 0;
|
||||
}
|
||||
mountSDbusy = false;
|
||||
}
|
||||
|
||||
void Config::_mountSD(){
|
||||
if(SDC_CS==255 || mountSDbusy || display.mode()==SDCHANGE) return;
|
||||
mountSDbusy = true;
|
||||
if(SD.sectorSize()<1) SDinit = _sdBegin();
|
||||
if(!_sdCardIsConnected()) {
|
||||
if(store.play_mode==PM_SDCARD){
|
||||
SDinit = false;
|
||||
}
|
||||
}else{
|
||||
if(!SDinit){
|
||||
if(!_sdBegin()){
|
||||
Serial.println("##[ERROR]#\tCard Mount Failed");
|
||||
}else{
|
||||
SDinit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
mountSDbusy = false;
|
||||
}
|
||||
|
||||
void Config::initPlaylistMode(){
|
||||
sdResumePos = 0;
|
||||
SDinit = false;
|
||||
if(SDC_CS!=255){
|
||||
if(!_sdBegin()){
|
||||
store.play_mode=PM_WEB;
|
||||
Serial.println("SD Mount Failed");
|
||||
}else{
|
||||
Serial.println("SD Mounted");
|
||||
if(store.play_mode==PM_SDCARD) {
|
||||
if(_cardStatus!=CS_MOUNTED){
|
||||
_cardStatus=CS_MOUNTED;
|
||||
if(_bootDone) Serial.println("Waiting for SD card indexing..."); else BOOTLOG("Waiting for SD card indexing...");
|
||||
initSDPlaylist();
|
||||
}else{
|
||||
if(backupSDStation==0) {
|
||||
store.lastStation = random(1, store.countStation);
|
||||
backupSDStation = store.lastStation;
|
||||
}else store.lastStation = backupSDStation;
|
||||
}
|
||||
}
|
||||
SDinit = true;
|
||||
}
|
||||
}else{
|
||||
store.play_mode=PM_WEB;
|
||||
}
|
||||
if(store.play_mode==PM_WEB && !emptyFS) initPlaylist();
|
||||
|
||||
if (store.lastStation == 0 && store.countStation > 0) {
|
||||
store.lastStation = 1;
|
||||
store.lastStation = store.play_mode==PM_WEB?1:random(1, store.countStation);
|
||||
save();
|
||||
}
|
||||
|
||||
_bootDone = true;
|
||||
loadStation(store.lastStation);
|
||||
|
||||
bootInfo();
|
||||
}
|
||||
|
||||
void Config::_initHW(){
|
||||
@@ -218,12 +317,51 @@ void Config::save() {
|
||||
store.lastStation = ls;
|
||||
store.play_mode = pm;
|
||||
}
|
||||
|
||||
void Config::setSnuffle(bool sn){
|
||||
sdSnuffle=sn;
|
||||
save();
|
||||
if(sdSnuffle) player.next();
|
||||
//player blah blah blah
|
||||
}
|
||||
|
||||
void Config::changeMode(int newmode){
|
||||
if(SDC_CS==255) return;
|
||||
if(!SDinit) {
|
||||
_mountSD();
|
||||
if(!SDinit){
|
||||
Serial.println("##[ERROR]#\tSD Not Found");
|
||||
netserver.requestOnChange(GETPLAYERMODE, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(store.play_mode==PM_SDCARD) store.lastStation = config.backupLastStation;
|
||||
if(newmode<0){
|
||||
store.play_mode++;
|
||||
if(store.play_mode > MAX_PLAY_MODE){
|
||||
store.play_mode=0;
|
||||
}
|
||||
}else{
|
||||
store.play_mode=(playMode_e)newmode;
|
||||
}
|
||||
save();
|
||||
if(store.play_mode==PM_SDCARD && _cardStatus!=CS_MOUNTED){
|
||||
display.putRequest(NEWMODE, SDCHANGE);
|
||||
while(display.mode()!=SDCHANGE)
|
||||
delay(10);
|
||||
delay(50);
|
||||
}
|
||||
initPlaylistMode();
|
||||
|
||||
if (store.smartstart == 1) player.sendCommand({PR_PLAY, store.lastStation});
|
||||
else
|
||||
player.sendCommand({PR_STOP, 0});
|
||||
netserver.requestOnChange(GETPLAYERMODE, 0);
|
||||
netserver.requestOnChange(GETMODE, 0);
|
||||
display.putRequest(NEWMODE, PLAYER);
|
||||
display.putRequest(NEWSTATION);
|
||||
}
|
||||
|
||||
#if IR_PIN!=255
|
||||
void Config::saveIR(){
|
||||
eepromWrite(EEPROM_START_IR, ircodes);
|
||||
@@ -325,10 +463,9 @@ void Config::initPlaylist() {
|
||||
}
|
||||
|
||||
bool endsWith (const char* base, const char* str) {
|
||||
//fb
|
||||
int slen = strlen(str) - 1;
|
||||
const char *p = base + strlen(base) - 1;
|
||||
while(p > base && isspace(*p)) p--; // rtrim
|
||||
while(p > base && isspace(*p)) p--;
|
||||
p -= slen;
|
||||
if (p < base) return false;
|
||||
return (strncmp(p, str, slen) == 0);
|
||||
@@ -338,11 +475,12 @@ bool Config::checkNoMedia(const char* path){
|
||||
char nomedia[BUFLEN]= {0};
|
||||
strlcat(nomedia, path, BUFLEN);
|
||||
strlcat(nomedia, "/.nomedia", BUFLEN);
|
||||
return SD.exists(nomedia);
|
||||
SDL(); bool nm = SD.exists(nomedia); SDU();
|
||||
return nm;
|
||||
}
|
||||
|
||||
void Config::listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8_t levels){
|
||||
File root = SD.open(dirname);
|
||||
SDL(); File root = SD.open(dirname); SDU();
|
||||
if(!root){
|
||||
Serial.println("##[ERROR]#\tFailed to open directory");
|
||||
return;
|
||||
@@ -352,9 +490,9 @@ void Config::listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8
|
||||
return;
|
||||
}
|
||||
|
||||
File file = root.openNextFile();
|
||||
SDL(); File file = root.openNextFile(); SDU();
|
||||
uint32_t pos = 0;
|
||||
|
||||
//vTaskDelay(5);
|
||||
while(file){
|
||||
|
||||
if(file.isDirectory()){
|
||||
@@ -368,19 +506,22 @@ void Config::listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8
|
||||
plSDindex.write((byte *) &pos, 4);
|
||||
}
|
||||
}
|
||||
file = root.openNextFile();
|
||||
SDL(); file = root.openNextFile(); SDU();
|
||||
}
|
||||
}
|
||||
|
||||
void Config::indexSDPlaylist() {
|
||||
mountSDbusy = true;
|
||||
File playlist = SPIFFS.open(PLAYLIST_SD_PATH, "w");
|
||||
if (!playlist) {
|
||||
mountSDbusy = false;
|
||||
return;
|
||||
}
|
||||
File index = SPIFFS.open(INDEX_SD_PATH, "w");
|
||||
listSD(playlist, index, "/", 2);
|
||||
index.close();
|
||||
playlist.close();
|
||||
mountSDbusy = false;
|
||||
}
|
||||
|
||||
void Config::initSDPlaylist() {
|
||||
@@ -390,6 +531,7 @@ void Config::initSDPlaylist() {
|
||||
File index = SPIFFS.open(INDEX_SD_PATH, "r");
|
||||
store.countStation = index.size() / 4;
|
||||
store.lastStation = random(1, store.countStation);
|
||||
backupSDStation = store.lastStation;
|
||||
index.close();
|
||||
save();
|
||||
}
|
||||
@@ -715,9 +857,10 @@ void Config::bootInfo() {
|
||||
BOOTLOG("flipscreen:\t%s", store.flipscreen?"true":"false");
|
||||
BOOTLOG("invertdisplay:\t%s", store.invertdisplay?"true":"false");
|
||||
BOOTLOG("showweather:\t%s", store.showweather?"true":"false");
|
||||
BOOTLOG("buttons:\tleft=%d, center=%d, right=%d, up=%d, down=%d, pullup=%s", BTN_LEFT, BTN_CENTER, BTN_RIGHT, BTN_UP, BTN_DOWN, BTN_INTERNALPULLUP?"true":"false");
|
||||
BOOTLOG("buttons:\tleft=%d, center=%d, right=%d, up=%d, down=%d, mode=%d, pullup=%s", BTN_LEFT, BTN_CENTER, BTN_RIGHT, BTN_UP, BTN_DOWN, BTN_MODE, BTN_INTERNALPULLUP?"true":"false");
|
||||
BOOTLOG("encoders:\tl1=%d, b1=%d, r1=%d, pullup=%s, l2=%d, b2=%d, r2=%d, pullup=%s", ENC_BTNL, ENC_BTNB, ENC_BTNR, ENC_INTERNALPULLUP?"true":"false", ENC2_BTNL, ENC2_BTNB, ENC2_BTNR, ENC2_INTERNALPULLUP?"true":"false");
|
||||
BOOTLOG("ir:\t\t%d", IR_PIN);
|
||||
if(SDC_CS!=255) BOOTLOG("SD:\t\t%d", SDC_CS);
|
||||
BOOTLOG("------------------------------------------------");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#define MAX_PLAY_MODE 1
|
||||
enum playMode_e : uint8_t { PM_WEB=0, PM_SDCARD=1 };
|
||||
enum cardStatus_e : uint8_t { CS_NONE=0, CS_PRESENT=1, CS_MOUNTED=2, CS_EJECTED=3 };
|
||||
enum BitrateFormat { BF_UNCNOWN, BF_MP3, BF_AAC, BF_FLAC, BF_OGG, BF_WAV };
|
||||
|
||||
void u8fix(char *src);
|
||||
@@ -159,8 +160,11 @@ class Config {
|
||||
uint16_t sleepfor;
|
||||
uint32_t sdResumePos;
|
||||
uint16_t backupLastStation;
|
||||
uint16_t backupSDStation;
|
||||
bool sdSnuffle;
|
||||
bool emptyFS;
|
||||
bool SDinit;
|
||||
bool mountSDbusy;
|
||||
public:
|
||||
Config() {};
|
||||
void save();
|
||||
@@ -190,6 +194,8 @@ class Config {
|
||||
void setBitrateFormat(BitrateFormat fmt) { configFmt = fmt; }
|
||||
void initPlaylist();
|
||||
void indexPlaylist();
|
||||
void initSDPlaylist();
|
||||
void indexSDPlaylist();
|
||||
uint8_t fillPlMenu(int from, uint8_t count, bool fromNextion=false);
|
||||
char * stationByNum(uint16_t num);
|
||||
void setTimezone(int8_t tzh, int8_t tzm);
|
||||
@@ -201,19 +207,26 @@ class Config {
|
||||
void bootInfo();
|
||||
void doSleepW();
|
||||
void setSnuffle(bool sn);
|
||||
void changeMode(int newmode=-1);
|
||||
void initPlaylistMode();
|
||||
void checkSD();
|
||||
cardStatus_e getSDStatus(){ return _cardStatus; };
|
||||
private:
|
||||
template <class T> int eepromWrite(int ee, const T& value);
|
||||
template <class T> int eepromRead(int ee, T& value);
|
||||
cardStatus_e _cardStatus;
|
||||
bool _bootDone;
|
||||
void setDefaults();
|
||||
Ticker _sleepTimer;
|
||||
static void doSleep();
|
||||
uint16_t color565(uint8_t r, uint8_t g, uint8_t b);
|
||||
void listSD(File &plSDfile, File &plSDindex, const char * dirname, uint8_t levels);
|
||||
void initSDPlaylist();
|
||||
void indexSDPlaylist();
|
||||
bool checkNoMedia(const char* path);
|
||||
void _initHW();
|
||||
bool _isFSempty();
|
||||
bool _sdCardIsConnected();
|
||||
void _mountSD();
|
||||
bool _sdBegin();
|
||||
char _stationBuf[BUFLEN/2];
|
||||
};
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ constexpr uint8_t nrOfButtons = sizeof(button) / sizeof(button[0]);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if TS_MODEL!=TS_MODEL_UNDEFINED
|
||||
#if (TS_MODEL!=TS_MODEL_UNDEFINED) && (DSP_MODEL!=DSP_DUMMY)
|
||||
#include "touchscreen.h"
|
||||
TouchScreen touchscreen;
|
||||
#endif
|
||||
@@ -114,7 +114,7 @@ void initControls() {
|
||||
button[i].setPressTicks(BTN_PRESS_TICKS);
|
||||
}
|
||||
#endif
|
||||
#if TS_MODEL!=TS_MODEL_UNDEFINED
|
||||
#if (TS_MODEL!=TS_MODEL_UNDEFINED) && (DSP_MODEL!=DSP_DUMMY)
|
||||
touchscreen.init();
|
||||
#endif
|
||||
#if IR_PIN!=255
|
||||
@@ -129,7 +129,7 @@ void initControls() {
|
||||
}
|
||||
|
||||
void loopControls() {
|
||||
if(display.mode()==LOST || display.mode()==UPDATING) return;
|
||||
if(display.mode()==LOST || display.mode()==UPDATING || display.mode()==SDCHANGE) return;
|
||||
if (ctrls_on_loop) ctrls_on_loop();
|
||||
#if ENC_BTNL!=255
|
||||
encoder1Loop();
|
||||
@@ -151,7 +151,7 @@ void loopControls() {
|
||||
#if IR_PIN!=255
|
||||
irLoop();
|
||||
#endif
|
||||
#if TS_MODEL!=TS_MODEL_UNDEFINED
|
||||
#if (TS_MODEL!=TS_MODEL_UNDEFINED) && (DSP_MODEL!=DSP_DUMMY)
|
||||
touchscreen.loop();
|
||||
#endif
|
||||
}
|
||||
@@ -504,15 +504,7 @@ void onBtnClick(int id) {
|
||||
break;
|
||||
}
|
||||
case EVT_BTNMODE: {
|
||||
if(SDC_CS==255) break;
|
||||
if(config.store.play_mode==PM_SDCARD) config.store.lastStation = config.backupLastStation;
|
||||
config.store.play_mode++;
|
||||
if(config.store.play_mode > MAX_PLAY_MODE){
|
||||
config.store.play_mode=0;
|
||||
}
|
||||
|
||||
config.save();
|
||||
ESP.restart();
|
||||
config.changeMode();
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
@@ -560,7 +552,7 @@ void setEncAcceleration(uint16_t acc){
|
||||
#endif
|
||||
}
|
||||
void flipTS(){
|
||||
#if TS_MODEL!=TS_MODEL_UNDEFINED
|
||||
#if (TS_MODEL!=TS_MODEL_UNDEFINED) && (DSP_MODEL!=DSP_DUMMY)
|
||||
touchscreen.flip();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -286,6 +286,7 @@ void Display::_swichMode(displayMode_e newmode) {
|
||||
if (newmode == LOST) _showDialog(const_DlgLost);
|
||||
if (newmode == UPDATING) _showDialog(const_DlgUpdate);
|
||||
if (newmode == SLEEPING) _showDialog("SLEEPING");
|
||||
if (newmode == SDCHANGE) _showDialog(const_waitForSD);
|
||||
if (newmode == INFO || newmode == SETTINGS || newmode == TIMEZONE || newmode == WIFI) _showDialog(const_DlgNextion);
|
||||
if (newmode == NUMBERS) _showDialog("");
|
||||
if (newmode == STATIONS) {
|
||||
@@ -419,6 +420,10 @@ void Display::loop() {
|
||||
#endif*/
|
||||
break;
|
||||
}
|
||||
case WAITFORSD: {
|
||||
if(_bootstring) _bootstring->setText(const_waitForSD);
|
||||
break;
|
||||
}
|
||||
case DSPRSSI: if(_rssi){ _setRSSI(request.payload); } if (_heapbar && config.store.audioinfo) _heapbar->setValue(player.isRunning()?player.inBufferFilled():0); break;
|
||||
case PSTART: _layoutChange(true); break;
|
||||
case PSTOP: _layoutChange(false); break;
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
#include "../displays/dspcore.h"
|
||||
|
||||
enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST, UPDATING, INFO, SETTINGS, TIMEZONE, WIFI, CLEAR, SLEEPING };
|
||||
enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS, LOST, UPDATING, INFO, SETTINGS, TIMEZONE, WIFI, CLEAR, SLEEPING, SDCHANGE };
|
||||
enum pages_e : uint8_t { PG_PLAYER=0, PG_DIALOG=1, PG_PLAYLIST=2 };
|
||||
//enum dialogType_e : uint8_t { DG_NONE=0, DG_VOLUME=1, DG_LOST=2, DG_UPDATING=3, DG_NEXTION=4 };
|
||||
|
||||
enum displayRequestType_e { BOOTSTRING, NEWMODE, CLOCK, NEWTITLE, NEWSTATION, NEXTSTATION, DRAWPLAYLIST, DRAWVOL, DBITRATE, AUDIOINFO, SHOWVUMETER, DSPRSSI, SHOWWEATHER, NEWWEATHER, PSTOP, PSTART, DSP_START };
|
||||
enum displayRequestType_e { BOOTSTRING, NEWMODE, CLOCK, NEWTITLE, NEWSTATION, NEXTSTATION, DRAWPLAYLIST, DRAWVOL, DBITRATE, AUDIOINFO, SHOWVUMETER, DSPRSSI, SHOWWEATHER, NEWWEATHER, PSTOP, PSTART, DSP_START, WAITFORSD };
|
||||
struct requestParams_t
|
||||
{
|
||||
displayRequestType_e type;
|
||||
|
||||
@@ -199,7 +199,17 @@ void NetServer::processQueue(){
|
||||
uint8_t clientId = request.clientId;
|
||||
switch (request.type) {
|
||||
case PLAYLIST: getPlaylist(clientId); break;
|
||||
case PLAYLISTSAVED: config.indexPlaylist(); config.initPlaylist(); getPlaylist(clientId); break;
|
||||
case PLAYLISTSAVED: {
|
||||
if(config.store.play_mode==PM_SDCARD) {
|
||||
// config.indexSDPlaylist();
|
||||
config.initSDPlaylist();
|
||||
}
|
||||
if(config.store.play_mode==PM_WEB){
|
||||
// config.indexPlaylist();
|
||||
config.initPlaylist();
|
||||
}
|
||||
getPlaylist(clientId); break;
|
||||
}
|
||||
case GETACTIVE: {
|
||||
bool dbgact = false, nxtn=false;
|
||||
String act = F("\"group_wifi\",");
|
||||
@@ -231,27 +241,30 @@ void NetServer::processQueue(){
|
||||
sprintf (wsbuf, "{\"act\":[%s]}", act.c_str());
|
||||
break;
|
||||
}
|
||||
case GETMODE: sprintf (wsbuf, "{\"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); if (config.store.play_mode==PM_SDCARD) { requestOnChange(SDPOS, clientId); requestOnChange(SDLEN, clientId); requestOnChange(SDSNUFFLE, clientId); } return; break;
|
||||
case GETSYSTEM: sprintf (wsbuf, "{\"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 (wsbuf, "{\"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 (wsbuf, "{\"tzh\":%d,\"tzm\":%d,\"sntp1\":\"%s\",\"sntp2\":\"%s\"}", config.store.tzHour, config.store.tzMin, config.store.sntp1, config.store.sntp2); break;
|
||||
case GETWEATHER: sprintf (wsbuf, "{\"wen\":%d,\"wlat\":\"%s\",\"wlon\":\"%s\",\"wkey\":\"%s\"}", config.store.showweather, config.store.weatherlat, config.store.weatherlon, config.store.weatherkey); break;
|
||||
case GETCONTROLS: sprintf (wsbuf, "{\"vols\":%d,\"enca\":%d,\"irtl\":%d}", config.store.volsteps, config.store.encacc, config.store.irtlp); break;
|
||||
case DSPON: sprintf (wsbuf, "{\"dspontrue\":%d}", 1); break;
|
||||
case STATION: requestOnChange(STATIONNAME, clientId); requestOnChange(ITEM, clientId); break;
|
||||
case STATIONNAME: sprintf (wsbuf, "{\"nameset\": \"%s\"}", config.station.name); break;
|
||||
case ITEM: sprintf (wsbuf, "{\"current\": %d}", config.store.lastStation); break;
|
||||
case TITLE: sprintf (wsbuf, "{\"meta\": \"%s\"}", config.station.title); telnet.printf("##CLI.META#: %s\n> ", config.station.title); break;
|
||||
case VOLUME: sprintf (wsbuf, "{\"vol\": %d}", config.store.volume); telnet.printf("##CLI.VOL#: %d\n", config.store.volume); break;
|
||||
case NRSSI: sprintf (wsbuf, "{\"rssi\": %d}", rssi); /*rssi = 255;*/ break;
|
||||
case SDPOS: sprintf (wsbuf, "{\"sdpos\": %d,\"sdend\": %d,\"sdtpos\": %d,\"sdtend\": %d}", player.getFilePos(), player.getFileSize(), player.getAudioCurrentTime(), player.getAudioFileDuration()); break;
|
||||
case SDLEN: sprintf (wsbuf, "{\"sdmin\": %d,\"sdmax\": %d}", player.sd_min, player.sd_max); break;
|
||||
case SDSNUFFLE: sprintf (wsbuf, "{\"snuffle\": %d}", config.sdSnuffle); break;
|
||||
case BITRATE: sprintf (wsbuf, "{\"bitrate\": %d}", config.station.bitrate); break;
|
||||
case MODE: sprintf (wsbuf, "{\"mode\": \"%s\"}", player.status() == PLAYING ? "playing" : "stopped"); telnet.info(); break;
|
||||
case EQUALIZER: sprintf (wsbuf, "{\"bass\": %d, \"middle\": %d, \"trebble\": %d}", config.store.bass, config.store.middle, config.store.trebble); break;
|
||||
case BALANCE: sprintf (wsbuf, "{\"balance\": %d}", config.store.balance); break;
|
||||
case GETMODE: sprintf (wsbuf, "{\"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); requestOnChange(SDINIT, clientId);requestOnChange(GETPLAYERMODE, clientId); if (config.store.play_mode==PM_SDCARD) { requestOnChange(SDPOS, clientId); requestOnChange(SDLEN, clientId); requestOnChange(SDSNUFFLE, clientId); } return; break;
|
||||
case GETSYSTEM: sprintf (wsbuf, "{\"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 (wsbuf, "{\"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 (wsbuf, "{\"tzh\":%d,\"tzm\":%d,\"sntp1\":\"%s\",\"sntp2\":\"%s\"}", config.store.tzHour, config.store.tzMin, config.store.sntp1, config.store.sntp2); break;
|
||||
case GETWEATHER: sprintf (wsbuf, "{\"wen\":%d,\"wlat\":\"%s\",\"wlon\":\"%s\",\"wkey\":\"%s\"}", config.store.showweather, config.store.weatherlat, config.store.weatherlon, config.store.weatherkey); break;
|
||||
case GETCONTROLS: sprintf (wsbuf, "{\"vols\":%d,\"enca\":%d,\"irtl\":%d}", config.store.volsteps, config.store.encacc, config.store.irtlp); break;
|
||||
case DSPON: sprintf (wsbuf, "{\"dspontrue\":%d}", 1); break;
|
||||
case STATION: requestOnChange(STATIONNAME, clientId); requestOnChange(ITEM, clientId); break;
|
||||
case STATIONNAME: sprintf (wsbuf, "{\"nameset\": \"%s\"}", config.station.name); break;
|
||||
case ITEM: sprintf (wsbuf, "{\"current\": %d}", config.store.lastStation); break;
|
||||
case TITLE: sprintf (wsbuf, "{\"meta\": \"%s\"}", config.station.title); telnet.printf("##CLI.META#: %s\n> ", config.station.title); break;
|
||||
case VOLUME: sprintf (wsbuf, "{\"vol\": %d}", config.store.volume); telnet.printf("##CLI.VOL#: %d\n", config.store.volume); break;
|
||||
case NRSSI: sprintf (wsbuf, "{\"rssi\": %d}", rssi); /*rssi = 255;*/ break;
|
||||
case SDPOS: sprintf (wsbuf, "{\"sdpos\": %d,\"sdend\": %d,\"sdtpos\": %d,\"sdtend\": %d}", player.getFilePos(), player.getFileSize(), player.getAudioCurrentTime(), player.getAudioFileDuration()); break;
|
||||
case SDLEN: sprintf (wsbuf, "{\"sdmin\": %d,\"sdmax\": %d}", player.sd_min, player.sd_max); break;
|
||||
case SDSNUFFLE: sprintf (wsbuf, "{\"snuffle\": %d}", config.sdSnuffle); break;
|
||||
case BITRATE: sprintf (wsbuf, "{\"bitrate\": %d}", config.station.bitrate); break;
|
||||
case MODE: sprintf (wsbuf, "{\"mode\": \"%s\"}", player.status() == PLAYING ? "playing" : "stopped"); telnet.info(); break;
|
||||
case EQUALIZER: sprintf (wsbuf, "{\"bass\": %d, \"middle\": %d, \"trebble\": %d}", config.store.bass, config.store.middle, config.store.trebble); break;
|
||||
case BALANCE: sprintf (wsbuf, "{\"balance\": %d}", config.store.balance); break;
|
||||
case SDINIT: sprintf (wsbuf, "{\"sdinit\": %d}", SDC_CS!=255); break;
|
||||
case GETPLAYERMODE: sprintf (wsbuf, "{\"playermode\": \"%s\"}", config.store.play_mode==PM_SDCARD?"modesd":"modeweb"); break;
|
||||
case CHANGEMODE: config.changeMode(newConfigMode); return; break;
|
||||
default: break;
|
||||
}
|
||||
if (strlen(wsbuf) > 0) {
|
||||
@@ -308,6 +321,7 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client
|
||||
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, "newmode") == 0 ) { newConfigMode = atoi(val); requestOnChange(CHANGEMODE, 0); return; }
|
||||
if (strcmp(cmd, "smartstart") == 0) {
|
||||
byte valb = atoi(val);
|
||||
config.store.smartstart = valb == 1 ? 1 : 2;
|
||||
@@ -527,6 +541,7 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client
|
||||
player.setVol(v);
|
||||
}
|
||||
if (strcmp(cmd, "sdpos") == 0) {
|
||||
return;
|
||||
if (config.store.play_mode==PM_SDCARD){
|
||||
config.sdResumePos = 0;
|
||||
if(!player.isRunning()){
|
||||
@@ -536,6 +551,7 @@ void NetServer::onWsMessage(void *arg, uint8_t *data, size_t len, uint8_t client
|
||||
player.setFilePos(atoi(val)-player.sd_min);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd, "snuffle") == 0) {
|
||||
config.setSnuffle(strcmp(val, "true") == 0);
|
||||
@@ -657,6 +673,7 @@ bool NetServer::importPlaylist() {
|
||||
}
|
||||
|
||||
void NetServer::requestOnChange(requestType_e request, uint8_t clientId) {
|
||||
if(nsQueue==NULL) return;
|
||||
nsRequestParams_t nsrequest;
|
||||
nsrequest.type = request;
|
||||
nsrequest.clientId = clientId;
|
||||
@@ -667,13 +684,13 @@ String processor(const String& var) { // %Templates%
|
||||
if (var == "ACTION") return (network.status == CONNECTED && !config.emptyFS)?"webboard":"";
|
||||
if (var == "UPLOADWIFI") return (network.status == CONNECTED)?" hidden":"";
|
||||
if (var == "VERSION") return YOVERSION;
|
||||
if (var == "MODE") {
|
||||
/*if (var == "MODE") {
|
||||
if(config.store.play_mode==PM_SDCARD) {
|
||||
return "modescard";
|
||||
}else{
|
||||
return "modeweb";
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return String();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
#include "../AsyncWebServer/ESPAsyncWebServer.h"
|
||||
#include "AsyncUDP.h"
|
||||
|
||||
enum requestType_e : uint8_t { PLAYLIST=1, STATION=2, STATIONNAME=3, ITEM=4, TITLE=5, VOLUME=6, NRSSI=7, BITRATE=8, MODE=9, EQUALIZER=10, BALANCE=11, PLAYLISTSAVED=12, GETMODE=13, GETINDEX=14, GETACTIVE=15, GETSYSTEM=16, GETSCREEN=17, GETTIMEZONE=18, GETWEATHER=19, GETCONTROLS=20, DSPON=21, SDPOS=22, SDLEN=23, SDSNUFFLE=24 };
|
||||
enum requestType_e : uint8_t { PLAYLIST=1, STATION=2, STATIONNAME=3, ITEM=4, TITLE=5, VOLUME=6, NRSSI=7, BITRATE=8, MODE=9, EQUALIZER=10, BALANCE=11, PLAYLISTSAVED=12, GETMODE=13, GETINDEX=14, GETACTIVE=15, GETSYSTEM=16, GETSCREEN=17, GETTIMEZONE=18, GETWEATHER=19, GETCONTROLS=20, DSPON=21, SDPOS=22, SDLEN=23, SDSNUFFLE=24, SDINIT=25, GETPLAYERMODE=26, CHANGEMODE=27 };
|
||||
enum import_e : uint8_t { IMDONE=0, IMPL=1, IMWIFI=2 };
|
||||
const char emptyfs_html[] PROGMEM = R"(
|
||||
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width, minimum-scale=0.25"><meta charset="UTF-8"><link rel="icon" href="data:;base64,iVBORw0KGgo="><title>ёRadio - WEB Board Uploader</title><style>body{background-color:#000;color:#e3d25f;font-size:20px;}
|
||||
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=0.25"><meta charset="UTF-8"><link rel="icon" href="data:;base64,iVBORw0KGgo="><title>ёRadio - WEB Board Uploader</title><style>body{background-color:#000;color:#e3d25f;font-size:20px;}
|
||||
hr{margin:20px 0;border:0; border-top:#555 1px solid;} p{text-align:center;margin-bottom:10px;} section{max-width:500px; text-align:center;margin:0 auto 30px auto;}
|
||||
input[type=file]{color:#ccc;} input[type=file]::file-selector-button, input[type=submit]{border:2px solid #e3d25f;color:#000;padding:6px 16px;border-radius:25px;background-color:#e3d25f;margin:0 6px;cursor:pointer;}
|
||||
input[type=submit]{font-size:18px;text-transform:uppercase;padding:8px 26px;margin-top:10px;font-family:Times;} span{color:#ccc} .flex{display:flex;justify-content: space-around;margin-top:10px;}
|
||||
@@ -59,6 +59,7 @@ class NetServer {
|
||||
void loop();
|
||||
void requestOnChange(requestType_e request, uint8_t clientId);
|
||||
void setRSSI(int val) { rssi = val; };
|
||||
int getRSSI() { return rssi; };
|
||||
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 irRecordEnable;
|
||||
@@ -69,7 +70,7 @@ class NetServer {
|
||||
private:
|
||||
requestType_e request;
|
||||
QueueHandle_t nsQueue;
|
||||
int rssi;
|
||||
int rssi, newConfigMode;
|
||||
void getPlaylist(uint8_t clientId);
|
||||
bool importPlaylist();
|
||||
static size_t chunkedHtmlPageCallback(uint8_t* buffer, size_t maxLen, size_t index);
|
||||
|
||||
@@ -14,6 +14,8 @@ bool getWeather(char *wstr);
|
||||
void doSync(void * pvParameters);
|
||||
|
||||
void ticks() {
|
||||
if(!display.ready()) return; //waiting for SD is ready
|
||||
|
||||
static const uint16_t weatherSyncInterval=1800;
|
||||
//static const uint16_t weatherSyncIntervalFail=10;
|
||||
static const uint16_t timeSyncInterval=3600;
|
||||
@@ -42,11 +44,10 @@ void ticks() {
|
||||
}
|
||||
if(player.isRunning() && config.store.play_mode==PM_SDCARD) netserver.requestOnChange(SDPOS, 0);
|
||||
if(divrssi) {
|
||||
int rs = WiFi.RSSI();
|
||||
netserver.setRSSI(rs);
|
||||
netserver.setRSSI(WiFi.RSSI());
|
||||
netserver.requestOnChange(NRSSI, 0);
|
||||
display.putRequest(DSPRSSI, rs);
|
||||
|
||||
display.putRequest(DSPRSSI, netserver.getRSSI());
|
||||
if(!config.mountSDbusy) player.sendCommand({PR_CHECKSD, 0});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef options_h
|
||||
#define options_h
|
||||
|
||||
#define YOVERSION "0.9.180"
|
||||
#define YOVERSION "0.9.200"
|
||||
|
||||
/*******************************************************
|
||||
DO NOT EDIT THIS FILE.
|
||||
@@ -306,7 +306,10 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti
|
||||
#define MAX_AUDIO_SOCKET_TIMEOUT false // max audio socket timeout?
|
||||
#endif
|
||||
#ifndef BITRATE_FULL
|
||||
#define BITRATE_FULL true
|
||||
#define BITRATE_FULL true // display bitreta badget
|
||||
#endif
|
||||
#ifndef SD_AUTOPLAY
|
||||
#define SD_AUTOPLAY true // auto play from SD card when inserted
|
||||
#endif
|
||||
/*
|
||||
*** ST7735 display submodel ***
|
||||
|
||||
@@ -60,7 +60,7 @@ void Player::init() {
|
||||
//setOutputPins(false);
|
||||
_volTimer=false;
|
||||
playmutex = xSemaphoreCreateMutex();
|
||||
randomSeed(analogRead(0));
|
||||
//randomSeed(analogRead(0));
|
||||
#if PLAYER_FORCE_MONO
|
||||
forceMono(true);
|
||||
#endif
|
||||
@@ -108,7 +108,7 @@ void Player::_stop(bool alreadyStopped){
|
||||
}
|
||||
|
||||
void Player::initHeaders(const char *file) {
|
||||
if(strlen(file)==0) return;
|
||||
if(strlen(file)==0 || true) return; //TODO Read TAGs
|
||||
connecttoFS(SD,file);
|
||||
eofHeader = false;
|
||||
while(!eofHeader) Audio::loop();
|
||||
@@ -139,6 +139,10 @@ void Player::loop() {
|
||||
Audio::setVolume(volToI2S(requestP.payload));
|
||||
break;
|
||||
}
|
||||
case PR_CHECKSD: {
|
||||
config.checkSD();
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -182,9 +186,18 @@ void Player::_play(uint16_t stationId) {
|
||||
netserver.loop();
|
||||
netserver.loop();
|
||||
config.setSmartStart(0);
|
||||
if (config.store.play_mode==PM_WEB?connecttohost(config.station.url):connecttoFS(SD,config.station.url,config.sdResumePos==0?_resumeFilePos:config.sdResumePos-player.sd_min)) {
|
||||
bool isConnected = false;
|
||||
if(config.store.play_mode==PM_SDCARD && SDC_CS!=255)
|
||||
isConnected=connecttoFS(SD,config.station.url,config.sdResumePos==0?_resumeFilePos:config.sdResumePos-player.sd_min);
|
||||
else config.store.play_mode=PM_WEB;
|
||||
if(config.store.play_mode==PM_WEB) isConnected=connecttohost(config.station.url);
|
||||
if(isConnected){
|
||||
//if (config.store.play_mode==PM_WEB?connecttohost(config.station.url):connecttoFS(SD,config.station.url,config.sdResumePos==0?_resumeFilePos:config.sdResumePos-player.sd_min)) {
|
||||
_status = PLAYING;
|
||||
if(config.store.play_mode==PM_SDCARD) config.sdResumePos = 0;
|
||||
if(config.store.play_mode==PM_SDCARD) {
|
||||
config.sdResumePos = 0;
|
||||
config.backupSDStation = stationId;
|
||||
}
|
||||
//config.setTitle("");
|
||||
config.setSmartStart(1);
|
||||
netserver.requestOnChange(MODE, 0);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define PLERR_LN 64
|
||||
#define SET_PLAY_ERROR(...) {char buff[512 + 64]; sprintf(buff,__VA_ARGS__); setError(buff);}
|
||||
|
||||
enum playerRequestType_e : uint8_t { PR_PLAY = 1, PR_STOP = 2, PR_PREV = 3, PR_NEXT = 4, PR_VOL = 5 };
|
||||
enum playerRequestType_e : uint8_t { PR_PLAY = 1, PR_STOP = 2, PR_PREV = 3, PR_NEXT = 4, PR_VOL = 5, PR_CHECKSD = 6 };
|
||||
struct playerRequestParams_t
|
||||
{
|
||||
playerRequestType_e type;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "options.h"
|
||||
#if TS_MODEL!=TS_MODEL_UNDEFINED
|
||||
#if (TS_MODEL!=TS_MODEL_UNDEFINED) && (DSP_MODEL!=DSP_DUMMY)
|
||||
|
||||
#include "touchscreen.h"
|
||||
#include "config.h"
|
||||
|
||||
@@ -38,14 +38,15 @@ void DspCore::setCursor(int16_t x, int16_t y){
|
||||
}
|
||||
|
||||
uint16_t DspCore::print(const char* s){
|
||||
TAKE_MUTEX();
|
||||
|
||||
if(_gFont){
|
||||
TAKE_MUTEX();
|
||||
drawGFXText(_cursorx, _cursory, s, _fgcolor);
|
||||
GIVE_MUTEX();
|
||||
return 0;
|
||||
}else{
|
||||
_cursorx=drawText(_cursorx, _cursory, s, _fgcolor);
|
||||
GIVE_MUTEX();
|
||||
//GIVE_MUTEX();
|
||||
return _cursorx;
|
||||
}
|
||||
}
|
||||
@@ -279,7 +280,10 @@ uint16_t DspCore::drawChar(uint16_t x, uint16_t y, uint16_t ch, uint16_t color)
|
||||
return cfont.width;
|
||||
}
|
||||
}
|
||||
return TFT_22_ILI9225::drawChar(x, y, ch, color);
|
||||
TAKE_MUTEX();
|
||||
uint16_t ret=TFT_22_ILI9225::drawChar(x, y, ch, color);
|
||||
GIVE_MUTEX();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DspCore::setClipping(clipArea ca){
|
||||
|
||||
@@ -43,6 +43,11 @@ void setup() {
|
||||
while(!display.ready()) delay(10);
|
||||
return;
|
||||
}
|
||||
if(SDC_CS!=255) {
|
||||
display.putRequest(WAITFORSD, 0);
|
||||
Serial.print("##[BOOT]#\tSD search\t");
|
||||
}
|
||||
config.initPlaylistMode();
|
||||
netserver.begin();
|
||||
telnet.begin();
|
||||
initControls();
|
||||
|
||||
Reference in New Issue
Block a user