Extended the sebsocket's capabilities. And moved a lot of html strings to PROGMEM to free up some RAM.
This commit is contained in:
		@@ -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();
 | 
			
		||||
 
 | 
			
		||||
@@ -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; i<effects_size; i++) {
 | 
			
		||||
		if (i>0) msg += ", ";
 | 
			
		||||
		msg += '"';
 | 
			
		||||
		msg += effects[i].name;
 | 
			
		||||
		msg += '"';
 | 
			
		||||
	}
 | 
			
		||||
	msg += "]}";
 | 
			
		||||
	client->text(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ws_send_settings(AsyncWebSocketClient* client) {
 | 
			
		||||
	String msg = "{\"settings\": [";
 | 
			
		||||
	for (int i=0; i<all_settings_size; i++) {
 | 
			
		||||
		if (i>0) 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:<key>:<value>\neffect:<effect>\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 = "<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>";
 | 
			
		||||
		String response = String(F("<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()) {
 | 
			
		||||
			message += "<strong>No SPIFFS file system found.</strong>";
 | 
			
		||||
			response += F("<strong>No SPIFFS file system found.</strong>");
 | 
			
		||||
		} else {
 | 
			
		||||
			message += "<ul>";
 | 
			
		||||
			response += F("<ul>");
 | 
			
		||||
			Dir dir = SPIFFS.openDir("/");
 | 
			
		||||
			while (dir.next()) {
 | 
			
		||||
				message += "<li>" + dir.fileName() + " (<a href='/delete?" + dir.fileName() + "'>delete</a>)</li>";
 | 
			
		||||
				char buffer[100];
 | 
			
		||||
				snprintf_P(buffer, 100, PSTR("<li>%s (<a href='/delete?%s'>delete</a>)</li>"), dir.fileName().c_str(), dir.fileName().c_str());
 | 
			
		||||
				response += buffer;
 | 
			
		||||
			}
 | 
			
		||||
			message += "</ul>";
 | 
			
		||||
			message += "<form action='/upload' method='POST'><input type='file' name='file' /><input type='submit' value='Upload file' /></form>";
 | 
			
		||||
			response += F("</ul>");
 | 
			
		||||
			response += F("<form action='/upload' method='POST'><input type='file' name='file' /><input type='submit' value='Upload file' /></form>");
 | 
			
		||||
		}
 | 
			
		||||
		message += "</body></html>";
 | 
			
		||||
		request->send(200, "text/html", message);
 | 
			
		||||
		response += F("</body></html>");
 | 
			
		||||
		request->send(200, "text/html", response);
 | 
			
		||||
	});
 | 
			
		||||
	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";
 | 
			
		||||
		String message = F("<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];
 | 
			
		||||
			uint16_t default_value = setting_default(&s);
 | 
			
		||||
			uint16_t value = *(s.value);
 | 
			
		||||
 | 
			
		||||
			message += "<tr><td>";
 | 
			
		||||
			message += F("<tr><td>");
 | 
			
		||||
			if (default_value != value) {
 | 
			
		||||
				message += "<strong>";
 | 
			
		||||
				message += F("<strong>");
 | 
			
		||||
			}
 | 
			
		||||
			message += s.name;
 | 
			
		||||
			if (default_value != value) {
 | 
			
		||||
				message += "<strong>";
 | 
			
		||||
				message += F("<strong>");
 | 
			
		||||
			}
 | 
			
		||||
			message += "</td><td>";
 | 
			
		||||
			message += F("</td><td>");
 | 
			
		||||
			message += value;
 | 
			
		||||
			if (default_value != value) {
 | 
			
		||||
				message += " (";
 | 
			
		||||
				message += default_value;
 | 
			
		||||
				message += ")";
 | 
			
		||||
			}
 | 
			
		||||
			message += "</td><td><form method='POST' action='/settings?redir=1'><input type='hidden' name='key' value='";
 | 
			
		||||
			message += s.name;
 | 
			
		||||
			message += "'/>";
 | 
			
		||||
			char buffer[150];
 | 
			
		||||
			snprintf_P(buffer, 150, PSTR("</td><td><form method='POST' action='/settings?redir=1'><input type='hidden' name='key' value='%s'/>"), s.name);
 | 
			
		||||
			message += buffer;
 | 
			
		||||
			if (s.type==TYPE_UINT8 || s.type==TYPE_UINT16) {
 | 
			
		||||
				message += "<input type='number' name='value' value='";
 | 
			
		||||
				message += value;
 | 
			
		||||
				message += "' min='0' max='";
 | 
			
		||||
				if (s.type==TYPE_UINT8) {
 | 
			
		||||
					message += "255";
 | 
			
		||||
				} else {
 | 
			
		||||
					message += "65535";
 | 
			
		||||
				}
 | 
			
		||||
				message += "' />";
 | 
			
		||||
				snprintf_P(buffer, 150, PSTR("<input type='number' name='value' value='%d' min='0' max='%d' />"), value, s.type==TYPE_UINT8 ? 255 : 65535);
 | 
			
		||||
			} else if (s.type==TYPE_BOOL) {
 | 
			
		||||
				message += "<input type='radio' name='value' value='0'";
 | 
			
		||||
				if (value==0) {
 | 
			
		||||
					message += " checked='checked'";
 | 
			
		||||
				}
 | 
			
		||||
				message += "> Off / <input type='radio' name='value' value='1'";
 | 
			
		||||
				if (value==1) {
 | 
			
		||||
					message += " checked='checked'";
 | 
			
		||||
				}
 | 
			
		||||
				message += "> On";
 | 
			
		||||
				snprintf_P(buffer, 150, PSTR("<input type='radio' name='value' value='0' %s> Off / <input type='radio' name='value' value='1' %s> On"), value==0?"checked":"", value==1?"checked":"");
 | 
			
		||||
			}
 | 
			
		||||
			message += "<input type='submit' value='Save' />";
 | 
			
		||||
			message += "</form></td></tr>\n";
 | 
			
		||||
			message += buffer;
 | 
			
		||||
			message += F("<input type='submit' value='Save' /></form></td></tr>\n");
 | 
			
		||||
		}
 | 
			
		||||
		message += "</table></body></html>";
 | 
			
		||||
		message += F("</table></body></html>");
 | 
			
		||||
		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 = "<html><head><title>Pitrix effects</title></head><body><h1>Pitrix settings</h1><a href='/'>Back to main page</a><table>";
 | 
			
		||||
		String message = F("<html><head><title>Pitrix effects</title></head><body><h1>Pitrix settings</h1><a href='/'>Back to main page</a><table>");
 | 
			
		||||
		char buffer[150];
 | 
			
		||||
		for (int i=0; i<effects_size; i++) {
 | 
			
		||||
			message += "<tr><td>";
 | 
			
		||||
			message += effects[i].name;
 | 
			
		||||
			message += "</td><td><form method='post' action='/effects'><input type='hidden' name='name' value='";
 | 
			
		||||
			message += effects[i].name;
 | 
			
		||||
			message += "'><input type='hidden' name='redir' value='1'><input type='submit' value='Select'></form></td></tr>";
 | 
			
		||||
			snprintf_P(buffer, 150, PSTR("<tr><td>%s</td><td><form method='post' action='/effects'><input type='hidden' name='name' value='%s'><input type='hidden' name='redir' value='1'><input type='submit' value='Select'></form></td></tr>"), effects[i].name, effects[i].name);
 | 
			
		||||
			message += buffer;
 | 
			
		||||
		}
 | 
			
		||||
		message += "</table></body></html>";
 | 
			
		||||
		message += F("</table></body></html>");
 | 
			
		||||
		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() {
 | 
			
		||||
				<title>Pitrix</title>
 | 
			
		||||
			</head>
 | 
			
		||||
			<body>
 | 
			
		||||
				<p>
 | 
			
		||||
					<button id='monitor_off'>Monitor OFF</button> 
 | 
			
		||||
					<button id='monitor_on'>Monitor ON</button>
 | 
			
		||||
				</p>
 | 
			
		||||
				<canvas id='target' width='800' height='500'></canvas>
 | 
			
		||||
				<script type='text/javascript'>
 | 
			
		||||
					width = height = 32;
 | 
			
		||||
					active = false;
 | 
			
		||||
					ctx = document.getElementById('target').getContext('2d');
 | 
			
		||||
					socket = new WebSocket((document.location.protocol=='https:' ? 'wss' : 'ws') + '://' + document.location.host + '/ws');
 | 
			
		||||
					socket.onopen = function() {
 | 
			
		||||
						socket.send('effects?');
 | 
			
		||||
						socket.send('settings?');
 | 
			
		||||
					};
 | 
			
		||||
					socket.binaryType = 'arraybuffer';
 | 
			
		||||
					socket.onmessage = function(message) {
 | 
			
		||||
						if ((typeof message.data) == 'string') {
 | 
			
		||||
							var j = JSON.parse(message.data);
 | 
			
		||||
							if (j.effects) {
 | 
			
		||||
								console.log('Got effects.');
 | 
			
		||||
								console.log(j.effects);
 | 
			
		||||
							}
 | 
			
		||||
							if (j.settings) {
 | 
			
		||||
								console.log('Got settings.');
 | 
			
		||||
								console.log(j.settings);
 | 
			
		||||
							}
 | 
			
		||||
							return;
 | 
			
		||||
						}
 | 
			
		||||
						if (!active) return;
 | 
			
		||||
						var buffer = new Uint8Array(message.data);
 | 
			
		||||
						var width = buffer[0];
 | 
			
		||||
						var height = buffer[1];
 | 
			
		||||
						width = buffer[0];
 | 
			
		||||
						height = buffer[1];
 | 
			
		||||
						if (buffer[2] != 255) return;
 | 
			
		||||
						var offset = 3;
 | 
			
		||||
						ctx.fillStyle = '#000000';
 | 
			
		||||
@@ -260,15 +323,20 @@ void http_server_setup() {
 | 
			
		||||
							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();
 | 
			
		||||
							ctx.fillRect(x*20+2, y*20+2, 16, 16);
 | 
			
		||||
						}
 | 
			
		||||
					};
 | 
			
		||||
					function redraw() {
 | 
			
		||||
						ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
 | 
			
		||||
					}
 | 
			
		||||
					document.getElementById('monitor_on').onclick = function() {
 | 
			
		||||
						socket.send('monitor:1');
 | 
			
		||||
						active = true;
 | 
			
		||||
					};
 | 
			
		||||
					document.getElementById('monitor_off').onclick = function() {
 | 
			
		||||
						socket.send('monitor:0');
 | 
			
		||||
						active = false;
 | 
			
		||||
						ctx.fillStyle = '0x80808080';
 | 
			
		||||
						ctx.fillRect(0, 0, width*20, height*20);
 | 
			
		||||
					};
 | 
			
		||||
				</script>
 | 
			
		||||
			</body>
 | 
			
		||||
		</html>
 | 
			
		||||
@@ -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; 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);
 | 
			
		||||
	if (ws.count()>0 && 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<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.binary(monitor_client, _buffer, _size);
 | 
			
		||||
			delete _buffer;
 | 
			
		||||
		} else {
 | 
			
		||||
			monitor_client = 0;
 | 
			
		||||
		}
 | 
			
		||||
		_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();
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user