index.html is now served from SPIFFS. You can add rfid tag -> folder mappings via the webinterface. And I've added the missing controller json data messages.
This commit is contained in:
parent
b9a4770ff2
commit
5c15a7d4cb
@ -1,4 +1,4 @@
|
|||||||
const char* html = R"V0G0N(<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
@ -61,6 +61,10 @@ const char* html = R"V0G0N(<!DOCTYPE html>
|
|||||||
<div class="col">
|
<div class="col">
|
||||||
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_open"><i class="fa fa-eject"></i></button>
|
<button type="button" class="btn btn-primary btn-lg btn-block" id="button_open"><i class="fa fa-eject"></i></button>
|
||||||
</div>
|
</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>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -112,6 +116,35 @@ const char* html = R"V0G0N(<!DOCTYPE html>
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="settingsModal" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" 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>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -176,6 +209,10 @@ update_controller = function(data) {
|
|||||||
$('#button_lock').removeClass('btn-danger', 'btn-warning').addClass('btn-primary');
|
$('#button_lock').removeClass('btn-danger', 'btn-warning').addClass('btn-primary');
|
||||||
$('#button_lock i').removeClass('fa-lock').addClass('fa-lock-open');
|
$('#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) {
|
update_playlist_manager = function(data) {
|
||||||
@ -184,7 +221,9 @@ update_playlist_manager = function(data) {
|
|||||||
$('#albums_without_id tr').remove();
|
$('#albums_without_id tr').remove();
|
||||||
data.unmapped = data.unmapped.sort();
|
data.unmapped = data.unmapped.sort();
|
||||||
for (var i=0; i<data.unmapped.length; i++) {
|
for (var i=0; i<data.unmapped.length; i++) {
|
||||||
var tr = $('<tr>').attr('data-folder', data.unmapped[i]).append($('<td>').html(data.unmapped[i].substr(1)));
|
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);
|
$('#albums_without_id').append(tr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -196,6 +235,7 @@ update_playlist_manager = function(data) {
|
|||||||
var folder = folders[i];
|
var folder = folders[i];
|
||||||
var tr = $('<tr>').attr('data-folder', folder);
|
var tr = $('<tr>').attr('data-folder', folder);
|
||||||
tr.append($('<td>').html(folder.substr(1)));
|
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);
|
$('#albums_with_id').append(tr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,6 +253,7 @@ process_ws_message = function(event) {
|
|||||||
case "position": update_position(json); break;
|
case "position": update_position(json); break;
|
||||||
case "player": update_player(json); break;
|
case "player": update_player(json); break;
|
||||||
case "playlist_manager": update_playlist_manager(json); break;
|
case "playlist_manager": update_playlist_manager(json); break;
|
||||||
|
case "controller": update_controller(json); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,9 +269,16 @@ $(function() {
|
|||||||
$('#button_track_prev').click(function(e) { ws.send("track_prev"); });
|
$('#button_track_prev').click(function(e) { ws.send("track_prev"); });
|
||||||
$('#button_open').click(function(e) { $('#openModal').modal('show'); });
|
$('#button_open').click(function(e) { $('#openModal').modal('show'); });
|
||||||
$('#track_list').on('click', 'tr', function(e) { ws.send("track=" + $(e.target).parent().data('track')); });
|
$('#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) { ws.send("play " + $(e.target).parent().data('folder')); $('#openModal').modal('hide'); });
|
$('#albums_without_id, #albums_with_id').on('click', 'tr', function(e) { 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_add_mapping').click(function(e) {
|
||||||
|
$('#settingsModal').modal('hide');
|
||||||
|
$('#openModal').modal('show');
|
||||||
|
$('.add_mapping_button').show();
|
||||||
|
});
|
||||||
|
$('#openModal').on('click', '.add_mapping_button', function(e) {console.log("add_mapping=" + $('#last_rfid_id').html() + "=" + $(e.target).parents('tr').data('folder')); $('#openModal').modal('hide'); $('.add_mapping_button').hide(); e.stopPropagation();});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
)V0G0N";
|
|
@ -49,6 +49,7 @@ public:
|
|||||||
void set_mqtt_client(MQTTClient* m);
|
void set_mqtt_client(MQTTClient* m);
|
||||||
void register_http_server(HTTPServer* h);
|
void register_http_server(HTTPServer* h);
|
||||||
void loop();
|
void loop();
|
||||||
|
void send_controller_status();
|
||||||
void send_player_status();
|
void send_player_status();
|
||||||
void send_playlist_manager_status();
|
void send_playlist_manager_status();
|
||||||
void send_position();
|
void send_position();
|
||||||
|
@ -15,4 +15,5 @@ public:
|
|||||||
Playlist* get_playlist_for_folder(String folder);
|
Playlist* get_playlist_for_folder(String folder);
|
||||||
void dump_ids();
|
void dump_ids();
|
||||||
String json();
|
String json();
|
||||||
|
bool add_mapping(String id, String folder);
|
||||||
};
|
};
|
||||||
|
@ -93,6 +93,7 @@ void Controller::_check_rfid() {
|
|||||||
if (_state != LOCKED) {
|
if (_state != LOCKED) {
|
||||||
_player->stop();
|
_player->stop();
|
||||||
}
|
}
|
||||||
|
send_controller_status();
|
||||||
} else {
|
} else {
|
||||||
uint32_t uid = _get_rfid_card_uid();
|
uint32_t uid = _get_rfid_card_uid();
|
||||||
if (uid > 0) {
|
if (uid > 0) {
|
||||||
@ -157,7 +158,8 @@ void Controller::_check_rfid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_player->play(pl);
|
_player->play(pl);
|
||||||
send_playlist_manager_status();
|
//send_playlist_manager_status();
|
||||||
|
send_controller_status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,6 +287,13 @@ bool Controller::process_message(String cmd) {
|
|||||||
_player->init();
|
_player->init();
|
||||||
} else if (cmd.equals("reboot")) {
|
} else if (cmd.equals("reboot")) {
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
|
} else if (cmd.startsWith("add_mapping=")) {
|
||||||
|
String rest = cmd.substring(12);
|
||||||
|
uint8_t idx = rest.indexOf('=');
|
||||||
|
String id = rest.substring(0, idx);
|
||||||
|
String folder = rest.substring(idx + 1);
|
||||||
|
_pm->add_mapping(id, folder);
|
||||||
|
send_playlist_manager_status();
|
||||||
} else {
|
} else {
|
||||||
ERROR("Unknown command: %s\n", cmd.c_str());
|
ERROR("Unknown command: %s\n", cmd.c_str());
|
||||||
return false;
|
return false;
|
||||||
@ -352,6 +361,7 @@ String Controller::json() {
|
|||||||
case LOCKING: json["state"] = "locking"; break;
|
case LOCKING: json["state"] = "locking"; break;
|
||||||
case NORMAL: json["state"] = "normal"; break;
|
case NORMAL: json["state"] = "normal"; break;
|
||||||
}
|
}
|
||||||
|
json["is_rfid_present"] = _rfid_present;
|
||||||
JsonObject rfid = json.createNestedObject("last_rfid");
|
JsonObject rfid = json.createNestedObject("last_rfid");
|
||||||
rfid["uid"] = _last_rfid_uid;
|
rfid["uid"] = _last_rfid_uid;
|
||||||
rfid["data"] = _last_rfid_data;
|
rfid["data"] = _last_rfid_data;
|
||||||
@ -376,12 +386,19 @@ void Controller::send_playlist_manager_status() {
|
|||||||
|
|
||||||
void Controller::send_position() {
|
void Controller::send_position() {
|
||||||
TRACE("In send_position()...\n");
|
TRACE("In send_position()...\n");
|
||||||
if (_http_server->ws->count() > 0) {
|
if (_http_server->ws->count() > 0 && _player->is_playing()) {
|
||||||
_http_server->ws->textAll(_player->position_json());
|
_http_server->ws->textAll(_player->position_json());
|
||||||
}
|
}
|
||||||
_last_position_info_at = millis();
|
_last_position_info_at = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Controller::send_controller_status() {
|
||||||
|
TRACE("In send_controller_status()...\n");
|
||||||
|
if (_http_server->ws->count() > 0) {
|
||||||
|
_http_server->ws->textAll(json());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Controller::inform_new_client(AsyncWebSocketClient* client) {
|
void Controller::inform_new_client(AsyncWebSocketClient* client) {
|
||||||
String s;
|
String s;
|
||||||
s += _pm->json();
|
s += _pm->json();
|
||||||
@ -389,6 +406,8 @@ void Controller::inform_new_client(AsyncWebSocketClient* client) {
|
|||||||
s += _player->json();
|
s += _player->json();
|
||||||
s += '\n';
|
s += '\n';
|
||||||
s += _player->position_json();
|
s += _player->position_json();
|
||||||
|
s += '\n';
|
||||||
|
s += json();
|
||||||
client->text(s);
|
client->text(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "http_server.h"
|
#include "http_server.h"
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
|
#include <SPIFFS.h>
|
||||||
|
|
||||||
HTTPServer::HTTPServer(Player* p, Controller* c) {
|
HTTPServer::HTTPServer(Player* p, Controller* c) {
|
||||||
_player = p;
|
_player = p;
|
||||||
@ -8,7 +9,7 @@ HTTPServer::HTTPServer(Player* p, Controller* c) {
|
|||||||
ws = new AsyncWebSocket("/ws");
|
ws = new AsyncWebSocket("/ws");
|
||||||
_server->addHandler(ws);
|
_server->addHandler(ws);
|
||||||
ws->onEvent([&](AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){this->_onEvent(server, client, type, arg, data, len);});
|
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("/", [&](AsyncWebServerRequest* req) {_handle_index(req);});
|
_server->on("/", [&](AsyncWebServerRequest* req) {req->send(SPIFFS, "/index.html", "text/html");});
|
||||||
_server->begin();
|
_server->begin();
|
||||||
MDNS.addService("http", "tcp", 80);
|
MDNS.addService("http", "tcp", 80);
|
||||||
}
|
}
|
||||||
@ -102,10 +103,3 @@ void HTTPServer::_onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HTTPServer::_handle_index(AsyncWebServerRequest* r) {
|
|
||||||
|
|
||||||
#include "index.html"
|
|
||||||
|
|
||||||
r->send(200, "text/html", html);
|
|
||||||
}
|
|
@ -110,3 +110,19 @@ String PlaylistManager::json() {
|
|||||||
}
|
}
|
||||||
return json.as<String>();
|
return json.as<String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PlaylistManager::add_mapping(String id, String folder) {
|
||||||
|
DEBUG("Adding Mapping: '%s'=>'%s'\n", id.c_str(), folder.c_str());
|
||||||
|
if (!SD.exists(folder)) return false;
|
||||||
|
File ids = SD.open(folder + "/ids.txt", "a");
|
||||||
|
String data = "\n";
|
||||||
|
data += id;
|
||||||
|
data += '\n';
|
||||||
|
char* buffer = new char[data.length()];
|
||||||
|
data.toCharArray(buffer, data.length());
|
||||||
|
ids.write((uint8_t *)buffer, data.length());
|
||||||
|
delete buffer;
|
||||||
|
ids.close();
|
||||||
|
_map[id] = folder;
|
||||||
|
return true;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user