From f56307e321183e9cce48b602f15f002de8c7316f Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Thu, 6 Jul 2023 20:59:50 +0200 Subject: [PATCH] Fix to Partition_Wizard for shelly (#19056) --- .../src/embedded/partition_core.be | 4 +- .../src/solidify/solidified_partition_core.h | 101 ++++++----- tasmota/berry/modules/Partition_Wizard.tapp | Bin 15541 -> 17544 bytes .../Partition_Wizard/partition_wizard.bec | Bin 15098 -> 17101 bytes tasmota/berry/modules/partition_wizard.be | 170 +++++++++++++----- 5 files changed, 181 insertions(+), 94 deletions(-) diff --git a/lib/libesp32/berry_tasmota/src/embedded/partition_core.be b/lib/libesp32/berry_tasmota/src/embedded/partition_core.be index abf48e813..08736292c 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/partition_core.be +++ b/lib/libesp32/berry_tasmota/src/embedded/partition_core.be @@ -300,8 +300,8 @@ class Partition_otadata #- load otadata from SPI Flash -# def load() import flash - var otadata0 = flash.read(0xE000, 32) - var otadata1 = flash.read(0xF000, 32) + var otadata0 = flash.read(self.offset, 32) + var otadata1 = flash.read(self.offset + 0x1000, 32) self.seq0 = otadata0.get(0, 4) #- ota_seq for block 1 -# self.seq1 = otadata1.get(0, 4) #- ota_seq for block 2 -# var valid0 = otadata0.get(28, 4) == self.crc32_ota_seq(self.seq0) #- is CRC32 valid? -# diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_partition_core.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_partition_core.h index d523d1331..caadd3a25 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_partition_core.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_partition_core.h @@ -248,65 +248,68 @@ be_local_closure(Partition_otadata_load, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ + ( &(const bvalue[ 9]) { /* constants */ /* K0 */ be_nested_str(flash), /* K1 */ be_nested_str(read), - /* K2 */ be_nested_str(seq0), - /* K3 */ be_nested_str(get), - /* K4 */ be_const_int(0), - /* K5 */ be_nested_str(seq1), - /* K6 */ be_nested_str(crc32_ota_seq), - /* K7 */ be_nested_str(_validate), + /* K2 */ be_nested_str(offset), + /* K3 */ be_nested_str(seq0), + /* K4 */ be_nested_str(get), + /* K5 */ be_const_int(0), + /* K6 */ be_nested_str(seq1), + /* K7 */ be_nested_str(crc32_ota_seq), + /* K8 */ be_nested_str(_validate), }), &be_const_str_load, &be_const_str_solidified, - ( &(const binstruction[46]) { /* code */ + ( &(const binstruction[48]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x5412DFFF, // 0002 LDINT R4 57344 + 0x88100102, // 0002 GETMBR R4 R0 K2 0x5416001F, // 0003 LDINT R5 32 0x7C080600, // 0004 CALL R2 3 0x8C0C0301, // 0005 GETMET R3 R1 K1 - 0x5416EFFF, // 0006 LDINT R5 61440 - 0x541A001F, // 0007 LDINT R6 32 - 0x7C0C0600, // 0008 CALL R3 3 - 0x8C100503, // 0009 GETMET R4 R2 K3 - 0x58180004, // 000A LDCONST R6 K4 - 0x541E0003, // 000B LDINT R7 4 - 0x7C100600, // 000C CALL R4 3 - 0x90020404, // 000D SETMBR R0 K2 R4 - 0x8C100703, // 000E GETMET R4 R3 K3 - 0x58180004, // 000F LDCONST R6 K4 - 0x541E0003, // 0010 LDINT R7 4 - 0x7C100600, // 0011 CALL R4 3 - 0x90020A04, // 0012 SETMBR R0 K5 R4 - 0x8C100503, // 0013 GETMET R4 R2 K3 - 0x541A001B, // 0014 LDINT R6 28 - 0x541E0003, // 0015 LDINT R7 4 - 0x7C100600, // 0016 CALL R4 3 - 0x8C140106, // 0017 GETMET R5 R0 K6 - 0x881C0102, // 0018 GETMBR R7 R0 K2 - 0x7C140400, // 0019 CALL R5 2 - 0x1C100805, // 001A EQ R4 R4 R5 - 0x8C140703, // 001B GETMET R5 R3 K3 - 0x541E001B, // 001C LDINT R7 28 - 0x54220003, // 001D LDINT R8 4 - 0x7C140600, // 001E CALL R5 3 - 0x8C180106, // 001F GETMET R6 R0 K6 - 0x88200105, // 0020 GETMBR R8 R0 K5 - 0x7C180400, // 0021 CALL R6 2 - 0x1C140A06, // 0022 EQ R5 R5 R6 - 0x5C180800, // 0023 MOVE R6 R4 - 0x741A0001, // 0024 JMPT R6 #0027 - 0x4C180000, // 0025 LDNIL R6 - 0x90020406, // 0026 SETMBR R0 K2 R6 - 0x5C180A00, // 0027 MOVE R6 R5 - 0x741A0001, // 0028 JMPT R6 #002B - 0x4C180000, // 0029 LDNIL R6 - 0x90020A06, // 002A SETMBR R0 K5 R6 - 0x8C180107, // 002B GETMET R6 R0 K7 - 0x7C180200, // 002C CALL R6 1 - 0x80000000, // 002D RET 0 + 0x88140102, // 0006 GETMBR R5 R0 K2 + 0x541A0FFF, // 0007 LDINT R6 4096 + 0x00140A06, // 0008 ADD R5 R5 R6 + 0x541A001F, // 0009 LDINT R6 32 + 0x7C0C0600, // 000A CALL R3 3 + 0x8C100504, // 000B GETMET R4 R2 K4 + 0x58180005, // 000C LDCONST R6 K5 + 0x541E0003, // 000D LDINT R7 4 + 0x7C100600, // 000E CALL R4 3 + 0x90020604, // 000F SETMBR R0 K3 R4 + 0x8C100704, // 0010 GETMET R4 R3 K4 + 0x58180005, // 0011 LDCONST R6 K5 + 0x541E0003, // 0012 LDINT R7 4 + 0x7C100600, // 0013 CALL R4 3 + 0x90020C04, // 0014 SETMBR R0 K6 R4 + 0x8C100504, // 0015 GETMET R4 R2 K4 + 0x541A001B, // 0016 LDINT R6 28 + 0x541E0003, // 0017 LDINT R7 4 + 0x7C100600, // 0018 CALL R4 3 + 0x8C140107, // 0019 GETMET R5 R0 K7 + 0x881C0103, // 001A GETMBR R7 R0 K3 + 0x7C140400, // 001B CALL R5 2 + 0x1C100805, // 001C EQ R4 R4 R5 + 0x8C140704, // 001D GETMET R5 R3 K4 + 0x541E001B, // 001E LDINT R7 28 + 0x54220003, // 001F LDINT R8 4 + 0x7C140600, // 0020 CALL R5 3 + 0x8C180107, // 0021 GETMET R6 R0 K7 + 0x88200106, // 0022 GETMBR R8 R0 K6 + 0x7C180400, // 0023 CALL R6 2 + 0x1C140A06, // 0024 EQ R5 R5 R6 + 0x5C180800, // 0025 MOVE R6 R4 + 0x741A0001, // 0026 JMPT R6 #0029 + 0x4C180000, // 0027 LDNIL R6 + 0x90020606, // 0028 SETMBR R0 K3 R6 + 0x5C180A00, // 0029 MOVE R6 R5 + 0x741A0001, // 002A JMPT R6 #002D + 0x4C180000, // 002B LDNIL R6 + 0x90020C06, // 002C SETMBR R0 K6 R6 + 0x8C180108, // 002D GETMET R6 R0 K8 + 0x7C180200, // 002E CALL R6 1 + 0x80000000, // 002F RET 0 }) ) ); diff --git a/tasmota/berry/modules/Partition_Wizard.tapp b/tasmota/berry/modules/Partition_Wizard.tapp index 9b19600a23fc3433305003ab8c9379ed8331873a..98bfc21b98ba0a2f175f3df902054f3f209d9854 100644 GIT binary patch delta 7854 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 SW&Wu-dh@!ky!UBH(fm|^r7%=LV8nMN8FTP+Y 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 E0ghrA{Qv*} diff --git a/tasmota/berry/modules/Partition_Wizard/partition_wizard.bec b/tasmota/berry/modules/Partition_Wizard/partition_wizard.bec index b5227ecd65055926674eeb041663a4415a1eb4dc..786b64901bbf01062b5a4d76c16a467b72ff6a90 100644 GIT binary patch literal 17101 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 delta 5630 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 OcbsQ-9*M%ezx-c?mG|NR diff --git a/tasmota/berry/modules/partition_wizard.be b/tasmota/berry/modules/partition_wizard.be index abda19956..9db989901 100644 --- a/tasmota/berry/modules/partition_wizard.be +++ b/tasmota/berry/modules/partition_wizard.be @@ -24,25 +24,49 @@ class Partition_wizard_UI if persist.find("factory_migrate") == true # remove marker to avoid bootloop if something goes wrong + tasmota.log("UPL: Resuming after step 1", 2) persist.remove("factory_migrate") persist.save() # continue the migration process 5 seconds after Wifi is connected def continue_after_5s() - tasmota.remove_rule("parwiz_5s") # first remove rule to avoid firing it again at Wifi reconnect + tasmota.remove_rule("parwiz_5s1") # first remove rule to avoid firing it again at Wifi reconnect + tasmota.remove_rule("parwiz_5s2") # first remove rule to avoid firing it again at Wifi reconnect tasmota.set_timer(5000, /-> self.do_safeboot_partitioning()) # delay by 5 s end - tasmota.add_rule("Wifi#Connected=1", continue_after_5s, "parwiz_5s") + tasmota.add_rule("Wifi#Connected=1", continue_after_5s, "parwiz_5s1") + tasmota.add_rule("Wifi#Connected==1", continue_after_5s, "parwiz_5s2") end end + # ---------------------------------------------------------------------- + # Patch partition core since we can't chang the solidified code + # ---------------------------------------------------------------------- + def patch_partition_core(p) + var otadata = p.otadata + + # patch load + import flash + var otadata0 = flash.read(otadata.offset, 32) + var otadata1 = flash.read(otadata.offset + 0x1000, 32) + otadata.seq0 = otadata0.get(0, 4) #- ota_seq for block 1 -# + otadata.seq1 = otadata1.get(0, 4) #- ota_seq for block 2 -# + var valid0 = otadata0.get(28, 4) == otadata.crc32_ota_seq(otadata.seq0) #- is CRC32 valid? -# + var valid1 = otadata1.get(28, 4) == otadata.crc32_ota_seq(otadata.seq1) #- is CRC32 valid? -# + if !valid0 otadata.seq0 = nil end + if !valid1 otadata.seq1 = nil end + + otadata._validate() + end + def default_safeboot_URL() + import string var arch_sub = tasmota.arch() if arch_sub[0..4] == "esp32" arch_sub = arch_sub[5..] # get the esp32 variant end - return format(self._default_safeboot_URL, arch_sub) + return string.format(self._default_safeboot_URL, arch_sub) end # create a method for adding a button to the main menu @@ -53,15 +77,34 @@ class Partition_wizard_UI "

") end + # ---------------------------------------------------------------------- + # Get last fs + # + # Get the last fs partition + # Return the actual slot + # ---------------------------------------------------------------------- + def get_last_fs(p) + var sz = size(p.slots) + var idx = 1 + while idx < sz + var slot = p.slots[-idx] + if slot.is_spiffs() + return slot + end + idx += 1 + end + return nil + end + #- ---------------------------------------------------------------------- -# #- Get fs unallocated size #- ---------------------------------------------------------------------- -# def get_unallocated_k(p) - var last_slot = p.slots[-1] - if last_slot.is_spiffs() + var last_fs = self.get_last_fs(p) + if last_fs != nil # verify that last slot is filesystem var flash_size_k = self.get_max_flash_size_k(p) - var partition_end_k = (last_slot.start + last_slot.sz) / 1024 # last kb used for fs + var partition_end_k = (last_fs.start + last_fs.sz) / 1024 # last kb used for fs if partition_end_k < flash_size_k return flash_size_k - partition_end_k end @@ -73,8 +116,8 @@ class Partition_wizard_UI #- Get max fs start address when expanded to maximum #- ---------------------------------------------------------------------- -# def get_max_fs_start_k(p) - var last_slot = p.slots[-1] - if last_slot.is_spiffs() # verify that last slot is filesystem + var last_fs = p.slots[-1] + if last_fs != nil # verify that last slot is filesystem # get end of previous partition slot var last_app = p.slots[-2] # round upper 64kB @@ -85,7 +128,7 @@ class Partition_wizard_UI end #- ---------------------------------------------------------------------- -# - #- Get max falsh size + #- Get max flash size # # Takes into account that the flash size written may not be accurate # and the flash chip may be larger @@ -99,15 +142,40 @@ class Partition_wizard_UI return flash_size_k end + # ---------------------------------------------------------------------- + # Remove any non wanted partion after last FS + # ---------------------------------------------------------------------- + def remove_partition_after_last_fs(p) + # remove any partition after last fs + do + var last_fs = self.get_last_fs(p) + var changed = false + if last_fs != nil + while true + var last_slot = p.slots[-1] + if !last_slot.is_spiffs() && (last_slot.type != 0) + p.slots.remove(size(p.slots) - 1) # remove last slot + changed = true + else + break + end + end + if changed p.save() end + end + end + end + #- ---------------------------------------------------------------------- -# #- Resize flash definition if needed #- ---------------------------------------------------------------------- -# def resize_max_flash_size_k(p) + self.remove_partition_after_last_fs(p) var flash_size_k = tasmota.memory()['flash'] var flash_size_real_k = tasmota.memory().find("flash_real", flash_size_k) var flash_definition_sector = self.get_flash_definition_sector(p) if (flash_size_k != flash_size_real_k) && flash_definition_sector != nil import flash + import string flash_size_k = flash_size_real_k # try to expand the flash size definition @@ -131,7 +199,7 @@ class Partition_wizard_UI var old_def = flash_def[3] flash_def[3] = (flash_def[3] & 0x0F) | flash_size_code flash.write(flash_definition_sector, flash_def) - tasmota.log(format("UPL: changing flash definition from 0x02X to 0x%02X", old_def, flash_def[3]), 3) + tasmota.log(string.format("UPL: changing flash definition from 0x02X to 0x%02X", old_def, flash_def[3]), 3) else raise "internal_error", "wrong flash size "+str(flash_size_real_m) end @@ -142,9 +210,9 @@ class Partition_wizard_UI #- Get current fs size #- ---------------------------------------------------------------------- -# def get_cur_fs_size_k(p) - var last_slot = p.slots[-1] - if last_slot.is_spiffs() # verify that last slot is filesystem - return (last_slot.sz + 1023) / 1024 + var last_fs = p.slots[-1] + if last_fs != nil + return (last_fs.sz + 1023) / 1024 end return 0 end @@ -171,13 +239,14 @@ class Partition_wizard_UI #- ---------------------------------------------------------------------- -# def show_resize_fs(p) import webserver + import string var unallocated = self.get_unallocated_k(p) # if there is unallocated space, propose only to claim it if unallocated > 0 webserver.content_send("
 Resize FS to max 

") - webserver.content_send(format("

You can expand the file system by %i KB.
Its content will be lost.

", unallocated)) + webserver.content_send(string.format("

You can expand the file system by %i KB.
Its content will be lost.

", unallocated)) webserver.content_send("
") @@ -190,7 +259,7 @@ class Partition_wizard_UI var flash_size_k = self.get_max_flash_size_k() var fs_max_size_k = flash_size_k - max_fs_start_k var current_fs_size_k = self.get_cur_fs_size_k(p) - #print(format(">>> max_fs_start_k=0x%X flash_size_k=0x%X fs_max_size_k=%i current_fs_size_k=%i", max_fs_start_k, flash_size_k, fs_max_size_k, current_fs_size_k)) + #print(string.format(">>> max_fs_start_k=0x%X flash_size_k=0x%X fs_max_size_k=%i current_fs_size_k=%i", max_fs_start_k, flash_size_k, fs_max_size_k, current_fs_size_k)) if max_fs_start_k > 0 && fs_max_size_k > 64 webserver.content_send("
 Resize FS 

") @@ -199,7 +268,7 @@ class Partition_wizard_UI webserver.content_send("") - webserver.content_send(format("", fs_max_size_k, current_fs_size_k)) + webserver.content_send(string.format("", fs_max_size_k, current_fs_size_k)) webserver.content_send("

") webserver.content_send("

") @@ -231,7 +300,7 @@ class Partition_wizard_UI def factory_migrate_eligible(p) if p.ota_max() <= 0 return false end # device does not have 2x OTA if p.get_factory_slot() != nil return false end - if !p.slots[-1].is_spiffs() return false end + if self.get_last_fs(p) == nil return false end return true # device does not have factory partition end @@ -254,11 +323,12 @@ class Partition_wizard_UI # - true if DONE # - string if ERROR, indicating the error def test_step_1(p) + import string if !self.factory_migrate_eligible(p) return "not eligible to migration" end var cur_part = p.otadata.active_otadata # -1=factory 0=ota_0 1=ota_1... if cur_part == 1 return true end - if cur_part != 0 return format("active_otadata=%i", cur_part) end # unsupported configuration + if cur_part != 0 return string.format("active_otadata=%i", cur_part) end # unsupported configuration # current partition is `app0` # get size of firmware in `app0` and check if it fits on `app1` var app0 = p.get_ota_slot(0) @@ -314,6 +384,7 @@ class Partition_wizard_UI # `app0` changed subtype to `factory` # `app1` moved to right after `factory` and resized # `app1` changed subtype to `app0` and renamed `app0` + # remove any partition past the last fs # # Returns: # - false if READY @@ -345,10 +416,11 @@ class Partition_wizard_UI static def copy_ota(from_addr, to_addr, sz) import flash + import string var size_left = sz var offset = 0 - tasmota.log(format("UPL: Copy flash from 0x%06X to 0x%06X (size: %ikB)", from_addr, to_addr, sz / 1024), 2) + tasmota.log(string.format("UPL: Copy flash from 0x%06X to 0x%06X (size: %ikB)", from_addr, to_addr, sz / 1024), 2) while size_left > 0 var b = flash.read(from_addr + offset, 4096) flash.erase(to_addr + offset, 4096) @@ -356,13 +428,14 @@ class Partition_wizard_UI size_left -= 4096 offset += 4096 if ((offset-4096) / 102400) < (offset / 102400) - tasmota.log(format("UPL: Progress %ikB", offset/1024), 3) + tasmota.log(string.format("UPL: Progress %ikB", offset/1024), 3) end end tasmota.log("UPL: done", 2) end def do_step_1(p) + import persist var step1_state = self.test_step_1(p) if step1_state == true return true end if type(step1_state) == 'string)' raise "internal_error", step1_state end @@ -377,11 +450,15 @@ class Partition_wizard_UI p.set_active(1) p.save() + persist.factory_migrate = true + persist.save() + tasmota.log("UPL: restarting on `app1`", 2) tasmota.cmd("Restart 1") end def do_step_2(p, safeboot_url) + import string if safeboot_url == nil || safeboot_url == "" safeboot_url = self.default_safeboot_URL() tasmota.log("UPL: no `safeboot` URL, defaulting to "+safeboot_url, 2) @@ -399,7 +476,7 @@ class Partition_wizard_UI var safeboot_size = cl.get_size() if safeboot_size <= 500000 raise "internal_error", "wrong safeboot size "+str(safeboot_size) end if safeboot_size > (self.app_size_min * 1024) raise "internal_error", "safeboot is too large "+str(safeboot_size / 1024)+"kB" end - tasmota.log(format("UPL: flashing `safeboot` from %s %ikB", safeboot_url, (safeboot_size / 1024) + 1), 2) + tasmota.log(string.format("UPL: flashing `safeboot` from %s %ikB", safeboot_url, (safeboot_size / 1024) + 1), 2) var app0 = p.get_ota_slot(0) if app0.start != 0x10000 raise "internal_error", "`app0` offset is not 0x10000" end cl.write_flash(app0.start) @@ -415,6 +492,9 @@ class Partition_wizard_UI if step3_state == true return true end if type(step3_state) == 'string' raise "internal_error", step3_state end + # remove any partition after last fs + self.remove_partition_after_last_fs(p) + var app0 = p.get_ota_slot(0) var app1 = p.get_ota_slot(1) if app0 == nil || app1 == nil raise "internal_error", "there are no `app0` or `app1` partitions" end @@ -479,6 +559,7 @@ class Partition_wizard_UI def show_migrate_to_factory(p) # display ota partitions import webserver + import string if !self.factory_migrate_eligible(p) return end @@ -488,20 +569,20 @@ class Partition_wizard_UI webserver.content_send("

Please see Safeboot layout documentation

") webserver.content_send("

 

") - webserver.content_send(format("

Step 1: %s

", self.display_step_state(self.test_step_1(p), "boot on `app1`"))) - webserver.content_send(format("

Step 2: %s

", self.display_step_state(self.test_step_2(p), "flash `safeboot` to `app0`"))) - webserver.content_send(format("

Step 3: %s

", self.display_step_state(self.test_step_3(p), "change partition map"))) - webserver.content_send(format("

Step 4: %s

", self.display_step_state(self.test_step_4(p), "flash final firmware"))) + webserver.content_send(string.format("

Step 1: %s

", self.display_step_state(self.test_step_1(p), "boot on `app1`"))) + webserver.content_send(string.format("

Step 2: %s

", self.display_step_state(self.test_step_2(p), "flash `safeboot` to `app0`"))) + webserver.content_send(string.format("

Step 3: %s

", self.display_step_state(self.test_step_3(p), "change partition map"))) + webserver.content_send(string.format("

Step 4: %s

", self.display_step_state(self.test_step_4(p), "flash final firmware"))) webserver.content_send("
") var ota_url = tasmota.cmd("OtaUrl").find("OtaUrl", "") - webserver.content_send(format("
OTA Url

", + webserver.content_send(string.format("
OTA Url

", ota_url)) import persist var safeboot_url = persist.find("safeboot_url", self.default_safeboot_URL()) - webserver.content_send(format("
SAFEBOOT Url (don't change)
", + webserver.content_send(string.format("
SAFEBOOT Url (don't change)
", safeboot_url)) webserver.content_send("

") @@ -515,6 +596,7 @@ class Partition_wizard_UI def show_current_partitions(p) # display ota partitions import webserver + import string var cur_part = p.otadata.active_otadata # -1=factory 0=ota_0 1=ota_1... webserver.content_send("
 Current partitions 

") @@ -531,22 +613,22 @@ class Partition_wizard_UI var usage_str = "unknown" var used = slot.get_image_size() if (used >= 0) && (used <= slot.sz) - usage_str = format("used %i%%", ((used / 1024) * 100) / (slot.sz / 1024)) + usage_str = string.format("used %i%%", ((used / 1024) * 100) / (slot.sz / 1024)) end - var title = format("%ssubtype:%s offset:0x%06X size:0x%06X", current_boot_partition ? "booted " : "", slot.subtype_to_string(), slot.start, slot.sz) + var title = string.format("%ssubtype:%s offset:0x%06X size:0x%06X", current_boot_partition ? "booted " : "", slot.subtype_to_string(), slot.start, slot.sz) var col_before = "" var col_after = "" if current_boot_partition col_before = "[" col_after = "]" end - # webserver.content_send(format("

%s [%s]: %i KB (%s)

", slot.label, slot.subtype_to_string(), slot.size / 1024, usage_str)) - webserver.content_send(format("", + # webserver.content_send(string.format("

%s [%s]: %i KB (%s)

", slot.label, slot.subtype_to_string(), slot.size / 1024, usage_str)) + webserver.content_send(string.format("", title, col_before, slot.label, col_after, slot.sz / 1024, usage_str)) elif slot.is_spiffs() # spiffs partition - var title = format("subtype:%s offset:0x%06X size:0x%06X", slot.subtype_to_string(), slot.start, slot.sz) - webserver.content_send(format("", title, slot.sz / 1024)) + var title = string.format("subtype:%s offset:0x%06X size:0x%06X", slot.subtype_to_string(), slot.start, slot.sz) + webserver.content_send(string.format("", title, slot.sz / 1024)) end end @@ -555,7 +637,7 @@ class Partition_wizard_UI var last_slot = p.slots[-1] # verify that last slot is file-system var partition_end_k = (last_slot.start + last_slot.sz) / 1024 # last kb used for fs - webserver.content_send(format("", + webserver.content_send(string.format("", partition_end_k * 1024, unallocated * 1024, unallocated)) end webserver.content_send("
%s%s%s %i KB  (%s)
%s%s%s %i KB  (%s)
fs %i KB
fs %i KB
<free>:  %i KB
<free>:  %i KB
") @@ -577,6 +659,7 @@ class Partition_wizard_UI import partition_core if !webserver.check_privileged_access() return nil end var p = partition_core.Partition() # load partition layout + self.patch_partition_core(p) webserver.content_start("Partition Wizard") #- title of the web page -# webserver.content_send_style() #- send standard Tasmota styles -# @@ -601,6 +684,7 @@ class Partition_wizard_UI ####################################################################### def page_part_ctl() import webserver + import string if !webserver.check_privileged_access() return nil end import partition_core @@ -609,6 +693,7 @@ class Partition_wizard_UI #- check that the partition is valid -# var p = partition_core.Partition() + self.patch_partition_core(p) try @@ -647,7 +732,7 @@ class Partition_wizard_UI var current_fs_size_k = self.get_cur_fs_size_k(p) var fs_target = int(webserver.arg("fs_size")) - if (fs_target < 64) || (fs_target > fs_max_size_k) raise "value_error", format("Invalid FS #%d", fs_target) end + if (fs_target < 64) || (fs_target > fs_max_size_k) raise "value_error", string.format("Invalid FS #%d", fs_target) end # apply the change # shrink last OTA App @@ -685,12 +770,12 @@ class Partition_wizard_UI raise "value_error", "Unknown command" end except .. as e, m - tasmota.log(format("BRY: Exception> '%s' - %s", e, m), 2) + tasmota.log(string.format("BRY: Exception> '%s' - %s", e, m), 2) #- display error page -# webserver.content_start("Parameter error") #- title of the web page -# webserver.content_send_style() #- send standard Tasmota styles -# - webserver.content_send(format("

Exception:
'%s'
%s

", e, m)) + webserver.content_send(string.format("

Exception:
'%s'
%s

", e, m)) # webserver.content_send("

") webserver.content_button(webserver.BUTTON_MANAGEMENT) #- button back to management page -# @@ -710,24 +795,23 @@ class Partition_wizard_UI def do_safeboot_partitioning() import webserver import partition_core + import string var p = partition_core.Partition() # load partition layout + self.patch_partition_core(p) if !self.factory_migrate_eligible(p) return true end # STEP 1 var step1_state = self.test_step_1(p) if type(step1_state) == 'string' return step1_state end if step1_state == false - import persist tasmota.log("UPL: Starting step 1", 2) try self.do_step_1(p) except .. as e, m - tasmota.log(format("UPL: error (%s) %s", e, m), 2) + tasmota.log(string.format("UPL: error (%s) %s", e, m), 2) return m end - persist.factory_migrate = true - persist.save() return false end tasmota.log("UPL: Step 1 Done", 2) @@ -742,7 +826,7 @@ class Partition_wizard_UI try self.do_step_2(p, safeboot_url) except .. as e, m - tasmota.log(format("UPL: error (%s) %s", e, m), 2) + tasmota.log(string.format("UPL: error (%s) %s", e, m), 2) return m end end @@ -756,7 +840,7 @@ class Partition_wizard_UI try self.do_step_3(p) except .. as e, m - tasmota.log(format("UPL: error (%s) %s", e, m), 2) + tasmota.log(string.format("UPL: error (%s) %s", e, m), 2) return m end end