Using websocket to get proper firmware upload byte count
This commit is contained in:
parent
da33a02844
commit
fc8eef73a6
|
@ -564,7 +564,7 @@ void loop()
|
|||
case CommStates::Idle:
|
||||
|
||||
#if USE_SW_WATCHDOG == 1
|
||||
timerWrite(watchdogTimer, 0); //reset timer (feed watchdog)
|
||||
feedWatchdog(); //reset timer (feed watchdog)
|
||||
#endif
|
||||
|
||||
moderator = 50;
|
||||
|
@ -1338,4 +1338,9 @@ int getBoardRevision()
|
|||
void ShowOTAScreen(int percent, bool webupdate)
|
||||
{
|
||||
ScreenManager.showOTAMessage(percent, webupdate);
|
||||
}
|
||||
}
|
||||
|
||||
void feedWatchdog()
|
||||
{
|
||||
timerWrite(watchdogTimer, 0); //reset timer (feed watchdog)
|
||||
}
|
||||
|
|
83
Arduino/BTCDieselHeater/data/uploadfirmware.html
Normal file
83
Arduino/BTCDieselHeater/data/uploadfirmware.html
Normal file
|
@ -0,0 +1,83 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<script>
|
||||
// global variables
|
||||
var sendSize;
|
||||
var Socket;
|
||||
|
||||
function _(el) {
|
||||
return document.getElementById(el);
|
||||
}
|
||||
function init() {
|
||||
Socket = new WebSocket('ws://' + window.location.hostname + ':81/');
|
||||
|
||||
Socket.onmessage = function(event){
|
||||
var response = JSON.parse(event.data);
|
||||
var key;
|
||||
for(key in response) {
|
||||
console.log("JSON decode:", key, response[key]);
|
||||
switch(key) {
|
||||
case "progress":
|
||||
// actual data bytes received as fed back via web socket
|
||||
var bytes = response[key];
|
||||
_("loaded_n_total").innerHTML = "Uploaded " + bytes + " bytes of " + sendSize;
|
||||
var percent = Math.round( 100 * (bytes / sendSize));
|
||||
_("progressBar").value = percent;
|
||||
_("status").innerHTML = percent+"% uploaded.. please wait";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function uploadFile() {
|
||||
var file = _("file1").files[0];
|
||||
sendSize = file.size;
|
||||
var formdata = new FormData();
|
||||
formdata.append("update", file);
|
||||
var ajax = new XMLHttpRequest();
|
||||
// progress is handled via websocket JSON sent from controller
|
||||
// using server side progress only shows the buffer filling, not actual delivery.
|
||||
ajax.addEventListener("load", completeHandler, false);
|
||||
ajax.addEventListener("error", errorHandler, false);
|
||||
ajax.addEventListener("abort", abortHandler, false);
|
||||
ajax.open("POST", "/updatenow");
|
||||
ajax.send(formdata);
|
||||
}
|
||||
function completeHandler(event) {
|
||||
console.log(event);
|
||||
_("status").innerHTML = event.target.responseText;
|
||||
_("progressBar").value = 0;
|
||||
_("loaded_n_total").innerHTML = "Uploaded " + sendSize + " bytes of " + sendSize;
|
||||
setTimeout(function () {
|
||||
window.location.assign("/");
|
||||
}, 5000);
|
||||
}
|
||||
function errorHandler(event) {
|
||||
console.log(event);
|
||||
_("status").innerHTML = "Upload Failed";
|
||||
}
|
||||
function abortHandler(event) {
|
||||
console.log(event);
|
||||
_("status").innerHTML = "Upload Aborted";
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
body {font-family: Arial, Helvetica, sans-serif;}
|
||||
</style>
|
||||
<title>Afterburner firmware update</title>
|
||||
</head>
|
||||
<body onload="javascript:init()">
|
||||
<h1>Afterburner firmware update</h1>
|
||||
<form id='upload_form' method='POST' enctype='multipart/form-data'>
|
||||
<input type='file' name='file1' id='file1'> <BR>
|
||||
<input type='button' value='Update' onclick="uploadFile()">
|
||||
<progress id="progressBar" value="0" max="100" style="width:300px;"></progress><BR>
|
||||
<h3 id="status"></h3>
|
||||
<p id="loaded_n_total"></p>
|
||||
<BR>
|
||||
<input type='button' onclick=window.location.assign("/") value='Cancel'>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -63,6 +63,7 @@ extern int getBoardRevision();
|
|||
extern void setupGPIO();
|
||||
extern void setGPIO(int channel, bool state);
|
||||
extern bool getGPIO(int channel);
|
||||
extern void feedWatchdog();
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "../Protocol/TxManage.h"
|
||||
#include "../Protocol/helpers.h"
|
||||
#include "../cfg/pins.h"
|
||||
#include "../cfg/BTCConfig.h"
|
||||
#include "Index.h"
|
||||
#include "../Utility/BTC_JSON.h"
|
||||
#include "../Utility/Moderator.h"
|
||||
|
@ -106,10 +107,6 @@ void handleReset() {
|
|||
server.send(200, "text/plain", "Start Config Portal - Resetting Wifi credentials!");
|
||||
DebugPort.println("diconnecting client and wifi, then rebooting");
|
||||
delay(500);
|
||||
//client.disconnect();
|
||||
// wifi_station_disconnect();
|
||||
// wm.disconnect();
|
||||
// wm.resetSettings();
|
||||
wifiEnterConfigPortal(true, true, 3000);
|
||||
}
|
||||
|
||||
|
@ -118,10 +115,6 @@ void handleFormat() {
|
|||
DebugPort.println("Formatting SPIFFS partition");
|
||||
delay(500);
|
||||
SPIFFS.format();
|
||||
//client.disconnect();
|
||||
// wifi_station_disconnect();
|
||||
// wm.disconnect();
|
||||
// wm.resetSettings();
|
||||
}
|
||||
|
||||
void handleBTCNotFound() {
|
||||
|
@ -142,10 +135,58 @@ void handleBTCNotFound() {
|
|||
}
|
||||
|
||||
const char* serverIndex = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<style>body {font-family: Arial, Helvetica, sans-serif;}</style>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function _(el) {
|
||||
return document.getElementById(el);
|
||||
}
|
||||
function uploadFile() {
|
||||
var file = _("update").files[0];
|
||||
var formdata = new FormData();
|
||||
formdata.append("update", file);
|
||||
var ajax = new XMLHttpRequest();
|
||||
ajax.upload.addEventListener("progress", progressHandler, false);
|
||||
ajax.addEventListener("load", completeHandler, false);
|
||||
ajax.addEventListener("error", errorHandler, false);
|
||||
ajax.addEventListener("abort", abortHandler, false);
|
||||
ajax.open("POST", "/updatenow")
|
||||
ajax.send(formdata);
|
||||
}
|
||||
function progressHandler(event) {
|
||||
_("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "event.total;
|
||||
var percent = (event.load / event.total) * 100;
|
||||
_("progressBar").value = Math.round(percent);
|
||||
_("status").innerHTML = Math.round(percent)+"% uploaded.. please wait";
|
||||
}
|
||||
function completeHandler(event) {
|
||||
_("status").innerHTML = event.target.responseText;
|
||||
_("progressBar").value = 0;
|
||||
}
|
||||
function errorHandler(event) {
|
||||
_("status").innerHTML = "Upload Failed";
|
||||
}
|
||||
function abortHandler(event) {
|
||||
_("status").innerHTML = "Upload Aborted";
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<title>Afterburner firmware update</title>
|
||||
<h1>Afterburner firmware update</h1>
|
||||
<form method='POST' action='/updatenow' enctype='multipart/form-data'><input type='file' name='update'><BR><BR><input type='submit' value='Update'> <input type='button' onclick=window.location.assign('/') value='Cancel'></form>
|
||||
<form method='POST' action='/updatenow' enctype='multipart/form-data'>
|
||||
<input type='file' name='update'>
|
||||
<BR>
|
||||
<BR>
|
||||
<input type='button' value='Update' onclick="uploadFile()"> <input type='button' onclick=window.location.assign('/') value='Cancel'>
|
||||
<progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
|
||||
<h3 id="status"></h3>
|
||||
<p id="loaded_n_total"</p>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
|
||||
const char* rootIndex = R"=====(
|
||||
|
@ -191,8 +232,6 @@ void initWebServer(void) {
|
|||
|
||||
server.on("/tst", HTTP_GET, []() {
|
||||
rootRedirect();
|
||||
// server.sendHeader("Connection", "close");
|
||||
// server.send(200, "text/html", rootIndex);
|
||||
});
|
||||
// magical code shamelessly lifted from Arduino WebUpdate example, modified
|
||||
// this allows pushing new firmware to the ESP from a WEB BROWSER!
|
||||
|
@ -206,23 +245,19 @@ void initWebServer(void) {
|
|||
}
|
||||
bUpdateAccessed = true;
|
||||
server.sendHeader("Connection", "close");
|
||||
server.send(200, "text/html", serverIndex);
|
||||
// server.send(200, "text/html", serverIndex); // transition to file upload page
|
||||
server.sendHeader("Cache-Control", "no-cache");
|
||||
handleFileRead("/uploadfirmware.html");
|
||||
|
||||
});
|
||||
server.on("/updatenow", HTTP_GET, []() { // handle attempts to just browse the /updatenow path - force redirect to root
|
||||
rootRedirect();
|
||||
// server.sendHeader("Connection", "close");
|
||||
// server.send(200, "text/html", rootIndex);
|
||||
});
|
||||
// actual guts that manages the new firmware upload
|
||||
server.on("/updatenow", HTTP_POST, []() {
|
||||
// completion functionality
|
||||
server.sendHeader("Connection", "close");
|
||||
server.send(200, "text/plain", (Update.hasError()) ? "FAIL - Afterburner will reboot shortly" : "OK - Afterburner will reboot shortly");
|
||||
delay(1000);
|
||||
rootRedirect();
|
||||
// server.sendHeader("Connection", "close");
|
||||
// server.send(200, "text/html", rootIndex); // req browser to redirect to root
|
||||
delay(1000);
|
||||
ESP.restart(); // reboot
|
||||
}, []() {
|
||||
if(bUpdateAccessed) { // only allow progression via /update, attempts to directly access /updatenow will fail
|
||||
|
@ -234,13 +269,16 @@ void initWebServer(void) {
|
|||
Update.printError(DebugPort);
|
||||
}
|
||||
} else if (upload.status == UPLOAD_FILE_WRITE) {
|
||||
#if USE_SW_WATCHDOG == 1
|
||||
feedWatchdog();
|
||||
#endif
|
||||
if(upload.totalSize) {
|
||||
char JSON[64];
|
||||
sprintf(JSON, "{\"progress\":%d}", upload.totalSize);
|
||||
sendWebServerString(JSON);
|
||||
// DebugPort.print(JSON);
|
||||
}
|
||||
DebugPort.print(".");
|
||||
// server.sendHeader("Connection", "close");
|
||||
// char web[128];
|
||||
// int progress = upload.currentSize / upload.totalSize;
|
||||
// sprintf(web, "<progress id=\"file\" max=\"100\" value=\"%d\" </progress>", progress);
|
||||
// server.send(200, "text/html", web);
|
||||
// server.send(200, "text/plain", ".");
|
||||
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
|
||||
Update.printError(DebugPort);
|
||||
}
|
||||
|
@ -260,8 +298,6 @@ void initWebServer(void) {
|
|||
else {
|
||||
// attempt to POST without using /update - force redirect to root
|
||||
rootRedirect();
|
||||
// server.sendHeader("Connection", "close");
|
||||
// server.send(200, "text/html", rootIndex); // req browser to redirect to root
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ bool initWifi(int initpin,const char *failedssid, const char *failedpassword)
|
|||
// if you get here you have connected to the WiFi
|
||||
isSTA = true;
|
||||
DebugPort.println("WiFiManager connected in STA mode OK");
|
||||
DebugPort.printf(" STA IP address: %s\r\n", WiFi.localIP().toString().c_str());
|
||||
DebugPort.printf(" STA IP address: %s\r\n", getWifiSTAAddrStr());
|
||||
// must use same radio channel as STA to go to STA+AP, otherwise we drop the STA!
|
||||
chnl = WiFi.channel();
|
||||
DebugPort.println("Now promoting to STA+AP mode...");
|
||||
|
@ -128,7 +128,7 @@ bool initWifi(int initpin,const char *failedssid, const char *failedpassword)
|
|||
WiFi.softAP(APname, failedpassword, chnl);
|
||||
WiFi.enableAP(true);
|
||||
DebugPort.printf(" AP SSID: %s\r\n", WiFi.softAPgetHostname());
|
||||
DebugPort.printf(" AP IP address: %s\r\n", WiFi.softAPIP().toString().c_str());
|
||||
DebugPort.printf(" AP IP address: %s\r\n", getWifiAPAddrStr());
|
||||
DebugPort.printf("WifiMode after initWifi = %d\r\n", WiFi.getMode());
|
||||
#endif
|
||||
|
||||
|
@ -267,7 +267,7 @@ void APstartedCallback(WiFiManager*)
|
|||
const char* getWifiAPAddrStr()
|
||||
{
|
||||
noInterrupts();
|
||||
IPAddress IPaddr = WiFi.softAPIP(); // use stepping stone - function returns an automatic stack var - LAME!
|
||||
static IPAddress IPaddr = WiFi.softAPIP(); // use stepping stone - function returns an automatic stack var - LAME!
|
||||
interrupts();
|
||||
return IPaddr.toString().c_str();
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ const char* getWifiAPAddrStr()
|
|||
const char* getWifiSTAAddrStr()
|
||||
{
|
||||
noInterrupts();
|
||||
IPAddress IPaddr = WiFi.localIP(); // use stepping stone - function returns an automatic stack var - LAME!
|
||||
static IPAddress IPaddr = WiFi.localIP(); // use stepping stone - function returns an automatic stack var - LAME!
|
||||
interrupts();
|
||||
return IPaddr.toString().c_str();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue