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:
@@ -146,6 +146,7 @@ void handleWebInterface();
|
|||||||
void startBleInterface();
|
void startBleInterface();
|
||||||
void handleBleInterface();
|
void handleBleInterface();
|
||||||
bool bleProtocolWrite(const char *message);
|
bool bleProtocolWrite(const char *message);
|
||||||
|
void buildDeviceName(char *nameBuffer, size_t bufferSize);
|
||||||
void startWifiProtocolInterface();
|
void startWifiProtocolInterface();
|
||||||
void handleWifiProtocolInterface();
|
void handleWifiProtocolInterface();
|
||||||
bool wifiProtocolWrite(const char *message);
|
bool wifiProtocolWrite(const char *message);
|
||||||
@@ -157,6 +158,11 @@ inline bool bleProtocolWrite(const char *message)
|
|||||||
(void)message;
|
(void)message;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
inline void buildDeviceName(char *nameBuffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
(void)nameBuffer;
|
||||||
|
(void)bufferSize;
|
||||||
|
}
|
||||||
inline void startWifiProtocolInterface() {}
|
inline void startWifiProtocolInterface() {}
|
||||||
inline void handleWifiProtocolInterface() {}
|
inline void handleWifiProtocolInterface() {}
|
||||||
inline bool wifiProtocolWrite(const char *message)
|
inline bool wifiProtocolWrite(const char *message)
|
||||||
@@ -168,5 +174,8 @@ inline bool wifiProtocolWrite(const char *message)
|
|||||||
void Log(const String &message);
|
void Log(const String &message);
|
||||||
void Log(const char *message);
|
void Log(const char *message);
|
||||||
String buildLogsJson(uint32_t sinceSeq);
|
String buildLogsJson(uint32_t sinceSeq);
|
||||||
|
void captureIncomingPrintLine(const char *line, ProtocolTransport transport);
|
||||||
|
String buildIncomingPrintLogText();
|
||||||
|
void clearIncomingPrintLog();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ SerialCommand::SerialCommand()
|
|||||||
: commandList(NULL),
|
: commandList(NULL),
|
||||||
commandCount(0),
|
commandCount(0),
|
||||||
defaultHandler(NULL),
|
defaultHandler(NULL),
|
||||||
|
lineHandler(NULL),
|
||||||
term('\r'), // default terminator for commands, newline character
|
term('\r'), // default terminator for commands, newline character
|
||||||
last(NULL)
|
last(NULL)
|
||||||
{
|
{
|
||||||
@@ -64,6 +65,10 @@ void SerialCommand::setDefaultHandler(void (*function)(const char *)) {
|
|||||||
defaultHandler = function;
|
defaultHandler = function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SerialCommand::setLineHandler(LineHandler function) {
|
||||||
|
lineHandler = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This checks the Serial stream for characters, and assembles them into a buffer.
|
* This checks the Serial stream for characters, and assembles them into a buffer.
|
||||||
@@ -92,6 +97,10 @@ void SerialCommand::readChar(char inChar) {
|
|||||||
Serial.println(buffer);
|
Serial.println(buffer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if ((lineHandler != NULL) && (bufPos > 0)) {
|
||||||
|
(*lineHandler)(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
char *command = strtok_r(buffer, delim, &last); // Search for command at start of buffer
|
char *command = strtok_r(buffer, delim, &last); // Search for command at start of buffer
|
||||||
if (command != NULL) {
|
if (command != NULL) {
|
||||||
boolean matched = false;
|
boolean matched = false;
|
||||||
|
|||||||
@@ -44,9 +44,12 @@
|
|||||||
|
|
||||||
class SerialCommand {
|
class SerialCommand {
|
||||||
public:
|
public:
|
||||||
|
typedef void (*LineHandler)(const char *);
|
||||||
|
|
||||||
SerialCommand(); // Constructor
|
SerialCommand(); // Constructor
|
||||||
void addCommand(const char *command, void(*function)()); // Add a command to the processing dictionary.
|
void addCommand(const char *command, void(*function)()); // Add a command to the processing dictionary.
|
||||||
void setDefaultHandler(void (*function)(const char *)); // A handler to call when no valid command received.
|
void setDefaultHandler(void (*function)(const char *)); // A handler to call when no valid command received.
|
||||||
|
void setLineHandler(LineHandler function); // Optional handler called with each completed input line.
|
||||||
|
|
||||||
void readSerial(); // Main entry point.
|
void readSerial(); // Main entry point.
|
||||||
void readSerial(Stream &stream); // Reads commands from any Stream-compatible transport.
|
void readSerial(Stream &stream); // Reads commands from any Stream-compatible transport.
|
||||||
@@ -65,6 +68,7 @@ class SerialCommand {
|
|||||||
|
|
||||||
// Pointer to the default handler function
|
// Pointer to the default handler function
|
||||||
void (*defaultHandler)(const char *);
|
void (*defaultHandler)(const char *);
|
||||||
|
LineHandler lineHandler;
|
||||||
|
|
||||||
char delim[2]; // null-terminated list of character to be used as delimeters for tokenizing (default " ")
|
char delim[2]; // null-terminated list of character to be used as delimeters for tokenizing (default " ")
|
||||||
char term; // Character that signals end of command (default '\n')
|
char term; // Character that signals end of command (default '\n')
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ board = esp32dev
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
monitor_port = /dev/cu.usb*
|
monitor_port = /dev/cu.usb*
|
||||||
upload_speed = 115200
|
|
||||||
upload_port = /dev/cu.usb*
|
upload_port = /dev/cu.usb*
|
||||||
lib_deps =
|
lib_deps =
|
||||||
arminjo/ServoEasing
|
arminjo/ServoEasing
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
constexpr char kBleDeviceNamePrefix[] = "EggDuino_";
|
constexpr char kBleDeviceNamePrefix[] = "EggBot_";
|
||||||
constexpr char kBleServiceUuid[] = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
|
constexpr char kBleServiceUuid[] = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
|
||||||
constexpr char kBleRxCharUuid[] = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";
|
constexpr char kBleRxCharUuid[] = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";
|
||||||
constexpr char kBleTxCharUuid[] = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";
|
constexpr char kBleTxCharUuid[] = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";
|
||||||
@@ -30,18 +30,6 @@ void logBleDiag(const String &message)
|
|||||||
Log(message);
|
Log(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildBleDeviceName(char *nameBuffer, size_t bufferSize)
|
|
||||||
{
|
|
||||||
if ((nameBuffer == NULL) || (bufferSize == 0))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tasmota-style chip ID uses the lower 24 bits of the ESP32 efuse MAC.
|
|
||||||
const uint32_t chipId = static_cast<uint32_t>(ESP.getEfuseMac() & 0xFFFFFFULL);
|
|
||||||
snprintf(nameBuffer, bufferSize, "%s%06X", kBleDeviceNamePrefix, chipId);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool queueBleByte(uint8_t value)
|
bool queueBleByte(uint8_t value)
|
||||||
{
|
{
|
||||||
bool queued = false;
|
bool queued = false;
|
||||||
@@ -112,7 +100,7 @@ class EggDuinoBleRxCallbacks : public NimBLECharacteristicCallbacks
|
|||||||
void startBleInterface()
|
void startBleInterface()
|
||||||
{
|
{
|
||||||
char bleDeviceName[32] = {0};
|
char bleDeviceName[32] = {0};
|
||||||
buildBleDeviceName(bleDeviceName, sizeof(bleDeviceName));
|
buildDeviceName(bleDeviceName, sizeof(bleDeviceName));
|
||||||
if (bleDeviceName[0] == '\0')
|
if (bleDeviceName[0] == '\0')
|
||||||
{
|
{
|
||||||
snprintf(bleDeviceName, sizeof(bleDeviceName), "%sUNKNOWN", kBleDeviceNamePrefix);
|
snprintf(bleDeviceName, sizeof(bleDeviceName), "%sUNKNOWN", kBleDeviceNamePrefix);
|
||||||
|
|||||||
@@ -8,11 +8,15 @@ namespace
|
|||||||
const char *kConfigPath = "/config.json";
|
const char *kConfigPath = "/config.json";
|
||||||
const size_t kConfigJsonCapacity = 4096;
|
const size_t kConfigJsonCapacity = 4096;
|
||||||
const byte kDnsPort = 53;
|
const byte kDnsPort = 53;
|
||||||
|
const unsigned long kWifiReconnectIntervalMs = 10000;
|
||||||
|
|
||||||
WebServer server(80);
|
WebServer server(80);
|
||||||
DNSServer dnsServer;
|
DNSServer dnsServer;
|
||||||
bool configStoreReady = false;
|
bool configStoreReady = false;
|
||||||
bool apModeActive = false;
|
bool apModeActive = false;
|
||||||
|
bool staReconnectEnabled = false;
|
||||||
|
bool staConnectionKnown = false;
|
||||||
|
unsigned long lastStaReconnectAttemptMs = 0;
|
||||||
|
|
||||||
void redirectToRoot()
|
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; }
|
#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; }
|
#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; }
|
#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>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -91,6 +96,7 @@ button { margin-top: 18px; border: 0; background: #0b5ed7; color: white; padding
|
|||||||
<button id="saveBtn" type="button">Speichern</button>
|
<button id="saveBtn" type="button">Speichern</button>
|
||||||
<div id="status"></div>
|
<div id="status"></div>
|
||||||
<div id="logTitle">Logs</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>
|
<div id="log"></div>
|
||||||
</main>
|
</main>
|
||||||
<script>
|
<script>
|
||||||
@@ -261,6 +267,15 @@ async function pollLogs() {
|
|||||||
server.send(200, "application/json", buildLogsJson(since));
|
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()
|
void handleNotFound()
|
||||||
{
|
{
|
||||||
if (apModeActive)
|
if (apModeActive)
|
||||||
@@ -275,6 +290,44 @@ async function pollLogs() {
|
|||||||
}
|
}
|
||||||
handleRoot();
|
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
|
} // namespace
|
||||||
|
|
||||||
ConfigParameter configParameters[] = {
|
ConfigParameter configParameters[] = {
|
||||||
@@ -500,18 +553,23 @@ void startWebInterface()
|
|||||||
initConfigStore();
|
initConfigStore();
|
||||||
bool staConnected = false;
|
bool staConnected = false;
|
||||||
apModeActive = false;
|
apModeActive = false;
|
||||||
|
staReconnectEnabled = !g_sWifiSsid.isEmpty();
|
||||||
|
staConnectionKnown = false;
|
||||||
|
lastStaReconnectAttemptMs = millis();
|
||||||
dnsServer.stop();
|
dnsServer.stop();
|
||||||
String hostName = g_sHostname;
|
char deviceName[32] = {0};
|
||||||
hostName.trim();
|
buildDeviceName(deviceName, sizeof(deviceName));
|
||||||
|
String hostName = String(deviceName);
|
||||||
if (hostName.isEmpty())
|
if (hostName.isEmpty())
|
||||||
{
|
{
|
||||||
hostName = "EggDuino";
|
hostName = "EggBot_UNKNOWN";
|
||||||
}
|
}
|
||||||
g_sHostname = hostName;
|
g_sHostname = hostName;
|
||||||
|
|
||||||
if (!g_sWifiSsid.isEmpty())
|
if (!g_sWifiSsid.isEmpty())
|
||||||
{
|
{
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.setAutoReconnect(true);
|
||||||
WiFi.setHostname(hostName.c_str());
|
WiFi.setHostname(hostName.c_str());
|
||||||
WiFi.begin(g_sWifiSsid.c_str(), g_sWifiPassword.c_str());
|
WiFi.begin(g_sWifiSsid.c_str(), g_sWifiPassword.c_str());
|
||||||
|
|
||||||
@@ -523,6 +581,7 @@ void startWebInterface()
|
|||||||
delay(250);
|
delay(250);
|
||||||
}
|
}
|
||||||
staConnected = (WiFi.status() == WL_CONNECTED);
|
staConnected = (WiFi.status() == WL_CONNECTED);
|
||||||
|
staConnectionKnown = staConnected;
|
||||||
if (staConnected)
|
if (staConnected)
|
||||||
{
|
{
|
||||||
Serial.println(String("http://") + WiFi.localIP().toString());
|
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_GET, handleGetConfig);
|
||||||
server.on("/api/config", HTTP_POST, handlePostConfig);
|
server.on("/api/config", HTTP_POST, handlePostConfig);
|
||||||
server.on("/api/logs", HTTP_GET, handleGetLogs);
|
server.on("/api/logs", HTTP_GET, handleGetLogs);
|
||||||
|
server.on("/api/print-log.txt", HTTP_GET, handleDownloadPrintLog);
|
||||||
server.onNotFound(handleNotFound);
|
server.onNotFound(handleNotFound);
|
||||||
server.begin();
|
server.begin();
|
||||||
startWifiProtocolInterface();
|
startWifiProtocolInterface();
|
||||||
@@ -546,11 +606,11 @@ void startWebInterface()
|
|||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
WiFi.softAPsetHostname(hostName.c_str());
|
WiFi.softAPsetHostname(hostName.c_str());
|
||||||
#endif
|
#endif
|
||||||
if (WiFi.softAP("EggDuino"))
|
if (WiFi.softAP(hostName.c_str()))
|
||||||
{
|
{
|
||||||
apModeActive = true;
|
apModeActive = true;
|
||||||
dnsServer.start(kDnsPort, "*", WiFi.softAPIP());
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -562,6 +622,7 @@ void startWebInterface()
|
|||||||
server.on("/api/config", HTTP_GET, handleGetConfig);
|
server.on("/api/config", HTTP_GET, handleGetConfig);
|
||||||
server.on("/api/config", HTTP_POST, handlePostConfig);
|
server.on("/api/config", HTTP_POST, handlePostConfig);
|
||||||
server.on("/api/logs", HTTP_GET, handleGetLogs);
|
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("/generate_204", HTTP_GET, redirectToRoot);
|
||||||
server.on("/gen_204", HTTP_GET, redirectToRoot);
|
server.on("/gen_204", HTTP_GET, redirectToRoot);
|
||||||
server.on("/hotspot-detect.html", HTTP_GET, redirectToRoot);
|
server.on("/hotspot-detect.html", HTTP_GET, redirectToRoot);
|
||||||
@@ -574,6 +635,8 @@ void startWebInterface()
|
|||||||
|
|
||||||
void handleWebInterface()
|
void handleWebInterface()
|
||||||
{
|
{
|
||||||
|
handleWifiReconnect();
|
||||||
|
|
||||||
if (apModeActive)
|
if (apModeActive)
|
||||||
{
|
{
|
||||||
dnsServer.processNextRequest();
|
dnsServer.processNextRequest();
|
||||||
|
|||||||
@@ -1,5 +1,41 @@
|
|||||||
#include "EggDuino.h"
|
#include "EggDuino.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool g_bPrintSessionActive = false;
|
||||||
|
|
||||||
|
void captureSerialProtocolLine(const char *line)
|
||||||
|
{
|
||||||
|
captureIncomingPrintLine(line, PROTOCOL_TRANSPORT_SERIAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
void captureBleProtocolLine(const char *line)
|
||||||
|
{
|
||||||
|
captureIncomingPrintLine(line, PROTOCOL_TRANSPORT_BLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void captureWifiProtocolLine(const char *line)
|
||||||
|
{
|
||||||
|
captureIncomingPrintLine(line, PROTOCOL_TRANSPORT_WIFI);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void startPrintSessionIfNeeded()
|
||||||
|
{
|
||||||
|
if (!g_bPrintSessionActive)
|
||||||
|
{
|
||||||
|
clearIncomingPrintLog();
|
||||||
|
g_bPrintSessionActive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopPrintSession()
|
||||||
|
{
|
||||||
|
g_bPrintSessionActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void queryPen()
|
void queryPen()
|
||||||
{
|
{
|
||||||
Log(__FUNCTION__);
|
Log(__FUNCTION__);
|
||||||
@@ -96,6 +132,8 @@ void stepperMove()
|
|||||||
sendAck();
|
sendAck();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startPrintSessionIfNeeded();
|
||||||
|
|
||||||
prepareMove(duration, penStepsEBB, rotStepsEBB);
|
prepareMove(duration, penStepsEBB, rotStepsEBB);
|
||||||
moveToDestination();
|
moveToDestination();
|
||||||
@@ -199,10 +237,12 @@ void enableMotors()
|
|||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
stopPrintSession();
|
||||||
motorsOff();
|
motorsOff();
|
||||||
sendAck();
|
sendAck();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
startPrintSessionIfNeeded();
|
||||||
motorsOn();
|
motorsOn();
|
||||||
sendAck();
|
sendAck();
|
||||||
break;
|
break;
|
||||||
@@ -216,10 +256,12 @@ void enableMotors()
|
|||||||
switch (value)
|
switch (value)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
stopPrintSession();
|
||||||
motorsOff();
|
motorsOff();
|
||||||
sendAck();
|
sendAck();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
startPrintSessionIfNeeded();
|
||||||
motorsOn();
|
motorsOn();
|
||||||
sendAck();
|
sendAck();
|
||||||
break;
|
break;
|
||||||
@@ -318,8 +360,11 @@ void makeComInterface()
|
|||||||
};
|
};
|
||||||
|
|
||||||
registerCommands(SCmd);
|
registerCommands(SCmd);
|
||||||
|
SCmd.setLineHandler(captureSerialProtocolLine);
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
registerCommands(g_BLECmd);
|
registerCommands(g_BLECmd);
|
||||||
|
g_BLECmd.setLineHandler(captureBleProtocolLine);
|
||||||
registerCommands(g_WifiCmd);
|
registerCommands(g_WifiCmd);
|
||||||
|
g_WifiCmd.setLineHandler(captureWifiProtocolLine);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
#ifdef ESP32
|
||||||
|
constexpr char kDeviceNamePrefix[] = "EggBot_";
|
||||||
|
#endif
|
||||||
|
|
||||||
int clampServoAngle(int angle)
|
int clampServoAngle(int angle)
|
||||||
{
|
{
|
||||||
if (angle < 0)
|
if (angle < 0)
|
||||||
@@ -36,6 +40,20 @@ uint_fast16_t servoSpeedFromRate(int rate)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
void buildDeviceName(char *nameBuffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
if ((nameBuffer == NULL) || (bufferSize == 0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tasmota-style chip ID uses the lower 24 bits of the ESP32 efuse MAC.
|
||||||
|
const uint32_t chipId = static_cast<uint32_t>(ESP.getEfuseMac() & 0xFFFFFFULL);
|
||||||
|
snprintf(nameBuffer, bufferSize, "%s%06X", kDeviceNamePrefix, chipId);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void updateStepCorrectionFactors()
|
void updateStepCorrectionFactors()
|
||||||
{
|
{
|
||||||
if (g_iRotMicrostep <= 0)
|
if (g_iRotMicrostep <= 0)
|
||||||
|
|||||||
@@ -3,12 +3,19 @@
|
|||||||
namespace {
|
namespace {
|
||||||
constexpr size_t kLogCapacity = 80;
|
constexpr size_t kLogCapacity = 80;
|
||||||
constexpr size_t kLogLineLength = 160;
|
constexpr size_t kLogLineLength = 160;
|
||||||
|
constexpr size_t kIncomingLogCapacity = 128;
|
||||||
|
constexpr size_t kIncomingLogLineLength = SERIALCOMMAND_BUFFER + 24;
|
||||||
|
|
||||||
char g_logLines[kLogCapacity][kLogLineLength];
|
char g_logLines[kLogCapacity][kLogLineLength];
|
||||||
uint32_t g_logSeq[kLogCapacity];
|
uint32_t g_logSeq[kLogCapacity];
|
||||||
size_t g_logWritePos = 0;
|
size_t g_logWritePos = 0;
|
||||||
uint32_t g_nextLogSeq = 1;
|
uint32_t g_nextLogSeq = 1;
|
||||||
|
|
||||||
|
char g_incomingLogLines[kIncomingLogCapacity][kIncomingLogLineLength];
|
||||||
|
uint32_t g_incomingLogSeq[kIncomingLogCapacity];
|
||||||
|
size_t g_incomingLogWritePos = 0;
|
||||||
|
uint32_t g_nextIncomingLogSeq = 1;
|
||||||
|
|
||||||
void appendJsonEscaped(String &out, const char *text) {
|
void appendJsonEscaped(String &out, const char *text) {
|
||||||
out += "\"";
|
out += "\"";
|
||||||
for (size_t i = 0; text[i] != '\0'; ++i) {
|
for (size_t i = 0; text[i] != '\0'; ++i) {
|
||||||
@@ -40,6 +47,18 @@ void appendJsonEscaped(String &out, const char *text) {
|
|||||||
}
|
}
|
||||||
out += "\"";
|
out += "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *transportLabel(ProtocolTransport transport) {
|
||||||
|
switch (transport) {
|
||||||
|
case PROTOCOL_TRANSPORT_BLE:
|
||||||
|
return "BLE";
|
||||||
|
case PROTOCOL_TRANSPORT_WIFI:
|
||||||
|
return "WIFI";
|
||||||
|
case PROTOCOL_TRANSPORT_SERIAL:
|
||||||
|
default:
|
||||||
|
return "SERIAL";
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void Log(const String &message) {
|
void Log(const String &message) {
|
||||||
@@ -89,3 +108,45 @@ String buildLogsJson(uint32_t sinceSeq) {
|
|||||||
output += "}";
|
output += "}";
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void captureIncomingPrintLine(const char *line, ProtocolTransport transport) {
|
||||||
|
if ((line == NULL) || (line[0] == '\0')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(
|
||||||
|
g_incomingLogLines[g_incomingLogWritePos],
|
||||||
|
kIncomingLogLineLength,
|
||||||
|
"[%010lu] %s %s",
|
||||||
|
static_cast<unsigned long>(millis()),
|
||||||
|
transportLabel(transport),
|
||||||
|
line
|
||||||
|
);
|
||||||
|
g_incomingLogSeq[g_incomingLogWritePos] = g_nextIncomingLogSeq++;
|
||||||
|
g_incomingLogWritePos = (g_incomingLogWritePos + 1) % kIncomingLogCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
String buildIncomingPrintLogText() {
|
||||||
|
String output;
|
||||||
|
output.reserve(4096);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < kIncomingLogCapacity; ++i) {
|
||||||
|
const size_t idx = (g_incomingLogWritePos + i) % kIncomingLogCapacity;
|
||||||
|
if (g_incomingLogSeq[idx] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
output += g_incomingLogLines[idx];
|
||||||
|
output += "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearIncomingPrintLog() {
|
||||||
|
for (size_t i = 0; i < kIncomingLogCapacity; ++i) {
|
||||||
|
g_incomingLogSeq[i] = 0;
|
||||||
|
g_incomingLogLines[i][0] = '\0';
|
||||||
|
}
|
||||||
|
g_incomingLogWritePos = 0;
|
||||||
|
g_nextIncomingLogSeq = 1;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user