From f8bd1a74613a79cad56b5b60079402d40a87d131 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Sun, 22 Mar 2020 12:37:19 +0000 Subject: [PATCH] Rename manager.py and expose its interfaces to all applications This is a big change that break compatiblity with existing applications *and* with existing installed versions of main.py. When upgrading it is import to update main.py: ./tools/wasptool --upload wasp/main.py --- docs/wasp.rst | 2 +- tools/wasptool | 15 +++++++- wasp/apps/clock.py | 21 +++++------ wasp/apps/flashlight.py | 9 ++--- wasp/apps/testapp.py | 18 ++++----- wasp/boards/pinetime/manifest.py | 2 +- wasp/main.py | 5 +-- wasp/{manager.py => wasp.py} | 65 ++++++++++++++++++-------------- 8 files changed, 75 insertions(+), 62 deletions(-) rename wasp/{manager.py => wasp.py} (72%) diff --git a/docs/wasp.rst b/docs/wasp.rst index 039e819..e1f5bec 100644 --- a/docs/wasp.rst +++ b/docs/wasp.rst @@ -4,7 +4,7 @@ WASP Internals System management ----------------- -.. automodule:: manager +.. automodule:: wasp :members: :undoc-members: diff --git a/tools/wasptool b/tools/wasptool index 72e88bc..e546016 100755 --- a/tools/wasptool +++ b/tools/wasptool @@ -14,6 +14,11 @@ import string import sys def sync(c): + """Stop the watch and synchronize with the command prompt. + + Sending a random print ensure the final export (of the prompt) + does not accidentally match a previously issued prompt. + """ tag = ''.join([random.choice(string.ascii_uppercase) for i in range(6)]) c.send('\x03') @@ -23,8 +28,14 @@ def sync(c): c.expect('>>> ') def unsync(c): - # Set the watch running again - c.sendline('wasp.run()') + """Set the watch running again. + + There must be an expect (or a sleep) since if we kill the subordinate + process too early then the sendline will not have completed. + """ + c.sendline('wasp.system.run()') + c.expect('Watch is running, use Ctrl-C to stop') + c.send('\x18') def paste(c, f, verbose=False): docstring = False diff --git a/wasp/apps/clock.py b/wasp/apps/clock.py index f99091a..55295aa 100644 --- a/wasp/apps/clock.py +++ b/wasp/apps/clock.py @@ -1,7 +1,6 @@ +import wasp + import fonts.clock as digits -import watch -import widgets -import manager DIGITS = ( digits.clock_0, @@ -18,28 +17,28 @@ DIGITS = ( MONTH = 'JanFebMarAprMayJunJulAugSepOctNovDec' -class ClockApp(object): +class ClockApp(): """Simple digital clock application. Shows a time (as HH:MM) together with a battery meter and the date. """ def __init__(self): - self.meter = widgets.BatteryMeter() + self.meter = wasp.widgets.BatteryMeter() def handle_event(self, event_view): """Process events that the app is subscribed to.""" - if event_view[0] == manager.EVENT_TICK: + if event_view[0] == wasp.EVENT_TICK: self.update() else: # TODO: Raise an unexpected event exception pass - def foreground(self, manager, effect=None): + def foreground(self, effect=None): """Activate the application.""" self.on_screen = ( -1, -1, -1, -1, -1, -1 ) self.draw(effect) - manager.request_tick(1000) + wasp.system.request_tick(1000) def tick(self, ticks): self.update() @@ -56,7 +55,7 @@ class ClockApp(object): def draw(self, effect=None): """Redraw the display from scratch.""" - draw = watch.drawable + draw = wasp.watch.drawable draw.fill() draw.rleblit(digits.clock_colon, pos=(2*48, 80), fg=0xb5b6) @@ -70,14 +69,14 @@ class ClockApp(object): The updates are a lazy as possible and rely on an prior call to draw() to ensure the screen is suitably prepared. """ - now = watch.rtc.get_localtime() + now = wasp.watch.rtc.get_localtime() if now[3] == self.on_screen[3] and now[4] == self.on_screen[4]: if now[5] != self.on_screen[5]: self.meter.update() self.on_screen = now return False - draw = watch.drawable + draw = wasp.watch.drawable draw.rleblit(DIGITS[now[4] % 10], pos=(4*48, 80)) draw.rleblit(DIGITS[now[4] // 10], pos=(3*48, 80), fg=0xbdb6) draw.rleblit(DIGITS[now[3] % 10], pos=(1*48, 80)) diff --git a/wasp/apps/flashlight.py b/wasp/apps/flashlight.py index f1f9418..13341b0 100644 --- a/wasp/apps/flashlight.py +++ b/wasp/apps/flashlight.py @@ -1,5 +1,4 @@ -import watch -import manager +import wasp class FlashlightApp(object): """Trivial flashlight application. @@ -10,11 +9,11 @@ class FlashlightApp(object): def __init__(self): self.backlight = None - def foreground(self, manager, effect=None): + def foreground(self, effect=None): """Activate the application.""" self.on_screen = ( -1, -1, -1, -1, -1, -1 ) self.draw(effect) - manager.request_tick(1000) + wasp.system.request_tick(1000) def background(self): """De-activate the application (without losing state).""" @@ -28,5 +27,5 @@ class FlashlightApp(object): def draw(self, effect=None): """Redraw the display from scratch.""" - display = watch.display + display = wasp.watch.display display.fill(0xffff) diff --git a/wasp/apps/testapp.py b/wasp/apps/testapp.py index 0ab33a3..fc32ea0 100644 --- a/wasp/apps/testapp.py +++ b/wasp/apps/testapp.py @@ -1,7 +1,5 @@ -import watch -import widgets -import manager import machine +import wasp class TestApp(): """Simple test application. @@ -11,11 +9,11 @@ class TestApp(): self.tests = ('Touch', 'String') self.test = self.tests[0] - def foreground(self, system, effect=None): + def foreground(self, effect=None): """Activate the application.""" self.on_screen = ( -1, -1, -1, -1, -1, -1 ) self.draw(effect) - system.request_event(manager.EVENT_TOUCH | manager.EVENT_SWIPE_UPDOWN) + wasp.system.request_event(wasp.EVENT_TOUCH | wasp.EVENT_SWIPE_UPDOWN) def background(self): """De-activate the application (without losing state).""" @@ -33,7 +31,7 @@ class TestApp(): self.draw() def touch(self, event): - draw = watch.drawable + draw = wasp.watch.drawable if self.test == 'Touch': draw.string('({}, {})'.format(event[1], event[2]), 0, 108, width=240) @@ -55,8 +53,8 @@ class TestApp(): def draw(self, effect=None): """Redraw the display from scratch.""" - watch.display.mute(True) - watch.drawable.fill() - watch.drawable.string('{} test'.format(self.test), + wasp.watch.display.mute(True) + wasp.watch.drawable.fill() + wasp.watch.drawable.string('{} test'.format(self.test), 0, 6, width=240) - watch.display.mute(False) + wasp.watch.display.mute(False) diff --git a/wasp/boards/pinetime/manifest.py b/wasp/boards/pinetime/manifest.py index 6a19c1a..cdf2e15 100644 --- a/wasp/boards/pinetime/manifest.py +++ b/wasp/boards/pinetime/manifest.py @@ -17,8 +17,8 @@ freeze('../..', 'fonts/sans24.py', 'icons.py', 'logo.py', - 'manager.py', 'shell.py', + 'wasp.py', 'widgets.py', ), opt=3 diff --git a/wasp/main.py b/wasp/main.py index cc4c8b6..4f1de10 100644 --- a/wasp/main.py +++ b/wasp/main.py @@ -1,3 +1,2 @@ -import manager, watch -wasp = manager.Manager(watch) -wasp.run() +import wasp +wasp.system.run() diff --git a/wasp/manager.py b/wasp/wasp.py similarity index 72% rename from wasp/manager.py rename to wasp/wasp.py index 055b7d1..81a8589 100644 --- a/wasp/manager.py +++ b/wasp/wasp.py @@ -1,5 +1,7 @@ import gc import machine +import watch +import widgets from apps.clock import ClockApp from apps.flashlight import FlashlightApp @@ -16,9 +18,7 @@ EVENT_SWIPE_UPDOWN = 0x0004 EVENT_BUTTON = 0x0008 class Manager(object): - def __init__(self, watch): - self.watch = watch - + def __init__(self): self.app = None self.applications = [ @@ -26,17 +26,17 @@ class Manager(object): FlashlightApp(), TestApp() ] - - self.watch.display.poweron() - self.switch(self.applications[0]) - self.watch.backlight.set(2) - - self.sleep_at = watch.rtc.uptime + 90 self.charging = True def switch(self, app): if self.app: self.app.background() + else: + # System start up... + watch.display.poweron() + watch.display.mute(True) + watch.backlight.set(2) + self.sleep_at = watch.rtc.uptime + 90 # Clear out any configuration from the old application self.event_mask = 0 @@ -44,9 +44,9 @@ class Manager(object): self.tick_expiry = None self.app = app - self.watch.display.mute(True) - app.foreground(self) - self.watch.display.mute(False) + watch.display.mute(True) + app.foreground() + watch.display.mute(False) def navigate(self, direction=None): """Navigate between different applications. @@ -76,10 +76,10 @@ class Manager(object): tick intervals are not possible. """ self.tick_period_ms = period_ms - self.tick_expiry = self.watch.rtc.get_uptime_ms() + period_ms + self.tick_expiry = watch.rtc.get_uptime_ms() + period_ms def handle_event(self, event): - self.sleep_at = self.watch.rtc.uptime + 15 + self.sleep_at = watch.rtc.uptime + 15 event_mask = self.event_mask if event[0] < 5: @@ -94,7 +94,7 @@ class Manager(object): self.app.touch(event) def tick(self): - rtc = self.watch.rtc + rtc = watch.rtc if self.sleep_at: if rtc.update() and self.tick_expiry: @@ -107,36 +107,36 @@ class Manager(object): ticks += 1 self.app.tick(ticks) - if self.watch.button.value(): - self.sleep_at = self.watch.rtc.uptime + 15 + if watch.button.value(): + self.sleep_at = watch.rtc.uptime + 15 - event = self.watch.touch.get_event() + event = watch.touch.get_event() if event: self.handle_event(event) - if self.watch.rtc.uptime > self.sleep_at: - self.watch.backlight.set(0) + if watch.rtc.uptime > self.sleep_at: + watch.backlight.set(0) if not self.app.sleep(): self.switch(self.applications[0]) self.app.sleep() - self.watch.display.poweroff() - self.charging = self.watch.battery.charging() + watch.display.poweroff() + self.charging = watch.battery.charging() self.sleep_at = None gc.collect() else: - self.watch.rtc.update() + watch.rtc.update() - charging = self.watch.battery.charging() - if self.watch.button.value() or self.charging != charging: - self.watch.display.poweron() + charging = watch.battery.charging() + if watch.button.value() or self.charging != charging: + watch.display.poweron() self.app.wake() - self.watch.backlight.set(2) + watch.backlight.set(2) # Discard any pending touch events - _ = self.watch.touch.get_event() + _ = watch.touch.get_event() - self.sleep_at = self.watch.rtc.uptime + 15 + self.sleep_at = watch.rtc.uptime + 15 def run(self): """Run the system manager synchronously. @@ -145,6 +145,13 @@ class Manager(object): normal execution context meaning any exceptions and other problems can be observed interactively via the console. """ + if not self.app: + self.switch(self.applications[0]) + + print('Watch is running, use Ctrl-C to stop') + while True: self.tick() machine.deepsleep() + +system = Manager()