diff --git a/include/http_server.h b/include/http_server.h index d047d0f..5bcf11a 100644 --- a/include/http_server.h +++ b/include/http_server.h @@ -10,6 +10,7 @@ extern AsyncWebServer http_server; extern File upload_file; +extern uint32_t monitor_client; void http_server_setup(); void http_server_send_framedata(); diff --git a/src/http_server.cpp b/src/http_server.cpp index b527f31..d4a0958 100644 --- a/src/http_server.cpp +++ b/src/http_server.cpp @@ -11,105 +11,152 @@ AsyncWebServer http_server(HTTP_SERVER_PORT); AsyncWebSocket ws("/ws"); +uint32_t monitor_client = 0; -File upload_file; - -/*void http_server_handle_file_upload() { - if (http_server.uri() != "/upload") return; - - HTTPUpload upload = http_server.upload(); - - if (upload.status == UPLOAD_FILE_START) { - String filename = upload.filename; - if (!filename.startsWith("/")) filename = "/" + filename; - LOGln("HTTP * Upload of %s starting...", upload.filename.c_str()); +void http_server_handle_file_upload(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final) { + File upload_file; + if (index == 0) { // Start of upload + LOGln("HTTP * Upload of %s starting...", filename.c_str()); upload_file = SPIFFS.open(filename, "w"); - } else if (upload.status == UPLOAD_FILE_WRITE) { - if (upload_file) upload_file.write(upload.buf, upload.currentSize); - } else if (upload.status == UPLOAD_FILE_END) { - if (upload_file) upload_file.close(); - LOGln("HTTP * Upload of %s with %d bytes done.", upload.filename.c_str(), upload.totalSize); + } else { + upload_file = SPIFFS.open(filename, "a"); } -}*/ + + upload_file.write(data, len); + + if (final) { + LOGln("HTTP * Upload of %s done.", filename.c_str()); + } +} + +void ws_send_effects(AsyncWebSocketClient* client) { + String msg = "{\"effects\": ["; + for (int i=0; i0) msg += ", "; + msg += '"'; + msg += effects[i].name; + msg += '"'; + } + msg += "]}"; + client->text(msg); +} + +void ws_send_settings(AsyncWebSocketClient* client) { + String msg = "{\"settings\": ["; + for (int i=0; i0) msg += ", "; + msg += "{\"name\":\""; + msg += all_settings[i].name; + msg += "\",\"value\":"; + msg += *(all_settings[i].value); + msg += ",\"type\":\""; + switch (all_settings[i].type) { + case TYPE_UINT8: msg += "uint8"; break; + case TYPE_UINT16: msg += "uint16"; break; + case TYPE_BOOL: msg += "bool"; break; + default: msg += "unknown"; + } + msg += "\"}"; + } + msg += "]}"; + client->text(msg); +} + +void ws_set_setting(String s) { + int8_t index = s.indexOf(":"); + if (index < 1) return; + String key = s.substring(0, index); + String value = s.substring(index+1); + change_setting(key.c_str(), value.toInt()); +} void handle_ws(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) { if (type == WS_EVT_CONNECT) { - LOGln("Websocket * Client connected."); + LOGln("Websocket * Client connected. ID: %d", client->id()); } else if (type == WS_EVT_DISCONNECT) { + if (monitor_client == client->id()) monitor_client=0; LOGln("Websocket * Client disconnected."); + } else if (type == WS_EVT_DATA) { + AwsFrameInfo* info = (AwsFrameInfo*)arg; + if (info->opcode == WS_TEXT) { + data[len] = 0; + String msg = String((char*)data); + LOGln("Websocket * In: %s", msg.c_str()); + if (msg.startsWith("effect:")) { + change_current_effect(msg.substring(7)); + } else if (msg.equals("effects?")) { + ws_send_effects(client); + } else if (msg.equals("settings?")) { + ws_send_settings(client); + } else if (msg.startsWith("setting:")) { + ws_set_setting(msg.substring(8)); + } else if (msg.equals("monitor:1")) { + monitor_client = client->id(); + } else if (msg.equals("monitor:0")) { + if (monitor_client == client->id()) monitor_client=0; + } else { + client->text("Unknown command. Accepted commands:\neffects?\nsettings?\nsetting::\neffect:\nmonitor:<0/1>"); + } + } } } void http_server_setup() { - PGM_P text_plain = PSTR("text/plain"); - PGM_P text_html = PSTR("text/html"); + static const char* PROGMEM text_plain = "text/plain"; + http_server.on("/", HTTP_GET, [&](AsyncWebServerRequest* request){ LOGln("HTTP * GET /"); - String message = "Pitrix

Pitrix

Settings

Effect

Known animations:

"; + String response = String(F("Pitrix

Pitrix

Settings

Effect

Known animations:

")); if (!SPIFFS.begin()) { - message += "No SPIFFS file system found."; + response += F("No SPIFFS file system found."); } else { - message += "
    "; + response += F("
      "); Dir dir = SPIFFS.openDir("/"); while (dir.next()) { - message += "
    • " + dir.fileName() + " (delete)
    • "; + char buffer[100]; + snprintf_P(buffer, 100, PSTR("
    • %s (delete)
    • "), dir.fileName().c_str(), dir.fileName().c_str()); + response += buffer; } - message += "
    "; - message += "
    "; + response += F("
"); + response += F("
"); } - message += ""; - request->send(200, "text/html", message); + response += F(""); + request->send(200, "text/html", response); }); http_server.on("/settings", HTTP_GET, [&](AsyncWebServerRequest* request) { - String message = "Pitrix settings

Pitrix settings

Back to main page\n"; + String message = F("Pitrix settings

Pitrix settings

Back to main page
\n"); for (int i=0; i\n"; + message += buffer; + message += F("\n"); } - message += "
"); if (default_value != value) { - message += ""; + message += F(""); } message += s.name; if (default_value != value) { - message += ""; + message += F(""); } - message += ""; + message += F(""); message += value; if (default_value != value) { message += " ("; message += default_value; message += ")"; } - message += "
"; + char buffer[150]; + snprintf_P(buffer, 150, PSTR("
"), s.name); + message += buffer; if (s.type==TYPE_UINT8 || s.type==TYPE_UINT16) { - message += ""; + snprintf_P(buffer, 150, PSTR(""), value, s.type==TYPE_UINT8 ? 255 : 65535); } else if (s.type==TYPE_BOOL) { - message += " Off / On"), value==0?"checked":"", value==1?"checked":""); } - message += ""; - message += "
"; + message += F(""); request->send(200, "text/html", message); }); http_server.on("/settings", HTTP_POST, [&](AsyncWebServerRequest* request) { @@ -122,9 +169,7 @@ void http_server_setup() { if (change_setting(name.c_str(), value)) { if (request->hasParam("redir")) { - AsyncWebServerResponse* response = request->beginResponse(301, "text/plain", "Moved"); - response->addHeader("Location", "/settings"); - request->send(response); + request->redirect("/settings"); } else { request->send(200, "text/plain", "OK"); } @@ -155,15 +200,13 @@ void http_server_setup() { request->send(500, "text/plain", "Could not read settings."); }); http_server.on("/effects", HTTP_GET, [&](AsyncWebServerRequest* request) { - String message = "Pitrix effects

Pitrix settings

Back to main page"; + String message = F("Pitrix effects

Pitrix settings

Back to main page
"); + char buffer[150]; for (int i=0; i"), effects[i].name, effects[i].name); + message += buffer; } - message += "
%s
"; + message += F(""); request->send(200, "text/html", message); }); http_server.on("/effects", HTTP_POST, [&](AsyncWebServerRequest* request) { @@ -174,9 +217,7 @@ void http_server_setup() { String name = request->getParam("name", true)->value(); if (change_current_effect(name)) { if (request->hasParam("redir")) { - AsyncWebServerResponse* response = request->beginResponse(301, "text/plain", "Moved"); - response->addHeader("Location", "/effects"); - request->send(response); + request->redirect("/effects"); } else { request->send(200, "text/plain", "OK"); } @@ -202,10 +243,9 @@ void http_server_setup() { SPIFFS.remove(file); request->send_P(200, text_plain, PSTR("OK")); }); - /*http_server.on("/upload", HTTP_POST, [](AsyncWebServerRequest* request) { - LOGln("HTTP * POST /upload"); - request->send(200, "text/plain", "OK"); - }, http_server_handle_file_upload);*/ + http_server.on("/upload", HTTP_POST, [](AsyncWebServerRequest* request) { + request->send(200); + }, http_server_handle_file_upload); http_server.on("/free_heap", HTTP_GET, [&](AsyncWebServerRequest* request){ LOGln("HTTP * GET /free_heap"); request->send(200, "text/plain", String(ESP.getFreeHeap())); @@ -242,15 +282,38 @@ void http_server_setup() { Pitrix +

