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
This commit is contained in:
parent
5a234c16ad
commit
f8bd1a7461
8 changed files with 75 additions and 62 deletions
|
@ -4,7 +4,7 @@ WASP Internals
|
|||
System management
|
||||
-----------------
|
||||
|
||||
.. automodule:: manager
|
||||
.. automodule:: wasp
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -17,8 +17,8 @@ freeze('../..',
|
|||
'fonts/sans24.py',
|
||||
'icons.py',
|
||||
'logo.py',
|
||||
'manager.py',
|
||||
'shell.py',
|
||||
'wasp.py',
|
||||
'widgets.py',
|
||||
),
|
||||
opt=3
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
import manager, watch
|
||||
wasp = manager.Manager(watch)
|
||||
wasp.run()
|
||||
import wasp
|
||||
wasp.system.run()
|
||||
|
|
|
@ -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()
|
Loading…
Reference in a new issue