Logging improvements

This commit is contained in:
2026-01-28 20:17:22 +01:00
parent 564ed20720
commit 2eabe931d8
11 changed files with 162 additions and 107 deletions

View File

@@ -18,18 +18,18 @@ Config::Config(Preferences& prefs)
}
[[noreturn]] void Config::error_abort() const {
ESP_LOGD(TAG, "Rebooting in about 2 seconds");
LOGD(TAG, "Rebooting in about 2 seconds");
esp_rom_uart_tx_wait_idle(0);
delay(2000); // to have a chance to read
abort();
}
void Config::load() {
ESP_LOGD(TAG, "Loading configuration");
LOGD(TAG, "Loading configuration");
prefs.begin(PREF_NAME, true);
for (const auto& def : configdefs) {
if (prefs.isKey(def.key)) {
ESP_LOGD(TAG, "Config option '%s' loaded from NVS", def.key);
LOGD(TAG, "Config option '%s' loaded from NVS", def.key);
switch (def.type) {
case ConfigType::BYTE:
values[def.key] = (uint8_t)prefs.getUChar(def.key, std::get<uint8_t>(def.defval));
@@ -54,7 +54,7 @@ void Config::load() {
break;
}
} else {
ESP_LOGD(TAG, "Using default for '%s'", def.key);
LOGD(TAG, "Using default for '%s'", def.key);
switch (def.type) {
case ConfigType::BYTE:
values[def.key] = std::get<uint8_t>(def.defval);
@@ -96,13 +96,13 @@ bool Config::save(JsonObject json) {
auto it = values.find(key);
if (it == values.end()) {
ESP_LOGE(TAG, "Unexpected missing key: %s", key);
LOGE(TAG, "Unexpected missing key: %s", key);
return false;
}
auto itdef = defs.find(key);
if (itdef == defs.end()) {
ESP_LOGE(TAG, "Unexpected missing defs key: %s", key);
LOGE(TAG, "Unexpected missing defs key: %s", key);
return false;
}
@@ -119,7 +119,7 @@ bool Config::save(JsonObject json) {
if (newval != *curval) {
values[key] = newval;
//prefs.putUChar(key, newval);
ESP_LOGI(TAG, "changing %s, replacing %d with %d", key, *curval, newval);
LOGI(TAG, "changing %s, replacing %d with %d", key, *curval, newval);
}
break;
}
@@ -164,46 +164,46 @@ bool Config::save(JsonObject json) {
void Config::dump() {
// only for debugging purposes,
ESP_LOGI(TAG, "========== Config options ==========");
LOGI(TAG, "========== Config options ==========");
for (const auto& def : configdefs) {
auto it = values.find(def.key);
if (it == values.end()) {
ESP_LOGW(TAG, "%s = <missing>", def.key);
LOGW(TAG, "%s = <missing>", def.key);
continue;
}
const ConfigValue& value = it->second;
switch (def.type) {
case ConfigType::BYTE:
if (auto v = std::get_if<uint8_t>(&value))
ESP_LOGI(TAG, "%s = %u", def.key, *v);
LOGI(TAG, "%s = %u", def.key, *v);
break;
case ConfigType::SHORT:
if (auto v = std::get_if<int16_t>(&value))
ESP_LOGI(TAG, "%s = %d", def.key, *v);
LOGI(TAG, "%s = %d", def.key, *v);
break;
case ConfigType::INT:
if (auto v = std::get_if<int32_t>(&value))
ESP_LOGI(TAG, "%s = %d", def.key, *v);
LOGI(TAG, "%s = %d", def.key, *v);
break;
case ConfigType::BOOL:
if (auto v = std::get_if<bool>(&value))
ESP_LOGI(TAG, "%s = %s", def.key, *v ? "true" : "false");
LOGI(TAG, "%s = %s", def.key, *v ? "true" : "false");
break;
case ConfigType::FLOAT:
if (auto v = std::get_if<float>(&value))
ESP_LOGI(TAG, "%s = %.3f", def.key, *v);
LOGI(TAG, "%s = %.3f", def.key, *v);
break;
case ConfigType::CHAR:
if (auto v = std::get_if<char>(&value))
ESP_LOGI(TAG, "%s = '%c'", def.key, *v);
LOGI(TAG, "%s = '%c'", def.key, *v);
break;
case ConfigType::STRING:
if (auto v = std::get_if<String>(&value))
ESP_LOGI(TAG, "%s = \"%s\"", def.key, v->c_str());
LOGI(TAG, "%s = \"%s\"", def.key, v->c_str());
break;
}
}
ESP_LOGI(TAG, "====================================");
LOGI(TAG, "====================================");
}
template<typename T>
@@ -214,12 +214,12 @@ T Config::get(const char* key) const {
uint8_t Config::getByte(const char* key) const {
auto it = values.find(key);
if (it == values.end()) {
ESP_LOGE(TAG, "Missing config key: %s", key);
LOGE(TAG, "Missing config key: %s", key);
error_abort();
}
if (auto v = std::get_if<uint8_t>(&it->second))
return *v;
ESP_LOGE(TAG, "Type mismatch for key: %s", key);
LOGE(TAG, "Type mismatch for key: %s", key);
error_abort();
}
@@ -238,59 +238,59 @@ int16_t Config::getShort(const char* key) const {
int32_t Config::getInt(const char* key) const {
auto it = values.find(key);
if (it == values.end()) {
ESP_LOGE(TAG, "Missing config key: %s", key);
LOGE(TAG, "Missing config key: %s", key);
error_abort();
}
if (auto v = std::get_if<int32_t>(&it->second))
return *v;
ESP_LOGE(TAG, "Type mismatch for key: %s", key);
LOGE(TAG, "Type mismatch for key: %s", key);
error_abort();
}
bool Config::getBool(const char* key) const {
auto it = values.find(key);
if (it == values.end())
ESP_LOGE(TAG, "Missing config key: %s", key);
LOGE(TAG, "Missing config key: %s", key);
abort();
if (auto v = std::get_if<bool>(&it->second))
return *v;
ESP_LOGE(TAG, "Type mismatch for key: %s", key);
LOGE(TAG, "Type mismatch for key: %s", key);
abort();
}
float Config::getFloat(const char* key) const {
auto it = values.find(key);
if (it == values.end()) {
ESP_LOGE(TAG, "Missing config key: %s", key);
LOGE(TAG, "Missing config key: %s", key);
error_abort();
}
if (auto v = std::get_if<float>(&it->second))
return *v;
ESP_LOGE(TAG, "Type mismatch for key: %s", key);
LOGE(TAG, "Type mismatch for key: %s", key);
error_abort();
}
char Config::getChar(const char* key) const {
auto it = values.find(key);
if (it == values.end()) {
ESP_LOGE(TAG, "Missing config key: %s", key);
LOGE(TAG, "Missing config key: %s", key);
error_abort();
}
if (auto v = std::get_if<char>(&it->second))
return *v;
ESP_LOGE(TAG, "Type mismatch for key: %s", key);
LOGE(TAG, "Type mismatch for key: %s", key);
error_abort();
}
const String& Config::getString(const char* key) const {
auto it = values.find(key);
if (it == values.end()) {
ESP_LOGE(TAG, "Missing config key: %s", key);
LOGE(TAG, "Missing config key: %s", key);
error_abort();
}
if (auto v = std::get_if<String>(&it->second))
return *v;
ESP_LOGE(TAG, "Type mismatch for key: %s", key);
LOGE(TAG, "Type mismatch for key: %s", key);
error_abort();
}

View File

@@ -1,6 +1,9 @@
#include "hash.h"
#include "mbedtls/md.h" // for SHA256
// Logging
static const char* TAG = "HASH";
String get_sha256(String payload) {
byte shaResult[32];
mbedtls_md_context_t ctx;
@@ -21,12 +24,14 @@ String get_sha256(String payload) {
buffer[sizeof(buffer) - 1] = '\0';
String hash = String(buffer);
Serial.print("SHA256 payload: ");
Serial.print(payload);
Serial.println();
Serial.print("SHA256-Hash: ");
Serial.print(hash);
Serial.println();
ESP_LOGI(TAG, "SHA256 payload: %s", payload);
ESP_LOGI(TAG, "SHA256 hash: %s", hash.c_str());
//Serial.print("SHA256 payload: ");
//Serial.print(payload);
//Serial.println();
//Serial.print("SHA256-Hash: ");
//Serial.print(hash);
//Serial.println();
return hash;
}

View File

@@ -35,6 +35,7 @@ __attribute__((section(".rodata_custom_desc"))) esp_app_desc_t custom_app_desc =
static const char* TAG = "MAIN";
uint64_t chipid = ESP.getEfuseMac();
uint8_t loglevel = 5;
const char* wifi_ssid = "OBPKP61";
const char* wifi_pass = "keypad61";
@@ -83,7 +84,7 @@ QueueHandle_t ledQueue = NULL;
QueueHandle_t keyQueue = NULL;
void ledTask(void *parameter) {
ESP_LOGI(TAG, "Starting LED task");
LOGI(TAG, "Starting LED task");
for (;;) {
vTaskDelay(5000);
ledcWrite(LEDC_RGBLED_G, 160); // a short activity flash
@@ -93,7 +94,7 @@ void ledTask(void *parameter) {
}
void sensorTask(void *parameter) {
ESP_LOGI(TAG, "Starting sensor task");
LOGI(TAG, "Starting sensor task");
for (;;) {
vTaskDelay(10000); // nothing yet
}
@@ -103,7 +104,7 @@ void keyTask(void *parameter) {
// short key press <= 1s
// medium key press >1s and < 3s
// long key press >= 3s
ESP_LOGI(TAG, "Starting keyboard task");
LOGI(TAG, "Starting keyboard task");
constexpr uint8_t NUM_BUTTONS = 7;
constexpr gpio_num_t buttonPins[NUM_BUTTONS] = {
@@ -160,12 +161,12 @@ void keyTask(void *parameter) {
}
void stopApTimerCallback(TimerHandle_t xTimer) {
ESP_LOGI(TAG, "reached AP switchoff time: accesspoint switched off ");
LOGI(TAG, "reached AP switchoff time: accesspoint switched off ");
WiFi.softAPdisconnect(true);
}
void cpuFreqTimerCallback(TimerHandle_t xTimer) {
ESP_LOGI(TAG, "after 3 minutes: set CPU frequency to 160MHz");
LOGI(TAG, "after 3 minutes: set CPU frequency to 160MHz");
setCpuFrequencyMhz(cpuspeed);
}
@@ -212,19 +213,20 @@ void setup() {
digitalWrite(RGBLED_G, LOW);
digitalWrite(RGBLED_B, LOW);
// Arduino ESP32 logging
esp_log_level_set("*", ESP_LOG_INFO);
esp_log_level_set("default", ESP_LOG_INFO);
esp_log_level_set("wifi", ESP_LOG_INFO);
esp_log_level_set("esp_timer", ESP_LOG_INFO);
esp_log_level_set("spi_flash", ESP_LOG_INFO);
esp_log_level_set("arduino", ESP_LOG_INFO);
ESP_LOGI(TAG, "Starting ...");
LOGI(TAG, "Starting ...");
config.load();
config.dump();
loglevel = config.getByte("logLevel");
if (loglevel > ESP_LOG_VERBOSE) {
loglevel = ESP_LOG_VERBOSE;
} else if (loglevel < 0) {
loglevel = ESP_LOG_NONE;
}
LOGI(TAG, "Setting loglevel to %d", loglevel);
esp_log_level_set("*", static_cast<esp_log_level_t>(loglevel));
keycode[0] = config.getByte("key1");
keycode[1] = config.getByte("key2");
keycode[2] = config.getByte("key3");
@@ -240,19 +242,19 @@ void setup() {
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
if (cause == ESP_SLEEP_WAKEUP_EXT0) {
ESP_LOGI(TAG, "Wake up by key");
LOGI(TAG, "Wake up by key");
} else {
destination = 'A';
}
// N2K basics
nodeid = N2K_DEFAULT_NODEID;
ESP_LOGI(TAG, "N2K default node is %d", nodeid);
LOGI(TAG, "N2K default node is %d", nodeid);
//preferences.begin(PREF_NAME, false);
//nodeid = preferences.getInt("LastNodeId", N2K_DEFAULT_NODEID);
//preferences.end();
nodeid = config.getByte("LastNodeId");
ESP_LOGI(TAG, "N2K node id set to %d from preferences", nodeid);
LOGI(TAG, "N2K node id set to %d from preferences", nodeid);
//cpuspeed = preferences.getInt("cpuSpeed", 160);
cpuspeed = config.getShort("cpuSpeed");
@@ -388,14 +390,14 @@ void setup() {
// I²C
// Serial.print("SHT31_LIB_VERSION: ");
// Serial.println(SHT31_LIB_VERSION);
ESP_LOGI(TAG, "SHT31_LIB_VERSION: %s", SHT31_LIB_VERSION);
LOGI(TAG, "SHT31_LIB_VERSION: %s", SHT31_LIB_VERSION);
Wire.begin(I2C_SDA, I2C_SCL);
Wire.setClock(I2C_SPEED);
uint16_t stat = sht.readStatus();
// stat = ffff anscheinend Fehler
// = 8010 läuft anscheinend
sht_available = (stat == 0x8010);
ESP_LOGI(TAG, "SHT31 state=0x%X", stat);
LOGI(TAG, "SHT31 state=0x%X", stat);
// Additional tests
String passhash = get_sha256("secretTEST");
@@ -417,10 +419,10 @@ void setup() {
ledQueue = xQueueCreate(5, sizeof(uint8_t));
if (esp_sleep_is_valid_wakeup_gpio(KEY_DST)) {
ESP_LOGI(TAG, "DST-key configured as wakeup-pin");
LOGI(TAG, "DST-key configured as wakeup-pin");
esp_sleep_enable_ext0_wakeup(KEY_DST, 0);
} else {
ESP_LOGI(TAG, "No wakeup feature available! Deep-sleep disabled.");
LOGI(TAG, "No wakeup feature available! Deep-sleep disabled.");
}
if (cpuspeed < 240) {
@@ -522,7 +524,7 @@ void send_sensor_temphum(float temp_k, float hum_perc) {
unsigned char instance = 0;
tN2kTempSource temp_src = N2kts_OutsideTemperature; // 1=outside, 2=inside
tN2kHumiditySource hum_src = N2khs_OutsideHumidity; // 0=inside, 1=outside
ESP_LOGI(TAG, "Sending temp=%f K, hum=%f %%", temp_k, hum_perc);
LOGI(TAG, "Sending temp=%f K, hum=%f %%", temp_k, hum_perc);
SetN2kPGN130312(N2kMsg, SID, instance, temp_src, temp_k);
NMEA2000.SendMsg(N2kMsg);
SetN2kPGN130313(N2kMsg, SID, instance, hum_src, hum_perc);
@@ -552,7 +554,7 @@ void loop() {
ledcWrite(LEDC_LED_C, 0);
ledcWrite(LEDC_LED_A, led_brightness);
}
ESP_LOGI(TAG, "New destination=%s", destination);
LOGI(TAG, "New destination=%s", destination);
}
} else if (event.pressType == ButtonPressType::LONG) {
shortBeep();
@@ -560,11 +562,11 @@ void loop() {
if (mode == 'N') {
mode = 'C';
ledcWrite(LEDC_RGBLED_B, rgb_brightness); // blue status indicator
ESP_LOGI(TAG, "Entering config mode");
LOGI(TAG, "Entering config mode");
} else {
mode = 'N';
ledcWrite(LEDC_RGBLED_B, 0);
ESP_LOGI(TAG, "Leaving config mode");
LOGI(TAG, "Leaving config mode");
}
}
} else {
@@ -588,19 +590,19 @@ void loop() {
switch (event.buttonId) {
case BUTTON_1: // switch day/night mode
if (ledmode == 'D') {
ESP_LOGI(TAG, "Night mode enabled");
LOGI(TAG, "Night mode enabled");
ledmode = 'N';
} else {
ESP_LOGI(TAG, "Day mode enabled");
LOGI(TAG, "Day mode enabled");
ledmode = 'D';
}
break;
case BUTTON_2: // switch audio on/off
if (audiomode == 'E') {
ESP_LOGI(TAG, "Disabled audio");
LOGI(TAG, "Disabled audio");
audiomode = 'D';
} else {
ESP_LOGI(TAG, "Enabled audio");
LOGI(TAG, "Enabled audio");
audiomode = 'E';
}
break;
@@ -618,13 +620,13 @@ void loop() {
case BUTTON_4: // reserved
break;
case BUTTON_5: // reset
ESP_LOGI(TAG, "Device reset");
LOGI(TAG, "Device reset");
esp_rom_uart_tx_wait_idle(0);
led_blink(LEDC_RGBLED_G, 3, 4095, 500);
ESP.restart();
break;
case BUTTON_6: // deep sleep
ESP_LOGI(TAG, "Going into deep sleep");
LOGI(TAG, "Going into deep sleep");
esp_rom_uart_tx_wait_idle(0);
led_blink(LEDC_RGBLED_B, 3, 4095, 500);
rtc_gpio_pullup_en(KEY_DST);

View File

@@ -7,6 +7,9 @@
#include <esp32/clk.h> // for cpu frequency
#include <Update.h>
// Logging
static const char* TAG = "WEB";
AsyncWebServer server(80);
class EmbeddedFile;
@@ -79,7 +82,7 @@ void webserver_init() {
}
// API fast hack
server.on("/api/capabilities", HTTP_GET, [](AsyncWebServerRequest *request){
server.on("/api/capabilities", HTTP_GET, [](AsyncWebServerRequest *request) {
StaticJsonDocument<100> doc;
doc["apPwChange"] = "true";
String out;
@@ -87,7 +90,7 @@ void webserver_init() {
request->send(200, "application/json", out);
});
server.on("/api/checkpass", HTTP_GET, [](AsyncWebServerRequest *request){
server.on("/api/checkpass", HTTP_GET, [](AsyncWebServerRequest *request) {
StaticJsonDocument<100> doc;
doc["status"] = "FAILED";
String out;
@@ -95,11 +98,11 @@ void webserver_init() {
request->send(200, "application/json", out);
});
server.on("/api/config", HTTP_GET, [](AsyncWebServerRequest *request){
server.on("/api/config", HTTP_GET, [](AsyncWebServerRequest *request) {
StaticJsonDocument<512> doc;
doc["systemName"] = config.getString("systemName");
doc["systemMode"] = String(config.getChar("systemMode"));
doc["logLevel"] = 0;
doc["logLevel"] = loglevel;
doc["version"] = VERSION;
doc["fwtype"] = "unknown"; // TODO ?
doc["salt"] = "secret";
@@ -127,13 +130,13 @@ void webserver_init() {
doc["key4long"] = longcode[BUTTON_4];
doc["key5long"] = longcode[BUTTON_5];
doc["key6long"] = longcode[BUTTON_6];
doc["envInterval"] = 5; // config.getShort("envInterval");
doc["envInterval"] = config.getShort("envInterval");
String out;
serializeJson(doc, out);
request->send(200, "application/json", out);
});
server.on("/api/resetconfig", HTTP_GET, [](AsyncWebServerRequest *request){
server.on("/api/resetconfig", HTTP_GET, [](AsyncWebServerRequest *request) {
StaticJsonDocument<100> doc;
doc["status"] = "FAILED";
String out;
@@ -141,7 +144,7 @@ void webserver_init() {
request->send(200, "application/json", out);
});
server.on("/api/status", HTTP_GET, [](AsyncWebServerRequest *request){
server.on("/api/status", HTTP_GET, [](AsyncWebServerRequest *request) {
StaticJsonDocument<200> doc;
doc["version"] = VERSION;
int cpu_freq = esp_clk_cpu_freq() / 1000000;
@@ -153,23 +156,38 @@ void webserver_init() {
doc["heap"]=(long)xPortGetFreeHeapSize();
doc["temp"] = String(temp, 1);
doc["hum"] = String(hum, 1);
switch (globalmode) {
case 'K':
doc["mode"] = "Keyboard";
break;
case 'A':
doc["mode"] = "Autopilot";
break;
case 'L':
doc["mode"] = "Logbook";
break;
default:
doc["mode"] = "*unknown*";
}
doc["status"] = "OK";
String out;
serializeJson(doc, out);
request->send(200, "application/json", out);
});
server.on("/api/fwinfo", HTTP_GET, [](AsyncWebServerRequest *request){
server.on("/api/fwinfo", HTTP_GET, [](AsyncWebServerRequest *request) {
StaticJsonDocument<200> doc;
doc["version"] = VERSION;
doc["build_date"] = BUILD_DATE;
doc["build_time"] = BUILD_TIME;
doc["idf"] = IDF_VERSION;
String out;
serializeJson(doc, out);
request->send(200, "application/json", out);
});
server.on("/api/setconfig", HTTP_POST, [](AsyncWebServerRequest *request){
server.on("/api/setconfig", HTTP_POST, [](AsyncWebServerRequest *request) {
LOGD(TAG, "API setconfig called");
StaticJsonDocument<100> doc;
doc["status"] = "FAILED";
String out;
@@ -177,7 +195,7 @@ void webserver_init() {
request->send(200, "application/json", out);
});
server.on("/api/update", HTTP_POST, [](AsyncWebServerRequest *request){
server.on("/api/update", HTTP_POST, [](AsyncWebServerRequest *request) {
// the request handler is triggered after the upload has finished...
// create the response, add header, and send response
@@ -207,7 +225,7 @@ void webserver_init() {
});
server.on("/api/devicelist", HTTP_GET, [](AsyncWebServerRequest *request){
server.on("/api/devicelist", HTTP_GET, [](AsyncWebServerRequest *request) {
// NMEA2000 device list
AsyncResponseStream *response = request->beginResponseStream("application/json");
response->print("[");