Compare commits
No commits in common. "ecc7c46b8d9c0dad0a2cb5b1801cbbf37d4a029a" and "65118fbc4273f111a0908f3f41bde62633b23eac" have entirely different histories.
ecc7c46b8d
...
65118fbc42
@ -28,7 +28,7 @@ lib_deps = ${extra.lib_deps}
|
|||||||
upload_port = /dev/cu.SLAB_USBtoUART
|
upload_port = /dev/cu.SLAB_USBtoUART
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
board_build.embed_txtfiles = src/index.html
|
board_build.embed_txtfiles = src/index.html
|
||||||
;board_build.partitions = partitions.csv
|
board_build.partitions = partitions.csv
|
||||||
;monitor_port = /dev/cu.wchusbserial1420
|
;monitor_port = /dev/cu.wchusbserial1420
|
||||||
|
|
||||||
[env:deploy]
|
[env:deploy]
|
||||||
|
@ -36,6 +36,7 @@ void Controller::register_http_server(HTTPServer* h) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::loop() {
|
void Controller::loop() {
|
||||||
|
TRACE("Controller::loop()...\n");
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
if ((_last_rfid_scan_at < now - RFID_SCAN_INTERVAL) || (now < _last_rfid_scan_at)) {
|
if ((_last_rfid_scan_at < now - RFID_SCAN_INTERVAL) || (now < _last_rfid_scan_at)) {
|
||||||
_check_rfid();
|
_check_rfid();
|
||||||
@ -65,6 +66,7 @@ void Controller::loop() {
|
|||||||
} else {
|
} else {
|
||||||
_last_wifi_try_at = now;
|
_last_wifi_try_at = now;
|
||||||
}
|
}
|
||||||
|
TRACE("Controller::loop() done.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Controller::_get_rfid_card_uid() {
|
uint32_t Controller::_get_rfid_card_uid() {
|
||||||
@ -83,7 +85,7 @@ uint32_t Controller::_get_rfid_card_uid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::_check_rfid() {
|
void Controller::_check_rfid() {
|
||||||
//TRACE("check_rfid running...\n");
|
TRACE("check_rfid running...\n");
|
||||||
MFRC522::StatusCode status;
|
MFRC522::StatusCode status;
|
||||||
if (_rfid_present) {
|
if (_rfid_present) {
|
||||||
byte buffer[2];
|
byte buffer[2];
|
||||||
@ -142,8 +144,7 @@ void Controller::_check_rfid() {
|
|||||||
if (time.tm_mon == 11) { // tm_mon is "months since january", so 11 means december.
|
if (time.tm_mon == 11) { // tm_mon is "months since january", so 11 means december.
|
||||||
pl->advent_shuffle(time.tm_mday);
|
pl->advent_shuffle(time.tm_mday);
|
||||||
} else {
|
} else {
|
||||||
DEBUG("Album is in advent mode, but it isn't december (yet). Not playing.\n");
|
// TODO
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else if (data.indexOf("[random]") != -1 && pl->is_fresh()) {
|
} else if (data.indexOf("[random]") != -1 && pl->is_fresh()) {
|
||||||
pl->shuffle();
|
pl->shuffle();
|
||||||
@ -199,7 +200,7 @@ String Controller::_read_rfid_data() {
|
|||||||
case MFRC522::PICC_TYPE_MIFARE_4K: sectors = 40; break;
|
case MFRC522::PICC_TYPE_MIFARE_4K: sectors = 40; break;
|
||||||
default: INFO("Unknown PICC type %s\n", String(MFRC522::PICC_GetTypeName(type)).c_str());
|
default: INFO("Unknown PICC type %s\n", String(MFRC522::PICC_GetTypeName(type)).c_str());
|
||||||
}
|
}
|
||||||
sectors = 2; // Pretend we have only two sectors, so we read only sector #1.
|
|
||||||
int good_key_index = -1;
|
int good_key_index = -1;
|
||||||
for (uint8_t sector=1; sector<sectors; sector++) {
|
for (uint8_t sector=1; sector<sectors; sector++) {
|
||||||
uint8_t blocks = (sector < 32) ? 4 : 16;
|
uint8_t blocks = (sector < 32) ? 4 : 16;
|
||||||
@ -243,6 +244,8 @@ String Controller::_read_rfid_data() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::_check_serial() {
|
void Controller::_check_serial() {
|
||||||
|
TRACE("check_serial running...\n");
|
||||||
|
|
||||||
if (Serial.available() > 0) {
|
if (Serial.available() > 0) {
|
||||||
char c = Serial.read();
|
char c = Serial.read();
|
||||||
Serial.printf("%c", c);
|
Serial.printf("%c", c);
|
||||||
@ -329,6 +332,8 @@ void Controller::_execute_command_help() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Controller::_check_buttons() {
|
void Controller::_check_buttons() {
|
||||||
|
TRACE("check_buttons running...\n");
|
||||||
|
|
||||||
if (BTN_PREV() && _debounce_button(0)) {
|
if (BTN_PREV() && _debounce_button(0)) {
|
||||||
if (_state == NORMAL) {
|
if (_state == NORMAL) {
|
||||||
player->track_prev();
|
player->track_prev();
|
||||||
|
@ -73,9 +73,6 @@ bool HTTPClientWrapper::_request(String method, String url, uint32_t offset, uin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_buffer_position = 0;
|
|
||||||
_buffer_length = 0;
|
|
||||||
|
|
||||||
_connected = true;
|
_connected = true;
|
||||||
_length = _http->getSize() + offset;
|
_length = _http->getSize() + offset;
|
||||||
if (_http->hasHeader("Content-Type")) {
|
if (_http->hasHeader("Content-Type")) {
|
||||||
|
@ -188,7 +188,7 @@ update_playlist = function(data) {
|
|||||||
tr = $('<tr>').data('track', i);
|
tr = $('<tr>').data('track', i);
|
||||||
tr.append($('<td>').html(i + 1));
|
tr.append($('<td>').html(i + 1));
|
||||||
tr.append($('<td>').html(data.current_track==i ? '<i class="fa fa-play"></i>' : ''));
|
tr.append($('<td>').html(data.current_track==i ? '<i class="fa fa-play"></i>' : ''));
|
||||||
tr.append($('<td>').html(data.files[i].title));
|
tr.append($('<td>').html(data.files[i].substr(data.files[i].title)));
|
||||||
$('#track_list').append(tr);
|
$('#track_list').append(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
46
src/main.cpp
46
src/main.cpp
@ -2,7 +2,6 @@
|
|||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <SD.h>
|
#include <SD.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <WiFiMulti.h>
|
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -20,22 +19,34 @@ HTTPServer* http_server;
|
|||||||
|
|
||||||
uint8_t SPIMaster::state = 0;
|
uint8_t SPIMaster::state = 0;
|
||||||
|
|
||||||
|
bool connect_to_wifi(String ssid, String pass) {
|
||||||
|
TRACE("Connecting to wifi \"%s\"...\n", ssid.c_str());
|
||||||
|
WiFi.mode(WIFI_AP_STA);
|
||||||
|
WiFi.begin(ssid.c_str(), pass.c_str());
|
||||||
|
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||||||
|
DEBUG("Could not connect to wifi \"%s\".\n", ssid.c_str());
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
INFO("Connected to \"%s\". IP address: %s\n", ssid.c_str(), WiFi.localIP().toString().c_str());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void wifi_connect() {
|
void wifi_connect() {
|
||||||
|
bool connected = false;
|
||||||
INFO("Connecting to WiFi...\n");
|
INFO("Connecting to WiFi...\n");
|
||||||
WiFiMulti wifi;
|
|
||||||
SPIMaster::select_sd();
|
SPIMaster::select_sd();
|
||||||
if (SD.exists("/_wifis.txt")) {
|
if (SD.exists("/_wifis.txt")) {
|
||||||
DEBUG("Reading /_wifis.txt\n");
|
DEBUG("Reading /_wifis.txt\n");
|
||||||
File f = SD.open("/_wifis.txt", "r");
|
File f = SD.open("/_wifis.txt", "r");
|
||||||
while (String line = f.readStringUntil('\n')) {
|
while (String line = f.readStringUntil('\n')) {
|
||||||
if (line.length()==0) {
|
if (line.length()==0 || line.startsWith("#") || line.indexOf('=')==-1) {
|
||||||
break;
|
|
||||||
} else if (line.startsWith("#") || line.indexOf('=')==-1) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String ssid = line.substring(0, line.indexOf('='));
|
String ssid = line.substring(0, line.indexOf('='));
|
||||||
String pass = line.substring(line.indexOf('=')+1);
|
String pass = line.substring(line.indexOf('=')+1);
|
||||||
wifi.addAP(ssid.c_str(), pass.c_str());
|
connected = connect_to_wifi(ssid, pass);
|
||||||
|
if (connected) break;
|
||||||
}
|
}
|
||||||
f.close();
|
f.close();
|
||||||
} else {
|
} else {
|
||||||
@ -45,20 +56,21 @@ void wifi_connect() {
|
|||||||
}
|
}
|
||||||
SPIMaster::select_sd(false);
|
SPIMaster::select_sd(false);
|
||||||
|
|
||||||
|
if (!connected) {
|
||||||
#if defined(WIFI_SSID) and defined(WIFI_PASS)
|
#if defined(WIFI_SSID) and defined(WIFI_PASS)
|
||||||
wifi.addAP(WIFI_SSID, WIFI_PASS);
|
DEBUG("Trying hardcoded WiFi data...\n");
|
||||||
|
connected = connect_to_wifi(WIFI_SSID, WIFI_PASS);
|
||||||
|
#else
|
||||||
|
DEBUG("No hardcoded WiFi data set.\n");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
if (wifi.run() == WL_CONNECTED) {
|
if (!connected) {
|
||||||
DEBUG("Connected to WiFi \"%s\".\n", WiFi.SSID().c_str());
|
INFO("No WiFi connection!\n");
|
||||||
} else {
|
|
||||||
DEBUG("No WiFi connection!\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// Small delay to give the Serial console a bit of time to connect.
|
delay(500);
|
||||||
delay(1000);
|
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
Serial.println("Starting...");
|
Serial.println("Starting...");
|
||||||
Serial.println("Started.");
|
Serial.println("Started.");
|
||||||
@ -114,12 +126,6 @@ void setup() {
|
|||||||
INFO("Could not fetch current time via NTP.\n");
|
INFO("Could not fetch current time via NTP.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VERSION
|
|
||||||
INFO("ESMP3 version %s (OTA_VERSION %d)\n", VERSION, OTA_VERSION);
|
|
||||||
#else
|
|
||||||
INFO("ESMP3, version unknown (OTA_VERSION %d)\n", OTA_VERSION);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
INFO("Initialization completed.\n");
|
INFO("Initialization completed.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,14 +464,14 @@ void Player::set_volume(uint8_t vol, bool save) {
|
|||||||
|
|
||||||
void Player::vol_up() {
|
void Player::vol_up() {
|
||||||
if (!is_playing()) return;
|
if (!is_playing()) return;
|
||||||
uint16_t vol = _volume + VOLUME_STEP;
|
uint8_t vol = _volume + VOLUME_STEP;
|
||||||
if (vol > VOLUME_MAX) vol=VOLUME_MAX;
|
if (vol > VOLUME_MAX) vol=VOLUME_MAX;
|
||||||
set_volume(vol);
|
set_volume(vol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::vol_down() {
|
void Player::vol_down() {
|
||||||
if (!is_playing()) return;
|
if (!is_playing()) return;
|
||||||
int16_t vol = _volume - VOLUME_STEP;
|
uint8_t vol = _volume - VOLUME_STEP;
|
||||||
if (vol < VOLUME_MIN) vol=VOLUME_MIN;
|
if (vol < VOLUME_MIN) vol=VOLUME_MIN;
|
||||||
set_volume(vol);
|
set_volume(vol);
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,6 @@ void xmlcb(uint8_t status, char* tagName, uint16_t tagLen, char* data, uint16_t
|
|||||||
xml_enclosure_url = "";
|
xml_enclosure_url = "";
|
||||||
} else if (tag.endsWith("/item") && (status & STATUS_END_TAG)) {
|
} else if (tag.endsWith("/item") && (status & STATUS_END_TAG)) {
|
||||||
if (xml_title.length()>0 && xml_url.length()>0) {
|
if (xml_title.length()>0 && xml_url.length()>0) {
|
||||||
if (xml_files_ptr->size() > 20) return;
|
|
||||||
DEBUG("Adding playlist entry: '%s' => '%s'\n", xml_title.c_str(), xml_url.c_str());
|
DEBUG("Adding playlist entry: '%s' => '%s'\n", xml_title.c_str(), xml_url.c_str());
|
||||||
xml_files_ptr->insert(xml_files_ptr->begin(), {.filename=xml_url, .title=xml_title, .id=xml_guid});
|
xml_files_ptr->insert(xml_files_ptr->begin(), {.filename=xml_url, .title=xml_title, .id=xml_guid});
|
||||||
}
|
}
|
||||||
@ -159,7 +158,6 @@ void Playlist::_parse_rss(HTTPClientWrapper* http) {
|
|||||||
while ((i = http->read()) >= 0) {
|
while ((i = http->read()) >= 0) {
|
||||||
xml.processChar(i);
|
xml.processChar(i);
|
||||||
}
|
}
|
||||||
_current_track = _files.size()-1;
|
|
||||||
xml_files_ptr = NULL;
|
xml_files_ptr = NULL;
|
||||||
if (xml_album_title.length()>0) {
|
if (xml_album_title.length()>0) {
|
||||||
_title = xml_album_title;
|
_title = xml_album_title;
|
||||||
@ -319,19 +317,12 @@ void Playlist::shuffle(uint8_t random_offset) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Playlist::advent_shuffle(uint8_t day) {
|
void Playlist::advent_shuffle(uint8_t day) {
|
||||||
TRACE("advent_shuffle running...\n");
|
if (day > 24) day = 24;
|
||||||
|
|
||||||
// Not enough songs till the current day? Play all songs in the default order.
|
|
||||||
if (day > _files.size()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are in the "different playlist every day" mode. So we don't persist it in order to not miss changes.
|
|
||||||
persistence = PERSIST_NONE;
|
|
||||||
|
|
||||||
|
if (day > _files.size()) return;
|
||||||
|
|
||||||
_files.insert(_files.begin(), _files[day - 1]);
|
_files.insert(_files.begin(), _files[day - 1]);
|
||||||
_files.erase(_files.begin() + day, _files.end());
|
_files.erase(_files.begin() + day - 1, _files.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Playlist::reset() {
|
void Playlist::reset() {
|
||||||
@ -384,7 +375,6 @@ void Playlist::json(JsonObject json) {
|
|||||||
JsonObject o = files.createNestedObject();
|
JsonObject o = files.createNestedObject();
|
||||||
o["filename"] = entry.filename;
|
o["filename"] = entry.filename;
|
||||||
o["title"] = entry.title;
|
o["title"] = entry.title;
|
||||||
o["id"] = entry.id;
|
|
||||||
}
|
}
|
||||||
json["current_track"] = _current_track;
|
json["current_track"] = _current_track;
|
||||||
json["has_track_next"] = has_track_next();
|
json["has_track_next"] = has_track_next();
|
||||||
|
@ -109,6 +109,7 @@ Playlist* PlaylistManager::get_playlist_for_folder(String folder) {
|
|||||||
p = new Playlist(folder);
|
p = new Playlist(folder);
|
||||||
_playlists[folder] = p;
|
_playlists[folder] = p;
|
||||||
if (p->persistence == PERSIST_PERMANENTLY) {
|
if (p->persistence == PERSIST_PERMANENTLY) {
|
||||||
|
// TODO Load persistence from file
|
||||||
String search = folder;
|
String search = folder;
|
||||||
search += "=";
|
search += "=";
|
||||||
SPIMaster::select_sd();
|
SPIMaster::select_sd();
|
||||||
@ -196,10 +197,7 @@ String PlaylistManager::create_mapping_txt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistManager::persist(Playlist* p) {
|
void PlaylistManager::persist(Playlist* p) {
|
||||||
if (p->persistence == PERSIST_NONE) {
|
if (p->persistence != PERSIST_PERMANENTLY) return;
|
||||||
_playlists.erase(p->path());
|
|
||||||
return;
|
|
||||||
} else if (p->persistence == PERSIST_PERMANENTLY) {
|
|
||||||
|
|
||||||
String search = p->path();
|
String search = p->path();
|
||||||
search += '=';
|
search += '=';
|
||||||
@ -233,7 +231,4 @@ void PlaylistManager::persist(Playlist* p) {
|
|||||||
dst.println(p->get_position());
|
dst.println(p->get_position());
|
||||||
dst.close();
|
dst.close();
|
||||||
SPIMaster::select_sd(false);
|
SPIMaster::select_sd(false);
|
||||||
|
|
||||||
_playlists.erase(p->path());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user