+ + +

@@ -288,79 +356,27 @@ void http_server_setup() { } void http_server_send_framedata() { - if (ws.count() > 0) { - uint16_t _size = LED_WIDTH * LED_HEIGHT * 3 + 4; - uint8_t* _buffer = new uint8_t[_size]; - _buffer[0] = LED_WIDTH; - _buffer[1] = LED_HEIGHT; - _buffer[2] = 255; - for (uint8_t y=0; y0 && monitor_client>0) { + if (ws.hasClient(monitor_client)) { + uint16_t _size = LED_WIDTH * LED_HEIGHT * 3 + 4; + uint8_t* _buffer = new uint8_t[_size]; + _buffer[0] = LED_WIDTH; + _buffer[1] = LED_HEIGHT; + _buffer[2] = 255; + for (uint8_t y=0; y -#include -#include "config.h" -#include "websockets.h" -#include "my_fastled.h" -#include "functions.h" -#include "effects.h" - -WebSocketsServer ws = WebSocketsServer(81); - -void ws_event(uint8_t num, WStype_t type, uint8_t* payload, size_t length) { - if (type == WStype_CONNECTED) { - LOGln("Websockets * Client connected."); - } else if (type == WStype_DISCONNECTED) { - LOGln("Websockets * Client disconnected."); - } else if (type == WStype_TEXT) { - String msg = String((char*)payload); - LOGln("Websockets * Received: %s", msg.c_str()); - - if (msg.startsWith("E:")) { - change_current_effect(msg.substring(2)); - } - } -} - -void websocket_setup() { - ws.begin(); - ws.onEvent(ws_event); -} - -void send_data() { - uint16_t _size = LED_WIDTH * LED_HEIGHT * 3 + 4; - uint8_t* _buffer = new uint8_t[_size]; - _buffer[0] = LED_WIDTH; - _buffer[1] = LED_HEIGHT; - _buffer[2] = 255; - for (uint8_t y=0; y0) { - send_data(); - } - ws.loop(); -} -*/