OBP60v/pages/clock.py

210 lines
6.1 KiB
Python

"""
Uhr
TODO: Zeitzone anzeigen. Abhängig von Lat, Lon
Es sollen verschiedene Modi unterstützt werden
- Analoguhr
- Digitaluhr
- Regattauhr / -timer
"""
import os
import cairo
import math
from .page import Page
from datetime import datetime
import astral
class Clock(Page):
def __init__(self, pageno, cfg, boatdata):
super().__init__(pageno, cfg, boatdata)
self.buttonlabel[1] = 'MODE'
self.buttonlabel[2] = 'TZ'
self.mode = ('A', 'D', 'T') # (A)nalog (D)igital (T)imer
self.modeindex = 1
self.utc = True
self.location = astral.Location(('Norderstedt', 'Germany', 53.710105, 10.0574378, 'UTC'))
self.location.astral = astral.Astral()
self.bgimg = cairo.ImageSurface.create_from_png(os.path.join(cfg['imgpath'], "unknown.png"))
def handle_key(self, buttonid):
if buttonid == 1:
if self.modeindex < len(self.mode) - 1:
self.modeindex += 1
else:
self.modeindex = 0
return True
if buttonid == 2:
self.utc = not self.utc
return True
return False
def draw(self, ctx):
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
# akuellen Modus anzeigen
if self.mode[self.modeindex] == 'A':
self.draw_analog(ctx)
elif self.mode[self.modeindex] == 'D':
self.draw_digital(ctx)
else:
self.draw_timer(ctx)
def draw_digital(self, ctx):
ts = datetime.now()
ctx.set_font_size(20)
ctx.move_to(10, 60)
ctx.show_text("RTC")
ctx.select_font_face("DSEG7 Classic")
ctx.set_font_size(80)
# Zentrieren funktioniert nicht richtig, da der Leerraum vor der "1"
# mitgerechnet wird. Dafür muß ggf. der Zeichensatz angepaßt werden.
# self.draw_text_center(ctx, 200, 150, ts.strftime("%H:%M:%S"))
ctx.move_to(-30, 200)
ctx.show_text(ts.strftime("%H:%M:%S"))
def draw_timer(self, ctx):
ts = datetime.now()
ctx.set_font_size(24)
ctx.move_to(10, 50)
ctx.show_text("Race Timer")
ctx.select_font_face("AtariST8x16SystemFont")
ctx.set_font_size(16)
self.draw_text_center(ctx, 200, 230, "Here be dragons")
ctx.save()
ctx.set_source_surface(self.bgimg, 140, 80)
ctx.paint()
ctx.restore()
def draw_analog(self, ctx):
ts = datetime.now()
sunrise = self.location.sunrise(ts)
sunset = self.location.sunset(ts)
#print(sunrise)
#print(sunset)
# Datum und Uhrzeit
# Sonnenaufgang
# Sonnenuntergang
# Wochentag
# ts.strftime('%a')
# Werte in den Ecken der Uhr
ctx.set_font_size(24)
ctx.move_to(10, 220)
ctx.show_text("Time")
ctx.move_to(10, 95)
ctx.show_text("Date")
ctx.move_to(335, 95)
ctx.show_text("SunR")
ctx.move_to(335, 220)
ctx.show_text("SunS")
ctx.stroke()
ctx.set_font_size(16)
ctx.move_to(10, 65)
ctx.show_text(ts.strftime("%d.%m.%Y"))
ctx.move_to(10, 250)
ctx.show_text(ts.strftime("%H:%M"))
ctx.move_to(335, 65)
ctx.show_text(sunrise.strftime("%H:%M"))
ctx.move_to(335, 250)
ctx.show_text(sunset.strftime("%H:%M"))
ctx.stroke()
# Horizontal separators
ctx.rectangle(0, 149, 60, 3)
ctx.rectangle(340, 149, 60, 3)
ctx.fill()
# Uhr
cx = 200
cy = 150
r = 110
ctx.arc(cx, cy, r + 10, 0, 2*math.pi)
ctx.arc(cx, cy, r + 7, 0, 2*math.pi)
ctx.stroke()
ctx.set_font_size(20)
self.draw_text_center(ctx, cx, cy-40, 'UTC' if self.utc else 'LOT')
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
ctx.set_font_size(24)
for i in range(360):
x = cx + (r - 30) * math.sin(i/180*math.pi)
y = cy - (r - 30) * math.cos(i/180*math.pi)
char = ""
if i == 0:
char = "12"
elif i == 90:
char = "3"
elif i == 180:
char = "6"
elif i == 270:
char = "9"
if i % 90 == 0:
#ctx.move_to(x, y)
self.draw_text_center(ctx, x, y, char)
#ctx.stroke()
ctx.set_line_width(3.0)
if i % 6 == 0:
if i % 30 == 0:
x0 = cx + (r - 10) * math.sin(i/180*math.pi)
y0 = cy - (r - 10) * math.cos(i/180*math.pi)
x1 = cx + (r + 10) * math.sin(i/180*math.pi)
y1 = cy - (r + 10) * math.cos(i/180*math.pi)
ctx.move_to(x0, y0)
ctx.line_to(x1, y1)
ctx.stroke()
else:
x = cx + r * math.sin(i/180*math.pi)
y = cy - r * math.cos(i/180*math.pi)
ctx.arc(x, y, 2, 0, 2*math.pi)
ctx.fill()
# Stundenzeiger
p = ((cx - 2, cy - (r - 50)), (cx + 2, cy - (r - 50)), (cx + 6, cy + 16), (cx - 6, cy + 16))
angle_h = (ts.hour % 12 + ts.minute / 60) * 30
zeiger = self.rotate((cx, cy), p, angle_h)
ctx.move_to(*zeiger[0])
for point in zeiger[1:]:
ctx.line_to(*point)
ctx.fill()
# Minutenzeiger
p = ((cx - 1, cy - (r - 15)), (cx + 1, cy - (r - 15)), (cx + 6, cy + 20), (cx - 6, cy + 20))
angle_m = ts.minute * 6
zeiger = self.rotate((cx, cy), p, angle_m)
ctx.move_to(*zeiger[0])
for point in zeiger[1:]:
ctx.line_to(*point)
ctx.fill()
# Zentraler Kreis
ctx.set_source_rgb(0, 0, 0)
ctx.arc(cx, cy, 12, 0, 2*math.pi)
ctx.fill()
# Wozu dieses?
ctx.set_source_rgb(0.86, 0.86, 0.86)
ctx.arc(cx, cy, 10, 0, 2*math.pi)
ctx.fill()
ctx.set_source_rgb(0, 0, 0)
ctx.arc(cx, cy, 2, 0, 2*math.pi)
ctx.fill()