diff --git a/data/http/icon.svg b/data/http/icon.svg
new file mode 100644
index 0000000..3855970
--- /dev/null
+++ b/data/http/icon.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/data/http/index.html b/data/http/index.html
new file mode 100644
index 0000000..11504ad
--- /dev/null
+++ b/data/http/index.html
@@ -0,0 +1,199 @@
+
+
+
+
+
+ Sporttafel
+
+
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+ |
+
+
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+
+ | |
+
+
+ |
+ |
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/data/index.html b/data/index.html
deleted file mode 100644
index 18b42d4..0000000
--- a/data/index.html
+++ /dev/null
@@ -1,182 +0,0 @@
-
-
-
-
-
- Sporttafel
-
-
-
-
-
-
- |
-
- |
-
-
- |
- |
-
-
- |
-
- |
-
-
- |
-
-
- |
-
-
- | |
-
-
- |
- |
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/app/App.h b/src/app/App.h
index 4edb077..2c7dd3b 100644
--- a/src/app/App.h
+++ b/src/app/App.h
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
class App {
@@ -17,6 +18,8 @@ class App {
bool dirty = true;
+ bool doForceNextHexBuffer = true;
+
public:
explicit App(const char *name) : name(name),
@@ -45,6 +48,7 @@ public:
if (dirty) {
dirty = false;
draw();
+ display.flush(doForceNextHexBuffer);
}
}
@@ -112,8 +116,9 @@ protected:
//
}
- void markDirty() {
+ void markDirty(const bool forceNextHexBuffer = false) {
dirty = true;
+ doForceNextHexBuffer = forceNextHexBuffer;
}
bool deserializeConfig(File file) {
diff --git a/src/app/AppMatch.h b/src/app/AppMatch.h
index ccc02cf..9a11dc2 100644
--- a/src/app/AppMatch.h
+++ b/src/app/AppMatch.h
@@ -70,7 +70,8 @@ protected:
configMillis = seconds * 1000;
totalMillis = configMillis;
- setState(PAUSE);
+
+ setState(PAUSE, true);
}
void _loop(const unsigned long dtMillis) override {
@@ -143,7 +144,6 @@ protected:
} else if (state == PAUSE) {
display.printf("PAUS");
}
- display.flush();
}
void confirm() override {
@@ -169,8 +169,8 @@ private:
blinkMillis = millis();
}
- void setState(const State newState) {
- if (state == newState) {
+ void setState(const State newState, const bool force = false) {
+ if (state == newState && !force) {
return;
}
state = newState;
diff --git a/src/core/http.cpp b/src/core/http.cpp
index dec7cb6..6dc0925 100644
--- a/src/core/http.cpp
+++ b/src/core/http.cpp
@@ -2,6 +2,7 @@
#include
#include
+
#include "log.h"
AsyncWebServer server(80);
@@ -10,11 +11,6 @@ AsyncWebSocket ws("/ws");
auto websocketStarted = false;
-void httpIndex(AsyncWebServerRequest *request) {
- info(request->url().c_str());
- request->send(LittleFS, "/index.html", "text/html");
-}
-
void httpActionLeft(AsyncWebServerRequest *request) {
if (app != nullptr) {
app->left();
@@ -77,34 +73,32 @@ void httpAppConfig(AsyncWebServerRequest *request) {
request->send(400);
}
-void httpSetup() {
- ws.onEvent([](AsyncWebSocket *socket, AsyncWebSocketClient *client, AwsEventType type, void *arg, unsigned char *message, unsigned length) {
- const char *t;
- switch (type) {
- case WS_EVT_CONNECT:
- t = "CONNECT";
- break;
- case WS_EVT_DISCONNECT:
- t = "DISCONNECT";
- break;
- case WS_EVT_PONG:
- t = "PONG";
- break;
- case WS_EVT_ERROR:
- t = "ERROR";
- break;
- case WS_EVT_DATA:
- t = "DATA";
- break;
- default:
- t = "[???]";
- break;
- }
- debug("%s: %s (%d bytes)", client->remoteIP().toString().c_str(), t, length);
- });
- server.addHandler(&ws);
+void httpNotFound(AsyncWebServerRequest *request) {
+ if (request->method() == HTTP_OPTIONS) {
+ request->send(200);
+ } else {
+ request->send(404, "text/plain", "Not found");
+ }
+}
- server.on("/", HTTP_GET, httpIndex);
+const char *getWebsocketTypeName(AwsEventType type) {
+ switch (type) {
+ case WS_EVT_CONNECT:
+ return "CONNECT";
+ case WS_EVT_DISCONNECT:
+ return "DISCONNECT";
+ case WS_EVT_PONG:
+ return "PONG";
+ case WS_EVT_ERROR:
+ return "ERROR";
+ case WS_EVT_DATA:
+ return "DATA";
+ default:
+ return "[???]";
+ }
+}
+
+void httpSetup() {
server.on("/action/left", HTTP_GET, httpActionLeft);
server.on("/action/up", HTTP_GET, httpActionUp);
server.on("/action/down", HTTP_GET, httpActionDown);
@@ -112,7 +106,15 @@ void httpSetup() {
server.on("/action/cancel", HTTP_GET, httpActionCancel);
server.on("/action/confirm", HTTP_GET, httpActionConfirm);
server.on("/app/config", HTTP_GET, httpAppConfig);
+ server.serveStatic("/", LittleFS, "/http/", "max-age=86400").setDefaultFile("index.html");
+ server.onNotFound(httpNotFound);
+ server.addHandler(&ws);
server.begin();
+
+ DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
+ DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods", "GET, POST, PUT");
+ DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "Content-Type");
+
websocketStarted = true;
}
@@ -121,6 +123,7 @@ void httpLoop() {
}
void websocketSend(const char *message) {
+void websocketSendAll(const char *message) {
if (websocketStarted) {
ws.textAll(message);
}
diff --git a/src/core/http.h b/src/core/http.h
index 05f75b2..fc51b15 100644
--- a/src/core/http.h
+++ b/src/core/http.h
@@ -6,5 +6,6 @@ void httpSetup();
void httpLoop();
void websocketSend(const char *message);
+void websocketSendAll(const char *message);
#endif
diff --git a/src/display/Display.h b/src/display/Display.h
index b8ac173..b5a26aa 100644
--- a/src/display/Display.h
+++ b/src/display/Display.h
@@ -3,7 +3,7 @@
// #include
-#include "../core/log.h"
+#include
#include "Color.h"
#include "font.h"
@@ -13,12 +13,16 @@
#define SEGMENTS_PER_DIGIT 7
#define PIXELS_PER_DOT 1
#define DOT_COUNT 4
-#define DIGITS 4
+#define DIGIT_COUNT 4
#define PIXELS_PER_DIGIT (PIXELS_PER_SEGMENT * SEGMENTS_PER_DIGIT)
#define TOTAL_DOT_PIXEL_COUNT (PIXELS_PER_DOT * DOT_COUNT)
-#define TOTAL_PIXEL_COUNT (DIGITS * PIXELS_PER_DIGIT + TOTAL_DOT_PIXEL_COUNT)
+#define TOTAL_SEGMENT_PIXEL_COUNT (DIGIT_COUNT * PIXELS_PER_DIGIT)
+#define TOTAL_PIXEL_COUNT (TOTAL_SEGMENT_PIXEL_COUNT + TOTAL_DOT_PIXEL_COUNT)
#define TOTAL_PIXEL_BYTE_COUNT (TOTAL_PIXEL_COUNT * sizeof(Color))
+#define HEX_BUFFER_SIZE (TOTAL_PIXEL_BYTE_COUNT + 1)
+
+#define HEX_BUFFER_MIN_WAIT_MS 500
class Display {
@@ -49,27 +53,18 @@ public:
memset(pixels, 0, TOTAL_PIXEL_BYTE_COUNT);
}
- void flush() {
+ void flush(const bool forceNextHexBuffer = false) {
// memcpy(leds.getPixels(), buffer, PIXEL_BYTE_COUNT);
// leds.show();
- const auto now = millis();
+ const auto now = millis() - HEX_BUFFER_MIN_WAIT_MS;
static auto last = now;
- if (now - last >= 500) {
+ if (now - last >= HEX_BUFFER_MIN_WAIT_MS || forceNextHexBuffer) {
last = now;
- send();
+ sendHexBuffer();
}
}
- void send() {
- char buffer[512];
- char *b = buffer;
- for (const auto& pixel: pixels) {
- b += snprintf(b, sizeof buffer - (b - buffer), "%X%X%X", pixel.r / 16, pixel.g / 16, pixel.b / 16);
- }
- websocketSend(buffer);
- }
-
void printf(const char *format, ...) {
char buffer[64];
@@ -148,6 +143,17 @@ public:
}
}
+private:
+
+ void sendHexBuffer() {
+ char hexBuffer[HEX_BUFFER_SIZE] = "";
+ auto b = hexBuffer;
+ for (const auto& pixel: pixels) {
+ b += snprintf(b, sizeof hexBuffer - (b - hexBuffer), "%X%X%X", pixel.r / 16, pixel.g / 16, pixel.b / 16);
+ }
+ websocketSendAll(hexBuffer);
+ }
+
};
extern Display display;