OBP60v/pages/tide.py

127 lines
3.8 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.station = "f3c6ee73-5561-4068-96ec-364016e7d9ef" # Schulau
self.app.web.set_pegel('List, Sylt')
self.app.web.refresh()
def draw(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