diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 080e70d..8057bc7 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,6 @@ { - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format "recommendations": [ + "pioarduino.pioarduino-ide", "platformio.platformio-ide" ], "unwantedRecommendations": [ diff --git a/.vscode/settings.json b/.vscode/settings.json index 5601ac9..a8b8076 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,25 @@ "files.associations": { "iostream": "cpp", "random": "cpp", - "vector": "cpp" + "vector": "cpp", + "array": "cpp", + "deque": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "string_view": "cpp", + "memory": "cpp", + "initializer_list": "cpp", + "regex": "cpp", + "istream": "cpp", + "ostream": "cpp", + "chrono": "cpp", + "list": "cpp", + "format": "cpp", + "mutex": "cpp", + "span": "cpp", + "text_encoding": "cpp", + "thread": "cpp", + "*.inc": "cpp" } } \ No newline at end of file diff --git a/documentation/old.md b/documentation/old.md index d17c7b9..1fa3ec8 100644 --- a/documentation/old.md +++ b/documentation/old.md @@ -17,7 +17,7 @@ void listNetworkInterfaces() { } void setEthernetAsDefault() { - logger.log(0, DEBUG, "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + Logger.log(0, ELOG_LEVEL_DEBUG, "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); listNetworkInterfaces(); // Attempt to locate the Ethernet network interface. // (The name may vary—on some systems it might be "eth0") @@ -31,8 +31,8 @@ void setEthernetAsDefault() { struct netif *eth_netif2 = netif_find("ETH_DEF"); if (netif) { netif_set_default(eth_netif2); - logger.log(0, DEBUG, "Ethernet set as default network interface."); + Logger.log(0, ELOG_LEVEL_DEBUG, "Ethernet set as default network interface."); } else { - logger.log(0, DEBUG, "Could not find Ethernet netif."); + Logger.log(0, ELOG_LEVEL_DEBUG, "Could not find Ethernet netif."); } } \ No newline at end of file diff --git a/lib/fetchOTA/fetchOTA.cpp b/lib/fetchOTA/fetchOTA.cpp index ccf7421..8b08b54 100644 --- a/lib/fetchOTA/fetchOTA.cpp +++ b/lib/fetchOTA/fetchOTA.cpp @@ -22,14 +22,14 @@ Firmware OTA::getLatestVersionOnServer() { HTTPClient http; http.begin(_serverUrl); int httpCode = http.GET(); - logger.log(0, DEBUG, "HTTP Code: %d", httpCode); + Logger.log(0, ELOG_LEVEL_DEBUG, "HTTP Code: %d", httpCode); if (httpCode != 200) { return createErrorResponse("HTTP GET request failed with code " + String(httpCode)); } String payload = http.getString(); - logger.log(0, DEBUG, "Payload: %s", payload.c_str()); + Logger.log(0, ELOG_LEVEL_DEBUG, "Payload: %s", payload.c_str()); DynamicJsonDocument doc(4096); DeserializationError error = deserializeJson(doc, payload); @@ -54,7 +54,7 @@ Firmware OTA::getLatestVersionOnServer() { deviceConfig }); } else { - logger.log(0, DEBUG, "Configuration %s does not match current device configuration %s", deviceConfig.c_str(), _current_device_configuration.c_str()); + Logger.log(0, ELOG_LEVEL_DEBUG, "Configuration %s does not match current device configuration %s", deviceConfig.c_str(), _current_device_configuration.c_str()); } } } @@ -67,7 +67,7 @@ Firmware OTA::getLatestVersionOnServer() { Configuration latest = getLatestConfiguration(configs.data(), configs.size()); if (!isVersionNewer(_currentVersion, latest.version)) { - logger.log(0, DEBUG, "No newer version found. Server version: %d.%d.%d", latest.version.major, latest.version.minor, latest.version.patch); + Logger.log(0, ELOG_LEVEL_DEBUG, "No newer version found. Server version: %d.%d.%d", latest.version.major, latest.version.minor, latest.version.patch); } return Firmware{ @@ -88,79 +88,79 @@ Firmware OTA::createErrorResponse(const String& errorMsg) { } void run_ota_update(String url, std::function callback_started, std::function callback_finished, std::function callback_progress, std::function callback_error) { - logger.log(0, DEBUG, "Starting OTA upgrade"); + Logger.log(0, ELOG_LEVEL_DEBUG, "Starting OTA upgrade"); HTTPUpdate httpUpdate; httpUpdate.onStart(callback_started); httpUpdate.onEnd(callback_finished); httpUpdate.onProgress(callback_progress); httpUpdate.onError(callback_error); - logger.log(0, DEBUG, "Defined callbacks, Starting update now"); + Logger.log(0, ELOG_LEVEL_DEBUG, "Defined callbacks, Starting update now"); t_httpUpdate_return ret; if (url.startsWith("https")) { - logger.log(0, DEBUG, "HTTPS URL"); - WiFiClientSecure client; - client.setInsecure(); + Logger.log(0, ELOG_LEVEL_DEBUG, "HTTPS URL"); + WiFiClient client; + // client.setInsecure(); ret = httpUpdate.update(client, url); } else if (url.startsWith("http")) { - logger.log(0, DEBUG, "HTTP URL"); + Logger.log(0, ELOG_LEVEL_DEBUG, "HTTP URL"); WiFiClient client; ret = httpUpdate.update(client, url); } else { - logger.log(0, ERROR, "URL is not valid: \n%s", url.c_str()); + Logger.log(0, ELOG_LEVEL_ERROR, "URL is not valid: \n%s", url.c_str()); } switch (ret) { case HTTP_UPDATE_FAILED: - logger.log(0, ERROR, "HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str()); + Logger.log(0, ELOG_LEVEL_ERROR, "HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str()); break; case HTTP_UPDATE_NO_UPDATES: - logger.log(0, ERROR, "HTTP_UPDATE_NO_UPDATES"); + Logger.log(0, ELOG_LEVEL_ERROR, "HTTP_UPDATE_NO_UPDATES"); break; case HTTP_UPDATE_OK: - logger.log(0, DEBUG, "Update done"); + Logger.log(0, ELOG_LEVEL_DEBUG, "Update done"); break; } } void run_ota_spiffs_update(String url, std::function callback_started, std::function callback_finished, std::function callback_progress, std::function callback_error) { - logger.log(0, DEBUG, "Starting OTA SPIFFS upgrade"); + Logger.log(0, ELOG_LEVEL_DEBUG, "Starting OTA SPIFFS upgrade"); HTTPUpdate httpUpdate; httpUpdate.onStart(callback_started); httpUpdate.onEnd(callback_finished); httpUpdate.onProgress(callback_progress); httpUpdate.onError(callback_error); - logger.log(0, DEBUG, "Defined callbacks, Starting update now"); + Logger.log(0, ELOG_LEVEL_DEBUG, "Defined callbacks, Starting update now"); t_httpUpdate_return ret; if (url.startsWith("https")) { - logger.log(0, DEBUG, "HTTPS URL"); - WiFiClientSecure client; - client.setInsecure(); + Logger.log(0, ELOG_LEVEL_DEBUG, "HTTPS URL"); + WiFiClient client; + // client.setInsecure(); ret = httpUpdate.updateSpiffs(client, url); } else if (url.startsWith("http")) { - logger.log(0, DEBUG, "HTTP URL"); + Logger.log(0, ELOG_LEVEL_DEBUG, "HTTP URL"); WiFiClient client; ret = httpUpdate.updateSpiffs(client, url); } else { - logger.log(0, ERROR, "URL is not valid: \n%s", url.c_str()); + Logger.log(0, ELOG_LEVEL_ERROR, "URL is not valid: \n%s", url.c_str()); } switch (ret) { case HTTP_UPDATE_FAILED: - logger.log(0, ERROR, "HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str()); + Logger.log(0, ELOG_LEVEL_ERROR, "HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str()); break; case HTTP_UPDATE_NO_UPDATES: - logger.log(0, ERROR, "HTTP_UPDATE_NO_UPDATES"); + Logger.log(0, ELOG_LEVEL_ERROR, "HTTP_UPDATE_NO_UPDATES"); break; case HTTP_UPDATE_OK: - logger.log(0, DEBUG, "SPIFFS Update done"); + Logger.log(0, ELOG_LEVEL_DEBUG, "SPIFFS Update done"); break; } } diff --git a/platformio.ini b/platformio.ini index 408d44d..0bda890 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,7 +12,7 @@ default_envs = ESP32_INA233, ESP32_INA226 [env:ESP32_INA233] -platform = espressif32 +platform = espressif32 @ 6.0.0 board = esp32dev framework = arduino monitor_speed = 115200 @@ -22,28 +22,28 @@ lib_deps = fetchOTA INA233 ESP32Ping - https://github.com/tobimai/elog.git#fix-syslog + x385832/Elog board_build.partitions = default.csv upload_protocol = espota upload_port = 192.168.5.205 -build_flags = -Wall -Wextra -DLOGGING_SPIFFS_DISABLE -DLOGGING_SD_DISABLE +build_flags = -Wall -Wextra -DLOGGING_SPIFFS_DISABLE -DLOGGING_SD_DISABLE -DELOG_SYSLOG_ENABLE -fexceptions [env:ESP32_INA226] -platform = espressif32 +platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.32/platform-espressif32.zip board = esp32dev framework = arduino monitor_speed = 115200 +; monitor_filters = esp32_exception_decoder lib_deps = - ottowinter/ESPAsyncWebServer-esphome@^3.3.0 - robtillaart/INA226@^0.4.4 + esp32async/AsyncTCP @ ~3.4.9 + esp32async/ESPAsyncWebServer @ ~3.8.1 + robtillaart/INA226@ ~0.6.4 bblanchon/ArduinoJson@^6.21.3 - jsc/ArduinoLog - ESP32Ping - https://github.com/tobimai/elog.git#fix-syslog -board_build.partitions = default.csv + x385832/Elog@~2.0.10 +board_build.partitions = min_spiffs.csv upload_protocol = espota -upload_port = 192.168.4.18 -build_flags = -Wall -Wextra -DUSE_INA226 -DLOGGING_SPIFFS_DISABLE -DLOGGING_SD_DISABLE +upload_port = 192.168.6.45 +build_flags = -Wall -Wextra -DUSE_INA226 -DLOGGING_SPIFFS_DISABLE -DLOGGING_SD_DISABLE -DELOG_SYSLOG_ENABLE -fexceptions [env:native] platform = native diff --git a/src/external_interfacing/leds.cpp b/src/external_interfacing/leds.cpp index 6f94ff0..f6e1e0a 100644 --- a/src/external_interfacing/leds.cpp +++ b/src/external_interfacing/leds.cpp @@ -7,93 +7,29 @@ extern ActiveErrors active_errors; extern WaterData water_data; -void display_percentage(float percentage) -{ - digitalWrite(LED_RED, 0); - - if (percentage > 0) { - digitalWrite(LED_1, 1); - } else { - digitalWrite(LED_1, 0); - } - if (percentage > 20) { - digitalWrite(LED_2, 1); - } else { - digitalWrite(LED_2, 0); - } - if (percentage > 40) { - digitalWrite(LED_3, 1); - } else { - digitalWrite(LED_3, 0); - } - if (percentage > 60) { - digitalWrite(LED_4, 1); - } else { - digitalWrite(LED_4, 0); - } - if (percentage > 80) { - digitalWrite(LED_5, 1); - } else { - digitalWrite(LED_5, 0); - } - - if (percentage > 10) { - delay(3000); - } else if (percentage > 0) { - for (int i = 0; i < 3; i++) { - digitalWrite(LED_1, 1); - delay(500); - digitalWrite(LED_1, 0); - delay(500); - } - } else if (percentage <= 0) { - for (int i = 0; i < 15; i++) { - digitalWrite(LED_1, 1); - delay(100); - digitalWrite(LED_1, 0); - delay(100); - } - } -} - -void display_error_code(byte err_code) -{ - digitalWrite(LED_RED, 1); - digitalWrite(LED_1, bitRead(err_code, 0)); - digitalWrite(LED_2, bitRead(err_code, 1)); - digitalWrite(LED_3, bitRead(err_code, 2)); - digitalWrite(LED_4, bitRead(err_code, 3)); - digitalWrite(LED_5, bitRead(err_code, 4)); -} - void display_task(void* parameter) { while (true) { if (!is_error(active_errors)) { // We have no error, refresh status display and wait half a second - display_percentage(water_data.percentage); + ledcWrite(LED_GREEN, 255); + ledcWrite(LED_RED, 0); } else { - // We have an error, display error code for 3 seconds and then water level for 3 seconds - if (active_errors.voltage_low) { - display_error_code(1); - LOG(WARNING, "Sensor Error - Voltage low"); - delay(3000); - } else if (active_errors.voltage_high) { - display_error_code(2); - LOG(WARNING, "Sensor Error - Voltage High"); - delay(3000); - } else if (active_errors.current_low) { - display_error_code(3); - LOG(WARNING, "Sensor Error - Current low"); - delay(3000); - } else if (active_errors.current_high) { - display_error_code(4); - LOG(WARNING, "Sensor Error - Current high"); - delay(3000); - } else { - delay(3000); - } - display_percentage(water_data.percentage); + ledcWrite(LED_RED, LED_RED_HIGH); + ledcWrite(LED_GREEN, 0); } + delay(250); } +} + + +// Setup pin modes etc. +void led_setup() { + pinMode(LED_RED, OUTPUT); + pinMode(LED_GREEN, OUTPUT); + + ledcAttach(LED_RED, LED_PWM_FREQUENCY, LED_PWM_RESOLUTION); + ledcAttach(LED_GREEN, LED_PWM_FREQUENCY, LED_PWM_RESOLUTION); + ledcWrite(LED_RED, LED_RED_HIGH); + ledcWrite(LED_GREEN, 255); } \ No newline at end of file diff --git a/src/external_interfacing/leds.h b/src/external_interfacing/leds.h index 2b6d858..05c0f6d 100644 --- a/src/external_interfacing/leds.h +++ b/src/external_interfacing/leds.h @@ -1,12 +1,14 @@ #include -#define LED_1 4 -#define LED_2 2 -#define LED_3 15 -#define LED_4 13 -#define LED_5 12 -#define LED_RED 14 +#define LED_RED 15 +#define LED_GREEN 2 +#define LED_PWM_FREQUENCY 5000 +#define LED_PWM_RESOLUTION 8 +#define LED_CHANNEL_RED 0 +#define LED_CHANNEL_GREEN 1 -void display_percentage(float percentage); -void display_error_code(byte err_code); -void display_task(void* parameter); \ No newline at end of file +#define LED_RED_HIGH 150 + +// void display_error_code(byte err_code); +void display_task(void* parameter); +void led_setup(); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index f21cfe2..0fcad25 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,9 +24,9 @@ #include "networking/json_builder.h" #include "networking/responses.h" #include -#include #include "time.h" #include "tools/log.h" +#include #define MYLOG 0 @@ -37,68 +37,64 @@ extern DeviceTelemetry telemetry; extern NetworkData wifi_data; extern NetworkData ethernet_data; extern SensorData shunt_data; +extern ActiveErrors active_errors; extern "C" int rom_phy_get_vdd33(); Version current_spiffs_version; AsyncWebServer server(80); -AsyncWebSocket webSocket("/webSocket"); +// AsyncWebSocket webSocket("/webSocket"); #define FORMAT_LITTLEFS_IF_FAILED true void setup() -{ - logger.registerSerial(MYLOG, DEBUG, "tst"); +{ + Logger.registerSerial(MYLOG, ELOG_LEVEL_DEBUG, "Serial"); + LOG(ELOG_LEVEL_DEBUG, "Init LEDs"); + led_setup(); + + prefs.begin("waterlevel", false); Serial.begin(115200); - LOG(DEBUG, "Init LEDs"); - pinMode(LED_1, OUTPUT); - pinMode(LED_2, OUTPUT); - pinMode(LED_3, OUTPUT); - pinMode(LED_4, OUTPUT); - pinMode(LED_5, OUTPUT); - pinMode(LED_RED, OUTPUT); - display_error_code(31); + delay(500); - display_error_code(17); init_sensor(); - LOG(DEBUG, "Beginning SPIFFS"); - SPIFFS.begin(true); + LOG(ELOG_LEVEL_DEBUG, "Beginning SPIFFS"); + //SPIFFS.begin(FORMAT_LITTLEFS_IF_FAILED); + LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED); // Read the current SPIFFS version from the versions file on the spiffs - File file = SPIFFS.open("/version", FILE_READ); + File file = LittleFS.open("/version", FILE_READ); if (!file) { Serial.println("Failed to open version file for reading"); } else { String version = file.readStringUntil('\n'); - LOG(DEBUG, "Version: %s", version); + LOG(ELOG_LEVEL_DEBUG, "Version: %s", version); current_spiffs_version = parseVersion(version.c_str()); - LOG(DEBUG, "Current SPIFFS Version: %d.%d.%d", current_spiffs_version.major, current_spiffs_version.minor, current_spiffs_version.patch); + LOG(ELOG_LEVEL_DEBUG, "Current SPIFFS Version: %d.%d.%d", current_spiffs_version.major, current_spiffs_version.minor, current_spiffs_version.patch); } - LOG(DEBUG, "SPIFFS initialized"); - display_error_code(19); + LOG(ELOG_LEVEL_DEBUG, "SPIFFS initialized"); - LOG(DEBUG, "Begin INA"); + LOG(ELOG_LEVEL_DEBUG, "Begin INA"); - display_error_code(22); /////////////////////////////// ROUTES /////////////////////////////// - LOG(DEBUG, "Route Setup"); + LOG(ELOG_LEVEL_DEBUG, "Route Setup"); // Normal HTML stuff - server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(SPIFFS, "/status.html", "text/html", false, processor); }); + server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(LittleFS, "/status.html", "text/html", false, processor); }); - server.on("/settings", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(SPIFFS, "/settings.html", "text/html", false, processor); }); + server.on("/settings", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(LittleFS, "/settings.html", "text/html", false, processor); }); - server.on("/export", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(SPIFFS, "/data_export.html", "text/html", false); }); + server.on("/export", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(LittleFS, "/data_export.html", "text/html", false); }); - server.on("/logic.js", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(SPIFFS, "/logic.js", "application/javascript", false, processor); }); + server.on("/logic.js", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(LittleFS, "/logic.js", "application/javascript", false, processor); }); - server.on("/update", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(SPIFFS, "/update_progress.html", "text/html", false, processor); }); + server.on("/update", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(LittleFS, "/update_progress.html", "text/html", false, processor); }); // API stuff - internal server.on("/update_wifi_credentials", HTTP_POST, [](AsyncWebServerRequest* request) { @@ -106,27 +102,27 @@ void setup() // For settings SSID if (request->hasParam(ssid_key, true) && request->hasParam(wifi_password_key, true)) { - LOG(DEBUG, "Updating SSID config"); - AsyncWebParameter* ssid_param = request->getParam(ssid_key, true); - AsyncWebParameter* password_param = request->getParam(wifi_password_key, true); + LOG(ELOG_LEVEL_DEBUG, "Updating SSID config"); + const AsyncWebParameter* ssid_param = request->getParam(ssid_key, true); + const AsyncWebParameter* password_param = request->getParam(wifi_password_key, true); prefs.putString(ssid_key, ssid_param->value().c_str()); prefs.putString(wifi_password_key, password_param->value().c_str()); } else { request->send(400, "text/plain", "Missing parameters"); // TODO add proper error messages } - request->send(SPIFFS, "/settings.html", "text/html", false, processor); // TODO add proper return templating + request->send(LittleFS, "/settings.html", "text/html", false, processor); // TODO add proper return templating }); server.on("/update_sensor_settings", HTTP_POST, [](AsyncWebServerRequest* request) { int params = request->params(); if (request->hasParam(level_sensor_range_key, true) && request->hasParam(water_level_min_key, true) && request->hasParam(water_level_max_key, true) && request->hasParam(water_volume_key, true)) { - LOG(DEBUG, "Updating Sensor config"); - AsyncWebParameter* range_param = request->getParam(level_sensor_range_key, true); - AsyncWebParameter* level_min_param = request->getParam(water_level_min_key, true); - AsyncWebParameter* level_max_param = request->getParam(water_level_max_key, true); - AsyncWebParameter* liters_param = request->getParam(water_volume_key, true); + LOG(ELOG_LEVEL_DEBUG, "Updating Sensor config"); + const AsyncWebParameter* range_param = request->getParam(level_sensor_range_key, true); + const AsyncWebParameter* level_min_param = request->getParam(water_level_min_key, true); + const AsyncWebParameter* level_max_param = request->getParam(water_level_max_key, true); + const AsyncWebParameter* liters_param = request->getParam(water_volume_key, true); String range_str = range_param->value(); String level_min_str = level_min_param->value(); @@ -144,44 +140,42 @@ void setup() // Convert the C string to a float using strtod float value = strtod(paramCStr, &endPtr); - LOG(DEBUG, "range_float:%D:", range_float); + LOG(ELOG_LEVEL_DEBUG, "range_float:%D:", range_float); prefs.putFloat(level_sensor_range_key, range_float); prefs.putFloat(water_level_min_key, level_min_float); prefs.putFloat(water_level_max_key, level_max_float); prefs.putFloat(water_volume_key, liters_float); - LOG(DEBUG, "range_float_after:%D:", prefs.getFloat(level_sensor_range_key, -1.0)); + LOG(ELOG_LEVEL_DEBUG, "range_float_after:%D:", prefs.getFloat(level_sensor_range_key, -1.0)); } else { - LOG(DEBUG, "!!!! FAIL lo"); + LOG(ELOG_LEVEL_DEBUG, "!!!! FAIL lo"); for (int i = 0; i < params; i++) { - AsyncWebParameter* p = request->getParam(i); + const AsyncWebParameter* p = request->getParam(i); if (p->isFile()) { // p->isPost() is also true - LOG(DEBUG, "POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); + LOG(ELOG_LEVEL_DEBUG, "POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); } else if (p->isPost()) { - LOG(DEBUG, "POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); + LOG(ELOG_LEVEL_DEBUG, "POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); } else { - LOG(DEBUG, "GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); + LOG(ELOG_LEVEL_DEBUG, "GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); } } request->send(400, "text/plain", "Missing parameters"); // TODO add proper error messages } - request->send(SPIFFS, "/settings.html", "text/html", false); // TODO add proper return templating + request->send(LittleFS, "/settings.html", "text/html", false); // TODO add proper return templating }); setup_api_endpoints(); - display_error_code(23); - webSocket.onEvent(onWsEvent); - server.addHandler(&webSocket); + // webSocket.onEvent(onWsEvent); + // server.addHandler(&webSocket); - server.on("/chota.css", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(SPIFFS, "/chota.css", "text/css", false); }); - server.on("/gauge.js", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(SPIFFS, "/gauge.js", "application/javascript", false); }); + server.on("/chota.css", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(LittleFS, "/chota.css", "text/css", false); }); + server.on("/gauge.js", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(LittleFS, "/gauge.js", "application/javascript", false); }); - display_error_code(24); - LOG(DEBUG, "OTA Setup"); + LOG(ELOG_LEVEL_DEBUG, "OTA Setup"); ArduinoOTA .onStart([]() { String type; @@ -191,39 +185,39 @@ void setup() type = "filesystem"; // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() - LOG(DEBUG, "Start updating %s", type); }) - .onEnd([]() { LOG(DEBUG, "\nEnd"); }) + LOG(ELOG_LEVEL_DEBUG, "Start updating %s", type); }) + .onEnd([]() { LOG(ELOG_LEVEL_DEBUG, "\nEnd"); }) .onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }) .onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); - if (error == OTA_AUTH_ERROR) LOG(DEBUG, "Auth Failed"); - else if (error == OTA_BEGIN_ERROR) LOG(DEBUG, "Begin Failed"); - else if (error == OTA_CONNECT_ERROR) LOG(DEBUG, "Connect Failed"); - else if (error == OTA_RECEIVE_ERROR) LOG(DEBUG, "Receive Failed"); - else if (error == OTA_END_ERROR) LOG(DEBUG, "End Failed"); }); + if (error == OTA_AUTH_ERROR) LOG(ELOG_LEVEL_DEBUG, "Auth Failed"); + else if (error == OTA_BEGIN_ERROR) LOG(ELOG_LEVEL_DEBUG, "Begin Failed"); + else if (error == OTA_CONNECT_ERROR) LOG(ELOG_LEVEL_DEBUG, "Connect Failed"); + else if (error == OTA_RECEIVE_ERROR) LOG(ELOG_LEVEL_DEBUG, "Receive Failed"); + else if (error == OTA_END_ERROR) LOG(ELOG_LEVEL_DEBUG, "End Failed"); }); - display_error_code(26); digitalWrite(LED_RED, 0); // Starting bootup sequence xTaskCreate(ethernet_task, "EthernetTask", 4096, NULL, 1, NULL); + xTaskCreate(wifi_task, "WiFiTask", 10000, NULL, 1, NULL); + + esp_netif_t* eth = esp_netif_get_handle_from_ifkey("ETH_DEF"); + esp_netif_t* wifi = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); - // Create Etnernet task and wait a second to see if there is connection - LOG(DEBUG, "Started Ethernet, waiting"); - delay(2000); if (ETH.linkUp()){ - LOG(DEBUG, "Ethernet connected, starting update checker"); + LOG(ELOG_LEVEL_DEBUG, "Ethernet connected, starting update checker"); xTaskCreate(check_update_task, "CheckUpdateTask", 1024 * 8, NULL, 1, NULL); } else { - LOG(DEBUG, "Ethernet not connected, starting update checker and WiFi Task"); - xTaskCreate(wifi_task, "WiFiTask", 10000, NULL, 1, NULL); + LOG(ELOG_LEVEL_DEBUG, "Ethernet not connected, starting update checker and WiFi Task"); + // esp_netif_set_default_netif(esp_netif_get_handle_from_ifkey("ETH_DEF")); xTaskCreate(check_update_task, "CheckUpdateTask", 1024 * 8, NULL, 1, NULL); delay(2000); } - LOG(DEBUG, "Getting time now"); + LOG(ELOG_LEVEL_DEBUG, "Getting time now"); // Configure time to UTC configTime(0, 0, "pool.ntp.org"); @@ -245,44 +239,24 @@ void setup() // Sanity check: Ensure the year is at least 2020. int currentYear = timeinfo.tm_year + 1900; // tm_year is years since 1900 if (currentYear < 2020) { - LOG(DEBUG, "Time not set properly: "); + LOG(ELOG_LEVEL_DEBUG, "Time not set properly: "); } else { - LOG(DEBUG, "Time is valid: %s", asctime(&timeinfo)); + LOG(ELOG_LEVEL_DEBUG, "Time is valid: %s", asctime(&timeinfo)); } // Setup syslog - logger.configureSyslog("192.168.6.11", 5514, "esp32"); - logger.registerSyslog(MYLOG, DEBUG, FAC_USER, "waterlevel"); - LOG(ERROR, "Here is an error message, error code: %d", 17); + LOG(ELOG_LEVEL_ERROR, "Here is an error message, error code: %d", 17); - LOG(DEBUG, "Starting webserver"); + LOG(ELOG_LEVEL_DEBUG, "Starting webserver"); server.begin(); ArduinoOTA.begin(); - display_error_code(25); - xTaskCreate(display_task, "DisplayTask", 10000, NULL, 1, NULL); xTaskCreate(read_sensor_task, "ReadSensorTask", 1024 * 4, NULL, 1, NULL); xTaskCreate(collect_internal_telemetry_task, "InternalTelemetryTask", 2048, NULL, 1, NULL); - - // Wait until there is network connection - while (true) { - if (WiFi.status() == WL_CONNECTED || ETH.localIP()) { - int pingResult = Ping.ping("8.8.8.8"); // Use Google's public DNS server as a test IP - if (pingResult >= 0) { - LOG(DEBUG, "Network connection established"); - break; - } else { - LOG(DEBUG, "Network not ready, retrying..."); - } - } else { - LOG(DEBUG, "No WiFi or Ethernet connection, retrying..."); - } - delay(1000); // Delay to prevent rapid retry - } - + xTaskCreate(display_task, "DisplayTask", 10000, NULL, 1, NULL); } diff --git a/src/networking/networking.cpp b/src/networking/networking.cpp index 484b1d1..a461700 100644 --- a/src/networking/networking.cpp +++ b/src/networking/networking.cpp @@ -1,11 +1,20 @@ #include -#include #include #include "../global_data/defines.h" #include #include "../global_data/global_data.h" #include +#define ETH_PHY_TYPE ETH_PHY_LAN8720 +#define ETH_PHY_ADDR 0 +#define ETH_PHY_MDC 23 +#define ETH_PHY_MDIO 18 +#define ETH_PHY_POWER 14 +#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN + + +#include + int64_t mac_address = ESP.getEfuseMac(); uint8_t failed_connection_attempts = 0; @@ -13,6 +22,7 @@ extern NetworkData wifi_data; extern NetworkData ethernet_data; extern Preferences prefs; +// Defines the type of connection for which the hostname should be created enum HostnameType { Wireless, Ethernet, @@ -28,28 +38,28 @@ const char * get_hostname(HostnameType host_type) { return (hostname + "-wl").c_str(); case Ethernet: return (hostname + "-eth").c_str(); - case Generic: + default: return hostname.c_str(); } } void wifi_task(void* parameter) { - LOG(DEBUG, "Starting WiFi Task"); + LOG(ELOG_LEVEL_DEBUG, "Starting WiFi Task"); WiFi.setHostname(get_hostname(Wireless)); while (true) { if (prefs.getString(ssid_key, "") == "" || failed_connection_attempts > 5) { wifi_data.link = false; if (failed_connection_attempts > 5) { - LOG(DEBUG, "Failed to connecto to currently saved SSID, starting SoftAP"); + LOG(ELOG_LEVEL_DEBUG, "Failed to connect to currently saved SSID, starting SoftAP"); } else { - LOG(DEBUG, "No SSID saved, starting SoftAP"); + LOG(ELOG_LEVEL_DEBUG, "No SSID saved, starting SoftAP"); } String ap_ssid = get_hostname(Wireless); - WiFi.softAP(ap_ssid, ""); + WiFi.softAP(ap_ssid.c_str(), ""); - LOG(DEBUG, "[WIFI_TASK] Waiting for SSID now..."); + LOG(ELOG_LEVEL_DEBUG, "[WIFI_TASK] Waiting for SSID now..."); String old_ssid = prefs.getString(ssid_key, "xxx"); while (prefs.getString(ssid_key, "") == "" || prefs.getString(ssid_key, "") == old_ssid) { @@ -65,13 +75,14 @@ void wifi_task(void* parameter) wifi_data.network_name = WiFi.SSID(); wifi_data.ip_address = WiFi.localIP().toString(); - LOG(DEBUG, "RSSI: %F, IP Address, %p, SSID: %s", float(WiFi.RSSI()), WiFi.localIP(), prefs.getString(ssid_key, "NOSSID")); - Serial.println(WiFi.channel()); + LOG(ELOG_LEVEL_DEBUG, "RSSI: %F, IP Address, %s, SSID: %s", float(WiFi.RSSI()), WiFi.localIP().toString(), prefs.getString(ssid_key, "NOSSID")); + Serial.println(WiFi.localIP()); delay(5000); } else { - LOG(DEBUG, "Connecting to %s using password %s", prefs.getString(ssid_key, ""), prefs.getString(wifi_password_key, "")); + LOG(ELOG_LEVEL_DEBUG, "Connecting to %s using password %s", prefs.getString(ssid_key, ""), prefs.getString(wifi_password_key, "")); WiFi.mode(WIFI_STA); - WiFi.begin(prefs.getString(ssid_key, ""), prefs.getString(wifi_password_key, "")); + + WiFi.begin(prefs.getString(ssid_key, "").c_str(), prefs.getString(wifi_password_key, "").c_str()); failed_connection_attempts++; delay(5000); } @@ -81,15 +92,14 @@ void wifi_task(void* parameter) void ethernet_task(void* parameter) { - LOG(DEBUG, "Connecting Ethernet"); - ETH.begin(0, 17, 23, 18); + LOG(ELOG_LEVEL_DEBUG, "Connecting Ethernet"); + ETH.begin(); ETH.setHostname(get_hostname(Ethernet)); while (true) { ethernet_data.link = ETH.linkUp(); ethernet_data.rssi = ETH.linkSpeed(); ethernet_data.ip_address = ETH.localIP().toString(); - Serial.println( ETH.localIP().toString()); - LOG(DEBUG, "Ethernet RSSI: %F, IP Address, %s, LINK: %s", float(ethernet_data.rssi), ETH.localIP().toString().c_str(), String(ethernet_data.link)); + LOG(ELOG_LEVEL_DEBUG, "Ethernet RSSI: %F, IP Address, %s, LINK: %s", float(ethernet_data.rssi), ETH.localIP().toString(), String(ethernet_data.link)); delay(60 * 1000); } } \ No newline at end of file diff --git a/src/sensor/sensor.cpp b/src/sensor/sensor.cpp index d935c44..662a8ee 100644 --- a/src/sensor/sensor.cpp +++ b/src/sensor/sensor.cpp @@ -26,7 +26,8 @@ extern SensorData shunt_data; float zero_value = 0.03; // Measured shunt voltage with nothing connected, used to fix measuring offset void init_sensor(){ - ina_sensor.begin(33, 32); + Wire.begin(33, 32); + ina_sensor.begin(); #ifdef USE_INA226 ina_sensor.setMaxCurrentShunt(0.02, 4, false); ina_sensor.setBusVoltageConversionTime(7); @@ -47,13 +48,13 @@ void read_sensor_task(void* parameter) // Get Values from sensor #ifndef USE_INA226 String chip_id = ina_sensor.get_device_model(); - LOG(DEBUG, "Chip Model: %s", chip_id.c_str()); + LOG(ELOG_LEVEL_DEBUG, "Chip Model: %s", chip_id.c_str()); #endif float bus_voltage = ina_sensor.getBusVoltage(); float shunt_voltage = ina_sensor.getShuntVoltage_mV() - zero_value; - LOG(DEBUG, "RAW Shunt voltage: %F mV", ina_sensor.getShuntVoltage_mV()); + LOG(ELOG_LEVEL_DEBUG, "RAW Shunt voltage: %F mV", ina_sensor.getShuntVoltage_mV()); float shunt_current = shunt_voltage / RESISTOR_VALUE; @@ -73,8 +74,8 @@ void read_sensor_task(void* parameter) float min_water_level_mA = 4 + min_water_level_mA_over_zero; float max_water_level_mA = 4 + max_water_level_mA_over_zero; - LOG(DEBUG, "max_water_level_mA: %F", max_water_level_mA); - LOG(DEBUG, "min_water_level_mA_over_zero: %F", min_water_level_mA_over_zero); + LOG(ELOG_LEVEL_DEBUG, "max_water_level_mA: %F", max_water_level_mA); + LOG(ELOG_LEVEL_DEBUG, "min_water_level_mA_over_zero: %F", min_water_level_mA_over_zero); // Current over the 0 level of the water float shunt_current_over_zero = shunt_current - min_water_level_mA; @@ -94,10 +95,10 @@ void read_sensor_task(void* parameter) active_errors.current_high = shunt_current > 20.2; active_errors.voltage_low = bus_voltage < 23; active_errors.voltage_high = bus_voltage > 25; - LOG(DEBUG, "Shunt current: %F", shunt_current); - LOG(DEBUG, "Shunt voltage: %F", shunt_voltage); - LOG(DEBUG, "Bus voltage: %F", bus_voltage); - LOG(DEBUG, "cm_over_zero: %F", cm_over_zero); + LOG(ELOG_LEVEL_DEBUG, "Shunt current: %F", shunt_current); + LOG(ELOG_LEVEL_DEBUG, "Shunt voltage: %F", shunt_voltage); + LOG(ELOG_LEVEL_DEBUG, "Bus voltage: %F", bus_voltage); + LOG(ELOG_LEVEL_DEBUG, "cm_over_zero: %F", cm_over_zero); shunt_data.bus_voltage = bus_voltage; shunt_data.shunt_voltage = shunt_voltage; diff --git a/src/tools/log.h b/src/tools/log.h index 3f46fef..ea0a3f7 100644 --- a/src/tools/log.h +++ b/src/tools/log.h @@ -1,9 +1,10 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include #define LOG(LEVEL, FMT, ...) \ do { \ - logger.log(0, LEVEL, "[Core: %i][Task: %s][%s] " FMT, \ + Logger.log(0, LEVEL, "[Core: %i][Task: %s][Fn: %s]" FMT, \ xPortGetCoreID(), \ pcTaskGetName(xTaskGetCurrentTaskHandle()), \ __FUNCTION__, \ diff --git a/src/tools/tools.cpp b/src/tools/tools.cpp index 8850a44..cf021c0 100644 --- a/src/tools/tools.cpp +++ b/src/tools/tools.cpp @@ -9,7 +9,7 @@ extern Preferences prefs; extern OTAStatus ota_status; -extern AsyncWebSocket webSocket; +// extern AsyncWebSocket webSocket; extern Version current_spiffs_version; @@ -36,28 +36,28 @@ String processor(const String& var) // OTA Callbacks void update_started() { - LOG(DEBUG, "OTA Update started"); + LOG(ELOG_LEVEL_DEBUG, "OTA Update started"); ota_status.update_progress = 0; } void update_finished() { - LOG(DEBUG, "OTA Update finished"); + LOG(ELOG_LEVEL_DEBUG, "OTA Update finished"); ota_status.update_progress = -1; - webSocket.textAll(String(-1).c_str()); + // webSocket.textAll(String(-1).c_str()); } void update_progress(int cur, int total) { ota_status.update_progress = 0; if (cur != 0 ) { ota_status.update_progress = int(float(cur)/float(total)*100); - LOG(DEBUG, "OTA Update progress: %d/%d, %i", cur, total, ota_status.update_progress); + LOG(ELOG_LEVEL_DEBUG, "OTA Update progress: %d/%d, %i", cur, total, ota_status.update_progress); } - webSocket.textAll(String(ota_status.update_progress).c_str()); - LOG(DEBUG, "OTA Update progress: %d/%d", cur, total); + // webSocket.textAll(String(ota_status.update_progress).c_str()); + LOG(ELOG_LEVEL_DEBUG, "OTA Update progress: %d/%d", cur, total); } void update_error(int err) { - LOG(ERROR, "OTA Update error: %d", err); + LOG(ELOG_LEVEL_ERROR, "OTA Update error: %d", err); ota_status.update_progress = -2; } @@ -76,20 +76,20 @@ void check_update_task(void* parameter) { // If there is a SPIFSS update it will be ran automatically, as SPIFFS is necessary for the firmware to run Firmware latest_spiff_version = spiffs_fs.getLatestVersionOnServer(); - LOG(DEBUG, "Required SPIFFS Version: %d.%d.%d; Current SPIFFS version: %d.%d.%d; Server SPIFFS Version: %d.%d.%d", REQUIRED_SPIFFS_VERSION.major, REQUIRED_SPIFFS_VERSION.minor, REQUIRED_SPIFFS_VERSION.patch, current_spiffs_version.major, current_spiffs_version.minor, current_spiffs_version.patch, latest_spiff_version.version.major, latest_spiff_version.version.minor, latest_spiff_version.version.patch); + LOG(ELOG_LEVEL_DEBUG, "Required SPIFFS Version: %d.%d.%d; Current SPIFFS version: %d.%d.%d; Server SPIFFS Version: %d.%d.%d", REQUIRED_SPIFFS_VERSION.major, REQUIRED_SPIFFS_VERSION.minor, REQUIRED_SPIFFS_VERSION.patch, current_spiffs_version.major, current_spiffs_version.minor, current_spiffs_version.patch, latest_spiff_version.version.major, latest_spiff_version.version.minor, latest_spiff_version.version.patch); if (latest_spiff_version.valid) { if (isVersionNewer(current_spiffs_version, REQUIRED_SPIFFS_VERSION)) { // If Required SPIFFS version is newer than current version, update - LOG(DEBUG, "New SPIFFS version, running update now"); + LOG(ELOG_LEVEL_DEBUG, "New SPIFFS version, running update now"); run_ota_spiffs_update(latest_spiff_version.url, update_started, update_finished, update_progress, update_error); // Reboot just to be safe ESP.restart(); } else if (isVersionNewer(REQUIRED_SPIFFS_VERSION, latest_spiff_version.version)) { // If Server has new SPIFFS version but it's not required - LOG(DEBUG, "New SPIFFS version available: %d.%d.%d, current version: %d.%d.%d but not necessary to update", latest_spiff_version.version.major, latest_spiff_version.version.minor, latest_spiff_version.version.patch, REQUIRED_SPIFFS_VERSION.major, REQUIRED_SPIFFS_VERSION.minor, REQUIRED_SPIFFS_VERSION.patch); + LOG(ELOG_LEVEL_DEBUG, "New SPIFFS version available: %d.%d.%d, current version: %d.%d.%d but not necessary to update", latest_spiff_version.version.major, latest_spiff_version.version.minor, latest_spiff_version.version.patch, REQUIRED_SPIFFS_VERSION.major, REQUIRED_SPIFFS_VERSION.minor, REQUIRED_SPIFFS_VERSION.patch); } else { - LOG(DEBUG, "No new SPIFFS version available"); + LOG(ELOG_LEVEL_DEBUG, "No new SPIFFS version available"); } } @@ -97,11 +97,11 @@ void check_update_task(void* parameter) { while (true) { Firmware fw = ota.getLatestVersionOnServer(); if (fw.valid) { - LOG(DEBUG, "New firmware available: %d.%d.%d, current version: %d.%d.%d", fw.version.major, fw.version.minor, fw.version.patch, current_software_version.major, current_software_version.minor, current_software_version.patch); + LOG(ELOG_LEVEL_DEBUG, "New firmware available: %d.%d.%d, current version: %d.%d.%d", fw.version.major, fw.version.minor, fw.version.patch, current_software_version.major, current_software_version.minor, current_software_version.patch); ota_status.latest_version = fw.version; ota_status.update_url = fw.url; if (isVersionNewer(current_software_version, fw.version)) { - LOG(DEBUG, "Remote version is newer than current version"); + LOG(ELOG_LEVEL_DEBUG, "Remote version is newer than current version"); ota_status.update_available = true; } else { ota_status.update_available = false; @@ -112,7 +112,7 @@ void check_update_task(void* parameter) { ota_status.update_available = false; } - LOG(DEBUG, "No new firmware available"); + LOG(ELOG_LEVEL_DEBUG, "No new firmware available"); } delay(1000 * 60 * 1); } @@ -122,19 +122,19 @@ void check_update_task(void* parameter) { void run_ota_update_task(void* parameter) { TaskArgs_t *args = (TaskArgs_t *) parameter; - LOG(DEBUG, "Running OTA upgrade now with URL: %s", args->ota_status.update_url.c_str()); + LOG(ELOG_LEVEL_DEBUG, "Running OTA upgrade now with URL: %s", args->ota_status.update_url.c_str()); run_ota_update(args->ota_status.update_url, update_started, update_finished, update_progress, update_error); vTaskDelete(NULL); } -void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, - void *arg, uint8_t *data, size_t len) { - if (type == WS_EVT_CONNECT) { - Serial.println("WebSocket client connected"); - } else if (type == WS_EVT_DISCONNECT) { - Serial.println("WebSocket client disconnected"); - } else if (type == WS_EVT_DATA) { - // Optionally process data received from the client - } -} +// void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, +// void *arg, uint8_t *data, size_t len) { +// if (type == WS_EVT_CONNECT) { +// Serial.println("WebSocket client connected"); +// } else if (type == WS_EVT_DISCONNECT) { +// Serial.println("WebSocket client disconnected"); +// } else if (type == WS_EVT_DATA) { +// // Optionally process data received from the client +// } +// } diff --git a/src/tools/tools.h b/src/tools/tools.h index c37bd57..839a48f 100644 --- a/src/tools/tools.h +++ b/src/tools/tools.h @@ -10,7 +10,7 @@ bool is_error(ActiveErrors active_errors); String processor(const String& var); void check_update_task(void* parameter); void run_ota_update_task(void* parameter); -void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,void *arg, uint8_t *data, size_t len); +// void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,void *arg, uint8_t *data, size_t len); typedef struct { OTAStatus ota_status; diff --git a/upload.sh b/upload.sh new file mode 100755 index 0000000..3fa5574 --- /dev/null +++ b/upload.sh @@ -0,0 +1,3 @@ +pio run -t upload -e ESP32_INA226 --upload-port 192.168.6.45 +pio run -t upload -e ESP32_INA226 --upload-port 192.168.6.47 +pio run -t upload -e ESP32_INA226 --upload-port 192.168.6.49 \ No newline at end of file