Add print log functionality and device name handling

- Introduced functions to capture and manage incoming print logs.
- Added a download link for the incoming print log in the web interface.
- Updated device name prefix for BLE and added device name building logic.
- Enhanced SerialCommand class with line handler support.
- Implemented WiFi reconnect logic and status tracking.
This commit is contained in:
2026-02-28 22:36:12 +01:00
parent 3580e32142
commit 83a55fcc47
9 changed files with 216 additions and 20 deletions

View File

@@ -8,11 +8,15 @@ namespace
const char *kConfigPath = "/config.json";
const size_t kConfigJsonCapacity = 4096;
const byte kDnsPort = 53;
const unsigned long kWifiReconnectIntervalMs = 10000;
WebServer server(80);
DNSServer dnsServer;
bool configStoreReady = false;
bool apModeActive = false;
bool staReconnectEnabled = false;
bool staConnectionKnown = false;
unsigned long lastStaReconnectAttemptMs = 0;
void redirectToRoot()
{
@@ -82,6 +86,7 @@ button { margin-top: 18px; border: 0; background: #0b5ed7; color: white; padding
#status { margin-top: 12px; min-height: 1.2em; }
#log { margin-top: 20px; border: 1px solid #d6dfef; border-radius: 8px; background: #0f172a; color: #d2e3ff; padding: 10px; height: 220px; overflow-y: auto; white-space: pre-wrap; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 0.9rem; }
#logTitle { margin-top: 24px; margin-bottom: 8px; font-weight: 700; }
#downloadPrintLog { display: inline-block; margin-top: 8px; color: #0b5ed7; text-decoration: none; font-weight: 600; }
</style>
</head>
<body>
@@ -91,6 +96,7 @@ button { margin-top: 18px; border: 0; background: #0b5ed7; color: white; padding
<button id="saveBtn" type="button">Speichern</button>
<div id="status"></div>
<div id="logTitle">Logs</div>
<a id="downloadPrintLog" href="/api/print-log.txt" download="incoming-print-log.txt">Incoming print log herunterladen</a>
<div id="log"></div>
</main>
<script>
@@ -261,6 +267,15 @@ async function pollLogs() {
server.send(200, "application/json", buildLogsJson(since));
}
void handleDownloadPrintLog()
{
server.sendHeader("Cache-Control", "no-store, no-cache, must-revalidate");
server.sendHeader("Pragma", "no-cache");
server.sendHeader("Expires", "0");
server.sendHeader("Content-Disposition", "attachment; filename=\"incoming-print-log.txt\"");
server.send(200, "text/plain; charset=utf-8", buildIncomingPrintLogText());
}
void handleNotFound()
{
if (apModeActive)
@@ -275,6 +290,44 @@ async function pollLogs() {
}
handleRoot();
}
void handleWifiReconnect()
{
if (!staReconnectEnabled || apModeActive)
{
return;
}
const wl_status_t wifiStatus = WiFi.status();
if (wifiStatus == WL_CONNECTED)
{
if (!staConnectionKnown)
{
staConnectionKnown = true;
Log(String("WLAN verbunden: ") + WiFi.localIP().toString());
}
return;
}
if (staConnectionKnown)
{
staConnectionKnown = false;
Log("WLAN Verbindung verloren");
}
const unsigned long now = millis();
if (now - lastStaReconnectAttemptMs < kWifiReconnectIntervalMs)
{
return;
}
lastStaReconnectAttemptMs = now;
if (!WiFi.reconnect())
{
WiFi.begin(g_sWifiSsid.c_str(), g_sWifiPassword.c_str());
}
Log("WLAN Reconnect versucht");
}
} // namespace
ConfigParameter configParameters[] = {
@@ -500,18 +553,23 @@ void startWebInterface()
initConfigStore();
bool staConnected = false;
apModeActive = false;
staReconnectEnabled = !g_sWifiSsid.isEmpty();
staConnectionKnown = false;
lastStaReconnectAttemptMs = millis();
dnsServer.stop();
String hostName = g_sHostname;
hostName.trim();
char deviceName[32] = {0};
buildDeviceName(deviceName, sizeof(deviceName));
String hostName = String(deviceName);
if (hostName.isEmpty())
{
hostName = "EggDuino";
hostName = "EggBot_UNKNOWN";
}
g_sHostname = hostName;
if (!g_sWifiSsid.isEmpty())
{
WiFi.mode(WIFI_STA);
WiFi.setAutoReconnect(true);
WiFi.setHostname(hostName.c_str());
WiFi.begin(g_sWifiSsid.c_str(), g_sWifiPassword.c_str());
@@ -523,6 +581,7 @@ void startWebInterface()
delay(250);
}
staConnected = (WiFi.status() == WL_CONNECTED);
staConnectionKnown = staConnected;
if (staConnected)
{
Serial.println(String("http://") + WiFi.localIP().toString());
@@ -536,6 +595,7 @@ void startWebInterface()
server.on("/api/config", HTTP_GET, handleGetConfig);
server.on("/api/config", HTTP_POST, handlePostConfig);
server.on("/api/logs", HTTP_GET, handleGetLogs);
server.on("/api/print-log.txt", HTTP_GET, handleDownloadPrintLog);
server.onNotFound(handleNotFound);
server.begin();
startWifiProtocolInterface();
@@ -546,11 +606,11 @@ void startWebInterface()
#ifdef ESP32
WiFi.softAPsetHostname(hostName.c_str());
#endif
if (WiFi.softAP("EggDuino"))
if (WiFi.softAP(hostName.c_str()))
{
apModeActive = true;
dnsServer.start(kDnsPort, "*", WiFi.softAPIP());
Serial.println(String("AP aktiv: EggDuino / http://") + WiFi.softAPIP().toString() + " (Name: " + hostName + ")");
Serial.println(String("AP aktiv: ") + hostName + " / http://" + WiFi.softAPIP().toString() + " (Name: " + hostName + ")");
}
else
{
@@ -562,6 +622,7 @@ void startWebInterface()
server.on("/api/config", HTTP_GET, handleGetConfig);
server.on("/api/config", HTTP_POST, handlePostConfig);
server.on("/api/logs", HTTP_GET, handleGetLogs);
server.on("/api/print-log.txt", HTTP_GET, handleDownloadPrintLog);
server.on("/generate_204", HTTP_GET, redirectToRoot);
server.on("/gen_204", HTTP_GET, redirectToRoot);
server.on("/hotspot-detect.html", HTTP_GET, redirectToRoot);
@@ -574,6 +635,8 @@ void startWebInterface()
void handleWebInterface()
{
handleWifiReconnect();
if (apModeActive)
{
dnsServer.processNextRequest();