Skip to content
Snippets Groups Projects
Commit 0c43ed1b authored by ave's avatar ave
Browse files

updat3r: add updat3r

parent 0e970806
Branches
No related tags found
No related merge requests found
from st3m.application import Application, ApplicationContext
from st3m.input import InputState
from st3m.goose import Optional
from st3m.utils import sd_card_plugged
from ctx import Context
import sys_kernel
import urequests
from st3m.ui.view import ViewManager
import st3m.wifi
class UpdaterApp(Application):
def __init__(self, app_ctx: ApplicationContext) -> None:
super().__init__(app_ctx)
def draw(self, ctx: Context) -> None:
ctx.text_align = ctx.CENTER
ctx.text_baseline = ctx.MIDDLE
ctx.font = ctx.get_font_name(1)
ctx.rgb(0, 0, 0).rectangle(-120, -120, 240, 240).fill()
ctx.rgb(1, 1, 1)
ctx.font_size = 15
ctx.move_to(0, -90)
ctx.text("you are running")
ctx.font_size = 25
ctx.move_to(0, -70)
ctx.text(self._firmware_version)
ctx.font_size = 15
state_lines = self._state_text.split("\n")
y_offset = max(-((len(state_lines) - 1) * 15 / 2), -30)
for line in self._state_text.split("\n"):
ctx.move_to(0, y_offset)
ctx.text(line)
y_offset += 15
def version_to_number(self, version: str):
if "dev" in version:
return 0
major, minor, patch = version.split(".")
version_number = (int(major) * 1000000) + (int(major) * 1000) + int(patch)
return version_number
def on_enter(self, vm: Optional[ViewManager]):
super().on_enter(vm)
self._firmware_version = sys_kernel.firmware_version()
self._firmware_version_number = self.version_to_number(self._firmware_version)
self.fetched_version = []
self.selected_version = None
self.download_instance = None
self.filename = None
self.use_dev_version = False
st3m.wifi.setup_wifi()
self.wlan_instance = st3m.wifi.iface
print(self.wlan_instance.active(), self.wlan_instance.isconnected())
self._sd_present = sd_card_plugged()
self._sd_failed = False
if self._sd_present:
self._state_text = "getting latest version..."
else:
self._state_text = "no SD card detected!\n\nif you have one in there\nturn off and on flow3r power (ha)\nthen try to reattempt\ndownloading the update"
def on_exit(self) -> None:
super().on_exit()
def download_file(self, url: str, path: str, block_size=40960) -> None:
path_fd = None
try:
path_fd = open(path, "wb")
except OSError as e:
if "EIO" in str(e):
self._sd_failed = True
return
req = urequests.get(url)
try:
while True:
new_data = req.raw.read(block_size)
path_fd.write(new_data)
yield path_fd.tell()
if len(new_data) < block_size:
break
finally:
path_fd.close()
req.close()
def download_file_no_yield(self, url: str, path: str, block_size=10240) -> None:
req = urequests.get(url)
print("opened url")
path_fd = open(path, "wb")
print("opened file")
while True:
new_data = req.raw.read(block_size)
path_fd.write(new_data)
print(path_fd.tell())
if len(new_data) < block_size:
break
path_fd.close()
print("closed file")
req.close()
print("closed req")
def change_selected_version(self):
if self.fetched_version and self.use_dev_version:
self.selected_version = self.fetched_version[-1]
self._state_text = "latest dev build\n\npress app shoulder button\nto start downloading\n\n(tilt shoulder left to\nswitch to latest version)"
elif self.fetched_version:
self.selected_version = self.fetched_version[0]
latest_version_number = self.version_to_number(
self.selected_version["tag"].replace("v", "")
)
self._state_text = f"latest version: {self.selected_version['name']}"
if latest_version_number > self._firmware_version_number:
self._state_text += (
"\n\npress app shoulder button\nto start downloading"
)
else:
self._state_text += "\n\nyou are up to date :)"
self._state_text += "\n\n(tilt shoulder right to\nswitch to dev version)"
def think(self, ins: InputState, delta_ms: int) -> None:
super().think(ins, delta_ms)
# TODO: verify hash
# TODO: download percentage
if self.input.buttons.app.right.pressed:
self.use_dev_version = True
self.change_selected_version()
elif self.input.buttons.app.left.pressed:
self.use_dev_version = False
self.change_selected_version()
if not self._sd_present:
return
if self._sd_failed:
self._state_text = "don't panic, but...\na weird SD bug happened D:\nturn off and on flow3r power (ha)\nthen try to reattempt\ndownloading the update\n\nyou got this."
return
if not self.fetched_version and self.wlan_instance.isconnected():
req = urequests.get("https://flow3r.garden/api/releases.json")
self.fetched_version = req.json()
req.close()
self.change_selected_version()
if self.download_instance is not None:
try:
download_state = next(self.download_instance)
self._state_text = (
f"downloading...\nDON'T TURN OFF YOUR BADGE!\n\n{download_state}b"
)
except StopIteration:
self.download_instance = None
self._state_text = f'downloaded to\n{self.filename}\n\nhold right shoulder when\nbooting then pick\n"Flash Firmware Image"\nto continue'
if self.selected_version and self.input.buttons.app.middle.pressed:
self._state_text = "downloading...\nDON'T TURN OFF YOUR BADGE!\n\n"
url = ""
for partition in self.selected_version["partitions"]:
if partition["name"] == "flow3r":
url = partition["url"]
break
self.filename = f"/sd/flow3r_{self.selected_version['tag']}.bin"
self.download_instance = self.download_file(url, self.filename)
# For running with `mpremote run`:
if __name__ == "__main__":
import st3m.run
st3m.run.run_view(UpdaterApp(ApplicationContext()))
[app]
name = "Check for Updates"
menu = "Hidden"
wifi_preference = true
[entry]
class = "UpdaterApp"
[metadata]
author = "ave"
license = "LGPL-3.0-only"
url = "https://git.flow3r.garden/flow3r/flow3r-firmware"
version = 1
...@@ -214,6 +214,7 @@ def run_main() -> None: ...@@ -214,6 +214,7 @@ def run_main() -> None:
MenuItemForeground("Settings", menu_settings), MenuItemForeground("Settings", menu_settings),
MenuItemAppLaunch(BundleMetadata("/flash/sys/apps/graphics_mode")), MenuItemAppLaunch(BundleMetadata("/flash/sys/apps/graphics_mode")),
MenuItemAppLaunch(BundleMetadata("/flash/sys/apps/gr33nhouse")), MenuItemAppLaunch(BundleMetadata("/flash/sys/apps/gr33nhouse")),
MenuItemAppLaunch(BundleMetadata("/flash/sys/apps/updat3r")),
MenuItemAction("Disk Mode (Flash)", machine.disk_mode_flash), MenuItemAction("Disk Mode (Flash)", machine.disk_mode_flash),
MenuItemAction("Disk Mode (SD)", machine.disk_mode_sd), MenuItemAction("Disk Mode (SD)", machine.disk_mode_sd),
MenuItemLaunchPersistentView("About", About), MenuItemLaunchPersistentView("About", About),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment