| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -5,18 +5,16 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "http_server.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "effects.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "my_wifi.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "functions.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "prototypes.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <FS.h>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#if defined( ESP8266 )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ESP8266WebServer http_server(HTTP_SERVER_PORT);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#elif defined( ESP32 )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ESP32WebServer http_server(HTTP_SERVER_PORT);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#endif
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				AsyncWebServer http_server(HTTP_SERVER_PORT);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				AsyncWebSocket ws("/ws");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				File upload_file;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void http_server_handle_file_upload() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/*void http_server_handle_file_upload() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (http_server.uri() != "/upload") return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					HTTPUpload upload = http_server.upload();
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -32,15 +30,20 @@ void http_server_handle_file_upload() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (upload_file) upload_file.close();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("HTTP * Upload of %s with %d bytes done.", upload.filename.c_str(), upload.totalSize);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}*/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void http_server_400() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.send(400);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				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.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					} else if (type == WS_EVT_DISCONNECT) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("Websocket * Client disconnected.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void http_server_setup() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					PGM_P text_plain = PSTR("text/plain");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/", HTTP_GET, [&](){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					PGM_P text_html = PSTR("text/html");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/", HTTP_GET, [&](AsyncWebServerRequest* request){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("HTTP * GET /");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String message = "<html><head><title>Pitrix</title></head><body><h1>Pitrix</h1><p><a href='/settings'>Settings</a></p><p><a href='/effects'>Effect</a></p><p>Known animations:</p>";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!SPIFFS.begin()) {
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -55,9 +58,9 @@ void http_server_setup() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							message += "<form action='/upload' method='POST'><input type='file' name='file' /><input type='submit' value='Upload file' /></form>";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						message += "</body></html>";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send(200, "text/html", message);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send(200, "text/html", message);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/settings", HTTP_GET, [&]() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/settings", HTTP_GET, [&](AsyncWebServerRequest* request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String message = "<html><head><title>Pitrix settings</title></head><body><h1>Pitrix settings</h1><a href='/'>Back to main page</a><table>\n";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (int i=0; i<all_settings_size; i++) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							Setting s = all_settings[i];
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -107,50 +110,51 @@ void http_server_setup() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							message += "</form></td></tr>\n";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						message += "</table></body></html>";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send(200, "text/html", message);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send(200, "text/html", message);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/settings", HTTP_POST, [&]() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!http_server.hasArg("key") || !http_server.hasArg("value")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send(400, "text/plain", "Missing argument.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/settings", HTTP_POST, [&](AsyncWebServerRequest* request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!request->hasParam("key", true) || !request->hasParam("value", true)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							request->send(400, "text/plain", "Missing argument.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String name = http_server.arg("key");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uint16_t value = http_server.arg("value").toInt();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String name = request->getParam("key", true)->value();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uint16_t value = request->getParam("value", true)->value().toInt();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (change_setting(name.c_str(), value)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (http_server.hasArg("redir")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								http_server.sendHeader("Location", "/settings");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								http_server.send(301);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (request->hasParam("redir")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								AsyncWebServerResponse* response = request->beginResponse(301, "text/plain", "Moved");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								response->addHeader("Location", "/settings");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								request->send(response);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							} else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								http_server.send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								request->send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							save_settings();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send(400, "text/plain", "Could not change setting.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							request->send(400, "text/plain", "Could not change setting.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/settings/load", HTTP_POST, [&]() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/settings/load", HTTP_POST, [&](AsyncWebServerRequest* request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						load_settings();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/settings/save", HTTP_POST, [&]() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/settings/save", HTTP_POST, [&](AsyncWebServerRequest* request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						save_settings();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/settings.txt", HTTP_GET, [&]() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/settings.txt", HTTP_GET, [&](AsyncWebServerRequest* request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						File f;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (SPIFFS.begin()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							f=SPIFFS.open("/pitrix_settings.txt", "r");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (f) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								String s = f.readString();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								f.close();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								http_server.send(200, "text/plain", s);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								request->send(200, "text/plain", s);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send(500, "text/plain", "Could not read settings.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send(500, "text/plain", "Could not read settings.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/effects", HTTP_GET, [&]() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/effects", HTTP_GET, [&](AsyncWebServerRequest* request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String message = "<html><head><title>Pitrix effects</title></head><body><h1>Pitrix settings</h1><a href='/'>Back to main page</a><table>";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						for (int i=0; i<effects_size; i++) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							message += "<tr><td>";
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -160,97 +164,203 @@ void http_server_setup() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							message += "'><input type='hidden' name='redir' value='1'><input type='submit' value='Select'></form></td></tr>";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						message += "</table></body></html>";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send(200, "text/html", message);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send(200, "text/html", message);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/effects", HTTP_POST, [&]() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!http_server.hasArg("name")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send(400, "text/plain", "Missing argument 'name'.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/effects", HTTP_POST, [&](AsyncWebServerRequest* request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!request->hasParam("name", true)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							request->send(400, "text/plain", "Missing argument 'name'.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String name = http_server.arg("name");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String name = request->getParam("name", true)->value();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (change_current_effect(name)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (http_server.hasArg("redir")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								http_server.sendHeader("Location", "/effects");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								http_server.send(301);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (request->hasParam("redir")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								AsyncWebServerResponse* response = request->beginResponse(301, "text/plain", "Moved");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								response->addHeader("Location", "/effects");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								request->send(response);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							} else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								http_server.send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								request->send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send(404, "text/plain", "Effect not found.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							request->send(404, "text/plain", "Effect not found.");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/delete", HTTP_GET, [&]() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/delete", HTTP_GET, [&](AsyncWebServerRequest* request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("HTTP * GET /delete");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (http_server.args()==0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send_P(400, text_plain, PSTR("No filename given"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (request->params()==0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							request->send_P(400, text_plain, PSTR("No filename given"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String file = http_server.arg(0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String file = request->getParam(0)->value();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (file == "/") {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send_P(400, text_plain, PSTR("Invalid path"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							request->send_P(400, text_plain, PSTR("Invalid path"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!SPIFFS.exists(file)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send_P(400, text_plain, PSTR("File does not exist."));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							request->send_P(400, text_plain, PSTR("File does not exist."));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						SPIFFS.remove(file);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send_P(200, text_plain, PSTR("OK"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send_P(200, text_plain, PSTR("OK"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/upload", HTTP_POST, []() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					/*http_server.on("/upload", HTTP_POST, [](AsyncWebServerRequest* request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("HTTP * POST /upload");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}, http_server_handle_file_upload);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/free_heap", HTTP_GET, [&](){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}, http_server_handle_file_upload);*/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/free_heap", HTTP_GET, [&](AsyncWebServerRequest* request){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("HTTP * GET /free_heap");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send(200, "text/plain", String(ESP.getFreeHeap()));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send(200, "text/plain", String(ESP.getFreeHeap()));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/uptime", HTTP_GET, [&](){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/uptime", HTTP_GET, [&](AsyncWebServerRequest* request){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("HTTP * GET /uptime");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send(200, "text/plain", String(millis()/1000));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send(200, "text/plain", String(millis()/1000));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/fps", HTTP_GET, [](){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/fps", HTTP_GET, [](AsyncWebServerRequest* request){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("HTTP * GET /fps");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send(200, "text/plain", String(FastLED.getFPS()));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send(200, "text/plain", String(FastLED.getFPS()));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/reboot", HTTP_POST, [](){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/reboot", HTTP_POST, [](AsyncWebServerRequest* request){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("HTTP * POST /reboot");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						ESP.restart();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/brightness", HTTP_POST, [&](){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("HTTP * POST /brightness with value %s", http_server.arg("plain").c_str());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!http_server.hasArg("plain")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send_P(400, text_plain, PSTR("No brightness given"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/mode", HTTP_POST, [&](AsyncWebServerRequest* request){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("HTTP * POST /mode with value %s", request->getParam("plain", true)->value().c_str());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!request->hasParam("plain", true)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							request->send_P(400, text_plain, PSTR("No effect given."));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						long val = http_server.arg("plain").toInt();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (val==0 || val>255) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send_P(400, text_plain, PSTR("New value out of bounds. (1-255)"));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						FastLED.setBrightness(val);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						http_server.send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/mode", HTTP_POST, [&](){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						LOGln("HTTP * POST /mode with value %s", http_server.arg("plain").c_str());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!http_server.hasArg("plain")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send_P(400, text_plain, PSTR("No effect given."));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String val = http_server.arg("plain");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						String val = request->getParam("plain", true)->value();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (change_current_effect(val)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							request->send(200, "text/plain", "OK");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							http_server.send_P(400, text_plain, PSTR("Unknown effect."));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							request->send_P(400, text_plain, PSTR("Unknown effect."));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.on("/monitor", HTTP_GET, [&](AsyncWebServerRequest* request) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						static const char* html PROGMEM = R"(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						<html>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							<head>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								<title>Pitrix</title>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							</head>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							<body>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								<canvas id='target' width='800' height='500'></canvas>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								<script type='text/javascript'>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									ctx = document.getElementById('target').getContext('2d');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									socket = new WebSocket((document.location.protocol=='https:' ? 'wss' : 'ws') + '://' + document.location.host + '/ws');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									socket.binaryType = 'arraybuffer';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									socket.onmessage = function(message) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										var buffer = new Uint8Array(message.data);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										var width = buffer[0];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										var height = buffer[1];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if (buffer[2] != 255) return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										var offset = 3;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										ctx.fillStyle = '#000000';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										ctx.fillRect(0, 0, 20*width, 20*height);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										for (var y=0; y<height; y++) for (var x=0; x<width; x++) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											var r = buffer[offset + 0];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											var g = buffer[offset + 1];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											var b = buffer[offset + 2];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											offset = offset + 3;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											ctx.beginPath();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											ctx.arc(x*20 + 10, y*20 + 10, 10, 0, 2*Math.PI, false);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											ctx.fillStyle = 'rgb('+r+','+g+','+b+')';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											ctx.fill();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									function redraw() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								</script>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							</body>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						</html>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						)";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						request->send_P(200, PSTR("text/html"), html);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					});
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ws.onEvent(handle_ws);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.addHandler(&ws);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.begin();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					MDNS.addService("_http", "_tcp", 80);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void http_server_loop() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					http_server.handleClient();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				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; y<LED_HEIGHT; y++) for(uint8_t x=0; x<LED_WIDTH; x++) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							uint16_t index = XYsafe(x, y);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							CRGB pixel = leds[index];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							_buffer[3 + (y*LED_WIDTH + x)*3 + 0] = (pixel.r==255 ? 254 : pixel.r);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							_buffer[3 + (y*LED_WIDTH + x)*3 + 1] = (pixel.g==255 ? 254 : pixel.g);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							_buffer[3 + (y*LED_WIDTH + x)*3 + 2] = (pixel.b==255 ? 254 : pixel.b);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						_buffer[_size - 1] = 255;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						ws.binaryAll(_buffer, _size);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						delete _buffer;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#endif
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/*
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <ESP8266WiFi.h>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <WebSocketsServer.h>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#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; y<LED_HEIGHT; y++) for(uint8_t x=0; x<LED_WIDTH; x++) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uint16_t index = XYsafe(x, y);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						CRGB pixel = leds[index];
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						_buffer[3 + (y*LED_WIDTH + x)*3 + 0] = (pixel.r==255 ? 254 : pixel.r);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						_buffer[3 + (y*LED_WIDTH + x)*3 + 1] = (pixel.g==255 ? 254 : pixel.g);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						_buffer[3 + (y*LED_WIDTH + x)*3 + 2] = (pixel.b==255 ? 254 : pixel.b);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					_buffer[_size - 1] = 255;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ws.broadcastBIN(_buffer, _size);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					delete _buffer;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void websocket_loop() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (ws.connectedClients()>0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						send_data();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ws.loop();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				*/
 | 
			
		
		
	
	
		
			
				
					
					| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				 
 |