Skip to content

Commit 17fee38

Browse files
osupdate: show info about update and 'Start OS Update' before updating
1 parent 9b7b8a7 commit 17fee38

File tree

5 files changed

+103
-26
lines changed

5 files changed

+103
-26
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
0.0.3
22
=====
3-
- Move from MANIFEST.MF to MANIFEST.JSON format for apps
43
- wificonf: scan and connect to wifi in background thread so app stays responsive
5-
- appstore: improve icon download handling
4+
- appstore: add 'update' button if a new version of an app is available
5+
- appstore: add 'restore' button to restore updated built-in apps to their original built-in version
6+
- osupdate: show info about update and 'Start OS Update' before updating
7+
- Introduce MANIFEST.JSON format for apps
68

79
0.0.2
810
=====

internal_filesystem/builtin/apps/com.example.osupdate/META-INF/MANIFEST.JSON

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
"publisher": "ACME Inc",
44
"short_description": "Operating System Updater",
55
"long_description": "",
6-
"icon_url": "http://demo.lnpiggy.com:2121/apps/com.example.osupdate_0.0.1.mpk_icon_64x64.png",
7-
"download_url": "http://demo.lnpiggy.com:2121/apps/com.example.osupdate_0.0.1.mpk",
6+
"icon_url": "http://demo.lnpiggy.com:2121/apps/com.example.osupdate_0.0.2.mpk_icon_64x64.png",
7+
"download_url": "http://demo.lnpiggy.com:2121/apps/com.example.osupdate_0.0.2.mpk",
88
"fullname": "com.example.osupdate",
9-
"version": "0.0.1",
9+
"version": "0.0.2",
1010
"entrypoint": "assets/osupdate.py",
1111
"category": "osupdate"
1212
}
Lines changed: 89 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,38 @@
11
appscreen = lv.screen_active()
2+
appscreen.clean()
23

34
import lvgl as lv
45
import ota.update
56
from esp32 import Partition
67
import urequests
8+
import ujson
79
import ota.status
10+
import network
11+
import time
12+
import _thread
813

9-
ota.status.status()
10-
current = Partition(Partition.RUNNING)
11-
current
12-
next_partition = current.get_next_update()
13-
next_partition
14+
status_label=None
15+
install_button=None
1416

15-
label = lv.label(appwindow)
16-
label.set_text("OS Update: 0.00%")
17-
label.align(lv.ALIGN.CENTER, 0, -30)
18-
19-
progress_bar = lv.bar(appwindow)
20-
progress_bar.set_size(200, 20)
21-
progress_bar.align(lv.ALIGN.BOTTOM_MID, 0, -50)
22-
progress_bar.set_range(0, 100)
23-
progress_bar.set_value(0, lv.ANIM.OFF)
2417

