Moved index.html from SPIFFS to program memory. Removed dependencies to SPIFFS. Also, we can use a different partition scheme with much more program space instead of reserving some of it for SPIFFS.
This commit is contained in:
@ -378,7 +378,6 @@ String Controller::json() {
|
||||
json["uptime"] = millis() / 1000;
|
||||
json["free_heap"] = ESP.getFreeHeap();
|
||||
JsonObject versions = json.createNestedObject("versions");
|
||||
versions["spiffs"] = spiffs_version;
|
||||
versions["ota"] = OTA_VERSION;
|
||||
#ifdef VERSION
|
||||
versions["release"] = VERSION;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "http_server.h"
|
||||
#include "main.h"
|
||||
#include "spi_master.h"
|
||||
#include <ESPmDNS.h>
|
||||
#include <SPIFFS.h>
|
||||
|
||||
HTTPServer::HTTPServer(Player* p, Controller* c) {
|
||||
_player = p;
|
||||
@ -12,7 +12,7 @@ HTTPServer::HTTPServer(Player* p, Controller* c) {
|
||||
ws->onEvent([&](AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){this->_onEvent(server, client, type, arg, data, len);});
|
||||
|
||||
_server->on("/", HTTP_GET, [&](AsyncWebServerRequest* req) {
|
||||
req->send(SPIFFS, "/index.html", "text/html");
|
||||
req->send(200, "text/html", (const char*)file_index_html_start);
|
||||
});
|
||||
_server->on("/upload", HTTP_POST, [](AsyncWebServerRequest* req) {
|
||||
req->send(200);
|
||||
|
324
src/index.html
Normal file
324
src/index.html
Normal file
@ -0,0 +1,324 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>ESMP3</title>
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha256-pasqAKBDmFT4eHoN2ndd6lN370kFiGUFyTiUHWhU7k8=" crossorigin="anonymous"></script>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
||||
<script src="https://kit.fontawesome.com/272149490a.js" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container bg-dark text-light">
|
||||
<div class="row">
|
||||
<div class="col-sm-1">
|
||||
<h1 id="play_state_icon"><i class="fa fa-stop"></i></h1>
|
||||
</div>
|
||||
<div class="col-sm-11">
|
||||
<h2><i class="fa fa-compact-disc"></i> <span id="album"></span></h2>
|
||||
<h2><i class="fa fa-scroll"></i> <span id="track"></span></h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<input type="range" class="custom-range" id="position_slider" disabled>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
</div>
|
||||
<div class="col-sm-1">
|
||||
<h3><i class="fa fa-volume-down"></i></h3>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<input type="range" class="custom-range" id="volume_slider">
|
||||
</div>
|
||||
<div class="col-sm-1">
|
||||
<h3><i class="fa fa-volume-up"></i></h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_track_prev"><i class="fa fa-step-backward"></i></button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_stop"><i class="fa fa-stop"></i></button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_play"><i class="fa fa-play"></i></button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_track_next"><i class="fa fa-step-forward"></i></button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_lock"><i class="fa fa-lock-open"></i></button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_open"><i class="fa fa-eject"></i></button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_settings"><i class="fa fa-cog"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<table class="table table-hover table-sm" id="track_list_table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th>Nr.</th>
|
||||
<th>Status</th>
|
||||
<th>Track</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="" id="track_list">
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="modal fade" id="openModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Album öffnen</h5>
|
||||
<button type="button" class="close" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h6>Open URL</h6>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">
|
||||
<i class="fa fa-link"></i>
|
||||
</span>
|
||||
</div>
|
||||
<input type="text" class="form-control" id="input_url" />
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-primary" id="button_url_open">Go</button>
|
||||
<button class="btn btn-danger" id="button_url_add_mapping" style="display: none;"><i class="fa fa-arrows-alt-h"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<div id="albums_without_id_area">
|
||||
<h6>Albums without RFID card</h6>
|
||||
<table class="table table-hover table-sm">
|
||||
<tbody id="albums_without_id">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h6>Albums with RFID</h6>
|
||||
<table class="table table-hover table-sm">
|
||||
<tbody id="albums_with_id">
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="settingsModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Settings</h5>
|
||||
<button type="button" class="close" data-dismiss="modal">
|
||||
<span>×</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<h6>Last RFID id:</h6>
|
||||
<span id="last_rfid_id"></span> <button class="btn btn-warning" id="button_add_mapping"><i class="fa fa-arrows-alt-h"></i></button>
|
||||
|
||||
<h6>Last RFID data:</h6>
|
||||
<span id="last_rfid_data"></span>
|
||||
|
||||
<h6>Actions</h6>
|
||||
<button type="button" class="btn btn-danger btn-lg btn-block" id="button_reset_vs1053">Reset VS1053 chip</button>
|
||||
<button type="button" class="btn btn-danger btn-lg btn-block" id="button_reboot">Reboot ESMP3</button>
|
||||
<button type="button" class="btn btn-danger btn-lg btn-block" id="button_update">Check for and install update</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
update_player = function(data) {
|
||||
$('#play_state_icon i').removeClass('fa-stop', 'fa-play').addClass(data.playing ? 'fa-play' : 'fa-stop');
|
||||
|
||||
if (data.playing) {
|
||||
$('#button_play').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
||||
$('#button_stop').removeClass('btn-secondary', 'btn-disabled').addClass('btn-primary');
|
||||
} else if (data.playlist) {
|
||||
$('#button_play').removeClass('btn-secondary', 'btn-disabled').addClass('btn-primary');
|
||||
$('#button_stop').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
||||
} else {
|
||||
$('#button_play').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
||||
$('#button_stop').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
||||
}
|
||||
|
||||
$('#volume_slider').attr('min', data.volume.min).attr('max', data.volume.max).val(data.volume.current);
|
||||
|
||||
if (data.playlist) update_playlist(data.playlist);
|
||||
}
|
||||
|
||||
update_playlist = function(data) {
|
||||
$('#track_list tr').remove();
|
||||
for (var i=0; i<data.files.length; i++) {
|
||||
tr = $('<tr>').data('track', i);
|
||||
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.files[i].substr(data.files[i].title)));
|
||||
$('#track_list').append(tr);
|
||||
}
|
||||
|
||||
if (data.has_track_next) {
|
||||
$('#button_track_next').removeClass('btn-secondary', 'btn-disabled').addClass('btn-primary');
|
||||
} else {
|
||||
$('#button_track_next').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
||||
}
|
||||
|
||||
if (data.has_track_prev) {
|
||||
$('#button_track_prev').removeClass('btn-secondary', 'btn-disabled').addClass('btn-primary');
|
||||
} else {
|
||||
$('#button_track_prev').removeClass('btn-primary').addClass('btn-secondary', 'btn-disabled');
|
||||
}
|
||||
|
||||
$('#album').html(data.title);
|
||||
var file = data.files[data.current_track];
|
||||
if (file) {
|
||||
$('#track').html(file.title);
|
||||
}
|
||||
}
|
||||
|
||||
update_controller = function(data) {
|
||||
if (data.lock_state == "locked") {
|
||||
$('#button_lock').removeClass('btn-primary', 'btn-warning').addClass('btn-danger');
|
||||
$('#button_lock i').removeClass('fa-lock-open').addClass('fa-lock');
|
||||
} else if (data.lock_state == "locking") {
|
||||
$('#button_lock').removeClass('btn-primary', 'btn-danger').addClass('btn-warning');
|
||||
$('#button_lock i').removeClass('fa-lock-open').addClass('fa-lock');
|
||||
} else {
|
||||
$('#button_lock').removeClass('btn-danger', 'btn-warning').addClass('btn-primary');
|
||||
$('#button_lock i').removeClass('fa-lock').addClass('fa-lock-open');
|
||||
}
|
||||
|
||||
$('#button_add_mapping').toggle(data.last_rfid.uid.length>0);
|
||||
$('#last_rfid_id').html(data.last_rfid.uid);
|
||||
$('#last_rfid_data').html(data.last_rfid.data);
|
||||
}
|
||||
|
||||
update_playlist_manager = function(data) {
|
||||
if (data.unmapped.length > 0) {
|
||||
$('#albums_without_id_area').show();
|
||||
$('#albums_without_id tr').remove();
|
||||
data.unmapped = data.unmapped.sort();
|
||||
for (var i=0; i<data.unmapped.length; i++) {
|
||||
var tr = $('<tr>').attr('data-folder', data.unmapped[i]);
|
||||
tr.append($('<td>').html(data.unmapped[i].substr(1)));
|
||||
tr.append($('<td>').append($('<button>').addClass('button btn-warning add_mapping_button').hide().append($('<i>').addClass('fa fa-arrows-alt-h'))));
|
||||
$('#albums_without_id').append(tr);
|
||||
}
|
||||
} else {
|
||||
$('#albums_without_id_area').hide();
|
||||
}
|
||||
|
||||
var folders = Object.keys(data.folders).sort();
|
||||
for (var i in folders) {
|
||||
var folder = folders[i];
|
||||
var tr = $('<tr>').attr('data-folder', folder);
|
||||
tr.append($('<td>').html(folder.substr(1)));
|
||||
tr.append($('<td>').append($('<button>').addClass('button btn-danger add_mapping_button').hide().append($('<i>').addClass('fa fa-arrows-alt-h'))));
|
||||
$('#albums_with_id').append(tr);
|
||||
}
|
||||
}
|
||||
|
||||
update_position = function(data) {
|
||||
$('#position_slider').attr('max', data.file_size).val(data.position);
|
||||
}
|
||||
|
||||
process_ws_message = function(event) {
|
||||
var data = event.data.split("\n");;
|
||||
for (var i=0; i<data.length; i++) {
|
||||
var json = JSON.parse(data[i]);
|
||||
console.log(json);
|
||||
if (json === null) continue;
|
||||
switch(json["_type"]) {
|
||||
case "position": update_position(json); break;
|
||||
case "player": update_player(json); break;
|
||||
case "playlist_manager": update_playlist_manager(json); break;
|
||||
case "controller": update_controller(json); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var play_on_click = true;
|
||||
|
||||
$(function() {
|
||||
ws = new WebSocket("ws://" + location.host + "/ws");
|
||||
ws.onmessage = process_ws_message;
|
||||
|
||||
$('#volume_slider').change(function(e) { ws.send("volume=" + e.target.value); });
|
||||
$('#button_play').click(function(e) { ws.send("play"); });
|
||||
$('#button_stop').click(function(e) { ws.send("stop"); });
|
||||
$('#button_track_next').click(function(e) { ws.send("track_next"); });
|
||||
$('#button_track_prev').click(function(e) { ws.send("track_prev"); });
|
||||
$('#button_open').click(function(e) { $('#openModal').modal('show'); });
|
||||
$('#track_list').on('click', 'tr', function(e) { ws.send("track=" + $(e.target).parent().data('track')); });
|
||||
$('#albums_without_id, #albums_with_id').on('click', 'tr', function(e) { if (play_on_click) {ws.send("play " + $(e.target).parents('tr').data('folder')); $('#openModal').modal('hide');} });
|
||||
$('#button_settings').click(function(e) { $('#settingsModal').modal('show'); });
|
||||
$('#button_reset_vs1053').click(function(e) { ws.send("reset_vs1053"); $('#settingsModal').modal('hide'); });
|
||||
$('#button_reboot').click(function(e) { ws.send("reboot"); $('#settingsModal').modal('hide'); });
|
||||
$('#button_update').click(function(e) { ws.send("update"); $('#settingsModal').modal('hide'); });
|
||||
$('#button_url_open').click(function(e) { ws.send("play " + $('#input_url').val()); $('#openModal').modal('hide');});
|
||||
$('#button_add_mapping').click(function(e) {
|
||||
$('#settingsModal').modal('hide');
|
||||
$('#openModal').modal('show');
|
||||
$('.add_mapping_button').show();
|
||||
$('#button_url_open').hide();
|
||||
$('#button_url_add_mapping').show();
|
||||
play_on_click = false;
|
||||
});
|
||||
$('#openModal').on('click', '.add_mapping_button', function(e) {
|
||||
ws.send("add_mapping=" + $('#last_rfid_id').html() + "=" + $(e.target).parents('tr').data('folder'));
|
||||
$('#openModal').modal('hide');
|
||||
$('.add_mapping_button').hide();
|
||||
$('#button_url_open').hide();
|
||||
$('#button_url_add_mapping').show();
|
||||
e.stopPropagation();
|
||||
play_on_click=true;
|
||||
return false;
|
||||
});
|
||||
$('#button_url_add_mapping').click(function(e) {
|
||||
ws.send("add_mapping=" + $('#last_rfid_id').html() + "=" + $('#input_url').val());
|
||||
$('#openModal').modal('hide');
|
||||
$('.add_mapping_button').hide();
|
||||
$('#button_url_open').hide();
|
||||
$('#button_url_add_mapping').show();
|
||||
e.stopPropagation();
|
||||
play_on_click=true;
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</html>
|
24
src/main.cpp
24
src/main.cpp
@ -3,7 +3,6 @@
|
||||
#include <SD.h>
|
||||
#include <WiFi.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <SPIFFS.h>
|
||||
#include "main.h"
|
||||
#include "config.h"
|
||||
#include "controller.h"
|
||||
@ -20,8 +19,6 @@ HTTPServer* http_server;
|
||||
|
||||
uint8_t SPIMaster::state = 0;
|
||||
|
||||
uint16_t spiffs_version = 0;
|
||||
|
||||
bool connect_to_wifi(String ssid, String pass) {
|
||||
TRACE("Connecting to wifi \"%s\"...\n", ssid.c_str());
|
||||
WiFi.mode(WIFI_AP_STA);
|
||||
@ -101,17 +98,6 @@ void setup() {
|
||||
}
|
||||
spi->select_sd(false);
|
||||
|
||||
DEBUG("Starting SPIFFS...\n");
|
||||
SPIFFS.begin(true);
|
||||
if (SPIFFS.exists("/_version.txt")) {
|
||||
File f = SPIFFS.open("/_version.txt", "r");
|
||||
spiffs_version = f.readString().toInt();
|
||||
f.close();
|
||||
DEBUG("SPIFFS filesystem version is %d.\n", spiffs_version);
|
||||
} else {
|
||||
DEBUG("No SPIFFS filesystem version found - setting spiffs_version to 0.\n");
|
||||
}
|
||||
|
||||
DEBUG("Initializing PlaylistManager...\n");
|
||||
pm = new PlaylistManager();
|
||||
|
||||
@ -122,10 +108,6 @@ void setup() {
|
||||
|
||||
wifi_connect();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MDNS.begin("esmp3");
|
||||
|
||||
DEBUG("Setting up HTTP server...\n");
|
||||
@ -144,12 +126,6 @@ void setup() {
|
||||
INFO("Could not fetch current time via NTP.\n");
|
||||
}
|
||||
|
||||
#ifdef OTA_UPDATE_URL
|
||||
if (spiffs_version < OTA_VERSION) {
|
||||
Updater::run(spiffs_version);
|
||||
}
|
||||
#endif
|
||||
|
||||
INFO("Initialization completed.\n");
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,7 @@
|
||||
#include "updater.h"
|
||||
#include "http_client_wrapper.h"
|
||||
|
||||
void Updater::run(uint16_t spiffs_version) {
|
||||
bool update_image = true;
|
||||
void Updater::run() {
|
||||
DEBUG("Updater is running...\n");
|
||||
HTTPClientWrapper* http = new HTTPClientWrapper();
|
||||
DEBUG("Requesting update info...\n");
|
||||
@ -26,12 +25,7 @@ void Updater::run(uint16_t spiffs_version) {
|
||||
}
|
||||
DEBUG("Found version %d. My version is %d.\n", version, OTA_VERSION);
|
||||
if (version <= OTA_VERSION) {
|
||||
if (spiffs_version>0 && spiffs_version < version) {
|
||||
update_image = false;
|
||||
DEBUG("SPIFFS needs an update. Continuing.\n");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
String image_path = "";
|
||||
@ -44,27 +38,15 @@ void Updater::run(uint16_t spiffs_version) {
|
||||
return;
|
||||
}
|
||||
|
||||
String spiffs_path = "";
|
||||
if (!read_line(&spiffs_path, http, "SPIFFS_PATH")) {
|
||||
return;
|
||||
}
|
||||
|
||||
String spiffs_md5 = "";
|
||||
if (!read_line(&spiffs_md5, http, "SPIFFS_MD5")) {
|
||||
return;
|
||||
}
|
||||
|
||||
http->close();
|
||||
delete http;
|
||||
|
||||
result = true;
|
||||
if (update_image) {
|
||||
result = do_update(U_FLASH, image_path, image_md5);
|
||||
if(do_update(U_FLASH, image_path, image_md5)) {
|
||||
DEBUG("Update done. Rebooting...\n");
|
||||
} else {
|
||||
DEBUG("Update failed. Rebooting...\n");
|
||||
}
|
||||
if (result) {
|
||||
do_update(U_SPIFFS, spiffs_path, spiffs_md5);
|
||||
}
|
||||
DEBUG("Done. Rebooting...\n");
|
||||
delay(1000);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user