Browse Source

Fixed two bugs and introduced file-upload (not yet functional!)

master
Torsten Stauder 5 years ago
parent
commit
f6801e6940
  1. 11
      html/website.html
  2. 10
      lib/nvsdump/src/nvsDump.h
  3. 4
      platformio.ini
  4. 88
      src/main.cpp
  5. 11
      src/websiteMgmt.h

11
html/website.html

@ -175,6 +175,17 @@
<button type="submit" class="btn btn-primary">Absenden</button> <button type="submit" class="btn btn-primary">Absenden</button>
</form> </form>
<div class="messages col-md-6 my-2"></div> <div class="messages col-md-6 my-2"></div>
</div>
<div class="container my-5" id="importNvs">
<h2>NVS-Importer (noch nicht funktional!)</h2>
<form action="/upload" enctype="multipart/form-data" method="POST">
<div class="form-group">
<label for="nvsUpload">NVS-Importer</label>
<input type="file" class="form-control-file" id="nvsUpload" name="nvsUpload" accept=".txt">
<button type="submit" class="btn btn-primary">Absenden</button>
</div>
</form>
<div class="messages col-md-6 my-2"></div>
</div> </div>
<script> <script>
var lastIdclicked = ''; var lastIdclicked = '';

10
lib/nvsdump/src/nvsDump.h

@ -63,16 +63,16 @@ uint8_t FindNsID (const esp_partition_t* nvs, const char* ns) {
while (offset < nvs->size) { while (offset < nvs->size) {
result = esp_partition_read ( nvs, offset, // Read 1 page in nvs partition
&buf,
sizeof(nvs_page) );
result = esp_partition_read (nvs, offset, // Read 1 page in nvs partition
&buf,
sizeof(nvs_page));
if (result != ESP_OK) { if (result != ESP_OK) {
dbgprint ("Error reading NVS!"); dbgprint ("Error reading NVS!");
break; break;
} }
i=0; i=0;
while (i < 126) { while (i < 126) {
bm = (buf.Bitmap[i/4] >> ((i % 4) * 2)) & 0x03 ; // Get bitmap for this entry
bm = (buf.Bitmap[i/4] >> ((i % 4) * 2)) & 0x03; // Get bitmap for this entry
if ((bm == 2) && if ((bm == 2) &&
(buf.Entry[i].Ns == 0) && (buf.Entry[i].Ns == 0) &&
(strcmp (ns, buf.Entry[i].Key) == 0)) { (strcmp (ns, buf.Entry[i].Key) == 0)) {
@ -81,7 +81,7 @@ uint8_t FindNsID (const esp_partition_t* nvs, const char* ns) {
break; break;
} else { } else {
if (bm == 2) { if (bm == 2) {
i += buf.Entry[i].Span ; // Next entry
i += buf.Entry[i].Span; // Next entry
} else { } else {
i++; i++;
} }

4
platformio.ini

@ -27,5 +27,5 @@ lib_deps =
https://github.com/bblanchon/ArduinoJson.git https://github.com/bblanchon/ArduinoJson.git
; Don't forget to run this script if you changed the html-files provided in any way ; Don't forget to run this script if you changed the html-files provided in any way
;extra_scripts =
; pre:processHtml.py
extra_scripts =
pre:processHtml.py

88
src/main.cpp

@ -152,8 +152,8 @@ typedef struct { // Bit field
playProps playProperties; playProps playProperties;
typedef struct { typedef struct {
char *nvsKey;
char *nvsEntry;
char nvsKey[13];
char nvsEntry[275];
} nvs_t; } nvs_t;
// Configuration of initial values (for the first start) goes here.... // Configuration of initial values (for the first start) goes here....
@ -187,6 +187,8 @@ char ftpPassword[15] = "esp32"; // FTP-password
uint8_t buttonDebounceInterval = 50; // Interval in ms to software-debounce buttons uint8_t buttonDebounceInterval = 50; // Interval in ms to software-debounce buttons
uint16_t intervalToLongPress = 700; // Interval in ms to distinguish between short and long press of previous/next-button uint16_t intervalToLongPress = 700; // Interval in ms to distinguish between short and long press of previous/next-button
// Where to store the backup-file
static const char backupFile[] PROGMEM = "/backup.txt";
// Don't change anything here unless you know what you're doing // Don't change anything here unless you know what you're doing
// HELPER // // HELPER //
@ -251,6 +253,7 @@ char mqtt_server[16] = "192.168.2.43"; // IP-address of MQTT-se
#endif #endif
char stringDelimiter[] = "#"; // Character used to encapsulate data in linear NVS-strings (don't change) char stringDelimiter[] = "#"; // Character used to encapsulate data in linear NVS-strings (don't change)
char stringOuterDelimiter[] = "^"; // Character used to encapsulate encapsulated data along with RFID-ID in backup-file
void notFound(AsyncWebServerRequest *request) { void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found"); request->send(404, "text/plain", "Not found");
@ -387,7 +390,7 @@ int countChars(const char* string, char ch) {
// Used to print content of sd-card (currently not used, maybe later :-)) // Used to print content of sd-card (currently not used, maybe later :-))
void printSdContent(File dir, uint16_t allocSize, uint8_t allocCount, char *sdContent, uint8_t depth) {
/*void printSdContent(File dir, uint16_t allocSize, uint8_t allocCount, char *sdContent, uint8_t depth) {
while (true) { while (true) {
File entry = dir.openNextFile(); File entry = dir.openNextFile();
if (!entry) { if (!entry) {
@ -417,7 +420,7 @@ void printSdContent(File dir, uint16_t allocSize, uint8_t allocCount, char *sdCo
} }
entry.close(); entry.close();
} }
}
}*/
void IRAM_ATTR onTimer() { void IRAM_ATTR onTimer() {
xSemaphoreGiveFromISR(timerSemaphore, NULL); xSemaphoreGiveFromISR(timerSemaphore, NULL);
@ -1145,12 +1148,13 @@ void playAudio(void *parameter) {
} }
if (playProperties.saveLastPlayPosition) { // Don't save for AUDIOBOOK_LOOP because not necessary if (playProperties.saveLastPlayPosition) { // Don't save for AUDIOBOOK_LOOP because not necessary
if (playProperties.currentTrackNumber + 1 < playProperties.numberOfTracks) { if (playProperties.currentTrackNumber + 1 < playProperties.numberOfTracks) {
// Only save if there's another track, otherwise it will be saved at end of playlist
// Only save if there's another track, otherwise it will be saved at end of playlist anyway
nvsRfidWriteWrapper(playProperties.playRfidTag, *(playProperties.playlist + playProperties.currentTrackNumber), 0, playProperties.playMode, playProperties.currentTrackNumber+1, playProperties.numberOfTracks); nvsRfidWriteWrapper(playProperties.playRfidTag, *(playProperties.playlist + playProperties.currentTrackNumber), 0, playProperties.playMode, playProperties.currentTrackNumber+1, playProperties.numberOfTracks);
} }
} }
if (playProperties.sleepAfterCurrentTrack) { // Go to sleep if "sleep after track" was requested if (playProperties.sleepAfterCurrentTrack) { // Go to sleep if "sleep after track" was requested
gotoSleep = true; gotoSleep = true;
break;
} }
if (!playProperties.repeatCurrentTrack) { // If endless-loop requested, track-number will not be incremented if (!playProperties.repeatCurrentTrack) { // If endless-loop requested, track-number will not be incremented
playProperties.currentTrackNumber++; playProperties.currentTrackNumber++;
@ -1795,6 +1799,7 @@ void deepSleepManager(void) {
#endif #endif
SPI.end(); SPI.end();
spiSD.end(); spiSD.end();
digitalWrite(POWER, LOW);
delay(200); delay(200);
esp_deep_sleep_start(); esp_deep_sleep_start();
} }
@ -2628,7 +2633,7 @@ bool processJsonRequest(char *_serialJson) {
if (s.compareTo(rfidString)) { if (s.compareTo(rfidString)) {
return false; return false;
} }
dumpNvsToSd("rfidTags", "/backup.txt");
dumpNvsToSd("rfidTags", (char *) FPSTR(backupFile)); // Store backup-file every time when a new rfid-tag is programmed
} else if (doc.containsKey("rfidAssign")) { } else if (doc.containsKey("rfidAssign")) {
const char *_rfidIdAssinId = object["rfidAssign"]["rfidIdMusic"]; const char *_rfidIdAssinId = object["rfidAssign"]["rfidIdMusic"];
@ -2644,7 +2649,7 @@ bool processJsonRequest(char *_serialJson) {
if (s.compareTo(rfidString)) { if (s.compareTo(rfidString)) {
return false; return false;
} }
dumpNvsToSd("rfidTags", "/backup.txt");
dumpNvsToSd("rfidTags", (char *) FPSTR(backupFile)); // Store backup-file every time when a new rfid-tag is programmed
} else if (doc.containsKey("wifiConfig")) { } else if (doc.containsKey("wifiConfig")) {
const char *_ssid = object["wifiConfig"]["ssid"]; const char *_ssid = object["wifiConfig"]["ssid"];
@ -2694,7 +2699,7 @@ void sendWebsocketData(uint32_t client, uint8_t code) {
// Processes websocket-requests // Processes websocket-requests
void onWebsocketEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){
void onWebsocketEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len){
if (type == WS_EVT_CONNECT){ if (type == WS_EVT_CONNECT){
//client connected //client connected
Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
@ -2805,7 +2810,7 @@ bool dumpNvsToSd(char *_namespace, char *_destFile) {
(buf.Entry[i].Ns == namespace_ID)) { // otherwise just my namespace (buf.Entry[i].Ns == namespace_ID)) { // otherwise just my namespace
if (isNumber(buf.Entry[i].Key)) { if (isNumber(buf.Entry[i].Key)) {
String s = prefsRfid.getString((const char *)buf.Entry[i].Key); String s = prefsRfid.getString((const char *)buf.Entry[i].Key);
backupFile.printf("%s^%s\n", buf.Entry[i].Key, s.c_str());
backupFile.printf("%s%s%s%s\n", stringOuterDelimiter, buf.Entry[i].Key, stringOuterDelimiter, s.c_str());
} }
} }
i += buf.Entry[i].Span; // Next entry i += buf.Entry[i].Span; // Next entry
@ -2822,6 +2827,60 @@ bool dumpNvsToSd(char *_namespace, char *_destFile) {
} }
// Handles uploaded files. Still in progress...
void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
/*if(!index){
Serial.printf("UploadStart: %s\n", filename.c_str());
}
for(size_t i=0; i<len; i++) {
if (data[i] != '\n') {
Serial.write(data[i]);
}
}
if(final){
Serial.printf("UploadEnd: %s, %u B\n", filename.c_str(), index+len);
}*/
char ebuf[290];
uint16_t j=0;
char *token;
uint8_t count=0;
nvs_t nvsEntry[1];
for(size_t i=0; i<len; i++) {
if (data[i] != '\n') {
ebuf[j++] = data[i];
//Serial.write(data[i]);
} else {
ebuf[j] = '\0';
j=0;
token = strtok(ebuf, stringOuterDelimiter);
while (token != NULL) {
if (!count) {
count++;
memcpy(nvsEntry[0].nvsKey, token, strlen(token));
nvsEntry[0].nvsKey[strlen(token)] = '\0';
Serial.printf("Col 1: %s\n", token);
} else if (count == 1) {
count = 0;
memcpy(nvsEntry[0].nvsEntry, token, strlen(token));
nvsEntry[0].nvsEntry[strlen(token)] = '\0';
Serial.printf("Col 2: %s\n", token);
}
//Serial.printf("%s\n", token);
delay(50);
token = strtok(NULL, stringOuterDelimiter);
}
//Serial.printf("%s => %s\n", nvsEntry[0].nvsKey, nvsEntry[0].nvsEntry);
delay(30);
/*if (isNumber(nvsEntry[0].nvsKey) && nvsEntry[0].nvsEntry[0] == '#') {
Serial.println("ok");
}*/
}
}
}
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
srand(esp_random()); srand(esp_random());
@ -3061,14 +3120,21 @@ void setup() {
lastTimeActiveTimestamp = millis(); // initial set after boot lastTimeActiveTimestamp = millis(); // initial set after boot
if (wifiManager() == WL_CONNECTED) { if (wifiManager() == WL_CONNECTED) {
// Websocket for Mgmt-Interface
// attach AsyncWebSocket for Mgmt-Interface
ws.onEvent(onWebsocketEvent); ws.onEvent(onWebsocketEvent);
wServer.addHandler(&ws); wServer.addHandler(&ws);
wServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
// attach AsyncEventSource
wServer.addHandler(&events);
wServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send_P(200, "text/html", mgtWebsite, templateProcessor); request->send_P(200, "text/html", mgtWebsite, templateProcessor);
}); });
wServer.on("/upload", HTTP_POST, [](AsyncWebServerRequest *request){
request->send(200);
}, handleUpload);
wServer.on("/restart", HTTP_GET, [] (AsyncWebServerRequest *request) { wServer.on("/restart", HTTP_GET, [] (AsyncWebServerRequest *request) {
request->send(200, "text/html", "<p>Der Tonuino wird neu gestartet...<br />Zur letzten Seite <a href=\"javascript:history.back()\">zur&uuml;ckkehren</a>.</p>"); request->send(200, "text/html", "<p>Der Tonuino wird neu gestartet...<br />Zur letzten Seite <a href=\"javascript:history.back()\">zur&uuml;ckkehren</a>.</p>");
Serial.flush(); Serial.flush();

11
src/websiteMgmt.h

@ -175,6 +175,17 @@ static const char mgtWebsite[] PROGMEM = "<!DOCTYPE html>\
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ <button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\
</form>\ </form>\
<div class=\"messages col-md-6 my-2\"></div>\ <div class=\"messages col-md-6 my-2\"></div>\
</div>\
<div class=\"container my-5\" id=\"importNvs\">\
<h2>NVS-Importer</h2>\
<form action=\"/upload\" enctype=\"multipart/form-data\" method=\"POST\">\
<div class=\"form-group\">\
<label for=\"nvsUpload\">NVS-Importer</label>\
<input type=\"file\" class=\"form-control-file\" id=\"nvsUpload\" name=\"nvsUpload\" accept=\".txt\">\
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\
</div>\
</form>\
<div class=\"messages col-md-6 my-2\"></div>\
</div>\ </div>\
<script>\ <script>\
var lastIdclicked = '';\ var lastIdclicked = '';\

Loading…
Cancel
Save