#include <WiFi.h>
#include <LITTLEFS.h>
#include <ESPAsyncWebServer.h>
#include <WebSocketsServer.h>
#include <queue>
#include <vector>
#include <ArduinoJson.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <map>
#include <set>
#include <sstream>
#include "class.h"
#define FORMAT_LITTLEFS_IF_FAILED false
#define RXD2 16
#define TXD2 17
#define RXD1 36
#define TXD1 39
#define DEBUG // comment to not run debug
// #define DEBUGPCB // comment to not run debugpcb
#ifndef DEBUG
#define DEBUG_BEGIN(x)
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINTF(x, y)
#else
#ifdef DEBUGPCB
#define DEBUG_BEGIN(baud, config, rxdpin, txdpin) Serial1.begin(baud, config, rxdpin, txdpin)
#define DEBUG_PRINT(x) Serial1.print(x)
#define DEBUG_PRINTLN(x) Serial1.println(x)
#define DEBUG_PRINTF(...) Serial1.printf(__VA_ARGS__)
#else
#define DEBUG_BEGIN(baud, config, rxdpin, txdpin) Serial.begin(baud)
#define DEBUG_PRINT(x) Serial.print(x)
#define DEBUG_PRINTLN(x) Serial.println(x)
#define DEBUG_PRINTF(...) Serial.printf(__VA_ARGS__)
#endif
#endif
// Constants
const int http_port = 80;
const int led_pin = 2;
// Globals
AsyncWebServer server(http_port);
WebSocketsServer webSocket = WebSocketsServer(81);
// Gcode Queue
std::queue<std::string> gcodeQueue;
// Writing Queue
std::queue<String> writingQueue;
bool waitingForOk = false;
/***********************************************************
Functions
*/
// Callback: receiving any WebSocket message
void onWebSocketEvent(uint8_t client_num,
WStype_t type,
uint8_t *payload,
size_t length)
{
// Figure out the type of WebSocket event
switch (type)
{
// Client has disconnected
case WStype_DISCONNECTED:
DEBUG_PRINTF("[%u] Disconnected!\n", client_num);
if (client_num == 0)
{
digitalWrite(led_pin, LOW);
}
break;
// New client has connected
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(client_num);
DEBUG_PRINTF("[%u] Connection from %s\n", client_num, ip.toString().c_str());
if (client_num == 0)
{
// main client connected
// Get the config.json file
File configjson = LITTLEFS.open("/config/config.json", "r");
if (!configjson)
{
DEBUG_PRINTLN("Failed to open config.json");
return;
}
// Parse the JSON file
StaticJsonDocument<512> doc;
DeserializationError error = deserializeJson(doc, configjson);
// Close the file as soon as you're done with it
configjson.close();
if (error)
{
DEBUG_PRINTLN("Failed to parse config.json");
return;
}
// Get the "turnoffboardled" boolean from the config.json file
bool turnoffboardled = doc["turnoffboardled"];
if (!turnoffboardled)
{
// main client connected and "turnoffboardled" is false
digitalWrite(led_pin, HIGH);
}
}
}
break;
// For everything else: do nothing
case WStype_TEXT:
DEBUG_PRINTF("[%u] Received text: %s\n", client_num, payload);
if (strcmp((char *)payload, "LEDON") == 0)
{
digitalWrite(led_pin, HIGH);
}
else if (strcmp((char *)payload, "LEDOFF") == 0)
{
digitalWrite(led_pin, LOW);
}
break;
case WStype_BIN:
case WStype_ERROR:
case WStype_FRAGMENT_TEXT_START:
case WStype_FRAGMENT_BIN_START:
case WStype_FRAGMENT:
case WStype_FRAGMENT_FIN:
default:
break;
}
}
// Callback: send 404 if requested file does not exist
void onPageNotFound(AsyncWebServerRequest *request)
{
IPAddress remote_ip = request->client()->remoteIP();
DEBUG_PRINTLN("[" + remote_ip.toString() +
"] HTTP GET request of " + request->url());
request->send(404, "text/plain", "Not found");
}
/***********************************************************
Main
*/
void ListAllFilesInDir(String directory)
{
File root = LITTLEFS.open(directory);
if (!root)
{
DEBUG_PRINTLN("Failed to open directory");
return;
}
if (!root.isDirectory())
{
DEBUG_PRINTLN("Not a directory");
return;
}
File file = root.openNextFile();
while (file)
{
if (file.isDirectory())
{
DEBUG_PRINT("DIR : ");
DEBUG_PRINTLN(file.name());
}
else
{
DEBUG_PRINT("FILE: ");
DEBUG_PRINTLN(file.name());
}
file = root.openNextFile();
}
}
void setup()
{
// Set LED pin as output
pinMode(led_pin, OUTPUT);
// Start debug port if DEBUG is defined and Serial1 if DEBUGPCB is defined else Serial
DEBUG_BEGIN(115200, SERIAL_8N1, RXD1, TXD1);
// Start Serial2 port
Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2);
// Make sure we can read the file system
if (!LITTLEFS.begin(FORMAT_LITTLEFS_IF_FAILED))
{
DEBUG_PRINTLN("Error mounting SPIFFS");
return;
}
int tBytes = LITTLEFS.totalBytes();
int uBytes = LITTLEFS.usedBytes();
DEBUG_PRINTLN("File system info");
DEBUG_PRINT("Total bytes: ");
DEBUG_PRINTLN(tBytes);
DEBUG_PRINT("Used bytes: ");
DEBUG_PRINTLN(uBytes);
// Get the Network name and password
File networkjson = LITTLEFS.open("/config/config.json", "r");
if (!networkjson || networkjson.isDirectory())
{
DEBUG_PRINTLN("Failed to open config.json");
return;
}
// Parse the JSON file
StaticJsonDocument<512> doc;
DeserializationError error = deserializeJson(doc, networkjson);
// Close the file as soon as you're done with it
networkjson.close();
if (error)
{
DEBUG_PRINTLN("Failed to parse config.json");
return;
}
// Get network name and password
const char *networkname = doc["networkname"];
const char *networkpassword = doc["networkpassword"];
DEBUG_PRINTLN("Network name: " + String(networkname));
DEBUG_PRINTLN("Network password: " + String(networkpassword));
// Start access point
WiFi.softAP(networkname, networkpassword);
// Print our IP address
DEBUG_PRINTLN();
DEBUG_PRINTLN("AP running");
DEBUG_PRINT("My IP address: ");
DEBUG_PRINTLN(WiFi.softAPIP());
server.serveStatic("/", LITTLEFS, "/");
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{
AsyncWebServerResponse* response = request->beginResponse(LITTLEFS, "/index.html", "text/html");
response->addHeader("Content-Encoding", "gzip");
request->send(response); });
// Handle file delete
server.on("/delete", HTTP_DELETE, [](AsyncWebServerRequest *request)
{
if (request->hasParam("filename")) { // if the request has a parameter named "filename"
String filename = request->getParam("filename")->value(); // get the value of the "filename" parameter
if (LITTLEFS.remove("/" + filename)) { // attempt to delete the file
request->send(200, "text/plain", "Successfull deleted file: " + filename); // if successful, send a 200 OK response
DEBUG_PRINTLN("Deleted file: " + filename);
} else {
request->send(500, "text/plain", "Failed to delete file"); // if unsuccessful, send a 500 Internal Server Error response
}
} else {
request->send(400, "text/plain", "Bad request"); // if the request does not have a "filename" parameter, send a 400 Bad Request response
} });
// Handle GET request for file list
server.on("/files", HTTP_GET, [](AsyncWebServerRequest *request)
{
if (request->hasParam("directory")) {
String directory = request->getParam("directory")->value();
ListAllFilesInDir(directory);
request->send(200, "text/plain", "");
} else {
request->send(400, "text/plain", "Bad request");
} });
// Handle requests for pages that do not exist
server.onNotFound(onPageNotFound);
// Start web server
server.begin();
// Start WebSocket server and assign callback
webSocket.begin();
// enable heartbeat for websocket
webSocket.enableHeartbeat(15000, 3000, 2);
webSocket.onEvent(onWebSocketEvent);
}
void loop()
{
webSocket.loop();
}
Aktuell nutze ich ListAllFilesInDir um mir die Dateinamen aus der Directory anzeigen zu lassen, ist aber sehr langsam bei vielen Dateien. Gibt es eine andere Möglichkeit das deutlich schneller zu machen? LG