2518
# Custom OTA update with LVGL progress
2619
def update_with_lvgl(url):
20+
global install_button, status_label
21+
install_button.add_flag(lv.obj.FLAG.HIDDEN) # or change to cancel button?
22+
status_label.set_text("Update in progress.\nNavigate away to cancel.")
23+
ota.status.status()
24+
current_partition = Partition(Partition.RUNNING)
25+
print(f"Current partition: {current_partition}")
26+
next_partition = current_partition.get_next_update()
27+
print(f"Next partition: {next_partition}")
28+
label = lv.label(appscreen)
29+
label.set_text("OS Update: 0.00%")
30+
label.align(lv.ALIGN.CENTER, 0, -30)
31+
progress_bar = lv.bar(appscreen)
32+
progress_bar.set_size(200, 20)
33+
progress_bar.align(lv.ALIGN.BOTTOM_MID, 0, -50)
34+
progress_bar.set_range(0, 100)
35+
progress_bar.set_value(0, lv.ANIM.OFF)
2736
def progress_callback(percent):
2837
print(f"OTA Update: {percent:.1f}%")
2938
label.set_text(f"OTA Update: {percent:.2f}%")
@@ -36,7 +45,8 @@ def progress_callback(percent):
3645
chunk_size = 4096
3746
i = 0
3847
print(f"Starting OTA update of size: {total_size}")
39-
while appscreen == lv.screen_active():
48+
while appscreen == lv.screen_active(): # stop if the user navigates away
49+
time.sleep_ms(100)
4050
chunk = response.raw.read(chunk_size)
4151
if not chunk:
4252
print("No chunk, breaking...")
@@ -51,9 +61,68 @@ def progress_callback(percent):
5161
if total_size:
5262
progress_callback(bytes_written / total_size * 100)
5363
response.close()
54-
next_partition.set_boot()
55-
import machine
56-
machine.reset()
64+
if bytes_written >= total_size: # if the update was completely installed
65+
next_partition.set_boot()
66+
import machine
67+
machine.reset()
68+
69+
def install_button_click(download_url):
70+
print(f"install_button_click for url {download_url}")
71+
try:
72+
_thread.stack_size(16384)
73+
_thread.start_new_thread(update_with_lvgl, (download_url,))
74+
except Exception as e:
75+
print("Could not start update_with_lvgl thread: ", e)
76+
77+
def handle_update_info(version, download_url, changelog):
78+
global install_button, status_label
79+
install_button.remove_flag(lv.obj.FLAG.HIDDEN)
80+
install_button.add_event_cb(lambda e, u=download_url: install_button_click(u), lv.EVENT.CLICKED, None)
81+
status_label.set_text(f"Installed version: {CURRENT_OS_VERSION}\nLatest version: {version}\n\nDetails:\n\n{changelog}")
82+
83+
def show_update_info():
84+
global status_label
85+
status_label.set_text("Checking for OS updates...")
86+
# URL of the JSON file
87+
url = "http://demo.lnpiggy.com:2121/osupdate.json" # Adjust if the actual JSON URL differs
88+
try:
89+
# Download the JSON
90+
response = urequests.get(url)
91+
# Check if request was successful
92+
if response.status_code == 200:
93+
# Parse JSON
94+
osupdate = ujson.loads(response.text)
95+
# Access attributes
96+
version = osupdate["version"]
97+
download_url = osupdate["download_url"]
98+
changelog = osupdate["changelog"]
99+
# Print the values
100+
print("Version:", version)
101+
print("Download URL:", download_url)
102+
print("Changelog:", changelog)
103+
handle_update_info(version, download_url, changelog)
104+
else:
105+
print("Failed to download JSON. Status code:", response.status_code)
106+
# Close response
107+
response.close()
108+
except Exception as e:
109+
print("Error:", str(e))
110+
111+
112+
install_button = lv.button(appscreen)
113+
install_button.align(lv.ALIGN.TOP_RIGHT, 0, NOTIFICATION_BAR_HEIGHT)
114+
install_button.add_flag(lv.obj.FLAG.HIDDEN) # button will be shown if there is an update available
115+
install_button.set_size(lv.SIZE_CONTENT, lv.pct(20))
116+
install_label = lv.label(install_button)
117+
install_label.set_text("Update OS")
118+
install_label.center()
119+
status_label = lv.label(appscreen)
120+
status_label.align(lv.ALIGN.TOP_LEFT,0,NOTIFICATION_BAR_HEIGHT)
121+
122+
if not network.WLAN(network.STA_IF).isconnected():
123+
status_label.set_text("Error: WiFi is not connected.")
124+
time.sleep(10)
125+
else:
126+
show_update_info()
57127

58-
# Start OTA update
59-
update_with_lvgl("http://demo.lnpiggy.com:2121/latest.bin")
128+
print("osupdate.py finished")

internal_filesystem/main.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import machine
44

55
# Constants
6-
CURRENT_VERSION = "0.0.1"
6+
CURRENT_OS_VERSION = "0.0.1"
77
TFT_HOR_RES=320
88
TFT_VER_RES=240
99
NOTIFICATION_BAR_HEIGHT=24
@@ -333,6 +333,7 @@ def execute_script(script_source, is_file, is_launcher, is_graphical):
333333
'parse_manifest': parse_manifest, # for launcher apps
334334
'restart_launcher': restart_launcher, # for appstore apps
335335
'show_launcher': show_launcher, # for apps that want to show the launcher
336+
'CURRENT_OS_VERSION': CURRENT_OS_VERSION, # for osupdate
336337
'__name__': "__main__"
337338
}
338339
print(f"Thread {thread_id}: starting script")

ota_updates/osupdate.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"version": "0.0.3",
3+
"download_url": "http://demo.lnpiggy.com:2121/osupdate_0.0.3.bin",
4+
"changelog": "- wificonf: scan and connect to wifi in background thread so app stays responsive\n- appstore: add 'update' button if a new version of an app is available\n- appstore: add 'restore' button to restore updated built-in apps to their original built-in version\n- osupdate: show info about update and 'Start OS Update' before updating\n- Introduce MANIFEST.JSON format for apps"
5+
}

0 commit comments

Comments
 (0)