Tidied browser update by adding new browserupload class.
Adding RTC register storage for frequent NV updates (fuel gauge, desired temp etc)
This commit is contained in:
parent
e50d93bb8c
commit
a543ba0748
|
@ -103,6 +103,7 @@
|
|||
#include "src/Utility/BTC_JSON.h"
|
||||
#include "src/Utility/BTC_GPIO.h"
|
||||
#include "src/Utility/BoardDetect.h"
|
||||
#include "src/Utility/FuelGauge.h"
|
||||
#include "src/OLED/ScreenManager.h"
|
||||
#include "src/OLED/KeyPad.h"
|
||||
#include "src/Utility/TempSense.h"
|
||||
|
@ -173,6 +174,7 @@ CGPIOin GPIOin;
|
|||
CGPIOout GPIOout;
|
||||
CGPIOalg GPIOalg;
|
||||
|
||||
|
||||
sRxLine PCline;
|
||||
long lastRxTime; // used to observe inter character delays
|
||||
bool bHasOEMController = false;
|
||||
|
@ -184,6 +186,7 @@ __NOINIT_ATTR bool bForceInit; // = false;
|
|||
__NOINIT_ATTR bool bUserON; // = false;
|
||||
__NOINIT_ATTR uint8_t demandDegC;
|
||||
__NOINIT_ATTR uint8_t demandPump;
|
||||
CFuelGauge FuelGauge;
|
||||
|
||||
bool bReportBlueWireData = REPORT_RAW_DATA;
|
||||
bool bReportJSONData = REPORT_JSON_TRANSMIT;
|
||||
|
@ -302,7 +305,9 @@ extern "C" unsigned long __wrap_millis() {
|
|||
void setup() {
|
||||
|
||||
// ensure cyclic mode is disabled after power on
|
||||
if(rtc_get_reset_reason(0) == 1 || bForceInit) {
|
||||
bool bPowerUpInit = false;
|
||||
if(rtc_get_reset_reason(0) == 1/* || bForceInit*/) {
|
||||
bPowerUpInit = true;
|
||||
bForceInit = false;
|
||||
bUserON = false;
|
||||
demandPump = demandDegC = 22;
|
||||
|
@ -437,6 +442,10 @@ void setup() {
|
|||
FilteredSamples.Fan.setAlpha(0.7);
|
||||
FilteredSamples.AmbientTemp.reset(-100.0);
|
||||
|
||||
// if(bPowerUpInit) {
|
||||
FuelGauge.init();
|
||||
// }
|
||||
|
||||
delay(1000); // just to hold the splash screeen for while
|
||||
}
|
||||
|
||||
|
@ -775,8 +784,10 @@ void loop()
|
|||
|
||||
ScreenManager.reqUpdate();
|
||||
}
|
||||
if(bHasHtrData)
|
||||
if(bHasHtrData) {
|
||||
updateFilteredData();
|
||||
FuelGauge.Integrate(HeaterFrame2.getPump_Actual());
|
||||
}
|
||||
updateJSONclients(bReportJSONData);
|
||||
CommState.set(CommStates::Idle);
|
||||
NVstore.doSave(); // now is a good time to store to the NV storage, well away from any blue wire activity
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
#include "src/Utility/BTC_JSON.h"
|
||||
#include "src/Utility/BTC_GPIO.h"
|
||||
#include "src/Utility/BoardDetect.h"
|
||||
#include "src/Utility/FuelGauge.h"
|
||||
#include "src/OLED/ScreenManager.h"
|
||||
#include "src/OLED/KeyPad.h"
|
||||
#include "src/Utility/TempSense.h"
|
||||
|
@ -173,6 +174,7 @@ CGPIOin GPIOin;
|
|||
CGPIOout GPIOout;
|
||||
CGPIOalg GPIOalg;
|
||||
|
||||
|
||||
sRxLine PCline;
|
||||
long lastRxTime; // used to observe inter character delays
|
||||
bool bHasOEMController = false;
|
||||
|
@ -184,6 +186,7 @@ __NOINIT_ATTR bool bForceInit; // = false;
|
|||
__NOINIT_ATTR bool bUserON; // = false;
|
||||
__NOINIT_ATTR uint8_t demandDegC;
|
||||
__NOINIT_ATTR uint8_t demandPump;
|
||||
CFuelGauge FuelGauge;
|
||||
|
||||
bool bReportBlueWireData = REPORT_RAW_DATA;
|
||||
bool bReportJSONData = REPORT_JSON_TRANSMIT;
|
||||
|
@ -302,7 +305,9 @@ extern "C" unsigned long __wrap_millis() {
|
|||
void setup() {
|
||||
|
||||
// ensure cyclic mode is disabled after power on
|
||||
if(rtc_get_reset_reason(0) == 1 || bForceInit) {
|
||||
bool bPowerUpInit = false;
|
||||
if(rtc_get_reset_reason(0) == 1/* || bForceInit*/) {
|
||||
bPowerUpInit = true;
|
||||
bForceInit = false;
|
||||
bUserON = false;
|
||||
demandPump = demandDegC = 22;
|
||||
|
@ -437,6 +442,10 @@ void setup() {
|
|||
FilteredSamples.Fan.setAlpha(0.7);
|
||||
FilteredSamples.AmbientTemp.reset(-100.0);
|
||||
|
||||
// if(bPowerUpInit) {
|
||||
FuelGauge.init();
|
||||
// }
|
||||
|
||||
delay(1000); // just to hold the splash screeen for while
|
||||
}
|
||||
|
||||
|
@ -775,8 +784,10 @@ void loop()
|
|||
|
||||
ScreenManager.reqUpdate();
|
||||
}
|
||||
if(bHasHtrData)
|
||||
if(bHasHtrData) {
|
||||
updateFilteredData();
|
||||
FuelGauge.Integrate(HeaterFrame2.getPump_Actual());
|
||||
}
|
||||
updateJSONclients(bReportJSONData);
|
||||
CommState.set(CommStates::Idle);
|
||||
NVstore.doSave(); // now is a good time to store to the NV storage, well away from any blue wire activity
|
||||
|
|
|
@ -27,19 +27,28 @@
|
|||
#include "../Utility/helpers.h"
|
||||
#include "../Protocol/Protocol.h"
|
||||
#include "../Utility/NVStorage.h"
|
||||
#include "../Utility/FuelGauge.h"
|
||||
|
||||
extern CFuelGauge FuelGauge;
|
||||
|
||||
|
||||
#define MINIFONT miniFontInfo
|
||||
|
||||
#define X_FAN_ICON 55
|
||||
//#define X_FAN_ICON 55
|
||||
#define X_FAN_ICON 49
|
||||
#define Y_FAN_ICON 39
|
||||
#define X_FUEL_ICON 81
|
||||
//#define X_FUEL_ICON 81
|
||||
#define X_FUEL_ICON 74
|
||||
#define Y_FUEL_ICON 39
|
||||
#define X_TARGET_ICON 31
|
||||
//#define X_TARGET_ICON 31
|
||||
#define X_TARGET_ICON 28
|
||||
#define Y_TARGET_ICON 39
|
||||
#define Y_BASELINE 58
|
||||
#define X_GLOW_ICON 97
|
||||
//#define X_GLOW_ICON 97
|
||||
#define X_GLOW_ICON 92
|
||||
#define Y_GLOW_ICON 38
|
||||
#define X_BOWSER_ICON 91
|
||||
#define Y_BOWSER_ICON 43
|
||||
#define X_BODY_BULB 119
|
||||
#define X_BULB 1 // >= 1
|
||||
#define Y_BULB 4
|
||||
|
@ -106,11 +115,13 @@ CDetailedScreen::show()
|
|||
_animateRPM = false;
|
||||
_animatePump = false;
|
||||
_animateGlow = false;
|
||||
bool bGlowActive = false;
|
||||
|
||||
if(runstate != 0 && runstate != 10) { // not idle modes
|
||||
float power = getHeaterInfo().getGlowPlug_Power();
|
||||
if(power > 1) {
|
||||
showGlowPlug(power);
|
||||
bGlowActive = true;
|
||||
}
|
||||
|
||||
if(_showTarget)
|
||||
|
@ -123,6 +134,9 @@ CDetailedScreen::show()
|
|||
showBodyThermometer(getHeaterInfo().getTemperature_HeatExchg());
|
||||
}
|
||||
|
||||
if(!bGlowActive) {
|
||||
showBowser(FuelGauge.Used_mL());
|
||||
}
|
||||
showRunState(runstate, errstate);
|
||||
return true;
|
||||
}
|
||||
|
@ -431,6 +445,20 @@ CDetailedScreen::showFuel(float rate)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
CDetailedScreen::showBowser(float used)
|
||||
{
|
||||
_display.setTextColor(WHITE);
|
||||
_drawBitmap(X_BOWSER_ICON, Y_BOWSER_ICON, BowserIconInfo);
|
||||
char msg[16];
|
||||
sprintf(msg, "%.02fL", used * 0.001);
|
||||
#ifdef MINI_FANLABEL
|
||||
CTransientFont AF(_display, &MINIFONT); // temporarily use a mini font
|
||||
#endif
|
||||
_printMenuText(X_BOWSER_ICON + (BowserIconInfo.width/2), Y_BASELINE, msg, false, eCentreJustify);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CDetailedScreen::showRunState(int runstate, int errstate)
|
||||
{
|
||||
|
|
|
@ -48,6 +48,7 @@ class CDetailedScreen : public CScreenHeader
|
|||
void showFanV(float volts);
|
||||
void showFuel(float rate);
|
||||
void showRunState(int state, int errstate);
|
||||
void showBowser(float used);
|
||||
public:
|
||||
CDetailedScreen(C128x64_OLED& display, CScreenManager& mgr);
|
||||
bool show();
|
||||
|
|
|
@ -942,3 +942,26 @@ const uint8_t PROGMEM wwwIcon[] =
|
|||
const BITMAP_INFO WWWIconInfo(10, 9, wwwIcon);
|
||||
|
||||
|
||||
//
|
||||
// Image data for bowser
|
||||
//
|
||||
|
||||
const uint8_t PROGMEM bowserIcon[] =
|
||||
{
|
||||
0x7E, 0x80, // ###### #
|
||||
0x7E, 0xC0, // ###### ##
|
||||
0x42, 0xC0, // # # ##
|
||||
0x42, 0x40, // # # #
|
||||
0x42, 0x40, // # # #
|
||||
0x7E, 0x40, // ###### #
|
||||
0x7F, 0x40, // ####### #
|
||||
0x7F, 0x40, // ####### #
|
||||
0x7F, 0xC0, // #########
|
||||
0x7E, 0x00, // ######
|
||||
0x7E, 0x00, // ######
|
||||
0xFF, 0x00, // ########
|
||||
};
|
||||
|
||||
const BITMAP_INFO BowserIconInfo(10, 12, bowserIcon);
|
||||
|
||||
|
||||
|
|
|
@ -128,3 +128,5 @@ extern const BITMAP_INFO UpdateIconInfo;
|
|||
|
||||
// Bitmap sizes for www
|
||||
extern const BITMAP_INFO WWWIconInfo;
|
||||
|
||||
extern const BITMAP_INFO BowserIconInfo;
|
|
@ -24,7 +24,7 @@
|
|||
#include "BTCDateTime.h"
|
||||
#include "TimerManager.h"
|
||||
#include <Wire.h>
|
||||
#include "../Libraries/RTClib/RTClib.h"
|
||||
//#include "DS3231Ex.h"
|
||||
#include "../Utility/helpers.h"
|
||||
#include "../Utility/NVStorage.h"
|
||||
#include "../Utility/DebugPort.h"
|
||||
|
@ -32,7 +32,7 @@
|
|||
|
||||
// create ONE of the RTClib supported real time clock classes
|
||||
#if RTC_USE_DS3231 == 1
|
||||
RTC_DS3231 rtc;
|
||||
RTC_DS3231Ex rtc;
|
||||
#elif RTC_USE_DS1307 == 1
|
||||
RTC_DS1307 rtc;
|
||||
#elif RTC_USE_PCF8523 == 1
|
||||
|
@ -105,6 +105,17 @@ CClock::set(const DateTime& newTimeDate)
|
|||
_rtc.adjust(newTimeDate);
|
||||
}
|
||||
|
||||
void
|
||||
CClock::saveData(uint8_t* pData, int len, int ofs)
|
||||
{
|
||||
_rtc.writeData(pData, len, ofs);
|
||||
}
|
||||
|
||||
void
|
||||
CClock::readData(uint8_t* pData, int len, int ofs)
|
||||
{
|
||||
_rtc.readData(pData, len, ofs);
|
||||
}
|
||||
|
||||
|
||||
void setDateTime(const char* newTime)
|
||||
|
@ -139,3 +150,56 @@ void setTime(const char* newTime)
|
|||
}
|
||||
}
|
||||
|
||||
#define _I2C_WRITE write
|
||||
#define _I2C_READ read
|
||||
|
||||
void RTC_DS3231Ex::writeData(uint8_t* pData, int len, int ofs) {
|
||||
Wire.beginTransmission(DS3231_ADDRESS);
|
||||
Wire._I2C_WRITE((byte)(7+ofs)); // start at alarm bytes
|
||||
for(int i=0; i<len; i++) {
|
||||
Wire._I2C_WRITE(*pData++);
|
||||
}
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
void RTC_DS3231Ex::readData(uint8_t* pData, int len, int ofs) {
|
||||
Wire.beginTransmission(DS3231_ADDRESS);
|
||||
Wire._I2C_WRITE((byte)(7+ofs)); // start at alarm bytes
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(DS3231_ADDRESS, len);
|
||||
for(int i=0; i<len; i++) {
|
||||
*pData++ = Wire._I2C_READ();
|
||||
}
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
void storeFuelGauge(float val)
|
||||
{
|
||||
Clock.saveData((uint8_t*)&val, 4, 0);
|
||||
}
|
||||
|
||||
void getStoredFuelGauge(float& val)
|
||||
{
|
||||
Clock.readData((uint8_t*)&val, 4, 0);
|
||||
}
|
||||
|
||||
void storeDesiredTemp(uint8_t val)
|
||||
{
|
||||
Clock.saveData((uint8_t*)&val, 1, 4);
|
||||
}
|
||||
|
||||
void getStoredDesiredTemp(uint8_t& val)
|
||||
{
|
||||
Clock.readData((uint8_t*)&val, 1, 4);
|
||||
}
|
||||
|
||||
void storeDesiredPump(uint8_t val)
|
||||
{
|
||||
Clock.saveData((uint8_t*)&val, 1, 5);
|
||||
}
|
||||
|
||||
void getStoredDesiredPump(uint8_t& val)
|
||||
{
|
||||
Clock.readData((uint8_t*)&val, 1, 5);
|
||||
}
|
||||
|
|
|
@ -22,15 +22,23 @@
|
|||
#ifndef __BTC_CLOCK_H__
|
||||
#define __BTC_CLOCK_H__
|
||||
|
||||
#include "../Libraries/RTClib/RTClib.h"
|
||||
#include "BTCDateTime.h"
|
||||
#include "../cfg/BTCConfig.h"
|
||||
|
||||
class RTC_DS3231Ex : public RTC_DS3231 {
|
||||
public:
|
||||
void writeData(uint8_t* pData, int len, int ofs=0);
|
||||
void readData(uint8_t* pData, int len, int ofs=0);
|
||||
};
|
||||
|
||||
|
||||
class CClock {
|
||||
// allow use of ONE of the RTClib supported RTC chips
|
||||
// reference to the selected rtc stored here
|
||||
#if RTC_USE_DS3231 == 1
|
||||
RTC_DS3231& _rtc;
|
||||
// RTC_DS3231& _rtc;
|
||||
RTC_DS3231Ex& _rtc;
|
||||
#elif RTC_USE_DS1307 == 1
|
||||
RTC_DS1307& _rtc;
|
||||
#elif RTC_USE_PCF8523 == 1
|
||||
|
@ -45,7 +53,8 @@ class CClock {
|
|||
public:
|
||||
// constructors for ONE of the RTClib supported RTC chips
|
||||
#if RTC_USE_DS3231 == 1
|
||||
CClock(RTC_DS3231& rtc) : _rtc(rtc) {};
|
||||
// CClock(RTC_DS3231& rtc) : _rtc(rtc) {};
|
||||
CClock(RTC_DS3231Ex& rtc) : _rtc(rtc) {};
|
||||
#elif RTC_USE_DS1307 == 1
|
||||
CClock(RTC_1307& rtc) : _rtc(rtc) {};
|
||||
#elif RTC_USE_PCF8523 == 1
|
||||
|
@ -57,6 +66,8 @@ public:
|
|||
const BTCDateTime& update();
|
||||
const BTCDateTime& get() const;
|
||||
void set(const DateTime& newTime);
|
||||
void saveData(uint8_t* pData, int len, int ofs);
|
||||
void readData(uint8_t* pData, int len, int ofs);
|
||||
};
|
||||
|
||||
extern CClock Clock;
|
||||
|
|
|
@ -124,6 +124,11 @@ CESP32_NVStorage::validatedLoad(const char* key, float& val, float defVal, float
|
|||
return true;
|
||||
}
|
||||
|
||||
bool finBounds(float test, float minLim, float maxLim)
|
||||
{
|
||||
return INBOUNDS(test, minLim, maxLim);
|
||||
}
|
||||
|
||||
bool u8inBounds(uint8_t test, uint8_t minLim, uint8_t maxLim)
|
||||
{
|
||||
return INBOUNDS(test, minLim, maxLim);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <functional>
|
||||
|
||||
|
||||
bool finBounds(float tets, float min, float max);
|
||||
bool u8inBounds(uint8_t test, uint8_t minLim, uint8_t maxLim);
|
||||
bool s8inBounds(int8_t test, int8_t minLim, int8_t maxLim);
|
||||
bool u8Match2(uint8_t test, uint8_t test1, uint8_t test2);
|
||||
|
|
|
@ -235,6 +235,7 @@ sHeaterTuning::load()
|
|||
validatedLoad("systemVoltage", sysVoltage, 120, u8Match2, 120, 240);
|
||||
validatedLoad("fanSensor", fanSensor, 1, u8inBounds, 1, 2);
|
||||
validatedLoad("glowDrive", glowDrive, 5, u8inBounds, 1, 6);
|
||||
validatedLoad("pumpCal", pumpCal, 0.02, 0.001, 1);
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
|
@ -251,6 +252,7 @@ sHeaterTuning::save()
|
|||
preferences.putUChar("systemVoltage", sysVoltage);
|
||||
preferences.putUChar("fanSensor", fanSensor);
|
||||
preferences.putUChar("glowDrive", glowDrive);
|
||||
preferences.putFloat("pumpCal", pumpCal);
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
uint8_t sysVoltage;
|
||||
uint8_t fanSensor;
|
||||
uint8_t glowDrive;
|
||||
float pumpCal;
|
||||
|
||||
bool valid() {
|
||||
bool retval = true;
|
||||
|
@ -50,6 +51,7 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
retval &= sysVoltage == 120 || sysVoltage == 240;
|
||||
retval &= fanSensor == 1 || fanSensor == 2;
|
||||
retval &= INBOUNDS(glowDrive, 1, 6);
|
||||
retval &= INBOUNDS(pumpCal, 0.001, 1.0);
|
||||
return retval;
|
||||
};
|
||||
void init() {
|
||||
|
@ -60,6 +62,7 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
sysVoltage = 120;
|
||||
fanSensor = 1;
|
||||
glowDrive = 5;
|
||||
pumpCal = 0.02;
|
||||
};
|
||||
void load();
|
||||
void save();
|
||||
|
@ -71,6 +74,7 @@ struct sHeaterTuning : public CESP32_NVStorage {
|
|||
sysVoltage = rhs.sysVoltage;
|
||||
fanSensor = rhs.fanSensor;
|
||||
glowDrive = rhs.glowDrive;
|
||||
pumpCal = rhs.pumpCal;
|
||||
return *this;
|
||||
}
|
||||
float getPmin() const;
|
||||
|
|
|
@ -84,6 +84,13 @@ extern float getGlowCurrent();
|
|||
extern float getFanSpeed();
|
||||
extern int sysUptime();
|
||||
|
||||
extern void storeFuelGauge(float val);
|
||||
extern void getStoredFuelGauge(float& val);
|
||||
extern void storeDesiredTemp(uint8_t val);
|
||||
extern void getStoredDesiredTemp(uint8_t& val);
|
||||
extern void storeDesiredPump(uint8_t val);
|
||||
extern void getStoredDesiredPump(uint8_t& val);
|
||||
|
||||
|
||||
extern void ShowOTAScreen(int percent=0, eOTAmodes updateType=eOTAnormal);
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <WiFiClient.h>
|
||||
#include <WebServer.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include "BrowserUpload.h"
|
||||
#include <Update.h>
|
||||
|
||||
extern WiFiManager wm;
|
||||
|
@ -48,9 +49,7 @@ extern const char* updateIndex;
|
|||
extern const char* formatDoneContent;
|
||||
extern const char* rebootIndex;
|
||||
|
||||
File fsUploadFile; // a File object to temporarily store the received file
|
||||
int SPIFFSupload = 0;
|
||||
|
||||
sBrowserUpload BrowserUpload;
|
||||
WebServer server(80);
|
||||
WebSocketsServer webSocket = WebSocketsServer(81);
|
||||
|
||||
|
@ -85,15 +84,6 @@ void build500Response(String& content, String file);
|
|||
|
||||
void initWebServer(void) {
|
||||
|
||||
Update
|
||||
.onProgress([](unsigned int progress, unsigned int total) {
|
||||
int percent = (progress / (total / 100));
|
||||
DebugPort.printf("Progress: %u%%\r", percent);
|
||||
DebugPort.handle(); // keep telnet spy alive
|
||||
ShowOTAScreen(percent, eOTAWWW); // WWW update in place
|
||||
DebugPort.print("^");
|
||||
});
|
||||
|
||||
if (MDNS.begin("Afterburner")) {
|
||||
DebugPort.println("MDNS responder started");
|
||||
}
|
||||
|
@ -299,11 +289,11 @@ function onWebSocket(event) {
|
|||
switch(key) {
|
||||
case 'progress':
|
||||
// actual data bytes received as fed back via web socket
|
||||
var bytes = response[key];
|
||||
if(bytes >= 0) {
|
||||
var progress = response[key];
|
||||
if(progress >= 0) {
|
||||
// normal progression
|
||||
_('loaded_n_total').innerHTML = 'Uploaded ' + bytes + ' bytes of ' + sendSize;
|
||||
var percent = Math.round( 100 * (bytes / sendSize));
|
||||
_('loaded_n_total').innerHTML = 'Uploaded ' + progress + ' bytes of ' + sendSize;
|
||||
var percent = Math.round( 100 * (progress / sendSize));
|
||||
_('progressBar').value = percent;
|
||||
_('status').innerHTML = percent+'% uploaded.. please wait';
|
||||
uploadErr = '';
|
||||
|
@ -311,10 +301,12 @@ function onWebSocket(event) {
|
|||
else {
|
||||
// upload failure
|
||||
_('progressBar').value = 0;
|
||||
if(bytes == -1)
|
||||
uploadErr = 'SPIFFS UPLOAD ABORTED - FILE TOO LARGE';
|
||||
else
|
||||
uploadErr = 'SPIFFS UPLOAD ABORTED - WRITE ERROR';
|
||||
switch(progress) {
|
||||
case -1: uploadErr = 'File too large - SPIFFS upload ABORTED'; break;
|
||||
case -2: uploadErr = 'Write error - SPIFFS upload ABORTED'; break;
|
||||
case -3: uploadErr = 'Update error - Firmware upload ABORTED'; break;
|
||||
case -4: uploadErr = 'Invalid file - Firmware upload ABORTED'; break;
|
||||
}
|
||||
ajax.abort();
|
||||
}
|
||||
break;
|
||||
|
@ -328,6 +320,7 @@ function init() {
|
|||
}
|
||||
|
||||
function uploadFile() {
|
||||
_('upload_form').hidden = true;
|
||||
_('cancel').hidden = true;
|
||||
_('upload').hidden = true;
|
||||
_('progressBar').hidden = false;
|
||||
|
@ -695,8 +688,8 @@ void onUploadCompletion()
|
|||
_SuppliedFileSize = 0;
|
||||
DebugPort.println("WEB: POST /updatenow completion");
|
||||
// completion functionality
|
||||
if(SPIFFSupload) {
|
||||
if(SPIFFSupload == 1) {
|
||||
if(BrowserUpload.isSPIFFSupload()) {
|
||||
if(BrowserUpload.isOK()) {
|
||||
DebugPort.println("WEB: SPIFFS OK");
|
||||
server.send(200, "text/plain", "OK - File uploaded to SPIFFS");
|
||||
// javascript reselects the /update page!
|
||||
|
@ -705,16 +698,16 @@ void onUploadCompletion()
|
|||
DebugPort.println("WEB: SPIFFS FAIL");
|
||||
server.send(500, "text/plain", "500: couldn't create file");
|
||||
}
|
||||
SPIFFSupload = 0;
|
||||
BrowserUpload.reset();
|
||||
}
|
||||
else {
|
||||
if(Update.hasError()) {
|
||||
DebugPort.println("WEB: UPDATE FAIL");
|
||||
server.send(200, "text/plain", "FAIL - Afterburner will reboot shortly");
|
||||
if(BrowserUpload.isOK()) {
|
||||
DebugPort.println("WEB: FIRMWARE UPDATE OK");
|
||||
server.send(200, "text/plain", "OK - Afterburner will reboot shortly");
|
||||
}
|
||||
else {
|
||||
DebugPort.println("WEB: UPDATE OK");
|
||||
server.send(200, "text/plain", "OK - Afterburner will reboot shortly");
|
||||
DebugPort.println("WEB: FIRMWARE UPDATE FAIL");
|
||||
server.send(200, "text/plain", "FAIL - Afterburner will reboot shortly");
|
||||
}
|
||||
delay(1000);
|
||||
// javascript redirects to root page so we go there after reboot!
|
||||
|
@ -748,130 +741,54 @@ void onUploadBegin()
|
|||
|
||||
void onUploadProgression()
|
||||
{
|
||||
char JSON[64];
|
||||
|
||||
if(bUpdateAccessed) { // only allow progression via /update, attempts to directly access /updatenow will fail
|
||||
HTTPUpload& upload = server.upload();
|
||||
String filename = upload.filename;
|
||||
if(!filename.startsWith("/")) filename = "/"+filename;
|
||||
|
||||
if (upload.status == UPLOAD_FILE_START) {
|
||||
DebugPort.setDebugOutput(true);
|
||||
if(filename.endsWith(".bin")) {
|
||||
// FIRMWARE UPLOAD START
|
||||
DebugPort.printf("Firmware update: %s\r\n", filename.c_str()); // name without leading slash
|
||||
|
||||
int sizetouse = -1; //start with max available size
|
||||
if(_SuppliedFileSize) {
|
||||
sizetouse = _SuppliedFileSize; // adapt to websocket supplied size
|
||||
}
|
||||
if (!Update.begin(sizetouse)) {
|
||||
Update.printError(DebugPort);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// SPIFFS UPLOAD START
|
||||
DebugPort.printf("SPIFFS upload: %s\r\n", filename.c_str());
|
||||
|
||||
// calcualte a *very wild* guess of max size me *may* be able to cope with
|
||||
int freebytes = SPIFFS.totalBytes() - SPIFFS.usedBytes();
|
||||
freebytes -= 8192; // at least 2 blocks must be kept free, each being 4k
|
||||
int pageestimate = ((_SuppliedFileSize) / 256) + 1 + 1; // +1 for shortfall, +1 for metadata
|
||||
freebytes -= pageestimate * 256;
|
||||
|
||||
SPIFFSupload = 2; // assume SPIFFS error for now...
|
||||
if(freebytes > 0) {
|
||||
// *may* have enough space, open a file
|
||||
fsUploadFile = SPIFFS.open(filename, "w"); // Open the file for writing in SPIFFS (create if it doesn't exist)
|
||||
if(fsUploadFile) {
|
||||
SPIFFSupload = 1; // opened OK, mark as SPIFFS uplaod in progress
|
||||
}
|
||||
}
|
||||
// not enough space - return error to browser via web socket, javascript will report error
|
||||
if(SPIFFSupload == 2) {
|
||||
sendWebSocketString("{\"progress\":-1}"); // feedback -ve byte count of update to browser via websocket
|
||||
}
|
||||
DebugPort.printf("SPIFFS freespace test = %d\r\n", freebytes); // report our space estimate
|
||||
}
|
||||
int sts = BrowserUpload.begin(filename, _SuppliedFileSize);
|
||||
sprintf(JSON, "{\"progress\":%d}", sts);
|
||||
sendWebSocketString(JSON); // feedback proper byte count of update to browser via websocket
|
||||
}
|
||||
|
||||
// handle file segments of form upload
|
||||
// handle file fragments of form upload
|
||||
else if (upload.status == UPLOAD_FILE_WRITE) {
|
||||
#if USE_SW_WATCHDOG == 1
|
||||
feedWatchdog(); // we get stuck here for a while, don't let the watchdog bite!
|
||||
#endif
|
||||
// SPIFFS upload in progress?
|
||||
if(SPIFFSupload == 1) {
|
||||
if(upload.totalSize) {
|
||||
// feed back bytes received over web socket for browser javascript progressbar update
|
||||
char JSON[64];
|
||||
sprintf(JSON, "{\"progress\":%d}", upload.totalSize);
|
||||
sendWebSocketString(JSON); // feedback proper byte count of update to browser via websocket
|
||||
}
|
||||
// show percentage on OLED
|
||||
int percent = 0;
|
||||
if(_SuppliedFileSize)
|
||||
percent = 100 * upload.totalSize / _SuppliedFileSize;
|
||||
ShowOTAScreen(percent, eOTAbrowser); // browser update
|
||||
}
|
||||
|
||||
DebugPort.print(".");
|
||||
|
||||
if(SPIFFSupload) {
|
||||
// SPIFFS update (may be error state)
|
||||
if(fsUploadFile) {
|
||||
// file is open, add new segment of data to file opened for writing
|
||||
if(fsUploadFile.write(upload.buf, upload.currentSize) != upload.currentSize) { // Write the received bytes to the file
|
||||
// ERROR! write operation failed if length does not match!
|
||||
Update.printError(DebugPort);
|
||||
fsUploadFile.close(); // close the file (fsUploadFile becomes NULL)
|
||||
sendWebSocketString("{\"progress\":-2}"); // feedback -ve byte count of update to browser via websocket - write error
|
||||
SPIFFSupload = 2; // flag SPIFFS error!
|
||||
DebugPort.printf("UPLOAD_FILE_WRITE error: removing %s\r\n", filename.c_str());
|
||||
SPIFFS.remove(filename.c_str()); // remove the bad file from SPIFFS
|
||||
}
|
||||
}
|
||||
int sts = BrowserUpload.fragment(upload);
|
||||
if(sts < 0) {
|
||||
sprintf(JSON, "{\"progress\":%d}", sts);
|
||||
sendWebSocketString(JSON); // feedback -ve byte count of update to browser via websocket - write error
|
||||
}
|
||||
else {
|
||||
// Firmware update, add new segment to OTA partition
|
||||
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
|
||||
// ERROR !
|
||||
Update.printError(DebugPort);
|
||||
sendWebSocketString("{\"progress\":-2}"); // feedback -ve byte count of update to browser via websocket - write error
|
||||
// upload still in progress?
|
||||
if(BrowserUpload.bUploadActive) { // show progress unless a write error has occured
|
||||
DebugPort.print(".");
|
||||
if(upload.totalSize) {
|
||||
// feed back bytes received over web socket for progressbar update on browser (via javascript)
|
||||
sprintf(JSON, "{\"progress\":%d}", upload.totalSize);
|
||||
sendWebSocketString(JSON); // feedback proper byte count of update to browser via websocket
|
||||
}
|
||||
// show percentage on OLED
|
||||
int percent = 0;
|
||||
if(_SuppliedFileSize)
|
||||
percent = 100 * upload.totalSize / _SuppliedFileSize;
|
||||
ShowOTAScreen(percent, eOTAbrowser); // browser update
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle end of upload
|
||||
else if (upload.status == UPLOAD_FILE_END) {
|
||||
if(SPIFFSupload == 1) {
|
||||
// SPIFFS completed OK up until the end - a winner!
|
||||
// ensure 100% is shown on browser
|
||||
char JSON[64];
|
||||
sprintf(JSON, "{\"progress\":%ld}", _SuppliedFileSize);
|
||||
sendWebSocketString(JSON); // feedback proper byte count of update to browser via websocket
|
||||
}
|
||||
int sts = BrowserUpload.end(upload);
|
||||
sprintf(JSON, "{\"progress\":%d}", sts);
|
||||
sendWebSocketString(JSON); // feedback proper byte count of update to browser via websocket
|
||||
delay(2000);
|
||||
|
||||
if(SPIFFSupload) {
|
||||
// any form of SPIFFS attempt (may be error)
|
||||
// Close the file if still open (did not encounter write error)
|
||||
if(fsUploadFile) {
|
||||
fsUploadFile.close();
|
||||
DebugPort.printf("handleFileUpload Size: %d\r\n", upload.totalSize);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// completion of firmware update
|
||||
// check the added CRC we genertaed matches
|
||||
// - this guards against malicious, badly formatted bin file attempts.
|
||||
if(!CheckFirmwareCRC(_SuppliedFileSize))
|
||||
Update.abort();
|
||||
|
||||
if (Update.end()) {
|
||||
DebugPort.printf("Update Success: %u\r\nRebooting...\r\n", upload.totalSize);
|
||||
} else {
|
||||
Update.printError(DebugPort);
|
||||
}
|
||||
}
|
||||
bUpdateAccessed = false; // close gate on POST to /updatenow
|
||||
} else {
|
||||
DebugPort.printf("Update Failed Unexpectedly (likely broken connection): status=%d\r\n", upload.status);
|
||||
|
|
Loading…
Reference in a new issue