# SPDX-License-Identifier: LGPL-3.0-or-later # Copyright (C) 2020 Johannes Wache """Fibonacci clock 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. 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 MONTH = 'JanFebMarAprMayJunJulAugSepOctNovDec' class FibonacciClockApp(): """Displays the time as a Fibonacci Clock """ NAME = 'Fibo' ICON = icons.app def __init__(self): self.meter = wasp.widgets.BatteryMeter() self.fields = b'\x05\x03\x02\x01\x01' self.color_codes = [0xffff,0xf800,0x07e0,0x001f] # White, red, green and blue def foreground(self): """Activate the application.""" self.on_screen = ( -1, -1, -1, -1, -1, -1 ) self.draw() wasp.system.request_tick(1000) def sleep(self): return True def wake(self): self.update() def tick(self, ticks): self.update() def draw(self): """Redraw the display from scratch.""" draw = wasp.watch.drawable draw.fill() 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. """ 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.on_screen = now return False draw = wasp.watch.drawable #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): if ((hr - self.fields[i]) >= 0): hr -= self.fields[i] field_colors[i] += 1 if ((mn - self.fields[i]) >= 0): mn -= self.fields[i] field_colors[i] += 2 draw.fill(x=71,y=51,w=23,h=23,bg=self.color_codes[field_colors[4]]) # 1 field draw.fill(x=71,y=76,w=23,h=23,bg=self.color_codes[field_colors[3]]) # 1 field draw.fill(x=21,y=51,w=48,h=48,bg=self.color_codes[field_colors[2]]) # 2 field draw.fill(x=21,y=101,w=73,h=73,bg=self.color_codes[field_colors[1]]) # 3 field draw.fill(x=96,y=51,w=123,h=123,bg=self.color_codes[field_colors[0]]) # 5 field self.on_screen = now month = now[1] - 1 month = MONTH[month*3:(month+1)*3] draw.string('{}. {} {}'.format(now[2], month, now[0]), 0, 185, width=240) self.meter.update() return True