2020-03-22 16:40:18 +01:00
|
|
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
# Copyright (C) 2020 Daniel Thompson
|
|
|
|
|
2020-05-14 23:29:35 +02:00
|
|
|
"""Self Tests
|
|
|
|
~~~~~~~~~~~~~
|
2021-01-13 22:51:17 +01:00
|
|
|
|
|
|
|
A collection of tests used to develop features or provide useful metrics such
|
|
|
|
as performance indicators or memory usage.
|
|
|
|
|
2023-03-07 02:02:07 +01:00
|
|
|
.. figure:: res/screenshots/TestApp.png
|
2021-01-13 22:51:17 +01:00
|
|
|
:width: 179
|
2020-05-14 23:29:35 +02:00
|
|
|
"""
|
|
|
|
|
2020-03-22 13:37:19 +01:00
|
|
|
import wasp
|
2020-12-12 22:35:45 +01:00
|
|
|
|
|
|
|
import gc
|
2020-12-29 21:07:50 +01:00
|
|
|
import fonts
|
2020-04-06 23:03:05 +02:00
|
|
|
import icons
|
2020-12-12 22:35:45 +01:00
|
|
|
import machine
|
2020-03-08 11:18:08 +01:00
|
|
|
|
2023-03-07 02:02:07 +01:00
|
|
|
from apps.system.pager import PagerApp
|
2020-11-14 21:36:41 +01:00
|
|
|
|
2020-03-08 21:48:48 +01:00
|
|
|
class TestApp():
|
2021-01-13 22:51:17 +01:00
|
|
|
"""Self test application."""
|
2020-04-06 23:03:05 +02:00
|
|
|
NAME = 'Self Test'
|
|
|
|
ICON = icons.app
|
2020-03-08 11:18:08 +01:00
|
|
|
|
|
|
|
def __init__(self):
|
2020-12-29 13:32:38 +01:00
|
|
|
self.tests = ('Alarm', 'Button', 'Checkbox', 'Crash', 'Colours', 'Fill', 'Fill-H', 'Fill-V', 'Free Mem', 'Line', 'Notifications', 'RLE', 'String', 'Touch', 'Wrap')
|
2020-03-08 21:48:48 +01:00
|
|
|
self.test = self.tests[0]
|
2020-04-05 10:48:03 +02:00
|
|
|
self.scroll = wasp.widgets.ScrollIndicator()
|
2020-03-08 11:18:08 +01:00
|
|
|
|
2020-12-29 13:32:38 +01:00
|
|
|
self._checkbox = wasp.widgets.Checkbox(4, 104, 'Check me')
|
2020-05-24 15:20:02 +02:00
|
|
|
self._sliders = (
|
|
|
|
wasp.widgets.Slider(32, 10, 90, 0xf800),
|
|
|
|
wasp.widgets.Slider(64, 10, 140, 0x27e4),
|
|
|
|
wasp.widgets.Slider(32, 10, 190, 0x211f),
|
|
|
|
)
|
2020-12-29 21:07:50 +01:00
|
|
|
self._spinner = wasp.widgets.Spinner(90, 60, 0, 99)
|
2020-05-24 15:20:02 +02:00
|
|
|
|
2020-03-28 18:19:34 +01:00
|
|
|
def foreground(self):
|
2020-03-08 11:18:08 +01:00
|
|
|
"""Activate the application."""
|
|
|
|
self.on_screen = ( -1, -1, -1, -1, -1, -1 )
|
2020-04-12 09:40:11 +02:00
|
|
|
self._draw()
|
2020-03-27 21:09:28 +01:00
|
|
|
wasp.system.request_event(wasp.EventMask.TOUCH |
|
2020-03-28 18:27:09 +01:00
|
|
|
wasp.EventMask.SWIPE_UPDOWN |
|
|
|
|
wasp.EventMask.BUTTON)
|
2020-03-08 11:18:08 +01:00
|
|
|
|
2020-03-28 18:27:09 +01:00
|
|
|
def press(self, button, state):
|
|
|
|
draw = wasp.watch.drawable
|
2020-11-14 21:36:41 +01:00
|
|
|
if self.test == 'Alarm':
|
|
|
|
self._test_alarm()
|
|
|
|
elif self.test == 'Button':
|
2020-03-28 18:27:09 +01:00
|
|
|
draw.string('{}: {}'.format(button, state), 0, 108, width=240)
|
2020-04-05 10:46:25 +02:00
|
|
|
elif self.test == 'Crash':
|
|
|
|
self.crash()
|
2020-04-12 09:40:11 +02:00
|
|
|
elif self.test == 'String':
|
|
|
|
self._benchmark_string()
|
|
|
|
elif self.test == 'Touch':
|
|
|
|
draw.string('Button', 0, 108, width=240)
|
2020-03-28 18:27:09 +01:00
|
|
|
|
2020-03-08 21:48:48 +01:00
|
|
|
def swipe(self, event):
|
|
|
|
tests = self.tests
|
2020-03-28 18:27:09 +01:00
|
|
|
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
|
2020-03-08 21:48:48 +01:00
|
|
|
self.test = tests[i]
|
2020-04-12 09:40:11 +02:00
|
|
|
self._draw()
|
2020-03-08 21:48:48 +01:00
|
|
|
|
2020-03-08 11:18:08 +01:00
|
|
|
def touch(self, event):
|
2020-12-29 13:32:38 +01:00
|
|
|
if self.test == 'Checkbox':
|
|
|
|
self._checkbox.touch(event)
|
|
|
|
elif self.test == 'Colours':
|
2020-05-24 15:20:02 +02:00
|
|
|
if event[2] > 90:
|
|
|
|
s = self._sliders[(event[2] - 90) // 50]
|
|
|
|
s.touch(event)
|
|
|
|
s.update()
|
|
|
|
self.scroll.draw()
|
|
|
|
self._update_colours()
|
2020-06-22 23:17:06 +02:00
|
|
|
elif self.test.startswith('Fill'):
|
|
|
|
self._benchmark_fill()
|
2020-07-19 21:50:33 +02:00
|
|
|
elif self.test == 'Notifications':
|
2020-12-29 21:07:50 +01:00
|
|
|
if self._spinner.touch(event):
|
|
|
|
notifications = wasp.system.notifications
|
|
|
|
|
|
|
|
if len(notifications) > self._spinner.value:
|
2020-07-19 21:50:33 +02:00
|
|
|
wasp.system.unnotify(
|
2020-12-29 21:07:50 +01:00
|
|
|
next(iter(notifications.keys())))
|
|
|
|
else:
|
|
|
|
wasp.system.notify(wasp.watch.rtc.get_uptime_ms(),
|
|
|
|
{
|
|
|
|
"src":"Hangouts",
|
|
|
|
"title":"A Name",
|
|
|
|
"body":"message contents"
|
|
|
|
})
|
2020-05-24 15:20:02 +02:00
|
|
|
elif self.test == 'RLE':
|
2020-04-12 09:40:11 +02:00
|
|
|
self._benchmark_rle()
|
|
|
|
elif self.test == 'String':
|
|
|
|
self._benchmark_string()
|
|
|
|
elif self.test == 'Touch':
|
2020-03-28 18:27:09 +01:00
|
|
|
wasp.watch.drawable.string('({}, {})'.format(
|
|
|
|
event[1], event[2]), 0, 108, width=240)
|
2020-04-11 21:14:30 +02:00
|
|
|
elif self.test == 'Wrap':
|
2020-04-12 09:40:11 +02:00
|
|
|
self._benchmark_wrap()
|
2020-12-11 09:12:09 +01:00
|
|
|
elif self.test == 'Line':
|
|
|
|
self._benchmark_line()
|
2020-04-06 23:03:54 +02:00
|
|
|
|
2020-11-14 21:36:41 +01:00
|
|
|
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)
|
|
|
|
|
2020-04-12 09:40:11 +02:00
|
|
|
def _benchmark_rle(self):
|
2020-04-06 23:03:54 +02:00
|
|
|
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):
|
2021-01-03 15:54:34 +01:00
|
|
|
draw.blit(icons.software, i+16, i+32)
|
2020-04-06 23:03:54 +02:00
|
|
|
elapsed = t.time()
|
|
|
|
t.stop()
|
|
|
|
del t
|
|
|
|
draw.string('{}s'.format(elapsed / 1000000), 12, 24+192)
|
2020-03-08 21:48:48 +01:00
|
|
|
|
2020-06-22 23:17:06 +02:00
|
|
|
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)
|
|
|
|
|
2020-04-12 09:40:11 +02:00
|
|
|
def _benchmark_string(self):
|
2020-03-28 18:27:09 +01:00
|
|
|
draw = wasp.watch.drawable
|
|
|
|
draw.fill(0, 0, 30, 240, 240-30)
|
2021-03-29 23:17:27 +02:00
|
|
|
draw.set_color(0xffff, 0x4208)
|
2020-04-06 23:03:05 +02:00
|
|
|
self.scroll.draw()
|
2020-03-28 18:27:09 +01:00
|
|
|
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)
|
2021-02-04 23:07:26 +01:00
|
|
|
draw.string("0123456789", 12, 24+120, width=228)
|
|
|
|
draw.string('!"£$%^&*()', 12, 24+144, width=228)
|
2020-03-28 18:27:09 +01:00
|
|
|
elapsed = t.time()
|
|
|
|
t.stop()
|
|
|
|
del t
|
|
|
|
draw.string('{}s'.format(elapsed / 1000000), 12, 24+192)
|
2020-12-11 09:12:09 +01:00
|
|
|
|
|
|
|
def _benchmark_line(self):
|
|
|
|
draw = wasp.watch.drawable
|
|
|
|
# instead of calculating by trig functions, use LUT
|
2020-12-12 13:24:40 +01:00
|
|
|
points = (0, 50), (19, 46), (35, 35), (46, 19),
|
2020-12-11 09:12:09 +01:00
|
|
|
|
2020-12-12 13:24:40 +01:00
|
|
|
draw.fill(0, 70, 70, 100, 100)
|
2020-12-11 09:12:09 +01:00
|
|
|
self.scroll.draw()
|
|
|
|
t = machine.Timer(id=1, period=8000000)
|
|
|
|
t.start()
|
|
|
|
for x, y in points:
|
2020-12-27 09:47:05 +01:00
|
|
|
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
|
2020-12-11 09:12:09 +01:00
|
|
|
elapsed = t.time()
|
|
|
|
t.stop()
|
|
|
|
del t
|
|
|
|
draw.string('{}s'.format(elapsed / 1000000), 12, 24+192)
|
2020-03-08 11:18:08 +01:00
|
|
|
|
2020-04-12 09:40:11 +02:00
|
|
|
def _benchmark_wrap(self):
|
2020-04-11 21:14:30 +02:00
|
|
|
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)
|
|
|
|
|
2020-04-12 09:40:11 +02:00
|
|
|
def _draw(self):
|
2020-03-08 11:18:08 +01:00
|
|
|
"""Redraw the display from scratch."""
|
2020-03-22 13:37:19 +01:00
|
|
|
wasp.watch.display.mute(True)
|
2020-04-05 10:46:25 +02:00
|
|
|
draw = wasp.watch.drawable
|
|
|
|
draw.fill()
|
2020-12-29 21:07:50 +01:00
|
|
|
draw.set_font(fonts.sans24)
|
2020-04-05 10:46:25 +02:00
|
|
|
draw.string('{} test'.format(self.test),
|
2020-03-08 21:48:48 +01:00
|
|
|
0, 6, width=240)
|
2020-04-05 10:46:25 +02:00
|
|
|
|
2020-11-14 21:36:41 +01:00
|
|
|
if self.test == 'Alarm':
|
|
|
|
draw.string("Press button to", 12, 24+24)
|
|
|
|
draw.string("set alarm.", 12, 24+48)
|
2020-12-29 13:32:38 +01:00
|
|
|
elif self.test == 'Checkbox':
|
|
|
|
self._checkbox.draw()
|
|
|
|
elif self.test == 'Crash':
|
2020-04-05 10:46:25 +02:00
|
|
|
draw.string("Press button to", 12, 24+24)
|
|
|
|
draw.string("throw exception.", 12, 24+48)
|
2020-05-24 15:20:02 +02:00
|
|
|
elif self.test == 'Colours':
|
|
|
|
for s in self._sliders:
|
|
|
|
s.draw()
|
|
|
|
self._update_colours()
|
2020-12-12 22:35:45 +01:00
|
|
|
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)
|
2020-07-19 21:50:33 +02:00
|
|
|
elif self.test == 'Notifications':
|
2020-12-29 21:07:50 +01:00
|
|
|
self._spinner.value = len(wasp.system.notifications)
|
|
|
|
self._spinner.draw()
|
2020-04-10 21:22:51 +02:00
|
|
|
elif self.test == 'RLE':
|
|
|
|
draw.blit(self.ICON, 120-48, 120-32)
|
2020-04-05 10:46:25 +02:00
|
|
|
|
2020-05-24 15:20:02 +02:00
|
|
|
self.scroll.draw()
|
2020-03-22 13:37:19 +01:00
|
|
|
wasp.watch.display.mute(False)
|
2020-05-24 15:20:02 +02:00
|
|
|
|
|
|
|
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)
|