Updated WebUI
This commit is contained in:
@@ -2,52 +2,46 @@
|
||||
|
||||
AsyncWebServer webServer(80);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RESPMSG_HIDE,
|
||||
RESPMSG_SUCCESS,
|
||||
RESPMSG_INFO,
|
||||
RESPMSG_WARNING,
|
||||
RESPMSG_DANGER
|
||||
} statusResponseMessage_Type_t;
|
||||
char StatusResponseMessage[64];
|
||||
statusResponseMessage_Type_t StatusResponseMessage_Type = RESPMSG_INFO;
|
||||
|
||||
#ifdef CAPTIVE
|
||||
DNSServer dnsServer;
|
||||
#endif
|
||||
AsyncWebServer server(80);
|
||||
const char *PARAM_MESSAGE = "message";
|
||||
|
||||
String processor(const String &var);
|
||||
void WebserverPOST_Callback(AsyncWebServerRequest *request);
|
||||
void WebserverNotFound_Callback(AsyncWebServerRequest *request);
|
||||
void Webserver_Callback(AsyncWebServerRequest *request);
|
||||
void WebserverCommands_Callback(String input);
|
||||
void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final);
|
||||
void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final);
|
||||
void WebServerEEJSON_Callback(AsyncWebServerRequest *request);
|
||||
void GetFlashVersion(char *buff, size_t buff_size);
|
||||
|
||||
AsyncWebSocket webSocket("/ws");
|
||||
|
||||
void WebsocketEvent_Callback(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len);
|
||||
void Websocket_HandleMessage(void *arg, uint8_t *data, size_t len);
|
||||
|
||||
void initWebUI()
|
||||
{
|
||||
if (!LittleFS.begin())
|
||||
{
|
||||
Serial.println("An Error has occurred while mounting LittleFS");
|
||||
Debug_pushMessage("An Error has occurred while mounting LittleFS\n");
|
||||
MaintainDTC(DTC_FLASHFS_ERROR, DTC_CRITICAL, true);
|
||||
return;
|
||||
}
|
||||
|
||||
GetFlashVersion(globals.FlashVersion, sizeof(globals.FlashVersion));
|
||||
|
||||
if (strcmp(globals.FlashVersion, QUOTE(FLASH_FS_VERSION)))
|
||||
char buffer[6];
|
||||
snprintf(buffer, sizeof(buffer), "%d.%02d", constants.Required_Flash_Version_major, constants.Required_Flash_Version_minor);
|
||||
if (strcmp(globals.FlashVersion, buffer))
|
||||
{
|
||||
MaintainDTC(DTC_FLASHFS_VERSION_ERROR, DTC_WARN, true);
|
||||
}
|
||||
|
||||
MDNS.begin(globals.DeviceName);
|
||||
MDNS.addService("telnet", "tcp", 23);
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
|
||||
webSocket.onEvent(WebsocketEvent_Callback);
|
||||
webServer.addHandler(&webSocket);
|
||||
|
||||
webServer.serveStatic("/static/", LittleFS, "/static/").setCacheControl("max-age=360000");
|
||||
webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
|
||||
{ request->redirect("/index.htm"); });
|
||||
@@ -63,51 +57,63 @@ void initWebUI()
|
||||
webServer.begin();
|
||||
}
|
||||
|
||||
void Webserver_Process()
|
||||
{
|
||||
webSocket.cleanupClients();
|
||||
}
|
||||
String processor(const String &var)
|
||||
{
|
||||
if (var == "HOSTNAME")
|
||||
return String(globals.DeviceName);
|
||||
if (var == "SYSTEM_STATUS")
|
||||
return String(globals.systemStatustxt);
|
||||
if (var == "SW_VERSION")
|
||||
{
|
||||
char buffer[6];
|
||||
snprintf(buffer, sizeof(buffer), "%d.%02d", constants.FW_Version_major, constants.FW_Version_minor);
|
||||
return String(buffer);
|
||||
}
|
||||
if (var == "FS_VERSION")
|
||||
return String(globals.FlashVersion);
|
||||
if (var == "GIT_REV")
|
||||
return String(constants.GitHash);
|
||||
|
||||
if (var == "SHOW_DTC_TABLE")
|
||||
return globals.systemStatus == sysStat_Error ? "" : "hidden";
|
||||
|
||||
if (var == "SHOW_RESP_MESSAGE")
|
||||
return StatusResponseMessage_Type != RESPMSG_HIDE ? "" : "hidden";
|
||||
|
||||
if (var == "RESP_MESSAGE_TYPE")
|
||||
{
|
||||
switch (StatusResponseMessage_Type)
|
||||
{
|
||||
case RESPMSG_SUCCESS:
|
||||
return "success";
|
||||
case RESPMSG_INFO:
|
||||
return "info";
|
||||
case RESPMSG_WARNING:
|
||||
return "warning";
|
||||
case RESPMSG_DANGER:
|
||||
return "danger";
|
||||
default:
|
||||
return "info";
|
||||
}
|
||||
}
|
||||
|
||||
if (var == "RESP_MESSAGE")
|
||||
return String(StatusResponseMessage);
|
||||
|
||||
if (var == "BAT_REMAIN_CAPACITY")
|
||||
return String(globals.battery_level);
|
||||
|
||||
if (var == "DEVICE_NAME")
|
||||
if (var == "DEVICENAME")
|
||||
return String(globals.DeviceName);
|
||||
|
||||
if (var == "BATTERY_TYPE")
|
||||
return String(ConfigData.batteryType);
|
||||
if (var == "BAT_VOLTAGE")
|
||||
return String((float)globals.loadvoltage_mV / 1000.0);
|
||||
|
||||
if (var == "PERSISTANCE_CHECKSUM")
|
||||
{
|
||||
char buffer[7];
|
||||
sprintf(buffer, "0x%04X", PersistenceData.checksum);
|
||||
return String(buffer);
|
||||
}
|
||||
if (var == "WRITE_CYCLE_COUNT")
|
||||
return String(PersistenceData.writeCycleCounter);
|
||||
if (var == "PERSISTENCE_MARKER")
|
||||
return String(globals.eePersistanceAdress);
|
||||
if (var == "EEPROM_VERSION")
|
||||
return String(ConfigData.EEPROM_Version);
|
||||
if (var == "CONFIG_CHECKSUM")
|
||||
{
|
||||
char buffer[7];
|
||||
sprintf(buffer, "0x%04X", ConfigData.checksum);
|
||||
return String(buffer);
|
||||
}
|
||||
if (var == "DTC_TABLE")
|
||||
{
|
||||
String temp;
|
||||
String temp = "";
|
||||
char buff_timestamp[16]; // Format: DD-hh:mm:ss:xxx
|
||||
|
||||
for (uint32_t i = 0; i < MAX_DTC_STORAGE; i++)
|
||||
{
|
||||
if (DTCStorage[i].Number > 0)
|
||||
if (DTCStorage[i].Number < DTC_LAST_DTC)
|
||||
{
|
||||
sprintf(buff_timestamp, "%02d-%02d:%02d:%02d:%03d",
|
||||
DTCStorage[i].timestamp / 86400000, // Days
|
||||
@@ -116,8 +122,23 @@ String processor(const String &var)
|
||||
DTCStorage[i].timestamp / 1000 % 60, // Seconds
|
||||
DTCStorage[i].timestamp % 1000); // milliseconds
|
||||
|
||||
temp = "<tr><td>" + String(buff_timestamp);
|
||||
temp = temp + "<tr data-dtc=" + String(DTCStorage[i].Number);
|
||||
temp = temp + " data-debugval=" + String(DTCStorage[i].debugVal) + "><td>" + String(buff_timestamp);
|
||||
temp = temp + "</td><td>" + String(DTCStorage[i].Number) + "</td><td>";
|
||||
temp = temp + "<img src=static/img/";
|
||||
switch (DTCStorage[i].severity)
|
||||
{
|
||||
case DTC_CRITICAL:
|
||||
temp = temp + "critical";
|
||||
break;
|
||||
case DTC_WARN:
|
||||
temp = temp + "warn";
|
||||
break;
|
||||
case DTC_INFO:
|
||||
temp = temp + "info";
|
||||
break;
|
||||
}
|
||||
temp = temp + ".png></td><td>";
|
||||
|
||||
if (DTCStorage[i].active == DTC_ACTIVE)
|
||||
temp = temp + "active";
|
||||
@@ -174,20 +195,15 @@ String processor(const String &var)
|
||||
if (var == "NAME_FAC_3")
|
||||
return FACTION_3_NAME;
|
||||
|
||||
if (var == "TITLE")
|
||||
return DEVICE_NAME;
|
||||
|
||||
if (var == "BATTERY_LEVEL")
|
||||
if (var == "BATTERY_SELECT_OPTIONS")
|
||||
{
|
||||
return String(globals.battery_level);
|
||||
}
|
||||
if (var == "BATTERY_TYPE")
|
||||
{
|
||||
return String(BatteryString[ConfigData.batteryType]);
|
||||
}
|
||||
if (var == "BATTERY_VOLTAGE")
|
||||
{
|
||||
return String((float)globals.loadvoltage_mV / 1000.0);
|
||||
String temp;
|
||||
for (uint32_t i = 0; i < BatteryString_Elements; i++)
|
||||
{
|
||||
String selected = ConfigData.batteryType == i ? " selected " : "";
|
||||
temp = temp + "<option value=\"" + i + "\"" + selected + ">" + BatteryString[i] + "</option>";
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
return String();
|
||||
@@ -196,19 +212,24 @@ String processor(const String &var)
|
||||
void Webserver_Callback(AsyncWebServerRequest *request)
|
||||
{
|
||||
request->send(LittleFS, "/index.htm", "text/html", false, processor);
|
||||
StatusResponseMessage_Type = RESPMSG_HIDE;
|
||||
}
|
||||
|
||||
void WebserverPOST_Callback(AsyncWebServerRequest *request)
|
||||
{
|
||||
request->send(LittleFS, "/post.htm", "text/html", false, processor);
|
||||
|
||||
Debug_pushMessage("POST:\n");
|
||||
int paramsNr = request->params();
|
||||
for (int i = 0; i < paramsNr; i++)
|
||||
{
|
||||
AsyncWebParameter *p = request->getParam(i);
|
||||
if (p->name() == "commandInput")
|
||||
WebserverCommands_Callback(p->value());
|
||||
Debug_pushMessage("%s : %s\n", p->name().c_str(), p->value().c_str());
|
||||
|
||||
// begin: POST Form Settings
|
||||
if (p->name() == "cmdsubmit")
|
||||
globals.requestEEAction = EE_CFG_SAVE;
|
||||
// end: POST Form Settings
|
||||
}
|
||||
request->send(LittleFS, "/index.htm", "text/html", false, processor);
|
||||
}
|
||||
|
||||
void WebserverNotFound_Callback(AsyncWebServerRequest *request)
|
||||
@@ -216,41 +237,6 @@ void WebserverNotFound_Callback(AsyncWebServerRequest *request)
|
||||
request->send(404, "text/html", "Not found");
|
||||
}
|
||||
|
||||
void WebserverCommands_Callback(String input)
|
||||
{
|
||||
String command = input.substring(0, input.indexOf(' '));
|
||||
command.toUpperCase();
|
||||
StatusResponseMessage_Type = RESPMSG_HIDE;
|
||||
|
||||
if (command == "RESET")
|
||||
{
|
||||
strcpy(StatusResponseMessage, "Counter Reset done");
|
||||
StatusResponseMessage_Type = RESPMSG_SUCCESS;
|
||||
|
||||
PersistenceData.faction_1_timer = 0;
|
||||
PersistenceData.faction_2_timer = 0;
|
||||
PersistenceData.faction_3_timer = 0;
|
||||
PersistenceData.activeFaction = NONE;
|
||||
}
|
||||
else if (command == "BAT3S")
|
||||
{
|
||||
strcpy(StatusResponseMessage, "Set BatteryType to LiPo 3S");
|
||||
StatusResponseMessage_Type = RESPMSG_SUCCESS;
|
||||
|
||||
ConfigData.batteryType = BATTERY_LIPO_3S;
|
||||
globals.requestEEAction = EE_CFG_SAVE;
|
||||
}
|
||||
else if (command == "BAT2S")
|
||||
{
|
||||
strcpy(StatusResponseMessage, "Set BatteryType to LiPo 2S");
|
||||
StatusResponseMessage_Type = RESPMSG_SUCCESS;
|
||||
|
||||
ConfigData.batteryType = BATTERY_LIPO_2S;
|
||||
globals.requestEEAction = EE_CFG_SAVE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GetFlashVersion(char *buff, size_t buff_size)
|
||||
{
|
||||
File this_file = LittleFS.open("version", "r");
|
||||
@@ -273,7 +259,7 @@ void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const Stri
|
||||
|
||||
if (!index)
|
||||
{
|
||||
Serial.println("Update");
|
||||
Debug_pushMessage("Update");
|
||||
size_t content_len = request->contentLength();
|
||||
int cmd = (filename.indexOf(".fs") > -1) ? U_FS : U_FLASH;
|
||||
Update.runAsync(true);
|
||||
@@ -289,7 +275,7 @@ void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const Stri
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.printf("Progress: %d%%\n", (Update.progress() * 100) / Update.size());
|
||||
Debug_pushMessage("Progress: %d%%\n", (Update.progress() * 100) / Update.size());
|
||||
}
|
||||
|
||||
if (final)
|
||||
@@ -304,8 +290,7 @@ void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const Stri
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Update complete");
|
||||
Serial.flush();
|
||||
Debug_pushMessage("Update complete\n");
|
||||
globals.systemStatus = sysStat_Shutdown;
|
||||
}
|
||||
}
|
||||
@@ -313,31 +298,68 @@ void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const Stri
|
||||
|
||||
void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final)
|
||||
{
|
||||
|
||||
bool ee_done = false;
|
||||
bool validext = false;
|
||||
static bool validext = false;
|
||||
static char *buffer = NULL;
|
||||
static uint32_t read_ptr = 0;
|
||||
DeserializationError error;
|
||||
|
||||
if (!index)
|
||||
{
|
||||
Serial.println("EEPROM restore");
|
||||
validext = (filename.indexOf(".ee.json") > -1);
|
||||
if (validext)
|
||||
{
|
||||
buffer = (char *)malloc(1536);
|
||||
read_ptr = 0;
|
||||
if (buffer == NULL)
|
||||
Debug_pushMessage("malloc() failed for EEPROM-Restore");
|
||||
}
|
||||
}
|
||||
|
||||
if (validext)
|
||||
if (buffer != NULL)
|
||||
{
|
||||
Serial.println("Restoring EEPROM-Stuff");
|
||||
memcpy(buffer + read_ptr, data, len);
|
||||
read_ptr = read_ptr + len;
|
||||
}
|
||||
|
||||
if (final)
|
||||
{
|
||||
if (buffer != NULL)
|
||||
{
|
||||
Serial.print(buffer);
|
||||
StaticJsonDocument<1536> doc;
|
||||
error = deserializeJson(doc, buffer);
|
||||
if (error)
|
||||
{
|
||||
Debug_pushMessage("deserializeJson() failed: %s\n", error.f_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
ConfigData.batteryType = (batteryType_t)doc["config"]["batteryType"].as<uint32_t>();
|
||||
ConfigData.EEPROM_Version = doc["config"]["EEPROM_Version"].as<uint32_t>();
|
||||
|
||||
PersistenceData.writeCycleCounter = doc["persis"]["writeCycleCounter"].as<uint16_t>();
|
||||
PersistenceData.activeFaction = (factions_t)doc["persis"]["activeFaction"].as<uint32_t>();
|
||||
PersistenceData.faction_1_timer = doc["persis"]["faction_1_timer"].as<uint32_t>();
|
||||
PersistenceData.faction_2_timer = doc["persis"]["faction_2_timer"].as<uint32_t>();
|
||||
PersistenceData.faction_3_timer = doc["persis"]["faction_3_timer"].as<uint32_t>();
|
||||
PersistenceData.checksum = doc["persis"]["checksum"].as<uint32_t>();
|
||||
|
||||
ee_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "Please wait while the device reboots");
|
||||
response->addHeader("Refresh", "20");
|
||||
response->addHeader("Location", "/");
|
||||
request->send(response);
|
||||
|
||||
if (ee_done)
|
||||
{
|
||||
Serial.println("Update complete");
|
||||
Serial.flush();
|
||||
Debug_pushMessage("Update complete");
|
||||
globals.systemStatus = sysStat_Shutdown;
|
||||
}
|
||||
else
|
||||
@@ -355,13 +377,16 @@ void WebServerEEJSON_Callback(AsyncWebServerRequest *request)
|
||||
char buffer[16];
|
||||
|
||||
fwinfo["DeviceName"] = globals.DeviceName;
|
||||
fwinfo["FW-Version"] = QUOTE(SW_VERSION);
|
||||
sprintf(buffer, "%d.%02d", constants.Required_Flash_Version_major, constants.Required_Flash_Version_minor);
|
||||
fwinfo["FW-Version"] = buffer;
|
||||
fwinfo["FS-Version"] = globals.FlashVersion;
|
||||
snprintf_P(buffer, sizeof(buffer), "%s", constants.GitHash);
|
||||
fwinfo["Git-Hash"] = buffer;
|
||||
|
||||
JsonObject config = json.createNestedObject("config");
|
||||
|
||||
config["EEPROM_Version"] = ConfigData.EEPROM_Version;
|
||||
|
||||
config["batteryType"] = ConfigData.batteryType;
|
||||
sprintf(buffer, "0x%08X", ConfigData.checksum);
|
||||
config["checksum"] = buffer;
|
||||
|
||||
@@ -373,7 +398,10 @@ void WebServerEEJSON_Callback(AsyncWebServerRequest *request)
|
||||
JsonObject persis = json.createNestedObject("persis");
|
||||
|
||||
persis["writeCycleCounter"] = PersistenceData.writeCycleCounter;
|
||||
|
||||
persis["activeFaction"] = PersistenceData.activeFaction;
|
||||
persis["faction_1_timer"] = PersistenceData.faction_1_timer;
|
||||
persis["faction_2_timer"] = PersistenceData.faction_2_timer;
|
||||
persis["faction_3_timer"] = PersistenceData.faction_3_timer;
|
||||
sprintf(buffer, "0x%08X", PersistenceData.checksum);
|
||||
persis["checksum"] = buffer;
|
||||
|
||||
@@ -382,4 +410,52 @@ void WebServerEEJSON_Callback(AsyncWebServerRequest *request)
|
||||
response->addHeader("Content-disposition", "attachment; filename=backup.ee.json");
|
||||
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void WebsocketEvent_Callback(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case WS_EVT_CONNECT:
|
||||
Debug_pushMessage("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
|
||||
break;
|
||||
case WS_EVT_DISCONNECT:
|
||||
Debug_pushMessage("WebSocket client #%u disconnected\n", client->id());
|
||||
break;
|
||||
case WS_EVT_DATA:
|
||||
Websocket_HandleMessage(arg, data, len);
|
||||
break;
|
||||
case WS_EVT_PONG:
|
||||
case WS_EVT_ERROR:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Websocket_HandleMessage(void *arg, uint8_t *data, size_t len)
|
||||
{
|
||||
AwsFrameInfo *info = (AwsFrameInfo *)arg;
|
||||
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT)
|
||||
{
|
||||
data[len] = 0;
|
||||
|
||||
Debug_pushMessage("Got WebSocket Message: %s \n", (char *)data);
|
||||
|
||||
if (strcmp((char *)data, "start") == 0)
|
||||
{
|
||||
SetDebugportStatus(dbg_Webui, enabled);
|
||||
}
|
||||
else if (strcmp((char *)data, "stop") == 0)
|
||||
{
|
||||
SetDebugportStatus(dbg_Webui, disabled);
|
||||
}
|
||||
else if (strcmp((char *)data, "foo") == 0)
|
||||
{
|
||||
Debug_pushMessage("Got WebSocket Message 'foo' from client\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Websocket_PushLiveDebug(String Message)
|
||||
{
|
||||
webSocket.textAll(Message + "\n");
|
||||
}
|
Reference in New Issue
Block a user