apps: steps: Add a history graph
The steplogger records steps but currently there is no way to see the data recorded on the device itself. Make a first attempt at graphing the step data. Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk>
This commit is contained in:
parent
72f5322cc3
commit
7a5990072c
3 changed files with 82 additions and 9 deletions
|
@ -47,7 +47,7 @@ class StepCounterApp():
|
|||
|
||||
def __init__(self):
|
||||
watch.accel.reset()
|
||||
self._count = 0
|
||||
self._scroll = wasp.widgets.ScrollIndicator()
|
||||
self._wake = 0
|
||||
|
||||
def foreground(self):
|
||||
|
@ -63,7 +63,9 @@ class StepCounterApp():
|
|||
"""
|
||||
wasp.system.cancel_alarm(self._wake, self._reset)
|
||||
wasp.system.bar.clock = True
|
||||
self._page = -1
|
||||
self._draw()
|
||||
wasp.system.request_event(wasp.EventMask.SWIPE_UPDOWN)
|
||||
wasp.system.request_tick(1000)
|
||||
|
||||
def background(self):
|
||||
|
@ -83,25 +85,48 @@ class StepCounterApp():
|
|||
self._wake += 24 * 60 * 60
|
||||
wasp.system.set_alarm(self._wake, self._reset)
|
||||
|
||||
def swipe(self, event):
|
||||
if event[0] == wasp.EventType.DOWN:
|
||||
if self._page == -1:
|
||||
return
|
||||
self._page -= 1
|
||||
else:
|
||||
self._page += 1
|
||||
|
||||
mute = wasp.watch.display.mute
|
||||
mute(True)
|
||||
self._draw()
|
||||
mute(False)
|
||||
|
||||
def tick(self, ticks):
|
||||
self._count += 686;
|
||||
if self._page == -1:
|
||||
self._update()
|
||||
|
||||
def _draw(self):
|
||||
"""Draw the display from scratch."""
|
||||
draw = wasp.watch.drawable
|
||||
draw.fill()
|
||||
draw.blit(feet, 12, 132-24)
|
||||
|
||||
if self._page == -1:
|
||||
self._update()
|
||||
wasp.system.bar.draw()
|
||||
else:
|
||||
self._update_graph()
|
||||
|
||||
def _update(self):
|
||||
draw = wasp.watch.drawable
|
||||
|
||||
# Draw the icon
|
||||
draw.blit(feet, 12, 132-24)
|
||||
|
||||
# Update the status bar
|
||||
now = wasp.system.bar.update()
|
||||
|
||||
# Update the scroll indicator
|
||||
scroll = self._scroll
|
||||
scroll.up = False
|
||||
scroll.draw()
|
||||
|
||||
# Update the step count
|
||||
count = watch.accel.steps
|
||||
t = str(count)
|
||||
|
@ -109,3 +134,44 @@ class StepCounterApp():
|
|||
draw.set_font(fonts.sans36)
|
||||
draw.set_color(draw.lighten(wasp.system.theme('spot1'), wasp.system.theme('contrast')))
|
||||
draw.string(t, 228-w, 132-18)
|
||||
|
||||
def _update_graph(self):
|
||||
draw = watch.drawable
|
||||
draw.set_font(fonts.sans24)
|
||||
draw.set_color(0xffff)
|
||||
|
||||
# Draw the date
|
||||
now = int(watch.rtc.time())
|
||||
then = now - ((24*60*60) * self._page)
|
||||
walltime = time.localtime(then)
|
||||
draw.string('{:02d}-{:02d}'.format(walltime[2], walltime[1]), 0, 0)
|
||||
|
||||
# Get the iterable step date for the currently selected date
|
||||
data = wasp.system.steps.data(then)
|
||||
|
||||
# Bail if there is no data
|
||||
if not data:
|
||||
draw.string('No data', 239-160, 0, 160, right=True)
|
||||
return
|
||||
|
||||
color = wasp.system.theme('spot2')
|
||||
|
||||
# Draw the frame
|
||||
draw.fill(0x3969, 0, 39, 240, 1)
|
||||
draw.fill(0x3969, 0, 239, 240, 1)
|
||||
for i in (0, 60, 90, 120, 150, 180, 239):
|
||||
draw.fill(0x3969, i, 39, 1, 201)
|
||||
|
||||
total = 0
|
||||
for x, d in enumerate(data):
|
||||
if d == 0 or x < 2:
|
||||
# TODO: the x < 2 conceals BUGZ
|
||||
continue
|
||||
total += d
|
||||
d = d // 3
|
||||
if d > 200:
|
||||
draw.fill(0xffff, x, 239-200, 1, 200)
|
||||
else:
|
||||
draw.fill(color, x, 239-d, 1, d)
|
||||
|
||||
draw.string(str(total), 239-160, 0, 160, right=True)
|
||||
|
|
|
@ -58,7 +58,7 @@ class StepIterator:
|
|||
self._f = None
|
||||
|
||||
class StepLogger:
|
||||
def __init__(self):
|
||||
def __init__(self, manager):
|
||||
self._data = array.array('H', (0,) * DUMP_LENGTH)
|
||||
self._steps = wasp.watch.accel.steps
|
||||
|
||||
|
@ -69,7 +69,7 @@ class StepLogger:
|
|||
|
||||
# Queue a tick
|
||||
self._t = int(wasp.watch.rtc.time()) // TICK_PERIOD * TICK_PERIOD
|
||||
wasp.system.set_alarm(self._t + TICK_PERIOD, self._tick)
|
||||
manager.set_alarm(self._t + TICK_PERIOD, self._tick)
|
||||
|
||||
def _tick(self):
|
||||
"""Capture the current step count in N minute intervals.
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
import gc
|
||||
import machine
|
||||
import micropython
|
||||
import steplogger
|
||||
import watch
|
||||
import widgets
|
||||
|
||||
|
@ -153,7 +154,13 @@ class Manager():
|
|||
(SoftwareApp, False),
|
||||
(SettingsApp, False) ):
|
||||
try:
|
||||
self.register(app(), qr)
|
||||
a = app()
|
||||
|
||||
# Special case for watches with working step counters!
|
||||
if isinstance(a, StepCounterApp):
|
||||
self.steps = steplogger.StepLogger(self)
|
||||
|
||||
self.register(a, qr)
|
||||
except:
|
||||
# Let's not bring the whole device down just because there's
|
||||
# an exception starting one of the apps...
|
||||
|
|
Loading…
Reference in a new issue