apps: WordClock: Add a new word-based clock app
Signed-off-by: Brendan M. Sleight <bms.git@barwap.com> [daniel@redfelineninja.org.uk: Squashed down into a single commit and updated subject] Signed-off-by: Daniel Thompson <daniel@redfelineninja.org.uk
This commit is contained in:
parent
867ed324b5
commit
cec8d97aeb
4 changed files with 201 additions and 0 deletions
|
@ -219,3 +219,7 @@ application (and the "blank" white screen is a torch application):
|
||||||
.. image:: res/TimerApp.png
|
.. image:: res/TimerApp.png
|
||||||
:alt: Countdown timer application running in the wasp-os simulator
|
:alt: Countdown timer application running in the wasp-os simulator
|
||||||
:width: 179
|
:width: 179
|
||||||
|
|
||||||
|
.. image:: res/WordClkApp.png
|
||||||
|
:alt: Shows a time as words in the wasp-os simulator
|
||||||
|
:width: 179
|
||||||
|
|
|
@ -15,6 +15,8 @@ Watch faces
|
||||||
|
|
||||||
.. automodule:: apps.fibonacci_clock
|
.. automodule:: apps.fibonacci_clock
|
||||||
|
|
||||||
|
.. automodule:: apps.word_clock
|
||||||
|
|
||||||
Built-in
|
Built-in
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|
BIN
res/WordClkApp.png
Normal file
BIN
res/WordClkApp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
195
wasp/apps/word_clock.py
Normal file
195
wasp/apps/word_clock.py
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
# Copyright (C) 2020 Daniel Thompson
|
||||||
|
# Copyright (C) 2021 Brendan Sleight
|
||||||
|
|
||||||
|
|
||||||
|
"""Word clock
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Shows a time as words together with a battery meter and the date.
|
||||||
|
|
||||||
|
.. figure:: res/WordClkApp.png
|
||||||
|
:width: 179
|
||||||
|
"""
|
||||||
|
|
||||||
|
import wasp
|
||||||
|
|
||||||
|
import icons
|
||||||
|
|
||||||
|
MONTH = 'JanFebMarAprMayJunJulAugSepOctNovDec'
|
||||||
|
|
||||||
|
|
||||||
|
class WordClockApp():
|
||||||
|
"""Simple digital clock application."""
|
||||||
|
NAME = 'WordClk'
|
||||||
|
ICON = icons.app
|
||||||
|
|
||||||
|
def foreground(self):
|
||||||
|
"""Activate the application.
|
||||||
|
|
||||||
|
Configure the status bar, redraw the display and request a periodic
|
||||||
|
tick callback every second.
|
||||||
|
"""
|
||||||
|
wasp.system.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):
|
||||||
|
"""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):
|
||||||
|
"""Periodic callback to update the display."""
|
||||||
|
self._draw()
|
||||||
|
|
||||||
|
def _draw(self, redraw=False):
|
||||||
|
"""Draw or lazily update the display.
|
||||||
|
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
draw = wasp.watch.drawable
|
||||||
|
hi = wasp.system.theme('bright')
|
||||||
|
|
||||||
|
if redraw:
|
||||||
|
now = wasp.watch.rtc.get_localtime()
|
||||||
|
|
||||||
|
# Clear the display and draw that static parts of the watch face
|
||||||
|
draw.fill()
|
||||||
|
|
||||||
|
# Redraw the status bar
|
||||||
|
wasp.system.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 = wasp.system.bar.update()
|
||||||
|
if not now or self._min == now[4]:
|
||||||
|
# Skip the update
|
||||||
|
return
|
||||||
|
draw.set_color(hi)
|
||||||
|
|
||||||
|
# Format the month as text
|
||||||
|
month = now[1] - 1
|
||||||
|
month = MONTH[month*3:(month+1)*3]
|
||||||
|
# Record the minute that is currently being displayed
|
||||||
|
self._hour = now[3]
|
||||||
|
self._min = now[4]
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
# self._hour = 23
|
||||||
|
# self._min = 59
|
||||||
|
|
||||||
|
# Convert to words
|
||||||
|
part_day = ""
|
||||||
|
hour = ""
|
||||||
|
part_hour = ""
|
||||||
|
minute_words= ""
|
||||||
|
|
||||||
|
part_day = ""
|
||||||
|
|
||||||
|
hours_a = ["midnight", "one", "two",
|
||||||
|
"three", "four", "five",
|
||||||
|
"six", "seven", "eight",
|
||||||
|
"nine", "ten", "eleven",
|
||||||
|
"twelve",
|
||||||
|
"one", "two",
|
||||||
|
"three", "four", "five",
|
||||||
|
"six", "seven", "eight",
|
||||||
|
"nine", "ten", "eleven"]
|
||||||
|
if (self._min > 32):
|
||||||
|
hour = hours_a[(self._hour + 1) % 24]
|
||||||
|
else:
|
||||||
|
hour = hours_a[self._hour % 24]
|
||||||
|
if (hour != "midnight" and hour != "twelve"):
|
||||||
|
if (self._hour >= 22):
|
||||||
|
part_day = " at night"
|
||||||
|
elif (self._hour >= 18):
|
||||||
|
part_day = " in the evening"
|
||||||
|
elif (self._hour >= 12):
|
||||||
|
part_day = " in the afternoon"
|
||||||
|
elif (self._hour >= 6):
|
||||||
|
part_day = " in the morning"
|
||||||
|
elif (self._hour >= 3):
|
||||||
|
part_day = " in the early hours"
|
||||||
|
elif (self._hour >= 0):
|
||||||
|
part_day = " at night"
|
||||||
|
|
||||||
|
if (self._min > 57):
|
||||||
|
part_hour = ""
|
||||||
|
elif (self._min > 52):
|
||||||
|
part_hour = "five to "
|
||||||
|
elif (self._min > 47):
|
||||||
|
part_hour = "ten to "
|
||||||
|
elif (self._min > 42):
|
||||||
|
part_hour = "quarter to "
|
||||||
|
elif (self._min > 37):
|
||||||
|
part_hour = "twenty to "
|
||||||
|
elif (self._min > 32):
|
||||||
|
part_hour = "twenty-five to "
|
||||||
|
elif (self._min > 27):
|
||||||
|
part_hour = "half past "
|
||||||
|
elif (self._min > 22):
|
||||||
|
part_hour = "twenty-five past "
|
||||||
|
elif (self._min > 17):
|
||||||
|
part_hour = "twenty past "
|
||||||
|
elif (self._min > 12):
|
||||||
|
part_hour = "quarter past "
|
||||||
|
elif (self._min > 7):
|
||||||
|
part_hour = "ten past "
|
||||||
|
elif (self._min > 2):
|
||||||
|
part_hour = "five past "
|
||||||
|
else:
|
||||||
|
part_hour = ""
|
||||||
|
|
||||||
|
minute_words_int = (self._min % 5)
|
||||||
|
if (minute_words_int == 4):
|
||||||
|
minute_words = "almost"
|
||||||
|
if (minute_words_int == 3):
|
||||||
|
minute_words = "coming up to"
|
||||||
|
if (minute_words_int == 2):
|
||||||
|
minute_words = "after"
|
||||||
|
if (minute_words_int == 1):
|
||||||
|
minute_words = "just gone"
|
||||||
|
|
||||||
|
self._words = ""
|
||||||
|
if (minute_words !=""):
|
||||||
|
self._words = minute_words + "\n"
|
||||||
|
if (part_hour !=""):
|
||||||
|
self._words = self._words + part_hour + "\n"
|
||||||
|
self._words = self._words + hour + "\n"
|
||||||
|
if (part_day !=""):
|
||||||
|
self._words = self._words + part_day
|
||||||
|
|
||||||
|
# No capitilise in Micropython
|
||||||
|
# ASCII convert
|
||||||
|
self._words = chr(ord(self._words[0])-32) + self._words[1:]
|
||||||
|
|
||||||
|
# Some phases may be 5 lines long, some may be 1
|
||||||
|
draw.fill(0, 0, 48)
|
||||||
|
|
||||||
|
chunks = draw.wrap(self._words, 240)
|
||||||
|
lines_of_text = len(chunks)-1
|
||||||
|
offset_y=int(((5-lines_of_text/2)*26))
|
||||||
|
|
||||||
|
for i in range(len(chunks)-1):
|
||||||
|
sub = self._words[chunks[i]:chunks[i+1]].rstrip()
|
||||||
|
draw.string(sub, 0, offset_y+26*i, 240)
|
||||||
|
|
||||||
|
draw.string('{} {} {}'.format(now[2], month, now[0]),
|
||||||
|
0, 214, width=240)
|
Loading…
Reference in a new issue