From 6cec8f0a118ad5a3d4242ed5f4216664e7ae64ee Mon Sep 17 00:00:00 2001 From: Tobias Maier Date: Mon, 17 Feb 2025 21:46:20 +0100 Subject: [PATCH] First Version to be updateable over API --- lib/fetchOTA/fetchOTA.cpp | 2 +- lib/fetchOTA/fetchOTA.h | 5 ++++- src/global_data/defines.h | 2 +- src/global_data/global_data.h | 1 + src/networking/responses.cpp | 20 +++++++++++++++++++- src/tools/tools.cpp | 25 +++++++++++++++++++++++-- src/tools/tools.h | 9 ++++++++- 7 files changed, 57 insertions(+), 7 deletions(-) diff --git a/lib/fetchOTA/fetchOTA.cpp b/lib/fetchOTA/fetchOTA.cpp index 575416f..5381a80 100644 --- a/lib/fetchOTA/fetchOTA.cpp +++ b/lib/fetchOTA/fetchOTA.cpp @@ -83,7 +83,7 @@ Firmware OTA::createErrorResponse(const String& errorMsg) { }; } -void OTA::run_ota_update(String url, std::function callback_started, std::function callback_finished, std::function callback_progress, std::function callback_error) { +void run_ota_update(String url, std::function callback_started, std::function callback_finished, std::function callback_progress, std::function callback_error) { Log.verbose("Starting OTA upgrade"); HTTPUpdate httpUpdate; httpUpdate.onStart(callback_started); diff --git a/lib/fetchOTA/fetchOTA.h b/lib/fetchOTA/fetchOTA.h index 58dcb3b..5920ebf 100644 --- a/lib/fetchOTA/fetchOTA.h +++ b/lib/fetchOTA/fetchOTA.h @@ -7,6 +7,7 @@ #include #endif +#pragma once class OTA { @@ -15,7 +16,7 @@ class OTA { Firmware getLatestVersionOnServer(); bool checkForUpdate(); - void run_ota_update(String url, std::function callback_started, std::function callback_finished, std::function callback_progress, std::function callback_error); + private: bool _isHTTPS = false; @@ -25,4 +26,6 @@ class OTA { Firmware 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); + #endif \ No newline at end of file diff --git a/src/global_data/defines.h b/src/global_data/defines.h index 522e81a..b02e49c 100644 --- a/src/global_data/defines.h +++ b/src/global_data/defines.h @@ -7,6 +7,6 @@ #define water_level_min_key "water_level_min" #define water_level_max_key "water_level_max" #define water_volume_key "water_volume" -#define current_software_version Version{0, 0, 9} +#define current_software_version Version{0, 0, 11} #define RESISTOR_VALUE 4 \ No newline at end of file diff --git a/src/global_data/global_data.h b/src/global_data/global_data.h index 4201337..f3288d0 100644 --- a/src/global_data/global_data.h +++ b/src/global_data/global_data.h @@ -45,4 +45,5 @@ struct OTAStatus { Version current_version; Version latest_version; int update_progress; + String update_url; }; \ No newline at end of file diff --git a/src/networking/responses.cpp b/src/networking/responses.cpp index 59eb5c9..824418c 100644 --- a/src/networking/responses.cpp +++ b/src/networking/responses.cpp @@ -6,6 +6,7 @@ #include #include #include "json_builder.h" +#include "../tools/tools.h" extern WaterData water_data; extern DeviceTelemetry telemetry; @@ -42,5 +43,22 @@ void setup_api_endpoints(){ String output; serializeJson(build_ota_json(ota_status), output); request->send(200, "application/json", output); - }); + }); + + server.on("/run_ota_update", HTTP_GET, [](AsyncWebServerRequest* request) { + if (ota_status.update_progress > -1) { + request->send(200, "text/plain", "OTA Update already in progress"); + return; + } else if (!ota_status.update_available) { + request->send(200, "text/plain", "No update available"); + return; + } + + static TaskArgs_t args = { + .ota_status = ota_status + }; + + xTaskCreate(run_ota_update_task, "RunOTAUpdate", 1024 * 8, (void *)&args, 1, NULL); + request->send(200, "text/plain", "OTA Update started"); + }); } \ No newline at end of file diff --git a/src/tools/tools.cpp b/src/tools/tools.cpp index cc8907c..446f5c7 100644 --- a/src/tools/tools.cpp +++ b/src/tools/tools.cpp @@ -53,7 +53,11 @@ void update_finished() { } void update_progress(int cur, int total) { - ota_status.update_progress = total/cur; + ota_status.update_progress = 0; + if (cur != 0 ) { + ota_status.update_progress = total/cur; + } + Log.verbose("OTA Update progress: %d/%d", cur, total); } @@ -63,6 +67,8 @@ void update_error(int err) { } void check_update_task(void* parameter) { + ota_status.current_version = current_software_version; + ota_status.update_progress = -1; #ifdef USE_INA226 OTA ota("https://iot.tobiasmaier.me/firmware/waterlevel", current_software_version, "INA226"); #else @@ -71,12 +77,27 @@ void check_update_task(void* parameter) { while (true) { Firmware fw = ota.getLatestVersionOnServer(); if (fw.valid) { - Log.verbose("New firmware available: %d.%d.%d, current versio: %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.verbose("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.update_available = true; ota_status.latest_version = fw.version; + ota_status.update_url = fw.url; } else { + if (fw.version.major != 0 && fw.version.minor != 0 && fw.version.patch != 0) { + ota_status.latest_version = fw.version; + ota_status.update_available = false; + } + Log.verbose("No new firmware available"); } delay(1000 * 60 * 1); } +} + + + +void run_ota_update_task(void* parameter) { + TaskArgs_t *args = (TaskArgs_t *) parameter; + Log.verbose("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); } \ No newline at end of file diff --git a/src/tools/tools.h b/src/tools/tools.h index abfdfd4..7956d3d 100644 --- a/src/tools/tools.h +++ b/src/tools/tools.h @@ -1,8 +1,15 @@ #include #include "../global_data/global_data.h" +#include void printSuffix(Print* _logOutput, int logLevel); void print_prefix(Print* _logOutput, int logLevel); bool is_error(ActiveErrors active_errors); String processor(const String& var); -void check_update_task(void* parameter); \ No newline at end of file +void check_update_task(void* parameter); +void run_ota_update_task(void* parameter); + + +typedef struct { + OTAStatus ota_status; +} TaskArgs_t; \ No newline at end of file