231f3b6fdd
Currently wasp-os enables a narrow set of applications because we don't want to consume RAM by importing the module and constructing the application. We can improve on this situation by providing a small (stateless) application that can be used to enable or diable applications. This allows all the ROMed applications to be enabled using the GUI without compromising on the ability to develop applications. In fact this application significantlly reduces the RAM consumed in the default case becasue the Self Test app does not need to maintain its state. Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk>
266 lines
8.8 KiB
Python
266 lines
8.8 KiB
Python
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
# Copyright (C) 2020 Daniel Thompson
|
|
|
|
"""Self Tests
|
|
~~~~~~~~~~~~~
|
|
"""
|
|
|
|
import wasp
|
|
|
|
import gc
|
|
import fonts
|
|
import icons
|
|
import machine
|
|
|
|
from apps.pager import PagerApp
|
|
|
|
class TestApp():
|
|
"""Simple test application.
|
|
|
|
.. figure:: res/SelfTestApp.png
|
|
:width: 179
|
|
|
|
Screenshot of the self test application
|
|
"""
|
|
NAME = 'Self Test'
|
|
ICON = icons.app
|
|
|
|
def __init__(self):
|
|
self.tests = ('Alarm', 'Button', 'Checkbox', 'Crash', 'Colours', 'Fill', 'Fill-H', 'Fill-V', 'Free Mem', 'Line', 'Notifications', 'RLE', 'String', 'Touch', 'Wrap')
|
|
self.test = self.tests[0]
|
|
self.scroll = wasp.widgets.ScrollIndicator()
|
|
|
|
self._checkbox = wasp.widgets.Checkbox(4, 104, 'Check me')
|
|
self._sliders = (
|
|
wasp.widgets.Slider(32, 10, 90, 0xf800),
|
|
wasp.widgets.Slider(64, 10, 140, 0x27e4),
|
|
wasp.widgets.Slider(32, 10, 190, 0x211f),
|
|
)
|
|
self._spinner = wasp.widgets.Spinner(90, 60, 0, 99)
|
|
|
|
def foreground(self):
|
|
"""Activate the application."""
|
|
self.on_screen = ( -1, -1, -1, -1, -1, -1 )
|
|
self._draw()
|
|
wasp.system.request_event(wasp.EventMask.TOUCH |
|
|
wasp.EventMask.SWIPE_UPDOWN |
|
|
wasp.EventMask.BUTTON)
|
|
|
|
def press(self, button, state):
|
|
draw = wasp.watch.drawable
|
|
if self.test == 'Alarm':
|
|
self._test_alarm()
|
|
elif self.test == 'Button':
|
|
draw.string('{}: {}'.format(button, state), 0, 108, width=240)
|
|
elif self.test == 'Crash':
|
|
self.crash()
|
|
elif self.test == 'String':
|
|
self._benchmark_string()
|
|
elif self.test == 'Touch':
|
|
draw.string('Button', 0, 108, width=240)
|
|
|
|
def swipe(self, event):
|
|
tests = self.tests
|
|
i = tests.index(self.test)
|
|
|
|
if event[0] == wasp.EventType.UP:
|
|
i += 1
|
|
if i >= len(tests):
|
|
i = 0
|
|
else:
|
|
i -= 1
|
|
if i < 0:
|
|
i = len(tests) - 1
|
|
self.test = tests[i]
|
|
self._draw()
|
|
|
|
def touch(self, event):
|
|
if self.test == 'Checkbox':
|
|
self._checkbox.touch(event)
|
|
elif self.test == 'Colours':
|
|
if event[2] > 90:
|
|
s = self._sliders[(event[2] - 90) // 50]
|
|
s.touch(event)
|
|
s.update()
|
|
self.scroll.draw()
|
|
self._update_colours()
|
|
elif self.test.startswith('Fill'):
|
|
self._benchmark_fill()
|
|
elif self.test == 'Notifications':
|
|
if self._spinner.touch(event):
|
|
notifications = wasp.system.notifications
|
|
|
|
if len(notifications) > self._spinner.value:
|
|
wasp.system.unnotify(
|
|
next(iter(notifications.keys())))
|
|
else:
|
|
wasp.system.notify(wasp.watch.rtc.get_uptime_ms(),
|
|
{
|
|
"src":"Hangouts",
|
|
"title":"A Name",
|
|
"body":"message contents"
|
|
})
|
|
elif self.test == 'RLE':
|
|
self._benchmark_rle()
|
|
elif self.test == 'String':
|
|
self._benchmark_string()
|
|
elif self.test == 'Touch':
|
|
wasp.watch.drawable.string('({}, {})'.format(
|
|
event[1], event[2]), 0, 108, width=240)
|
|
elif self.test == 'Wrap':
|
|
self._benchmark_wrap()
|
|
elif self.test == 'Line':
|
|
self._benchmark_line()
|
|
|
|
def _alarm(self):
|
|
wasp.system.wake()
|
|
wasp.system.switch(PagerApp('Alarm triggered'))
|
|
|
|
def _test_alarm(self):
|
|
def nop():
|
|
pass
|
|
now = wasp.watch.rtc.time()
|
|
wasp.system.set_alarm(now + 30, self._alarm)
|
|
wasp.system.set_alarm(now + 30, nop)
|
|
if not wasp.system.cancel_alarm(now + 30, nop):
|
|
bug()
|
|
wasp.watch.drawable.string("Done.", 12, 24+80)
|
|
|
|
def _benchmark_rle(self):
|
|
draw = wasp.watch.drawable
|
|
draw.fill(0, 0, 30, 240, 240-30)
|
|
self.scroll.draw()
|
|
t = machine.Timer(id=1, period=8000000)
|
|
t.start()
|
|
for i in range(0, 128, 16):
|
|
draw.blit(icons.software, i+16, i+32)
|
|
elapsed = t.time()
|
|
t.stop()
|
|
del t
|
|
draw.string('{}s'.format(elapsed / 1000000), 12, 24+192)
|
|
|
|
def _benchmark_fill(self):
|
|
draw = wasp.watch.drawable
|
|
draw.fill(0, 0, 30, 240, 240-30)
|
|
self.scroll.draw()
|
|
t = machine.Timer(id=1, period=8000000)
|
|
if self.test == 'Fill':
|
|
t.start()
|
|
draw.fill(0xffff, 60, 60, 120, 120)
|
|
elapsed = t.time()
|
|
elif self.test == 'Fill-H':
|
|
t.start()
|
|
for i in range(60, 180, 2):
|
|
draw.fill(0xffff, 60, i, 120, 1)
|
|
elapsed = t.time()
|
|
elif self.test == 'Fill-V':
|
|
t.start()
|
|
for i in range(60, 180, 2):
|
|
draw.fill(0xffff, i, 60, 1, 120)
|
|
elapsed = t.time()
|
|
|
|
t.stop()
|
|
del t
|
|
draw.string('{}s'.format(elapsed / 1000000), 12, 24+192)
|
|
|
|
def _benchmark_string(self):
|
|
draw = wasp.watch.drawable
|
|
draw.fill(0, 0, 30, 240, 240-30)
|
|
self.scroll.draw()
|
|
t = machine.Timer(id=1, period=8000000)
|
|
t.start()
|
|
draw.string("The quick brown", 12, 24+24)
|
|
draw.string("fox jumped over", 12, 24+48)
|
|
draw.string("the lazy dog.", 12, 24+72)
|
|
draw.string("0123456789", 12, 24+120)
|
|
draw.string('!"£$%^&*()', 12, 24+144)
|
|
elapsed = t.time()
|
|
t.stop()
|
|
del t
|
|
draw.string('{}s'.format(elapsed / 1000000), 12, 24+192)
|
|
|
|
def _benchmark_line(self):
|
|
draw = wasp.watch.drawable
|
|
# instead of calculating by trig functions, use LUT
|
|
points = (0, 50), (19, 46), (35, 35), (46, 19),
|
|
|
|
draw.fill(0, 70, 70, 100, 100)
|
|
self.scroll.draw()
|
|
t = machine.Timer(id=1, period=8000000)
|
|
t.start()
|
|
for x, y in points:
|
|
draw.line(120, 120, 120+x, 120+y, 4, 0xfb00) # red
|
|
draw.line(120, 120, 120+y, 120-x, 3, 0x07c0) # green
|
|
draw.line(120, 120, 120-x, 120-y, 5, 0x6b3f) # blue
|
|
draw.line(120, 120, 120-y, 120+x, 2, 0xffe0) # yellow
|
|
elapsed = t.time()
|
|
t.stop()
|
|
del t
|
|
draw.string('{}s'.format(elapsed / 1000000), 12, 24+192)
|
|
|
|
def _benchmark_wrap(self):
|
|
draw = wasp.watch.drawable
|
|
draw.fill(0, 0, 30, 240, 240-30)
|
|
self.scroll.draw()
|
|
t = machine.Timer(id=1, period=8000000)
|
|
t.start()
|
|
draw = wasp.watch.drawable
|
|
s = 'This\nis a very long string that will need to be wrappedinmultipledifferentways!'
|
|
chunks = draw.wrap(s, 240)
|
|
|
|
for i in range(len(chunks)-1):
|
|
sub = s[chunks[i]:chunks[i+1]].rstrip()
|
|
draw.string(sub, 0, 48+24*i)
|
|
elapsed = t.time()
|
|
t.stop()
|
|
del t
|
|
draw.string('{}s'.format(elapsed / 1000000), 12, 24+192)
|
|
|
|
def _draw(self):
|
|
"""Redraw the display from scratch."""
|
|
wasp.watch.display.mute(True)
|
|
draw = wasp.watch.drawable
|
|
draw.fill()
|
|
draw.set_font(fonts.sans24)
|
|
draw.string('{} test'.format(self.test),
|
|
0, 6, width=240)
|
|
|
|
if self.test == 'Alarm':
|
|
draw.string("Press button to", 12, 24+24)
|
|
draw.string("set alarm.", 12, 24+48)
|
|
elif self.test == 'Checkbox':
|
|
self._checkbox.draw()
|
|
elif self.test == 'Crash':
|
|
draw.string("Press button to", 12, 24+24)
|
|
draw.string("throw exception.", 12, 24+48)
|
|
elif self.test == 'Colours':
|
|
for s in self._sliders:
|
|
s.draw()
|
|
self._update_colours()
|
|
elif self.test == 'Free Mem':
|
|
if wasp.watch.free:
|
|
draw.string("Boot: {}".format(wasp.watch.free), 12, 3*24)
|
|
draw.string("Init: {}".format(wasp.free), 12, 4*24)
|
|
draw.string("Now: {}".format(gc.mem_free()), 12, 5*24)
|
|
gc.collect()
|
|
draw.string("GC: {}".format(gc.mem_free()), 12, 6*24)
|
|
else:
|
|
draw.string("Not supported", 12, 4*24)
|
|
elif self.test == 'Notifications':
|
|
self._spinner.value = len(wasp.system.notifications)
|
|
self._spinner.draw()
|
|
elif self.test == 'RLE':
|
|
draw.blit(self.ICON, 120-48, 120-32)
|
|
|
|
self.scroll.draw()
|
|
wasp.watch.display.mute(False)
|
|
|
|
def _update_colours(self):
|
|
draw = wasp.watch.drawable
|
|
r = self._sliders[0].value
|
|
g = self._sliders[1].value
|
|
b = self._sliders[2].value
|
|
rgb = (r << 11) + (g << 5) + b
|
|
|
|
draw.string('RGB565 #{:04x}'.format(rgb), 0, 6, width=240)
|
|
draw.fill(rgb, 60, 35, 120, 50)
|