diff --git a/wasp/apps/clock.py b/wasp/apps/clock.py index 88ed2c7..5919ebf 100644 --- a/wasp/apps/clock.py +++ b/wasp/apps/clock.py @@ -13,16 +13,9 @@ import icons import fonts.clock as digits DIGITS = ( - digits.clock_0, - digits.clock_1, - digits.clock_2, - digits.clock_3, - digits.clock_4, - digits.clock_5, - digits.clock_6, - digits.clock_7, - digits.clock_8, - digits.clock_9 + digits.clock_0, digits.clock_1, digits.clock_2, digits.clock_3, + digits.clock_4, digits.clock_5, digits.clock_6, digits.clock_7, + digits.clock_8, digits.clock_9 ) MONTH = 'JanFebMarAprMayJunJulAugSepOctNovDec' @@ -39,60 +32,78 @@ class ClockApp(): ICON = icons.clock def __init__(self): - self.meter = wasp.widgets.BatteryMeter() - self.notifier = wasp.widgets.NotificationBar() + self._bar = wasp.widgets.StatusBar() def foreground(self): - """Activate the application.""" - self.on_screen = ( -1, -1, -1, -1, -1, -1 ) - self.draw() + """Activate the application. + + Configure the status bar, redraw the display and request a periodic + tick callback every second. + """ + self._bar.clock = False + self._draw(True) wasp.system.request_tick(1000) def sleep(self): + """Prepare to enter the low power mode. + + :returns: True, which tells the system manager not to automatically + switch to the default application before sleeping. + """ return True def wake(self): - self.update() + """Return from low power mode. + + Time will have changes whilst we have been asleep so we must + udpate the display (but there is no need for a full redraw because + the display RAM is preserved during a sleep. + """ + self._draw() def tick(self, ticks): - self.update() + """Periodic callback to update the display.""" + self._draw() - def draw(self): - """Redraw the display from scratch.""" - draw = wasp.watch.drawable + def _draw(self, redraw=False): + """Draw or lazily update the display. - draw.fill() - draw.rleblit(digits.clock_colon, pos=(2*48, 80), fg=0xb5b6) - self.on_screen = ( -1, -1, -1, -1, -1, -1 ) - self.update() - self.meter.draw() - - def update(self): - """Update the display (if needed). - - The updates are a lazy as possible and rely on an prior call to - draw() to ensure the screen is suitably prepared. + The updates are as lazy by default and avoid spending time redrawing + if the time on display has not changed. However if redraw is set to + True then a full redraw is be performed. """ - 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.notifier.update() - self.on_screen = now - return False - draw = wasp.watch.drawable + + if redraw: + now = wasp.watch.rtc.get_localtime() + + # Clear the display and draw that static parts of the watch face + draw.fill() + draw.rleblit(digits.clock_colon, pos=(2*48, 80), fg=0xb5b6) + + # Redraw the status bar + self._bar.draw() + else: + # The update is doubly lazy... we update the status bar and if + # the status bus update reports a change in the time of day + # then we compare the minute on display to make sure we + # only update the main clock once per minute. + now = self._bar.update() + if not now or self._min == now[4]: + # Skip the update + return + + # Format the month as text + month = now[1] - 1 + month = MONTH[month*3:(month+1)*3] + + # Draw the changeable parts of the watch face 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)) draw.rleblit(DIGITS[now[3] // 10], pos=(0*48, 80), fg=0xbdb6) - self.on_screen = now - - month = now[1] - 1 - month = MONTH[month*3:(month+1)*3] draw.string('{} {} {}'.format(now[2], month, now[0]), 0, 180, width=240) - self.meter.update() - self.notifier.update() - return True + # Record the minute that is currently being displayed + self._min = now[4]