208 lines
6.2 KiB
Python
208 lines
6.2 KiB
Python
"""
|
|
|
|
Tide Vorausschau
|
|
|
|
"""
|
|
|
|
import cairo
|
|
from .page import Page
|
|
from datetime import datetime
|
|
|
|
class Tide(Page):
|
|
|
|
def __init__(self, pageno, cfg, appdata, boatdata):
|
|
super().__init__(pageno, cfg, appdata, boatdata)
|
|
|
|
self.buttonlabel[1] = 'MODE'
|
|
self.mode = 'N' # (N)ormal, (C)onfiguration
|
|
|
|
self.station = "f3c6ee73-5561-4068-96ec-364016e7d9ef" # Schulau
|
|
self.pegel = 'List, Sylt'
|
|
self.app.web.set_pegel(self.pegel)
|
|
self.app.web.refresh()
|
|
|
|
# Steuerung der Stationsliste
|
|
self.list_max = 10
|
|
self.list_top = 0
|
|
self.list_ix = 0
|
|
self.list_pegel = self.pegel
|
|
self.list_count = len(self.app.web.pegeldata)
|
|
|
|
def handle_key(self, buttonid):
|
|
if buttonid == 1:
|
|
if self.mode == 'N':
|
|
self.mode = 'C'
|
|
self.buttonlabel[3] = '#UP'
|
|
self.buttonlabel[4] = '#DOWN'
|
|
self.buttonlabel[5] = 'SET'
|
|
else:
|
|
self.mode = 'N'
|
|
self.buttonlabel[3] = '#PREV'
|
|
self.buttonlabel[4] = '#NEXT'
|
|
self.buttonlabel[5] = ''
|
|
return True
|
|
if self.mode == 'C':
|
|
if buttonid == 3:
|
|
# Up
|
|
self.list_ix -= 1
|
|
if self.list_ix < self.list_top:
|
|
self.list_top -= 1
|
|
elif buttonid == 4:
|
|
# Down
|
|
self.list_ix += 1
|
|
if self.list_ix > self.list_top + self.list_max:
|
|
self.list_top += 1
|
|
elif buttonid == 5:
|
|
# Set
|
|
print(self.list_pegel)
|
|
self.pegel = self.list_pegel
|
|
self.app.web.set_pegel(self.list_pegel)
|
|
self.app.web.refresh()
|
|
return True
|
|
return False
|
|
|
|
def draw_config(self, ctx):
|
|
# Auswahl
|
|
# - Station
|
|
# - Zeitraum
|
|
#
|
|
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
|
ctx.set_font_size(20)
|
|
|
|
ctx.move_to(2, 50)
|
|
ctx.show_text("Tide configuration")
|
|
|
|
y = 80
|
|
dy = 20
|
|
ctx.set_font_size(20)
|
|
i = 0
|
|
ix = -1
|
|
for pd in self.app.web.pegeldata:
|
|
ix += 1
|
|
if ix < self.list_top:
|
|
continue
|
|
ctx.move_to(20, y + dy * i)
|
|
ctx.show_text(pd)
|
|
self.list_pegel = pd
|
|
if self.list_ix == ix:
|
|
ctx.show_text(' X')
|
|
i += 1
|
|
if self.pegel == pd:
|
|
ctx.show_text(' *')
|
|
if ix > self.list_top + self.list_max - 1:
|
|
break
|
|
|
|
def draw_normal(self, ctx):
|
|
# Title
|
|
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
|
|
ctx.set_font_size(24)
|
|
ctx.move_to(8, 40)
|
|
ctx.show_text("Tide prediction")
|
|
ctx.set_font_size(10)
|
|
|
|
# Daten holen
|
|
self.app.web.set_timestamp(2, 48)
|
|
ymin, ymax = self.app.web.get_tide_minmax()
|
|
rawdata = self.app.web.get_tide()
|
|
|
|
# scale_y_step
|
|
scale_y_step = 50
|
|
ymin = min(ymin, self.app.web.tide['MNW']) - 10
|
|
ymin = (ymin // scale_y_step - 1) * scale_y_step
|
|
ymax = max(ymax, self.app.web.tide['MHW']) + 10
|
|
ymax = (ymax // scale_y_step + 1) * scale_y_step
|
|
#self.tide['warning'] = wvdata["warning"]
|
|
#self.tide['forecast_ts'] = wvdata["creation_forecast"]
|
|
|
|
x0 = 40 # links unten
|
|
y0 = 250
|
|
x1 = 380 # rechts oben
|
|
y1 = 60
|
|
|
|
ctx.set_line_width(1)
|
|
ctx.set_dash((2, 2), 0)
|
|
y = (self.app.web.tide['MNW'] - ymin) / (ymax - ymin) * (y0 - y1)
|
|
ctx.move_to(x0 - 8, y0 - y)
|
|
ctx.line_to(x1 + 8, y0 - y)
|
|
y = (self.app.web.tide['MHW'] - ymin) / (ymax - ymin) * (y0 - y1)
|
|
ctx.move_to(x0 - 8, y0 - y)
|
|
ctx.line_to(x1 + 8, y0 - y)
|
|
ctx.stroke()
|
|
ctx.set_dash([])
|
|
|
|
ctx.set_font_size(16)
|
|
ctx.set_line_width(2)
|
|
|
|
ctx.move_to(220, 40)
|
|
self.draw_text_ralign(ctx, 392, 36, self.app.web.tide['station'])
|
|
|
|
ctx.move_to(8, 50)
|
|
calc_ts = datetime.fromisoformat(self.app.web.tide['forecast_ts'])
|
|
self.draw_text_ralign(ctx, 392, 52, "calc: " + calc_ts.strftime('%H:%M'))
|
|
#self.tide['area'] = wvdata["area"]
|
|
|
|
# X-Achse
|
|
ctx.move_to(x0 + 0.5, y0 + 0.5)
|
|
ctx.line_to(x0 + 0.5, y1 + 0.5)
|
|
ctx.stroke()
|
|
|
|
# Pfeilspitze Y
|
|
ctx.move_to(x1 + 0.5, y0 + 0.5 - 4)
|
|
ctx.line_to(x1 + 0.5 + 12, y0 + 0.5)
|
|
ctx.line_to(x1 + 0.5, y0 + 0.5 + 4)
|
|
ctx.close_path()
|
|
ctx.fill()
|
|
|
|
# Pfeilspitze Y
|
|
ctx.move_to(x0 + 0.5 - 4, y1 + 0.5)
|
|
ctx.line_to(x0 + 0.5, y1 + 0.5 - 12)
|
|
ctx.line_to(x0 + 0.5 + 4, y1 + 0.5)
|
|
ctx.close_path()
|
|
ctx.fill()
|
|
|
|
# self.draw_text_center(ctx, x0 - 20, y0 + (y1 -y0) / 2, "Höhe, cm", rotate=True)
|
|
self.draw_text_center(ctx, 60, 150, "height, cm", rotate=True)
|
|
#self.draw_text_center(ctx, 100, 100, "Höhe, cm", rotate=False)
|
|
#ctx.move_to(90, 90) # Rotationsursprung
|
|
#ctx.line_to(110, 110)
|
|
#ctx.move_to(90, 110)
|
|
#ctx.line_to(110, 90)
|
|
#ctx.stroke()
|
|
|
|
# Y-Achse
|
|
ctx.move_to(x0 + 0.5, y0 + 0.5)
|
|
ctx.line_to(x1 + 0.5, y0 + 0.5)
|
|
self.draw_text_center(ctx, x0 + (x1 - x0) / 2, y0 + 12, "time, h")
|
|
ctx.stroke()
|
|
|
|
ctx.move_to(x0 - 32, y0 + 8)
|
|
ctx.show_text(str(ymin))
|
|
|
|
ctx.move_to(x0 - 32, y1 + 8)
|
|
ctx.show_text(str(ymax))
|
|
|
|
# Anzahl Meßwerte für die X-Achse
|
|
#ctx.move_to(x0 + 16, y0 + 16)
|
|
#ctx.show_text(f"n = {len(rawdata)}")
|
|
|
|
dx = (x1 - x0) / len(rawdata)
|
|
x = x0
|
|
prev_valid = False
|
|
for val in rawdata:
|
|
if val is not None:
|
|
y = (val - ymin) / (ymax - ymin) * (y0 - y1)
|
|
if prev_valid:
|
|
ctx.line_to(x, y0 - y)
|
|
else:
|
|
ctx.move_to(x, y0 - y)
|
|
prev_valid = True
|
|
else:
|
|
prev_valid = False
|
|
x += dx
|
|
|
|
def draw(self, ctx):
|
|
if self.mode == 'N':
|
|
self.draw_normal(ctx)
|
|
else:
|
|
self.draw_config(ctx)
|