Refactored error logger to reduce memory footprint
This commit is contained in:
parent
a486f1be30
commit
9e437d1e0d
@ -160,11 +160,33 @@
|
|||||||
});
|
});
|
||||||
setInterval(function() {
|
setInterval(function() {
|
||||||
loadLog();
|
loadLog();
|
||||||
}, 5000);
|
}, 30000);
|
||||||
|
|
||||||
function loadLog() {
|
function loadLog() {
|
||||||
$("#logContent").load("/log");
|
var url2 = "/log2";
|
||||||
//$("#logContent").load("/test/log");
|
var url1 = "/log";
|
||||||
|
//var url2 = "/test/log2";
|
||||||
|
//var url1 = "/test/log1";
|
||||||
|
var log = "";
|
||||||
|
|
||||||
|
$.get(url2, function(data) {
|
||||||
|
console.log(data);
|
||||||
|
var list = data.split("\n");
|
||||||
|
list.forEach(function (item, index) {
|
||||||
|
log = item + "\n" + log;
|
||||||
|
});
|
||||||
|
}).always( function() {
|
||||||
|
$.get(url1, function(data) {
|
||||||
|
console.log(data);
|
||||||
|
var list = data.split("\n");
|
||||||
|
list.forEach(function (item, index) {
|
||||||
|
log = item + "\n" + log;
|
||||||
|
});
|
||||||
|
}).always( function() {
|
||||||
|
console.log(log);
|
||||||
|
$("#logContent").text(log);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -182,13 +204,13 @@
|
|||||||
|
|
||||||
<div class="collapse row-margin-10" id="collapseLog">
|
<div class="collapse row-margin-10" id="collapseLog">
|
||||||
<div class="card card-body">
|
<div class="card card-body">
|
||||||
<pre><code class="card-text" id="logContent"></code></pre>
|
<pre><code class="card-text" id="logContent" data-bs-toggle="tooltip" title="Shows the last errors on the device, newest on top.">Loading log data, please wait...</code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="collapse row-margin-10" id="collapseSupport">
|
<div class="collapse row-margin-10" id="collapseSupport">
|
||||||
<div class="card card-body">
|
<div class="card card-body">
|
||||||
<pre><code class="card-text" id="supportContent"></code></pre>
|
<pre><code class="card-text" id="supportContent">Collecting support data, please wait...</code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -357,7 +379,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
setInterval(getStatus, 3000);
|
setInterval(getStatus, 5000);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
21
src/calc.cpp
21
src/calc.cpp
@ -52,8 +52,7 @@ int createFormula(RawFormulaData &fd, char *formulaBuffer,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (noAngles < 3) {
|
if (noAngles < 3) {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("CALC: Not enough values for deriving formula");
|
||||||
errLog.addEntry(F("CALC: Not enough values for deriving formula"));
|
|
||||||
return ERR_FORMULA_NOTENOUGHVALUES;
|
return ERR_FORMULA_NOTENOUGHVALUES;
|
||||||
} else {
|
} else {
|
||||||
double coeffs[order + 1];
|
double coeffs[order + 1];
|
||||||
@ -98,13 +97,8 @@ int createFormula(RawFormulaData &fd, char *formulaBuffer,
|
|||||||
|
|
||||||
// If the deviation is more than 2 degress we mark it as failed.
|
// If the deviation is more than 2 degress we mark it as failed.
|
||||||
if (dev * 1000 > myAdvancedConfig.getMaxFormulaCreationDeviation()) {
|
if (dev * 1000 > myAdvancedConfig.getMaxFormulaCreationDeviation()) {
|
||||||
char s[120];
|
writeErrorLog("CALC: Validation failed on angle %F, deviation too large %.2F SG, formula order %d",
|
||||||
snprintf(&s[0], sizeof(s),
|
|
||||||
"CALC: Validation failed on angle %f, deviation too large "
|
|
||||||
"%.2f SG, formula order %d",
|
|
||||||
fd.a[i], dev * 1000, order);
|
fd.a[i], dev * 1000, order);
|
||||||
ErrorFileLog errLog;
|
|
||||||
errLog.addEntry(&s[0]);
|
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,8 +112,7 @@ int createFormula(RawFormulaData &fd, char *formulaBuffer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("CALC: Internal error finding formula.");
|
||||||
errLog.addEntry(F("CALC: Internal error finding formula."));
|
|
||||||
return ERR_FORMULA_INTERNAL;
|
return ERR_FORMULA_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,8 +157,7 @@ double calculateGravity(double angle, double temp, const char *tempFormula) {
|
|||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("CALC: Failed to parse gravity expression %d", err);
|
||||||
errLog.addEntry("CALC: Failed to parse gravity expression " + String(err));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,10 +203,7 @@ double gravityTemperatureCorrectionC(double gravitySG, double tempC,
|
|||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("CALC: Failed to parse expression for gravity temperature correction %d", err);
|
||||||
errLog.addEntry(
|
|
||||||
"CALC: Failed to parse expression for gravity temperature correction " +
|
|
||||||
String(err));
|
|
||||||
return gravitySG;
|
return gravitySG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +145,7 @@ bool Config::saveFile() {
|
|||||||
File configFile = LittleFS.open(CFG_FILENAME, "w");
|
File configFile = LittleFS.open(CFG_FILENAME, "w");
|
||||||
|
|
||||||
if (!configFile) {
|
if (!configFile) {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("CFG : Failed to save configuration.");
|
||||||
errLog.addEntry(F("CFG : Failed to save configuration."));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,16 +175,14 @@ bool Config::loadFile() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!LittleFS.exists(CFG_FILENAME)) {
|
if (!LittleFS.exists(CFG_FILENAME)) {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("CFG : Configuration file does not exist.");
|
||||||
errLog.addEntry(F("CFG : Configuration file does not exist."));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
File configFile = LittleFS.open(CFG_FILENAME, "r");
|
File configFile = LittleFS.open(CFG_FILENAME, "r");
|
||||||
|
|
||||||
if (!configFile) {
|
if (!configFile) {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("CFG : Failed to load configuration.");
|
||||||
errLog.addEntry(F("CFG : Failed to load configuration."));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,8 +198,7 @@ bool Config::loadFile() {
|
|||||||
configFile.close();
|
configFile.close();
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("CFG : Failed to parse configuration (json)");
|
||||||
errLog.addEntry(F("CFG : Failed to parse configuration (json)"));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,8 +373,7 @@ bool AdvancedConfig::saveFile() {
|
|||||||
File configFile = LittleFS.open(CFG_HW_FILENAME, "w");
|
File configFile = LittleFS.open(CFG_HW_FILENAME, "w");
|
||||||
|
|
||||||
if (!configFile) {
|
if (!configFile) {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("CFG : Failed to write hardware configuration ");
|
||||||
errLog.addEntry(F("CFG : Failed to write hardware configuration "));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,8 +424,7 @@ bool AdvancedConfig::loadFile() {
|
|||||||
File configFile = LittleFS.open(CFG_HW_FILENAME, "r");
|
File configFile = LittleFS.open(CFG_HW_FILENAME, "r");
|
||||||
|
|
||||||
if (!configFile) {
|
if (!configFile) {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("CFG : Failed to read hardware configuration");
|
||||||
errLog.addEntry(F("CFG : Failed to read hardware configuration "));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,8 +440,7 @@ bool AdvancedConfig::loadFile() {
|
|||||||
configFile.close();
|
configFile.close();
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("CFG : Failed to parse hardware configuration (json)");
|
||||||
errLog.addEntry(F("CFG : Failed to parse hardware configuration (json)"));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +46,7 @@ bool GyroSensor::setup() {
|
|||||||
uint8_t id = accelgyro.getDeviceID();
|
uint8_t id = accelgyro.getDeviceID();
|
||||||
|
|
||||||
if (id != 0x34 && id != 0x38) { // Allow both MPU6050 and MPU6000
|
if (id != 0x34 && id != 0x38) { // Allow both MPU6050 and MPU6000
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("GYRO: Failed to connect to gyro, is it connected?");
|
||||||
errLog.addEntry(F("GYRO: Failed to connect to gyro, is it connected?"));
|
|
||||||
_sensorConnected = false;
|
_sensorConnected = false;
|
||||||
} else {
|
} else {
|
||||||
#if !defined(GYRO_DISABLE_LOGGING)
|
#if !defined(GYRO_DISABLE_LOGGING)
|
||||||
@ -294,9 +293,7 @@ void GyroSensor::applyCalibration() {
|
|||||||
if ((_calibrationOffset.ax + _calibrationOffset.ay + _calibrationOffset.az +
|
if ((_calibrationOffset.ax + _calibrationOffset.ay + _calibrationOffset.az +
|
||||||
_calibrationOffset.gx + _calibrationOffset.gy + _calibrationOffset.gz) ==
|
_calibrationOffset.gx + _calibrationOffset.gy + _calibrationOffset.gz) ==
|
||||||
0) {
|
0) {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("GYRO: No valid calibration values, please calibrate the device.");
|
||||||
errLog.addEntry(
|
|
||||||
F("GYRO: No valid calibration values, please calibrate the device."));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
133
src/helper.cpp
133
src/helper.cpp
@ -47,75 +47,40 @@ void tcp_cleanup() {
|
|||||||
while (tcp_tw_pcbs) tcp_abort(tcp_tw_pcbs);
|
while (tcp_tw_pcbs) tcp_abort(tcp_tw_pcbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
void writeErrorLog(const char *format, ...) {
|
||||||
// Convert sg to plato
|
File f = LittleFS.open(ERR_FILENAME, "a");
|
||||||
//
|
|
||||||
|
if (f && f.size() > ERR_FILEMAXSIZE) {
|
||||||
|
f.close();
|
||||||
|
LittleFS.remove(ERR_FILENAME2);
|
||||||
|
LittleFS.rename(ERR_FILENAME, ERR_FILENAME2);
|
||||||
|
f = LittleFS.open(ERR_FILENAME, "a");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f) {
|
||||||
|
va_list arg;
|
||||||
|
va_start(arg, format);
|
||||||
|
char buf[80];
|
||||||
|
vsnprintf(&buf[0], sizeof(buf), format, arg);
|
||||||
|
f.write(&buf[0], strlen(&buf[0]));
|
||||||
|
Log.error(&buf[0]);
|
||||||
|
va_end(arg);
|
||||||
|
f.println();
|
||||||
|
f.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double convertToPlato(double sg) {
|
double convertToPlato(double sg) {
|
||||||
if (sg) return 259 - (259 / sg);
|
if (sg) return 259 - (259 / sg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Convert plato to sg
|
|
||||||
//
|
|
||||||
double convertToSG(double plato) { return 259 / (259 - plato); }
|
double convertToSG(double plato) { return 259 / (259 - plato); }
|
||||||
|
|
||||||
//
|
|
||||||
// Conversion to F
|
|
||||||
//
|
|
||||||
float convertCtoF(float c) { return (c * 1.8) + 32.0; }
|
float convertCtoF(float c) { return (c * 1.8) + 32.0; }
|
||||||
|
|
||||||
//
|
|
||||||
// Conversion to C
|
|
||||||
//
|
|
||||||
float convertFtoC(float f) { return (f - 32.0) / 1.8; }
|
float convertFtoC(float f) { return (f - 32.0) / 1.8; }
|
||||||
|
|
||||||
//
|
|
||||||
// Load error log from disk
|
|
||||||
//
|
|
||||||
ErrorFileLog::ErrorFileLog() {
|
|
||||||
File errFile = LittleFS.open(ERR_FILENAME, "r");
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (errFile) {
|
|
||||||
do {
|
|
||||||
_errors[i] = errFile.readStringUntil('\n');
|
|
||||||
_errors[i].replace("\r", "");
|
|
||||||
_errors[i].replace("\n", "");
|
|
||||||
} while (_errors[i++].length());
|
|
||||||
errFile.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add new entry to top of error log
|
|
||||||
//
|
|
||||||
void ErrorFileLog::addEntry(String err) {
|
|
||||||
for (int i = (ERR_COUNT - 1); i > 0; i--) {
|
|
||||||
_errors[i] = _errors[i - 1];
|
|
||||||
}
|
|
||||||
_errors[0] = err;
|
|
||||||
err += String(CR);
|
|
||||||
Log.error(err.c_str());
|
|
||||||
save();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Save error log
|
|
||||||
//
|
|
||||||
void ErrorFileLog::save() {
|
|
||||||
File errFile = LittleFS.open(ERR_FILENAME, "w");
|
|
||||||
if (errFile) {
|
|
||||||
for (int i = 0; i < ERR_COUNT; i++) {
|
|
||||||
errFile.println(_errors[i]);
|
|
||||||
}
|
|
||||||
errFile.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Load history log of floats
|
|
||||||
//
|
|
||||||
FloatHistoryLog::FloatHistoryLog(String fName) {
|
FloatHistoryLog::FloatHistoryLog(String fName) {
|
||||||
_fName = fName;
|
_fName = fName;
|
||||||
|
|
||||||
@ -133,9 +98,6 @@ FloatHistoryLog::FloatHistoryLog(String fName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Add entry to top of log
|
|
||||||
//
|
|
||||||
void FloatHistoryLog::addEntry(float time) {
|
void FloatHistoryLog::addEntry(float time) {
|
||||||
for (int i = (10 - 1); i > 0; i--) {
|
for (int i = (10 - 1); i > 0; i--) {
|
||||||
_runTime[i] = _runTime[i - 1];
|
_runTime[i] = _runTime[i - 1];
|
||||||
@ -144,9 +106,6 @@ void FloatHistoryLog::addEntry(float time) {
|
|||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Save log
|
|
||||||
//
|
|
||||||
void FloatHistoryLog::save() {
|
void FloatHistoryLog::save() {
|
||||||
File runFile = LittleFS.open(_fName, "w");
|
File runFile = LittleFS.open(_fName, "w");
|
||||||
if (runFile) {
|
if (runFile) {
|
||||||
@ -157,9 +116,6 @@ void FloatHistoryLog::save() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Print the heap information.
|
|
||||||
//
|
|
||||||
void printHeap(String prefix) {
|
void printHeap(String prefix) {
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
Log.notice(
|
Log.notice(
|
||||||
@ -175,9 +131,6 @@ void printHeap(String prefix) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Enter deep sleep for the defined duration (Argument is seconds)
|
|
||||||
//
|
|
||||||
void deepSleep(int t) {
|
void deepSleep(int t) {
|
||||||
#if LOG_LEVEL == 6 && !defined(HELPER_DISABLE_LOGGING)
|
#if LOG_LEVEL == 6 && !defined(HELPER_DISABLE_LOGGING)
|
||||||
Log.verbose(F("HELP: Entering sleep mode for %ds." CR), t);
|
Log.verbose(F("HELP: Entering sleep mode for %ds." CR), t);
|
||||||
@ -186,9 +139,6 @@ void deepSleep(int t) {
|
|||||||
ESP.deepSleep(wake);
|
ESP.deepSleep(wake);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Print the build options used
|
|
||||||
//
|
|
||||||
void printBuildOptions() {
|
void printBuildOptions() {
|
||||||
Log.notice(F("Build options: %s (%s) LOGLEVEL %d "
|
Log.notice(F("Build options: %s (%s) LOGLEVEL %d "
|
||||||
#ifdef SKIP_SLEEPMODE
|
#ifdef SKIP_SLEEPMODE
|
||||||
@ -201,9 +151,6 @@ void printBuildOptions() {
|
|||||||
CFG_APPVER, CFG_GITREV, LOG_LEVEL);
|
CFG_APPVER, CFG_GITREV, LOG_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Configure serial debug output
|
|
||||||
//
|
|
||||||
SerialDebug::SerialDebug(const uint32_t serialSpeed) {
|
SerialDebug::SerialDebug(const uint32_t serialSpeed) {
|
||||||
// Start serial with auto-detected rate (default to defined BAUD)
|
// Start serial with auto-detected rate (default to defined BAUD)
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
@ -214,18 +161,12 @@ SerialDebug::SerialDebug(const uint32_t serialSpeed) {
|
|||||||
getLog()->notice(F("SDBG: Serial logging started at %u." CR), serialSpeed);
|
getLog()->notice(F("SDBG: Serial logging started at %u." CR), serialSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Print the timestamp (ms since start of device)
|
|
||||||
//
|
|
||||||
void printTimestamp(Print* _logOutput, int _logLevel) {
|
void printTimestamp(Print* _logOutput, int _logLevel) {
|
||||||
char c[12];
|
char c[12];
|
||||||
snprintf(c, sizeof(c), "%10lu ", millis());
|
snprintf(c, sizeof(c), "%10lu ", millis());
|
||||||
_logOutput->print(c);
|
_logOutput->print(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Read and calculate the battery voltage
|
|
||||||
//
|
|
||||||
void BatteryVoltage::read() {
|
void BatteryVoltage::read() {
|
||||||
// The analog pin can only handle 3.3V maximum voltage so we need to reduce
|
// The analog pin can only handle 3.3V maximum voltage so we need to reduce
|
||||||
// the voltage (from max 5V)
|
// the voltage (from max 5V)
|
||||||
@ -251,9 +192,6 @@ void BatteryVoltage::read() {
|
|||||||
|
|
||||||
PerfLogging myPerfLogging;
|
PerfLogging myPerfLogging;
|
||||||
|
|
||||||
//
|
|
||||||
// Clear the current cache
|
|
||||||
//
|
|
||||||
void PerfLogging::clear() {
|
void PerfLogging::clear() {
|
||||||
// Clear the measurements
|
// Clear the measurements
|
||||||
if (first == 0) return;
|
if (first == 0) return;
|
||||||
@ -270,17 +208,11 @@ void PerfLogging::clear() {
|
|||||||
} while (pe != 0);
|
} while (pe != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Start measuring this performance point
|
|
||||||
//
|
|
||||||
void PerfLogging::start(const char* key) {
|
void PerfLogging::start(const char* key) {
|
||||||
PerfEntry* pe = add(key);
|
PerfEntry* pe = add(key);
|
||||||
pe->start = millis();
|
pe->start = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Finalize measuring of this performance point
|
|
||||||
//
|
|
||||||
void PerfLogging::stop(const char* key) {
|
void PerfLogging::stop(const char* key) {
|
||||||
PerfEntry* pe = find(key);
|
PerfEntry* pe = find(key);
|
||||||
|
|
||||||
@ -293,9 +225,6 @@ void PerfLogging::stop(const char* key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Print the collected performance data
|
|
||||||
//
|
|
||||||
void PerfLogging::print() {
|
void PerfLogging::print() {
|
||||||
PerfEntry* pe = first;
|
PerfEntry* pe = first;
|
||||||
|
|
||||||
@ -305,9 +234,6 @@ void PerfLogging::print() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Push collected performance data to influx (use influx configuration)
|
|
||||||
//
|
|
||||||
void PerfLogging::pushInflux() {
|
void PerfLogging::pushInflux() {
|
||||||
if (!myConfig.isInfluxDb2Active()) return;
|
if (!myConfig.isInfluxDb2Active()) return;
|
||||||
|
|
||||||
@ -409,29 +335,19 @@ void PerfLogging::pushInflux() {
|
|||||||
|
|
||||||
#endif // COLLECT_PERFDATA
|
#endif // COLLECT_PERFDATA
|
||||||
|
|
||||||
//
|
|
||||||
// Convert float to formatted string with n decimals. Buffer should be at least
|
|
||||||
// 10 chars.
|
|
||||||
//
|
|
||||||
char* convertFloatToString(float f, char* buffer, int dec) {
|
char* convertFloatToString(float f, char* buffer, int dec) {
|
||||||
dtostrf(f, 6, dec, buffer);
|
dtostrf(f, 6, dec, buffer);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Reduce precision to n decimals
|
|
||||||
//
|
|
||||||
float reduceFloatPrecision(float f, int dec) {
|
float reduceFloatPrecision(float f, int dec) {
|
||||||
char buffer[5];
|
char buffer[5];
|
||||||
dtostrf(f, 6, dec, &buffer[0]);
|
dtostrf(f, 6, dec, &buffer[0]);
|
||||||
return atof(&buffer[0]);
|
return atof(&buffer[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// urlencode
|
// urlencode
|
||||||
//
|
|
||||||
// https://circuits4you.com/2019/03/21/esp8266-url-encode-decode-example/
|
// https://circuits4you.com/2019/03/21/esp8266-url-encode-decode-example/
|
||||||
//
|
|
||||||
String urlencode(String str) {
|
String urlencode(String str) {
|
||||||
String encodedString;
|
String encodedString;
|
||||||
encodedString.reserve(str.length() * 2);
|
encodedString.reserve(str.length() * 2);
|
||||||
@ -475,9 +391,6 @@ unsigned char h2int(char c) {
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// urlencode string
|
|
||||||
//
|
|
||||||
String urldecode(String str) {
|
String urldecode(String str) {
|
||||||
String encodedString;
|
String encodedString;
|
||||||
encodedString.reserve(str.length());
|
encodedString.reserve(str.length());
|
||||||
|
@ -28,13 +28,17 @@ SOFTWARE.
|
|||||||
#include <main.hpp>
|
#include <main.hpp>
|
||||||
|
|
||||||
#define ERR_FILENAME "/error.log"
|
#define ERR_FILENAME "/error.log"
|
||||||
#define ERR_COUNT 15
|
#define ERR_FILENAME2 "/error2.log"
|
||||||
|
#define ERR_FILEMAXSIZE 250
|
||||||
|
|
||||||
#define RUNTIME_FILENAME "/runtime.log"
|
#define RUNTIME_FILENAME "/runtime.log"
|
||||||
|
|
||||||
// tcp cleanup
|
// tcp cleanup
|
||||||
void tcp_cleanup();
|
void tcp_cleanup();
|
||||||
|
|
||||||
|
// Error logging
|
||||||
|
void writeErrorLog(const char *format, ...);
|
||||||
|
|
||||||
// Sleep mode
|
// Sleep mode
|
||||||
void deepSleep(int t);
|
void deepSleep(int t);
|
||||||
|
|
||||||
@ -67,16 +71,6 @@ class SerialDebug {
|
|||||||
static Logging* getLog() { return &Log; }
|
static Logging* getLog() { return &Log; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ErrorFileLog {
|
|
||||||
private:
|
|
||||||
String _errors[ERR_COUNT];
|
|
||||||
|
|
||||||
public:
|
|
||||||
ErrorFileLog();
|
|
||||||
void addEntry(String error);
|
|
||||||
void save();
|
|
||||||
};
|
|
||||||
|
|
||||||
class FloatHistoryLog {
|
class FloatHistoryLog {
|
||||||
private:
|
private:
|
||||||
String _fName;
|
String _fName;
|
||||||
|
@ -34,9 +34,6 @@ SOFTWARE.
|
|||||||
|
|
||||||
#define PUSHINT_FILENAME "/push.dat"
|
#define PUSHINT_FILENAME "/push.dat"
|
||||||
|
|
||||||
//
|
|
||||||
// Decrease counters
|
|
||||||
//
|
|
||||||
void PushIntervalTracker::update(const int index, const int defaultValue) {
|
void PushIntervalTracker::update(const int index, const int defaultValue) {
|
||||||
if (_counters[index] <= 0)
|
if (_counters[index] <= 0)
|
||||||
_counters[index] = defaultValue;
|
_counters[index] = defaultValue;
|
||||||
@ -44,9 +41,6 @@ void PushIntervalTracker::update(const int index, const int defaultValue) {
|
|||||||
_counters[index]--;
|
_counters[index]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Load data from file
|
|
||||||
//
|
|
||||||
void PushIntervalTracker::load() {
|
void PushIntervalTracker::load() {
|
||||||
File intFile = LittleFS.open(PUSHINT_FILENAME, "r");
|
File intFile = LittleFS.open(PUSHINT_FILENAME, "r");
|
||||||
|
|
||||||
@ -232,8 +226,7 @@ void PushTarget::sendInfluxDb2(TemplatingEngine& engine, bool isSecure) {
|
|||||||
_lastSuccess = true;
|
_lastSuccess = true;
|
||||||
Log.notice(F("PUSH: InfluxDB2 push successful, response=%d" CR), _lastCode);
|
Log.notice(F("PUSH: InfluxDB2 push successful, response=%d" CR), _lastCode);
|
||||||
} else {
|
} else {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("PUSH: Influxdb push failed response=%d", _lastCode);
|
||||||
errLog.addEntry("PUSH: Influxdb push failed response=" + String(_lastCode));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSecure) {
|
if (isSecure) {
|
||||||
@ -261,8 +254,7 @@ void PushTarget::addHttpHeader(HTTPClient& http, String header) {
|
|||||||
value.c_str());
|
value.c_str());
|
||||||
http.addHeader(name, value);
|
http.addHeader(name, value);
|
||||||
} else {
|
} else {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("PUSH: Unable to set header, invalid value %s", header.c_str());
|
||||||
errLog.addEntry("PUSH: Unable to set header, invalid value " + header);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,9 +330,7 @@ void PushTarget::sendHttpPost(TemplatingEngine& engine, bool isSecure,
|
|||||||
_lastSuccess = true;
|
_lastSuccess = true;
|
||||||
Log.notice(F("PUSH: HTTP post successful, response=%d" CR), _lastCode);
|
Log.notice(F("PUSH: HTTP post successful, response=%d" CR), _lastCode);
|
||||||
} else {
|
} else {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("PUSH: HTTP post failed response=%d http%d", _lastCode, index+1);
|
||||||
errLog.addEntry("PUSH: HTTP post failed response=" + String(_lastCode) +
|
|
||||||
String(index == 0 ? " (http)" : " (http2)"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSecure) {
|
if (isSecure) {
|
||||||
@ -399,8 +389,7 @@ void PushTarget::sendHttpGet(TemplatingEngine& engine, bool isSecure) {
|
|||||||
_lastSuccess = true;
|
_lastSuccess = true;
|
||||||
Log.notice(F("PUSH: HTTP get successful, response=%d" CR), _lastCode);
|
Log.notice(F("PUSH: HTTP get successful, response=%d" CR), _lastCode);
|
||||||
} else {
|
} else {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("PUSH: HTTP get failed response=%d", _lastCode);
|
||||||
errLog.addEntry("PUSH: HTTP get failed response=" + String(_lastCode));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSecure) {
|
if (isSecure) {
|
||||||
@ -419,7 +408,7 @@ void PushTarget::sendHttpGet(TemplatingEngine& engine, bool isSecure) {
|
|||||||
void PushTarget::sendMqtt(TemplatingEngine& engine, bool isSecure,
|
void PushTarget::sendMqtt(TemplatingEngine& engine, bool isSecure,
|
||||||
bool skipHomeAssistantRegistration) {
|
bool skipHomeAssistantRegistration) {
|
||||||
#if !defined(PUSH_DISABLE_LOGGING)
|
#if !defined(PUSH_DISABLE_LOGGING)
|
||||||
Log.notice(F("PUSH: Sending values to mqtt. Skip HA registration %s" CR),
|
Log.notice(F("PUSH: Sending values to mqtt. Skip HA registration=%s" CR),
|
||||||
skipHomeAssistantRegistration ? "yes" : "no");
|
skipHomeAssistantRegistration ? "yes" : "no");
|
||||||
#endif
|
#endif
|
||||||
_lastCode = 0;
|
_lastCode = 0;
|
||||||
@ -496,10 +485,7 @@ void PushTarget::sendMqtt(TemplatingEngine& engine, bool isSecure,
|
|||||||
Log.notice(F("PUSH: MQTT publish successful on %s" CR), topic.c_str());
|
Log.notice(F("PUSH: MQTT publish successful on %s" CR), topic.c_str());
|
||||||
_lastCode = 0;
|
_lastCode = 0;
|
||||||
} else {
|
} else {
|
||||||
_lastCode = mqtt.lastError();
|
writeErrorLog("PUSH: MQTT push on %s failed error=%d", topic.c_str(), mqtt.lastError());
|
||||||
ErrorFileLog errLog;
|
|
||||||
errLog.addEntry("PUSH: MQTT push on " + topic +
|
|
||||||
" failed error=" + String(mqtt.lastError()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,9 +169,6 @@ void WebServerHandler::webHandleUpload() {
|
|||||||
LOG_PERF_STOP("webserver-api-upload");
|
LOG_PERF_STOP("webserver-api-upload");
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Callback from webServer when / has been accessed.
|
|
||||||
//
|
|
||||||
void WebServerHandler::webHandleUploadFile() {
|
void WebServerHandler::webHandleUploadFile() {
|
||||||
LOG_PERF_START("webserver-api-upload-file");
|
LOG_PERF_START("webserver-api-upload-file");
|
||||||
Log.verbose(F("WEB : webServer callback for /api/upload(post)." CR));
|
Log.verbose(F("WEB : webServer callback for /api/upload(post)." CR));
|
||||||
@ -213,9 +210,7 @@ void WebServerHandler::webHandleUploadFile() {
|
|||||||
maxSketchSpace / 1024);
|
maxSketchSpace / 1024);
|
||||||
|
|
||||||
if (!Update.begin(maxSketchSpace, U_FLASH, PIN_LED)) {
|
if (!Update.begin(maxSketchSpace, U_FLASH, PIN_LED)) {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("WEB : Not enough space to store for this firmware.");
|
||||||
errLog.addEntry(
|
|
||||||
F("WEB : Not enough space to store for this firmware."));
|
|
||||||
_uploadReturn = 500;
|
_uploadReturn = 500;
|
||||||
}
|
}
|
||||||
} else if (upload.status == UPLOAD_FILE_WRITE) {
|
} else if (upload.status == UPLOAD_FILE_WRITE) {
|
||||||
@ -237,9 +232,7 @@ void WebServerHandler::webHandleUploadFile() {
|
|||||||
delay(500);
|
delay(500);
|
||||||
ESP_RESET();
|
ESP_RESET();
|
||||||
} else {
|
} else {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("WEB : Failed to finish firmware flashing error=%d", Update.getError());
|
||||||
errLog.addEntry("WEB : Failed to finish firmware flashing error=" +
|
|
||||||
String(Update.getError()));
|
|
||||||
_uploadReturn = 500;
|
_uploadReturn = 500;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -895,8 +888,7 @@ void WebServerHandler::webHandleConfigFormatWrite() {
|
|||||||
_server->sendHeader("Location", "/format.htm", true);
|
_server->sendHeader("Location", "/format.htm", true);
|
||||||
_server->send(302, "text/plain", "Format updated");
|
_server->send(302, "text/plain", "Format updated");
|
||||||
} else {
|
} else {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("WEB : Unable to store format file");
|
||||||
errLog.addEntry(F("WEB : Unable to store format file"));
|
|
||||||
_server->send(400, "text/plain", "Unable to store format in file.");
|
_server->send(400, "text/plain", "Unable to store format in file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,8 +946,6 @@ void WebServerHandler::webHandleTestPush() {
|
|||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.notice(F("WEB : Push completed" CR));
|
|
||||||
|
|
||||||
DynamicJsonDocument doc(100);
|
DynamicJsonDocument doc(100);
|
||||||
doc[PARAM_PUSH_ENABLED] = enabled;
|
doc[PARAM_PUSH_ENABLED] = enabled;
|
||||||
doc[PARAM_PUSH_SUCCESS] = push.getLastSuccess();
|
doc[PARAM_PUSH_SUCCESS] = push.getLastSuccess();
|
||||||
@ -1305,6 +1295,7 @@ bool WebServerHandler::setupWebServer() {
|
|||||||
_server->on("/firmware.htm",
|
_server->on("/firmware.htm",
|
||||||
std::bind(&WebServerHandler::webReturnFirmwareHtm, this));
|
std::bind(&WebServerHandler::webReturnFirmwareHtm, this));
|
||||||
_server->serveStatic("/log", LittleFS, ERR_FILENAME);
|
_server->serveStatic("/log", LittleFS, ERR_FILENAME);
|
||||||
|
_server->serveStatic("/log2", LittleFS, ERR_FILENAME2);
|
||||||
_server->serveStatic("/runtime", LittleFS, RUNTIME_FILENAME);
|
_server->serveStatic("/runtime", LittleFS, RUNTIME_FILENAME);
|
||||||
|
|
||||||
// Dynamic content
|
// Dynamic content
|
||||||
|
15
src/wifi.cpp
15
src/wifi.cpp
@ -203,9 +203,7 @@ bool WifiConnection::waitForConnection(int maxTime) {
|
|||||||
|
|
||||||
if (i++ >
|
if (i++ >
|
||||||
(maxTime * 10)) { // Try for maxTime seconds. Since delay is 100ms.
|
(maxTime * 10)) { // Try for maxTime seconds. Since delay is 100ms.
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("WIFI: Failed to connect to wifi %d",WiFi.status());
|
||||||
errLog.addEntry("WIFI: Failed to connect to wifi " +
|
|
||||||
String(WiFi.status()));
|
|
||||||
WiFi.disconnect();
|
WiFi.disconnect();
|
||||||
Serial.print(CR);
|
Serial.print(CR);
|
||||||
return false; // Return to main that we have failed to connect.
|
return false; // Return to main that we have failed to connect.
|
||||||
@ -346,9 +344,7 @@ bool WifiConnection::updateFirmware() {
|
|||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case HTTP_UPDATE_FAILED: {
|
case HTTP_UPDATE_FAILED: {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("WIFI: OTA update failed %d", ESPhttpUpdate.getLastError());
|
||||||
errLog.addEntry("WIFI: OTA update failed " +
|
|
||||||
String(ESPhttpUpdate.getLastError()));
|
|
||||||
} break;
|
} break;
|
||||||
case HTTP_UPDATE_NO_UPDATES:
|
case HTTP_UPDATE_NO_UPDATES:
|
||||||
break;
|
break;
|
||||||
@ -378,9 +374,7 @@ void WifiConnection::downloadFile(HTTPClient &http, String &fname) {
|
|||||||
f.close();
|
f.close();
|
||||||
Log.notice(F("WIFI: Downloaded file %s." CR), fname.c_str());
|
Log.notice(F("WIFI: Downloaded file %s." CR), fname.c_str());
|
||||||
} else {
|
} else {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("WIFI: Failed to download html-file %d", httpResponseCode);
|
||||||
errLog.addEntry("WIFI: Failed to download html-file " +
|
|
||||||
String(httpResponseCode));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,8 +413,7 @@ bool WifiConnection::checkFirmwareVersion() {
|
|||||||
#endif
|
#endif
|
||||||
DeserializationError err = deserializeJson(ver, payload);
|
DeserializationError err = deserializeJson(ver, payload);
|
||||||
if (err) {
|
if (err) {
|
||||||
ErrorFileLog errLog;
|
writeErrorLog("WIFI: Failed to parse version.json");
|
||||||
errLog.addEntry(F("WIFI: Failed to parse version.json"));
|
|
||||||
} else {
|
} else {
|
||||||
#if LOG_LEVEL == 6 && !defined(WIFI_DISABLE_LOGGING)
|
#if LOG_LEVEL == 6 && !defined(WIFI_DISABLE_LOGGING)
|
||||||
Log.verbose(F("WIFI: Project %s version %s." CR),
|
Log.verbose(F("WIFI: Project %s version %s." CR),
|
||||||
|
7
test/log1
Normal file
7
test/log1
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Log Entry 11
|
||||||
|
Log Entry 12
|
||||||
|
Log Entry 13
|
||||||
|
Log Entry 14
|
||||||
|
Log Entry 15
|
||||||
|
Log Entry 16
|
||||||
|
Log Entry 17
|
Loading…
Reference in New Issue
Block a user