diff --git a/lib/libesp32/berry_tasmota/src/embedded/partition_core.be b/lib/libesp32/berry_tasmota/src/embedded/partition_core.be index abf48e8137b8..08736292c421 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 d523d13313c0..caadd3a25e97 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 9b19600a23fc..98bfc21b98ba 100644 Binary files a/tasmota/berry/modules/Partition_Wizard.tapp and b/tasmota/berry/modules/Partition_Wizard.tapp differ diff --git a/tasmota/berry/modules/Partition_Wizard/partition_wizard.bec b/tasmota/berry/modules/Partition_Wizard/partition_wizard.bec index b5227ecd6505..786b64901bbf 100644 Binary files a/tasmota/berry/modules/Partition_Wizard/partition_wizard.bec and b/tasmota/berry/modules/Partition_Wizard/partition_wizard.bec differ diff --git a/tasmota/berry/modules/partition_wizard.be b/tasmota/berry/modules/partition_wizard.be index abda199564ba..9db98990145b 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