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
|
System management
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
.. automodule:: manager
|
.. automodule:: wasp
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,11 @@ import string
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
def sync(c):
|
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)])
|
tag = ''.join([random.choice(string.ascii_uppercase) for i in range(6)])
|
||||||
|
|
||||||
c.send('\x03')
|
c.send('\x03')
|
||||||
|
@ -23,8 +28,14 @@ def sync(c):
|
||||||
c.expect('>>> ')
|
c.expect('>>> ')
|
||||||
|
|
||||||
def unsync(c):
|
def unsync(c):
|
||||||
# Set the watch running again
|
"""Set the watch running again.
|
||||||
c.sendline('wasp.run()')
|
|
||||||
|
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):
|
def paste(c, f, verbose=False):
|
||||||
docstring = False
|
docstring = False
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
|
import wasp
|
||||||
|
|
||||||
import fonts.clock as digits
|
import fonts.clock as digits
|
||||||
import watch
|
|
||||||
import widgets
|
|
||||||
import manager
|
|
||||||
|
|
||||||
DIGITS = (
|
DIGITS = (
|
||||||
digits.clock_0,
|
digits.clock_0,
|
||||||
|
@ -18,28 +17,28 @@ DIGITS = (
|
||||||
|
|
||||||
MONTH = 'JanFebMarAprMayJunJulAugSepOctNovDec'
|
MONTH = 'JanFebMarAprMayJunJulAugSepOctNovDec'
|
||||||
|
|
||||||
class ClockApp(object):
|
class ClockApp():
|
||||||
"""Simple digital clock application.
|
"""Simple digital clock application.
|
||||||
|
|
||||||
Shows a time (as HH:MM) together with a battery meter and the date.
|
Shows a time (as HH:MM) together with a battery meter and the date.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.meter = widgets.BatteryMeter()
|
self.meter = wasp.widgets.BatteryMeter()
|
||||||
|
|
||||||
def handle_event(self, event_view):
|
def handle_event(self, event_view):
|
||||||
"""Process events that the app is subscribed to."""
|
"""Process events that the app is subscribed to."""
|
||||||
if event_view[0] == manager.EVENT_TICK:
|
if event_view[0] == wasp.EVENT_TICK:
|
||||||
self.update()
|
self.update()
|
||||||
else:
|
else:
|
||||||
# TODO: Raise an unexpected event exception
|
# TODO: Raise an unexpected event exception
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def foreground(self, manager, effect=None):
|
def foreground(self, effect=None):
|
||||||
"""Activate the application."""
|
"""Activate the application."""
|
||||||
self.on_screen = ( -1, -1, -1, -1, -1, -1 )
|
self.on_screen = ( -1, -1, -1, -1, -1, -1 )
|
||||||
self.draw(effect)
|
self.draw(effect)
|
||||||
manager.request_tick(1000)
|
wasp.system.request_tick(1000)
|
||||||
|
|
||||||
def tick(self, ticks):
|
def tick(self, ticks):
|
||||||
self.update()
|
self.update()
|
||||||
|
@ -56,7 +55,7 @@ class ClockApp(object):
|
||||||
|
|
||||||
def draw(self, effect=None):
|
def draw(self, effect=None):
|
||||||
"""Redraw the display from scratch."""
|
"""Redraw the display from scratch."""
|
||||||
draw = watch.drawable
|
draw = wasp.watch.drawable
|
||||||
|
|
||||||
draw.fill()
|
draw.fill()
|
||||||
draw.rleblit(digits.clock_colon, pos=(2*48, 80), fg=0xb5b6)
|
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
|
The updates are a lazy as possible and rely on an prior call to
|
||||||
draw() to ensure the screen is suitably prepared.
|
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[3] == self.on_screen[3] and now[4] == self.on_screen[4]:
|
||||||
if now[5] != self.on_screen[5]:
|
if now[5] != self.on_screen[5]:
|
||||||
self.meter.update()
|
self.meter.update()
|
||||||
self.on_screen = now
|
self.on_screen = now
|
||||||
return False
|
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=(4*48, 80))
|
||||||
draw.rleblit(DIGITS[now[4] // 10], pos=(3*48, 80), fg=0xbdb6)
|
draw.rleblit(DIGITS[now[4] // 10], pos=(3*48, 80), fg=0xbdb6)
|
||||||
draw.rleblit(DIGITS[now[3] % 10], pos=(1*48, 80))
|
draw.rleblit(DIGITS[now[3] % 10], pos=(1*48, 80))
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import watch
|
import wasp
|
||||||
import manager
|
|
||||||
|
|
||||||
class FlashlightApp(object):
|
class FlashlightApp(object):
|
||||||
"""Trivial flashlight application.
|
"""Trivial flashlight application.
|
||||||
|
@ -10,11 +9,11 @@ class FlashlightApp(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.backlight = None
|
self.backlight = None
|
||||||
|
|
||||||
def foreground(self, manager, effect=None):
|
def foreground(self, effect=None):
|
||||||
"""Activate the application."""
|
"""Activate the application."""
|
||||||
self.on_screen = ( -1, -1, -1, -1, -1, -1 )
|
self.on_screen = ( -1, -1, -1, -1, -1, -1 )
|
||||||
self.draw(effect)
|
self.draw(effect)
|
||||||
manager.request_tick(1000)
|
wasp.system.request_tick(1000)
|
||||||
|
|
||||||
def background(self):
|
def background(self):
|
||||||
"""De-activate the application (without losing state)."""
|
"""De-activate the application (without losing state)."""
|
||||||
|
@ -28,5 +27,5 @@ class FlashlightApp(object):
|
||||||
|
|
||||||
def draw(self, effect=None):
|
def draw(self, effect=None):
|
||||||
"""Redraw the display from scratch."""
|
"""Redraw the display from scratch."""
|
||||||
display = watch.display
|
display = wasp.watch.display
|
||||||
display.fill(0xffff)
|
display.fill(0xffff)
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import watch
|
|
||||||
import widgets
|
|
||||||
import manager
|
|
||||||
import machine
|
import machine
|
||||||
|
import wasp
|
||||||
|
|
||||||
class TestApp():
|
class TestApp():
|
||||||
"""Simple test application.
|
"""Simple test application.
|
||||||
|
@ -11,11 +9,11 @@ class TestApp():
|
||||||
self.tests = ('Touch', 'String')
|
self.tests = ('Touch', 'String')
|
||||||
self.test = self.tests[0]
|
self.test = self.tests[0]
|
||||||
|
|
||||||
def foreground(self, system, effect=None):
|
def foreground(self, effect=None):
|
||||||
"""Activate the application."""
|
"""Activate the application."""
|
||||||
self.on_screen = ( -1, -1, -1, -1, -1, -1 )
|
self.on_screen = ( -1, -1, -1, -1, -1, -1 )
|
||||||
self.draw(effect)
|
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):
|
def background(self):
|
||||||
"""De-activate the application (without losing state)."""
|
"""De-activate the application (without losing state)."""
|
||||||
|
@ -33,7 +31,7 @@ class TestApp():
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
def touch(self, event):
|
def touch(self, event):
|
||||||
draw = watch.drawable
|
draw = wasp.watch.drawable
|
||||||
if self.test == 'Touch':
|
if self.test == 'Touch':
|
||||||
draw.string('({}, {})'.format(event[1], event[2]),
|
draw.string('({}, {})'.format(event[1], event[2]),
|
||||||
0, 108, width=240)
|
0, 108, width=240)
|
||||||
|
@ -55,8 +53,8 @@ class TestApp():
|
||||||
|
|
||||||
def draw(self, effect=None):
|
def draw(self, effect=None):
|
||||||
"""Redraw the display from scratch."""
|
"""Redraw the display from scratch."""
|
||||||
watch.display.mute(True)
|
wasp.watch.display.mute(True)
|
||||||
watch.drawable.fill()
|
wasp.watch.drawable.fill()
|
||||||
watch.drawable.string('{} test'.format(self.test),
|
wasp.watch.drawable.string('{} test'.format(self.test),
|
||||||
0, 6, width=240)
|
0, 6, width=240)
|
||||||
watch.display.mute(False)
|
wasp.watch.display.mute(False)
|
||||||
|
|
|
@ -17,8 +17,8 @@ freeze('../..',
|
||||||
'fonts/sans24.py',
|
'fonts/sans24.py',
|
||||||
'icons.py',
|
'icons.py',
|
||||||
'logo.py',
|
'logo.py',
|
||||||
'manager.py',
|
|
||||||
'shell.py',
|
'shell.py',
|
||||||
|
'wasp.py',
|
||||||
'widgets.py',
|
'widgets.py',
|
||||||
),
|
),
|
||||||
opt=3
|
opt=3
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
import manager, watch
|
import wasp
|
||||||
wasp = manager.Manager(watch)
|
wasp.system.run()
|
||||||
wasp.run()
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import gc
|
import gc
|
||||||
import machine
|
import machine
|
||||||
|
import watch
|
||||||
|
import widgets
|
||||||
|
|
||||||
from apps.clock import ClockApp
|
from apps.clock import ClockApp
|
||||||
from apps.flashlight import FlashlightApp
|
from apps.flashlight import FlashlightApp
|
||||||
|
@ -16,9 +18,7 @@ EVENT_SWIPE_UPDOWN = 0x0004
|
||||||
EVENT_BUTTON = 0x0008
|
EVENT_BUTTON = 0x0008
|
||||||
|
|
||||||
class Manager(object):
|
class Manager(object):
|
||||||
def __init__(self, watch):
|
def __init__(self):
|
||||||
self.watch = watch
|
|
||||||
|
|
||||||
self.app = None
|
self.app = None
|
||||||
|
|
||||||
self.applications = [
|
self.applications = [
|
||||||
|
@ -26,17 +26,17 @@ class Manager(object):
|
||||||
FlashlightApp(),
|
FlashlightApp(),
|
||||||
TestApp()
|
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
|
self.charging = True
|
||||||
|
|
||||||
def switch(self, app):
|
def switch(self, app):
|
||||||
if self.app:
|
if self.app:
|
||||||
self.app.background()
|
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
|
# Clear out any configuration from the old application
|
||||||
self.event_mask = 0
|
self.event_mask = 0
|
||||||
|
@ -44,9 +44,9 @@ class Manager(object):
|
||||||
self.tick_expiry = None
|
self.tick_expiry = None
|
||||||
|
|
||||||
self.app = app
|
self.app = app
|
||||||
self.watch.display.mute(True)
|
watch.display.mute(True)
|
||||||
app.foreground(self)
|
app.foreground()
|
||||||
self.watch.display.mute(False)
|
watch.display.mute(False)
|
||||||
|
|
||||||
def navigate(self, direction=None):
|
def navigate(self, direction=None):
|
||||||
"""Navigate between different applications.
|
"""Navigate between different applications.
|
||||||
|
@ -76,10 +76,10 @@ class Manager(object):
|
||||||
tick intervals are not possible.
|
tick intervals are not possible.
|
||||||
"""
|
"""
|
||||||
self.tick_period_ms = period_ms
|
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):
|
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
|
event_mask = self.event_mask
|
||||||
if event[0] < 5:
|
if event[0] < 5:
|
||||||
|
@ -94,7 +94,7 @@ class Manager(object):
|
||||||
self.app.touch(event)
|
self.app.touch(event)
|
||||||
|
|
||||||
def tick(self):
|
def tick(self):
|
||||||
rtc = self.watch.rtc
|
rtc = watch.rtc
|
||||||
|
|
||||||
if self.sleep_at:
|
if self.sleep_at:
|
||||||
if rtc.update() and self.tick_expiry:
|
if rtc.update() and self.tick_expiry:
|
||||||
|
@ -107,36 +107,36 @@ class Manager(object):
|
||||||
ticks += 1
|
ticks += 1
|
||||||
self.app.tick(ticks)
|
self.app.tick(ticks)
|
||||||
|
|
||||||
if self.watch.button.value():
|
if watch.button.value():
|
||||||
self.sleep_at = self.watch.rtc.uptime + 15
|
self.sleep_at = watch.rtc.uptime + 15
|
||||||
|
|
||||||
event = self.watch.touch.get_event()
|
event = watch.touch.get_event()
|
||||||
if event:
|
if event:
|
||||||
self.handle_event(event)
|
self.handle_event(event)
|
||||||
|
|
||||||
if self.watch.rtc.uptime > self.sleep_at:
|
if watch.rtc.uptime > self.sleep_at:
|
||||||
self.watch.backlight.set(0)
|
watch.backlight.set(0)
|
||||||
if not self.app.sleep():
|
if not self.app.sleep():
|
||||||
self.switch(self.applications[0])
|
self.switch(self.applications[0])
|
||||||
self.app.sleep()
|
self.app.sleep()
|
||||||
self.watch.display.poweroff()
|
watch.display.poweroff()
|
||||||
self.charging = self.watch.battery.charging()
|
self.charging = watch.battery.charging()
|
||||||
self.sleep_at = None
|
self.sleep_at = None
|
||||||
|
|
||||||
gc.collect()
|
gc.collect()
|
||||||
else:
|
else:
|
||||||
self.watch.rtc.update()
|
watch.rtc.update()
|
||||||
|
|
||||||
charging = self.watch.battery.charging()
|
charging = watch.battery.charging()
|
||||||
if self.watch.button.value() or self.charging != charging:
|
if watch.button.value() or self.charging != charging:
|
||||||
self.watch.display.poweron()
|
watch.display.poweron()
|
||||||
self.app.wake()
|
self.app.wake()
|
||||||
self.watch.backlight.set(2)
|
watch.backlight.set(2)
|
||||||
|
|
||||||
# Discard any pending touch events
|
# 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):
|
def run(self):
|
||||||
"""Run the system manager synchronously.
|
"""Run the system manager synchronously.
|
||||||
|
@ -145,6 +145,13 @@ class Manager(object):
|
||||||
normal execution context meaning any exceptions and other problems
|
normal execution context meaning any exceptions and other problems
|
||||||
can be observed interactively via the console.
|
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:
|
while True:
|
||||||
self.tick()
|
self.tick()
|
||||||
machine.deepsleep()
|
machine.deepsleep()
|
||||||
|
|
||||||
|
system = Manager()
|
Loading…
Reference in a new issue