added command log_events

This commit is contained in:
Paul
2019-10-02 19:20:55 +02:00
parent 79bc45051f
commit b00405e5b7
8 changed files with 155 additions and 24 deletions

View File

@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- new `mqttlog` command also shows which MQTT topics it is subscribed too - new `mqttlog` command also shows which MQTT topics it is subscribed too
- Optimized event log loading in web and added integrity checks on all config and log files during boot - Optimized event log loading in web and added integrity checks on all config and log files during boot
- `autodetect quick` - `autodetect quick`
- `log_events` option, now optional to save the log events to SPIFFS
### Fixed ### Fixed
@@ -25,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Faster detection of EMS devices on bus by using the 0x07 telegram instead of the brute-force scan - Faster detection of EMS devices on bus by using the 0x07 telegram instead of the brute-force scan
- Fixes to the default HA climate component .yaml file to support latest Home Assistance ('heat' added) - Fixes to the default HA climate component .yaml file to support latest Home Assistance ('heat' added)
- Update documentation in Wiki on MQTT and troubleshooting - Update documentation in Wiki on MQTT and troubleshooting
- Slowed down firmware upload via the Web to prevent users rebooting too early
### Removed ### Removed

View File

@@ -46,6 +46,7 @@ MyESP::MyESP() {
_ota_post_callback_f = nullptr; _ota_post_callback_f = nullptr;
_load_average = 100; // calculated load average _load_average = 100; // calculated load average
_general_serial = true; // serial is set to on as default _general_serial = true; // serial is set to on as default
_general_log_events = true; // all logs are written to an event log in SPIFFS
_have_ntp_time = false; _have_ntp_time = false;
// telnet // telnet
@@ -665,6 +666,7 @@ void MyESP::_printSetCommands() {
myDebug_P(PSTR(" set mqtt_port [value]")); myDebug_P(PSTR(" set mqtt_port [value]"));
myDebug_P(PSTR(" set ntp_enabled <on | off>")); myDebug_P(PSTR(" set ntp_enabled <on | off>"));
myDebug_P(PSTR(" set serial <on | off>")); myDebug_P(PSTR(" set serial <on | off>"));
myDebug_P(PSTR(" set log_events <on | off>"));
// call callback function // call callback function
if (_telnet_callback_f) { if (_telnet_callback_f) {
@@ -722,7 +724,9 @@ void MyESP::_printSetCommands() {
#else #else
myDebug_P(PSTR(" serial=%s"), (_general_serial) ? "on" : "off"); myDebug_P(PSTR(" serial=%s"), (_general_serial) ? "on" : "off");
#endif #endif
myDebug_P(PSTR(" ntp_enabled=%s"), (_ntp_enabled) ? "on" : "off"); myDebug_P(PSTR(" ntp_enabled=%s"), (_ntp_enabled) ? "on" : "off");
myDebug_P(PSTR(" log_events=%s"), (_general_log_events) ? "on" : "off");
// print any custom settings // print any custom settings
if (_fs_setlist_callback_f) { if (_fs_setlist_callback_f) {
@@ -887,6 +891,21 @@ bool MyESP::_changeSetting(uint8_t wc, const char * setting, const char * value)
save_config = false; save_config = false;
} }
} }
} else if (strcmp(setting, "log_events") == 0) {
save_config = true;
if (value) {
if (strcmp(value, "on") == 0) {
_general_log_events = true;
save_config = true;
myDebug_P(PSTR("Event logging on"));
} else if (strcmp(value, "off") == 0) {
_general_log_events = false;
save_config = true;
myDebug_P(PSTR("Event logging off"));
} else {
save_config = false;
}
}
} else { } else {
// finally check for any custom commands // finally check for any custom commands
if (_fs_setlist_callback_f) { if (_fs_setlist_callback_f) {
@@ -1599,9 +1618,14 @@ bool MyESP::_fs_validateConfigFile(const char * filename, size_t maxsize, JsonDo
return true; return true;
} }
// validates a log file in SPIFFS // validates the event log file in SPIFFS
// returns true if all OK // returns true if all OK
bool MyESP::_fs_validateLogFile(const char * filename) { bool MyESP::_fs_validateLogFile(const char * filename) {
// exit if we have disabled logging
if (!_general_log_events) {
return true;
}
// see if we can open it // see if we can open it
File eventlog = SPIFFS.open(filename, "r"); File eventlog = SPIFFS.open(filename, "r");
if (!eventlog) { if (!eventlog) {
@@ -1727,6 +1751,7 @@ bool MyESP::_fs_loadConfig() {
_general_password = strdup(general["password"] | MYESP_HTTP_PASSWORD); _general_password = strdup(general["password"] | MYESP_HTTP_PASSWORD);
_ws->setAuthentication("admin", _general_password); _ws->setAuthentication("admin", _general_password);
_general_hostname = strdup(general["hostname"]); _general_hostname = strdup(general["hostname"]);
_general_log_events = general["log_events"] | false; // default is off
// serial is only on when booting // serial is only on when booting
#ifdef FORCE_SERIAL #ifdef FORCE_SERIAL
@@ -1808,7 +1833,10 @@ bool MyESP::fs_saveCustomConfig(JsonObject root) {
} }
*/ */
if (_general_log_events) {
_writeEvent("INFO", "system", "Custom config stored in the SPIFFS", ""); _writeEvent("INFO", "system", "Custom config stored in the SPIFFS", "");
}
myDebug_P(PSTR("[FS] custom config saved")); myDebug_P(PSTR("[FS] custom config saved"));
ok = true; ok = true;
} }
@@ -1841,7 +1869,9 @@ bool MyESP::fs_saveConfig(JsonObject root) {
configFile.close(); configFile.close();
if (n) { if (n) {
if (_general_log_events) {
_writeEvent("INFO", "system", "System config stored in the SPIFFS", ""); _writeEvent("INFO", "system", "System config stored in the SPIFFS", "");
}
myDebug_P(PSTR("[FS] system config saved")); myDebug_P(PSTR("[FS] system config saved"));
ok = true; ok = true;
} }
@@ -1924,7 +1954,9 @@ void MyESP::_fs_setup() {
if (!SPIFFS.begin()) { if (!SPIFFS.begin()) {
myDebug_P(PSTR("[FS] Formatting filesystem...")); myDebug_P(PSTR("[FS] Formatting filesystem..."));
if (SPIFFS.format()) { if (SPIFFS.format()) {
if (_general_log_events) {
_writeEvent("WARN", "system", "File system formatted", ""); _writeEvent("WARN", "system", "File system formatted", "");
}
} else { } else {
myDebug_P(PSTR("[FS] Failed to format file system")); myDebug_P(PSTR("[FS] Failed to format file system"));
} }
@@ -1959,7 +1991,9 @@ void MyESP::_fs_setup() {
} else { } else {
myDebug_P(PSTR("[FS] Resetting event log")); myDebug_P(PSTR("[FS] Resetting event log"));
SPIFFS.remove(MYESP_EVENTLOG_FILE); SPIFFS.remove(MYESP_EVENTLOG_FILE);
_writeEvent("WARN", "system", "Event Log", "Log was reset due to corruption somewhere"); if (_general_log_events) {
_writeEvent("WARN", "system", "Event Log", "Log was erased due to probable file corruption");
}
} }
if (_ota_post_callback_f) { if (_ota_post_callback_f) {
@@ -2184,6 +2218,7 @@ void MyESP::crashInfo() {
#endif #endif
// write a log entry to SPIFFS // write a log entry to SPIFFS
// assumes we have "log_events" on
void MyESP::_writeEvent(const char * type, const char * src, const char * desc, const char * data) { void MyESP::_writeEvent(const char * type, const char * src, const char * desc, const char * data) {
// this will also create the file if its doesn't exist // this will also create the file if its doesn't exist
File eventlog = SPIFFS.open(MYESP_EVENTLOG_FILE, "a"); File eventlog = SPIFFS.open(MYESP_EVENTLOG_FILE, "a");
@@ -2617,8 +2652,9 @@ void MyESP::_webserver_setup() {
return; return;
} }
if (!index) { if (!index) {
ETS_UART_INTR_DISABLE(); // disable all UART interrupts to be safe
_writeEvent("INFO", "system", "Firmware update started", ""); _writeEvent("INFO", "system", "Firmware update started", "");
//Serial.printf("[SYSTEM] Firmware update started: %s\n", filename.c_str()); // enable for debugging //Serial.printf("[SYSTEM] Firmware update started: %s\n", filename.c_str()); // enable for debugging XXX
Update.runAsync(true); Update.runAsync(true);
if (!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)) { if (!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)) {
_writeEvent("ERRO", "system", "Not enough space to update", ""); _writeEvent("ERRO", "system", "Not enough space to update", "");
@@ -2634,7 +2670,6 @@ void MyESP::_webserver_setup() {
if (final) { if (final) {
if (Update.end(true)) { if (Update.end(true)) {
_writeEvent("INFO", "system", "Firmware update finished", ""); _writeEvent("INFO", "system", "Firmware update finished", "");
//Serial.printf("[SYSTEM] Firmware update finished: %uB\n", index + len); // enable for debugging
_shouldRestart = !Update.hasError(); _shouldRestart = !Update.hasError();
} else { } else {
_writeEvent("ERRO", "system", "Firmware update failed", ""); _writeEvent("ERRO", "system", "Firmware update failed", "");
@@ -2682,11 +2717,9 @@ void MyESP::_webserver_setup() {
//static String remoteIP = (String)address[0] + "." + (String)address[1] + "." + (String)address[2] + "." + (String)address[3]; //static String remoteIP = (String)address[0] + "." + (String)address[1] + "." + (String)address[2] + "." + (String)address[3];
if (!request->authenticate(MYESP_HTTP_USERNAME, _general_password)) { if (!request->authenticate(MYESP_HTTP_USERNAME, _general_password)) {
//_writeEvent("WARN", "system", "New login attempt", remoteIP);
return request->requestAuthentication(); return request->requestAuthentication();
} }
request->send(200, "text/plain", "Success"); request->send(200, "text/plain", "Success");
// _writeEvent("INFO", "system", "Login successful", remoteIP);
}); });
_webServer->rewrite("/", "/index.html"); _webServer->rewrite("/", "/index.html");
@@ -2799,8 +2832,10 @@ void MyESP::_bootupSequence() {
if (boot_status == MYESP_BOOTSTATUS_BOOTED) { if (boot_status == MYESP_BOOTSTATUS_BOOTED) {
if ((_ntp_enabled) && (now() > 10000) && !_have_ntp_time) { if ((_ntp_enabled) && (now() > 10000) && !_have_ntp_time) {
_have_ntp_time = true; _have_ntp_time = true;
if (_general_log_events) {
_writeEvent("INFO", "system", "System booted", ""); _writeEvent("INFO", "system", "System booted", "");
} }
}
return; return;
} }
@@ -2829,10 +2864,12 @@ void MyESP::_bootupSequence() {
// write a log message if we're not using NTP, otherwise wait for the internet time to arrive // write a log message if we're not using NTP, otherwise wait for the internet time to arrive
if (!_ntp_enabled) { if (!_ntp_enabled) {
if (_general_log_events) {
_writeEvent("INFO", "system", "System booted", ""); _writeEvent("INFO", "system", "System booted", "");
} }
} }
} }
}
// setup MyESP // setup MyESP
void MyESP::begin(const char * app_hostname, const char * app_name, const char * app_version, const char * app_url, const char * app_updateurl) { void MyESP::begin(const char * app_hostname, const char * app_name, const char * app_version, const char * app_url, const char * app_updateurl) {
@@ -2898,7 +2935,9 @@ void MyESP::loop() {
} }
if (_shouldRestart) { if (_shouldRestart) {
if (_general_log_events) {
_writeEvent("INFO", "system", "System is restarting", ""); _writeEvent("INFO", "system", "System is restarting", "");
}
myDebug("[SYSTEM] Restarting..."); myDebug("[SYSTEM] Restarting...");
_deferredReset(500, CUSTOM_RESET_TERMINAL); _deferredReset(500, CUSTOM_RESET_TERMINAL);
ESP.restart(); ESP.restart();

View File

@@ -400,11 +400,12 @@ class MyESP {
char * _app_updateurl; char * _app_updateurl;
bool _suspendOutput; bool _suspendOutput;
bool _general_serial; bool _general_serial;
unsigned long _getUptime(); bool _general_log_events;
char * _getBuildTime();
char * _buildTime; char * _buildTime;
bool _timerequest; bool _timerequest;
bool _formatreq; bool _formatreq;
unsigned long _getUptime();
char * _getBuildTime();
bool _hasValue(char * s); bool _hasValue(char * s);
void _printHeap(const char * s); void _printHeap(const char * s);

View File

@@ -130,7 +130,7 @@
<span class="col-xs-9 col-md-5"> <span class="col-xs-9 col-md-5">
<select class="form-control input-sm" id="tx_mode"> <select class="form-control input-sm" id="tx_mode">
<option selected="selected" value="1">1 (EMS generic)</option> <option selected="selected" value="1">1 (EMS generic)</option>
<option value="2">2 (EMS+/EMS2.0)</option> <option value="2">2 (EMS+)</option>
<option value="3">3 (Junkers Heatronic)</option> <option value="3">3 (Junkers Heatronic)</option>
</select> </select>
</span> </span>

View File

@@ -1 +1 @@
#define APP_VERSION "1.9.1b9" #define APP_VERSION "1.9.1b10"

View File

@@ -53,6 +53,30 @@
</div> </div>
</div> </div>
<div id="progressupload">
<br>
<br>
<div class="container">
<div class="row">
<br>
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Please wait for about a minute while the firmware uploads...</h3>
</div>
<div class="panel-body">
<div class="progress">
<div id="updateprog" class="progress-bar progress-bar-striped active" role="progressbar"
aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%">0%
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="generalcontent"> <div id="generalcontent">
<br> <br>
<legend>General Settings</legend> <legend>General Settings</legend>
@@ -90,6 +114,21 @@
</form> </form>
</div> </div>
<br> <br>
</div>
<div class="row form-group">
<label class="col-xs-3">Event Logging<i style="margin-left: 10px;" class="glyphicon glyphicon-info-sign"
aria-hidden="true" data-toggle="popover" data-trigger="hover" data-placement="right"
data-content="Enabling logging of all events to the device's storage"></i></label>
<div class="col-xs-9">
<form>
<label class="radio-inline">
<input type="radio" value="1" name="logeventsenabled">Enabled</label>
<label class="radio-inline">
<input type="radio" value="0" name="logeventsenabled" checked>Disabled</label>
</form>
</div>
<br>
<br> <br>
<div class="col-xs-9 col-md-8"> <div class="col-xs-9 col-md-8">
<button onclick="savegeneral()" class="btn btn-primary btn-sm pull-right">Save</button> <button onclick="savegeneral()" class="btn btn-primary btn-sm pull-right">Save</button>
@@ -112,6 +151,8 @@
<br> <br>
<legend>Event Log</legend> <legend>Event Log</legend>
<h6 class="text-muted">Dates shown in () represent elapsed time in seconds when NTP Time is disabled</h6> <h6 class="text-muted">Dates shown in () represent elapsed time in seconds when NTP Time is disabled</h6>
<div id="logevents" class="label label-danger">Event Logging has been disabled. See Settings->General Settings.
</div>
<br> <br>
<div class="panel panel-default"> <div class="panel panel-default">
<div> <div>
@@ -216,7 +257,8 @@
<div id="networkcontent"> <div id="networkcontent">
<br> <br>
<legend>Wireless Settings</legend> <legend>Wireless Settings</legend>
<h6 class="text-muted">Enter the wireless network settings here, or use Scan to find nearby networks to join</h6> <h6 class="text-muted">Enter the wireless network settings here, or use Scan to find nearby networks to join
</h6>
<br> <br>
<div class="row form-group"> <div class="row form-group">
<label class="col-xs-3">Mode<i style="margin-left: 10px;" class="glyphicon glyphicon-info-sign" <label class="col-xs-3">Mode<i style="margin-left: 10px;" class="glyphicon glyphicon-info-sign"
@@ -225,7 +267,8 @@
<div class="col-xs-9"> <div class="col-xs-9">
<form> <form>
<label class="radio-inline"> <label class="radio-inline">
<input type="radio" value="1" name="wmode" id="wmodeap" onclick="handleAP();" checked>Access Point <input type="radio" value="1" name="wmode" id="wmodeap" onclick="handleAP();" checked>Access
Point
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input type="radio" value="0" name="wmode" id="wmodesta" onclick="handleSTA();">Client</label> <input type="radio" value="0" name="wmode" id="wmodesta" onclick="handleSTA();">Client</label>
@@ -262,7 +305,8 @@
<div id="ntpcontent"> <div id="ntpcontent">
<br> <br>
<legend>Time Settings</legend> <legend>Time Settings</legend>
<h6 class="text-muted">With Network Time Protocol (NTP) enabled, all times are adjusted to the local timezone and <h6 class="text-muted">With Network Time Protocol (NTP) enabled, all times are adjusted to the local timezone
and
respect daylight saving respect daylight saving
time (DST)</h6> time (DST)</h6>
<br> <br>

View File

@@ -18,7 +18,8 @@ var config = {
"general": { "general": {
"hostname": "", "hostname": "",
"serial": false, "serial": false,
"password": "admin" "password": "admin",
"log_events": true
}, },
"mqtt": { "mqtt": {
"enabled": false, "enabled": false,
@@ -151,6 +152,11 @@ function savegeneral() {
config.general.serial = true; config.general.serial = true;
} }
config.general.log_events = false;
if (parseInt($("input[name=\"logeventsenabled\"]:checked").val()) === 1) {
config.general.log_events = true;
}
saveconfig(); saveconfig();
} }
@@ -239,6 +245,32 @@ function inProgress(callback) {
}).hide().fadeIn(); }).hide().fadeIn();
} }
function inProgressUpload() {
$("body").load("myesp.html #progressupload", function (responseTxt, statusTxt, xhr) {
if (statusTxt === "success") {
$(".progress").css("height", "40");
$(".progress").css("font-size", "xx-large");
var i = 0;
var prg = setInterval(function () {
$(".progress-bar").css("width", i + "%").attr("aria-valuenow", i).html(i + "%");
i = i + 1;
if (i === 101) {
clearInterval(prg);
document.getElementById("updateprog").className = "progress-bar progress-bar-success";
document.getElementById("updateprog").innerHTML = "Completed";
}
}, 500);
$.ajax({
url: "/update",
type: "POST",
data: formData,
processData: false,
contentType: false
});
}
}).hide().fadeIn();
}
function handleSTA() { function handleSTA() {
document.getElementById("scanb").style.display = "block"; document.getElementById("scanb").style.display = "block";
document.getElementById("hidessid").style.display = "block"; document.getElementById("hidessid").style.display = "block";
@@ -274,6 +306,10 @@ function listgeneral() {
if (config.general.serial) { if (config.general.serial) {
$("input[name=\"serialenabled\"][value=\"1\"]").prop("checked", true); $("input[name=\"serialenabled\"][value=\"1\"]").prop("checked", true);
} }
if (config.general.log_events) {
$("input[name=\"logeventsenabled\"][value=\"1\"]").prop("checked", true);
}
} }
function listmqtt() { function listmqtt() {
@@ -423,7 +459,15 @@ function getContent(contentname) {
page = 1; page = 1;
data = []; data = [];
getEvents(); getEvents();
if (config.general.log_events) {
document.getElementById("logevents").style.display = "none";
} else {
document.getElementById("logevents").style.display = "block";
}
break; break;
case "#customcontent": case "#customcontent":
listcustom(); listcustom();
break; break;
@@ -552,7 +596,7 @@ function initEventTable() {
var dup = JSON.parse(data[i]); var dup = JSON.parse(data[i]);
dup.uid = i + 1; dup.uid = i + 1;
} catch (e) { } catch (e) {
var dup = { "uid": i, "type": "ERRO", "src": "SYS", "desc": "Error in logfile entry", "data": data[i], "time": 1 } var dup = { "uid": i + 1, "type": "ERRO", "src": "SYS", "desc": "Error in log file", "data": data[i], "time": 1 }
} }
newlist[i].value = dup; newlist[i].value = dup;
@@ -866,7 +910,7 @@ function connectWS() {
function upload() { function upload() {
formData.append("bin", $("#binform")[0].files[0]); formData.append("bin", $("#binform")[0].files[0]);
inProgress("upload"); inProgressUpload();
} }
function login() { function login() {

View File

@@ -69,7 +69,8 @@ var configfile = {
"general": { "general": {
"hostname": "myesp", "hostname": "myesp",
"password": "admin", "password": "admin",
"serial": true "serial": true,
"log_events": true
}, },
"mqtt": { "mqtt": {
"enabled": false, "enabled": false,