2020-10-10 14:12:18 +02:00
|
|
|
# SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
# Copyright (C) 2020 Johannes Wache
|
2020-10-25 09:55:00 +01:00
|
|
|
|
2020-10-10 14:12:18 +02:00
|
|
|
"""Fibonacci clock
|
2020-10-25 09:55:00 +01:00
|
|
|
~~~~~~~~~~~~~~~~~~
|
2020-10-10 14:12:18 +02:00
|
|
|
|
|
|
|
The Fibonacci sequence is a sequence of numbers created by the Italian
|
|
|
|
mathematician Fibonacci in the 13th century. This is a sequence starting with
|
|
|
|
1 and 1, where each subsequent number is the sum of the previous two. For the
|
|
|
|
clock I used the first 5 terms: 1, 1, 2, 3 and 5.
|
|
|
|
|
2020-11-08 15:28:38 +01:00
|
|
|
.. figure:: res/FiboApp.png
|
|
|
|
:width: 179
|
|
|
|
|
|
|
|
Screenshot of the fibonacci clock application
|
|
|
|
|
2020-10-10 14:12:18 +02:00
|
|
|
The screen of the clock is made up of five squares whose side lengths match
|
|
|
|
the first five Fibonacci numbers: 1, 1, 2, 3 and 5. The hours are displayed
|
|
|
|
using red and the minutes using green. When a square is used to display both
|
|
|
|
the hours and minutes it turns blue. White squares are ignored.
|
|
|
|
|
|
|
|
To tell time on the Fibonacci clock you need to do some calculations. To read
|
|
|
|
the hour, simply add up the corresponding values of the red and blue squares.
|
|
|
|
To read the minutes, do the same with the green and blue squares. The minutes
|
|
|
|
are displayed in 5 minute increments (0 to 12) so you have to multiply your
|
|
|
|
result by 5 to get the actual number.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import wasp
|
|
|
|
import icons
|
|
|
|
|
2020-10-25 09:55:00 +01:00
|
|
|
COLORS = [0xffff,0xf800,0x07e0,0x001f] # White, red, green and blue
|
|
|
|
FIELDS = b'\x05\x03\x02\x01\x01'
|
2020-10-10 14:12:18 +02:00
|
|
|
MONTH = 'JanFebMarAprMayJunJulAugSepOctNovDec'
|
|
|
|
|
2020-10-10 15:06:44 +02:00
|
|
|
# 2-bit RLE, generated from res/fibo_icon.png, 246 bytes
|
|
|
|
icon = (
|
|
|
|
b'\x02'
|
|
|
|
b'`@'
|
|
|
|
b'?\xff\xffk\xd3\x01\xc9\x01@\x1er\x10\xd3\x01\xc9\x01'
|
|
|
|
b'r\x10\xd3\x01\xc9\x01r\x10\xd3\x01\xc9\x01r\x10\xd3\x01'
|
|
|
|
b'\xc9\x01r\x10\xd3\x01\xc9\x01r\x10\xd3\x01\xc9\x01r\x10'
|
|
|
|
b'\xd3\x01\xc9\x01r\x10\xd3\x01\xc9\x01r\x10\xd3\x0br\x10'
|
|
|
|
b'\xd3\x01I\x01r\x10\xd3\x01I\x01r\x10\xd3\x01I\x01'
|
|
|
|
b'r\x10\xd3\x01I\x01r\x10\xd3\x01I\x01r\x10\xd3\x01'
|
|
|
|
b'I\x01r\x10\xd3\x01I\x01r\x10\xd3\x01I\x01r\x10'
|
|
|
|
b'\xd3\x01I\x01r.r\x10\xdd\x01r\x10\xdd\x01r\x10'
|
|
|
|
b'\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10'
|
|
|
|
b'\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10'
|
|
|
|
b'\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10'
|
|
|
|
b'\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10'
|
|
|
|
b'\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10'
|
|
|
|
b'\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10'
|
|
|
|
b'\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r\x10\xdd\x01r?'
|
|
|
|
b'\xff\xffk'
|
|
|
|
)
|
|
|
|
|
2020-10-10 14:12:18 +02:00
|
|
|
class FibonacciClockApp():
|
2020-11-08 15:28:38 +01:00
|
|
|
"""Displays the time as a Fibonacci Clock.
|
2020-10-10 14:12:18 +02:00
|
|
|
"""
|
|
|
|
NAME = 'Fibo'
|
2020-10-10 15:06:44 +02:00
|
|
|
ICON = icon
|
2020-10-10 14:12:18 +02:00
|
|
|
|
|
|
|
def foreground(self):
|
|
|
|
"""Activate the application."""
|
2020-11-04 20:00:37 +01:00
|
|
|
wasp.system.bar.clock = False
|
2020-10-25 09:55:00 +01:00
|
|
|
self._draw(True)
|
2020-10-10 14:12:18 +02:00
|
|
|
wasp.system.request_tick(1000)
|
|
|
|
|
|
|
|
def sleep(self):
|
|
|
|
return True
|
|
|
|
|
|
|
|
def wake(self):
|
2020-10-25 09:55:00 +01:00
|
|
|
self._draw()
|
2020-10-10 14:12:18 +02:00
|
|
|
|
|
|
|
def tick(self, ticks):
|
2020-10-25 09:55:00 +01:00
|
|
|
self._draw()
|
2020-10-10 14:12:18 +02:00
|
|
|
|
2020-10-25 09:55:00 +01:00
|
|
|
def _draw(self, redraw=False):
|
|
|
|
"""Draw or lazily update the display."""
|
2020-10-10 14:12:18 +02:00
|
|
|
draw = wasp.watch.drawable
|
|
|
|
|
2020-10-25 09:55:00 +01:00
|
|
|
if redraw:
|
|
|
|
now = wasp.watch.rtc.get_localtime()
|
|
|
|
draw.fill()
|
2020-11-04 20:00:37 +01:00
|
|
|
wasp.system.bar.draw()
|
2020-10-25 09:55:00 +01:00
|
|
|
else:
|
2020-11-04 20:00:37 +01:00
|
|
|
now = wasp.system.bar.update()
|
2020-10-25 09:55:00 +01:00
|
|
|
if not now or self._min == now[4]:
|
|
|
|
return
|
2020-10-10 14:12:18 +02:00
|
|
|
|
|
|
|
#calculate colors of fields:
|
|
|
|
field_colors = bytearray(5)
|
|
|
|
hr = now[3]
|
|
|
|
mn = now[4] // 5 # Clock can only display every 5 minutes
|
|
|
|
if (hr >= 12):
|
|
|
|
hr -= 12
|
|
|
|
for i in range(5):
|
2020-10-25 09:55:00 +01:00
|
|
|
if ((hr - FIELDS[i]) >= 0):
|
|
|
|
hr -= FIELDS[i]
|
2020-10-10 14:12:18 +02:00
|
|
|
field_colors[i] += 1
|
|
|
|
|
2020-10-25 09:55:00 +01:00
|
|
|
if ((mn - FIELDS[i]) >= 0):
|
|
|
|
mn -= FIELDS[i]
|
2020-10-10 14:12:18 +02:00
|
|
|
field_colors[i] += 2
|
|
|
|
|
2020-10-25 09:55:00 +01:00
|
|
|
draw.fill(x=71,y=60,w=23,h=23,bg=COLORS[field_colors[4]]) # 1 field
|
|
|
|
draw.fill(x=71,y=85,w=23,h=23,bg=COLORS[field_colors[3]]) # 1 field
|
|
|
|
draw.fill(x=21,y=60,w=48,h=48,bg=COLORS[field_colors[2]]) # 2 field
|
|
|
|
draw.fill(x=21,y=110,w=73,h=73,bg=COLORS[field_colors[1]]) # 3 field
|
|
|
|
draw.fill(x=96,y=60,w=123,h=123,bg=COLORS[field_colors[0]]) # 5 field
|
2020-10-10 14:12:18 +02:00
|
|
|
|
|
|
|
month = now[1] - 1
|
|
|
|
month = MONTH[month*3:(month+1)*3]
|
2020-10-10 22:38:48 +02:00
|
|
|
draw.string('{} {} {}'.format(now[2], month, now[0]),
|
|
|
|
0, 202, width=240)
|
2020-10-10 14:12:18 +02:00
|
|
|
|
2020-10-25 09:55:00 +01:00
|
|
|
# Record the minute that is currently being displayed
|
|
|
|
self._min = now[4]
|