diff --git a/platformio.ini b/platformio.ini index 9d2fcb9..82fb428 100644 --- a/platformio.ini +++ b/platformio.ini @@ -21,11 +21,11 @@ board = d1_mini build_unflags = build_flags = #-O0 -Wl,-Map,output.map -D BAUD=${common_env_data.monitor_speed} - #-D ACTIVATE_OTA # TODO: Download html files to FS to reduce image size + -D ACTIVATE_OTA -D ACTIVATE_PUSH #-D SKIP_SLEEPMODE -D USE_LITTLEFS=true - -D EMBED_HTML + #-D EMBED_HTML -D CFG_APPVER="\"0.2.0\"" lib_deps = # https://github.com/jrowberg/i2cdevlib.git # Using local copy of this library @@ -43,7 +43,9 @@ upload_speed = ${common_env_data.upload_speed} monitor_speed = ${common_env_data.monitor_speed} framework = ${common_env_data.framework} platform = ${common_env_data.platform} -extra_scripts = script/copy_firmware.py +extra_scripts = + script/copy_firmware.py + script/create_versionjson.py build_unflags = ${common_env_data.build_unflags} build_flags = ${common_env_data.build_flags} @@ -59,7 +61,9 @@ upload_speed = ${common_env_data.upload_speed} monitor_speed = ${common_env_data.monitor_speed} framework = ${common_env_data.framework} platform = ${common_env_data.platform} -extra_scripts = script/copy_firmware.py +extra_scripts = + script/copy_firmware.py + script/create_versionjson.py build_unflags = ${common_env_data.build_unflags} build_flags = ${common_env_data.build_flags} diff --git a/script/copy_firmware.py b/script/copy_firmware.py index f6b162d..e49fc99 100644 --- a/script/copy_firmware.py +++ b/script/copy_firmware.py @@ -19,16 +19,6 @@ def after_build(source, target, env): print( "Copy file : " + source + " -> " + target ) shutil.copyfile( source, target ) - target = dir + "\\bin\\version.json" - ver = get_build_flag_value("CFG_APPVER") - print( "Creating version.json" ) - f = open( target, "w" ) - f.write( "{ \"project\":\"gravmon\", \"version\":" + ver + " }" ) - f.close() - -print( "Adding custom build step: ") -#env.AddPreAction("buildprog", after_build) +print( "Adding custom build step (copy firmware): ") env.AddPostAction("buildprog", after_build) -#env.AddPreAction("upload", after_build) -#env.AddPostAction("upload", after_build) diff --git a/script/create_versionjson.py b/script/create_versionjson.py new file mode 100644 index 0000000..183ad1d --- /dev/null +++ b/script/create_versionjson.py @@ -0,0 +1,50 @@ +Import("env", "projenv") +import shutil + +def get_build_flag_value(flag_name): + build_flags = env.ParseFlags(env['BUILD_FLAGS']) + flags_with_value_list = [build_flag for build_flag in build_flags.get('CPPDEFINES') if type(build_flag) == list] + defines = {k: v for (k, v) in flags_with_value_list} + return defines.get(flag_name) + +def after_build(source, target, env): + print( "Executing custom step " ) + dir = env.GetLaunchDir() + #name = env.get( "PIOENV" ) + + # Copy file 1 + source = dir + "\\data\\index.min.htm" + target = dir + "\\bin\\index.min.htm" + print( "Copy file : " + source + " -> " + target ) + shutil.copyfile( source, target ) + + # Copy file 2 + source = dir + "\\data\\device.min.htm" + target = dir + "\\bin\\device.min.htm" + print( "Copy file : " + source + " -> " + target ) + shutil.copyfile( source, target ) + + # Copy file 3 + source = dir + "\\data\\config.min.htm" + target = dir + "\\bin\\config.min.htm" + print( "Copy file : " + source + " -> " + target ) + shutil.copyfile( source, target ) + + # Copy file 4 + source = dir + "\\data\\about.min.htm" + target = dir + "\\bin\\about.min.htm" + print( "Copy file : " + source + " -> " + target ) + shutil.copyfile( source, target ) + + target = dir + "\\bin\\version.json" + ver = get_build_flag_value("CFG_APPVER") + + print( "Creating version.json" ) + f = open( target, "w" ) + f.write( "{ \"project\":\"gravmon\", \"version\":" + ver + ", " ) + f.write( " \"html\": [ \"index.min.htm\", \"device.min.htm\", \"config.min.htm\", \"about.min.htm\" ] }" ) + f.close() + + +print( "Adding custom build step: (create json)") +env.AddPreAction("buildprog", after_build) diff --git a/src/main.cpp b/src/main.cpp index 9945ef1..e32dfb4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -132,16 +132,15 @@ void setup() { if( myWifi.isConnected() ) { Log.notice(F("Main: Connected to wifi ip=%s." CR), myWifi.getIPAddress().c_str() ); +#if defined( ACTIVATE_OTA ) + if( !sleepModeActive && myWifi.checkFirmwareVersion() ) { + myWifi.updateFirmware(); + } +#endif if( !sleepModeActive ) if( myWebServer.setupWebServer() ) Log.notice(F("Main: Webserver is running." CR) ); } - -#if defined( ACTIVATE_OTA ) - if( !sleepModeActive && myWifi.isConnected() && myWifi.checkFirmwareVersion() ) { - myWifi.updateFirmware(); - } -#endif } // diff --git a/src/wifi.cpp b/src/wifi.cpp index a707cb6..cc2a889 100644 --- a/src/wifi.cpp +++ b/src/wifi.cpp @@ -29,7 +29,6 @@ SOFTWARE. #include "tempsensor.h" #include #include -#include #include #include #include @@ -39,7 +38,6 @@ Wifi myWifi; WiFiManager myWifiManager; // TODO: ADD MDNS setting to WIFI portal..... -// TODO: Download html files during OTA update to reduce image size. // // Connect to last known access point or create one if connection is not working. @@ -112,6 +110,33 @@ bool Wifi::updateFirmware() { return false; } +// +// Download and save file +// +void Wifi::downloadFile(const char *fname) { +#if LOG_LEVEL==6 + Log.verbose(F("WIFI: Download file %s." CR), fname); +#endif + WiFiClient client; + HTTPClient http; + String serverPath = myConfig.getOtaURL(); + serverPath += fname; + + // Your Domain name with URL path or IP address with path + http.begin( client, serverPath); + int httpResponseCode = http.GET(); + + if (httpResponseCode==200) { + File f = LittleFS.open( fname, "w" ); + http.writeToStream( &f ); + f.close(); + Log.notice(F("WIFI: Downloaded file %s." CR), fname); + } else { + Log.error(F("WIFI: HTTP Response code %d" CR), httpResponseCode); + } + http.end(); +} + // // Check what firmware version is available over OTA // @@ -137,13 +162,13 @@ bool Wifi::checkFirmwareVersion() { #if LOG_LEVEL==6 Log.verbose(F("WIFI: Payload %s." CR), payload.c_str()); #endif - DynamicJsonDocument ver(256); + DynamicJsonDocument ver(300); DeserializationError err = deserializeJson(ver, payload); if( err ) { - Log.error(F("WIFI: Failed to parse json" CR)); + Log.error(F("WIFI: Failed to parse json, %s" CR), err); } else { #if LOG_LEVEL==6 - Log.verbose(F("WIFI: Project %s version %s." CR), ver["project"].as(), ver["version"].as()); + Log.verbose(F("WIFI: Project %s version %s." CR), (const char*) ver["project"], (const char*) ver["version"]); #endif int newVer[3]; int curVer[3]; @@ -164,6 +189,19 @@ bool Wifi::checkFirmwareVersion() { newFirmware = true; } } + + // Download new html files to filesystem if they are present. + if( !ver["html"].isNull() && newFirmware ) { + Log.notice(F("OTA : Downloading new html files." CR)); + htmlFiles = ver["html"].as(); + for(JsonVariant v : htmlFiles) { + String s = v; +#if LOG_LEVEL==6 + Log.verbose(F("OTA : Html file found %s" CR), s.c_str() ); +#endif + downloadFile( s.c_str() ); + } + } } } else { Log.error(F("WIFI: HTTP Response code %d" CR), httpResponseCode); @@ -189,8 +227,6 @@ bool Wifi::parseFirmwareVersionString( int (&num)[3], const char *version ) { strcpy( &temp[0], version ); - // TODO: Do some error checking on the string, lenght etc. - while ((s = strtok_r(p, ".", &p)) != NULL) { num[i++] = atoi( s ); } diff --git a/src/wifi.h b/src/wifi.h index e5cca0a..c2c22ab 100644 --- a/src/wifi.h +++ b/src/wifi.h @@ -26,16 +26,19 @@ SOFTWARE. // Include #include +#include // classes class Wifi { private: // WIFI - bool connectedFlag = false; + bool connectedFlag = false; + JsonArray htmlFiles; // OTA bool newFirmware = false; bool parseFirmwareVersionString( int (&num)[3], const char *version ); + void downloadFile(const char *fname); public: // WIFI