OBP60v/pages/fluid.py

138 lines
4.1 KiB
Python

"""
Füllstandsanzeige Tank
0: "Fuel",
1: "Water",
2: "Gray Water",
3: "Live Well",
4: "Oil",
5: "Black Water",
6: "Fuel Gasoline",
14: "Error",
15: "Unavailable"
"""
import os
import cairo
import math
from .page import Page
import nmea2000.lookup
class Fluid(Page):
def __init__(self, pageno, cfg, boatdata, fluidtype):
super().__init__(pageno, cfg, boatdata)
self.fluidtype = int(fluidtype)
if self.fluidtype == 0:
self.symbol = cairo.ImageSurface.create_from_png(os.path.join(cfg['imgpath'], "fuelpump.png"))
else:
self.symbol = None
def draw(self, ctx):
# Zentrum Instrument
cx = 200
cy = 150
# Radius
r = 110
# Füllstand von 0 - 100%
# 0 = -120°, 100 = +120°
level = self.bd.tank[0].volume or 0
angle = -120 + level * 2.4
# Rahmen
ctx.set_source_rgb(*self.fgcolor)
ctx.set_line_width(3)
ctx.arc(cx, cy, r, 0, 2*math.pi)
ctx.stroke()
# Symbol, sofern vorhanden
if self.symbol:
ctx.save()
ctx.set_source_surface(self.symbol, cx - 8, cy - 50)
ctx.paint()
ctx.restore()
# Fluidtype
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
ctx.set_font_size(24)
ctx.move_to(20, 60)
ctx.show_text(nmea2000.lookup.fluidtype[self.fluidtype])
ctx.stroke()
# Zeigerrahmen im Zentrum
ctx.arc(cx, cy, 8, 0, 2*math.pi)
ctx.stroke()
# Zeiger in Nullposition
# Variante 1, einseitig
#p = ((cx - 1, cy - (r - 20)), (cx + 1, cy - (r - 20)), (cx + 4, cy), (cx - 4, cy))
# Variante 2, überstehend
p = ((cx - 1, cy - (r - 20)), (cx + 1, cy - (r - 20)), (cx + 6, cy + 15), (cx - 6, cy + 15))
# Zeiger für aktuellen Meßwert
zeiger = self.rotate((cx, cy), p, angle)
# Zeiger zeichnen
ctx.move_to(*zeiger[0])
for point in zeiger[1:]:
ctx.line_to(*point)
ctx.fill()
# Lösche das Zentrum heraus
ctx.set_source_rgb(*self.bgcolor)
ctx.arc(cx, cy, 6, 0, 2*math.pi)
ctx.fill()
ctx.set_source_rgb(*self.fgcolor)
# Simple Skala direkt zeichnen
# 50%-Wert oben in der Mitte
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
ctx.set_font_size(16)
ctx.move_to(cx, cy -r)
ctx.line_to(cx, cy -r + 16)
# linker Anschlag 0%
self.draw_text_center(ctx, cx, cy - r + 30, "1/2")
l = self.rotate((cx, cy), ((cx, cy - r + 16), (cx, cy - r)), -120)
ctx.move_to(*l[0])
ctx.line_to(*l[1])
# rechter Anschlag 100%
l = self.rotate((cx, cy), ((cx, cy - r + 16), (cx, cy - r)), 120)
ctx.move_to(*l[0])
ctx.line_to(*l[1])
# 25%
l = self.rotate((cx, cy), ((cx, cy - r + 16), (cx, cy - r)), -60)
ctx.move_to(*l[0])
ctx.line_to(*l[1])
tx, ty = self.rotate((cx, cy), ((cx, cy - r + 30),), -60)[0]
self.draw_text_center(ctx, tx, ty, "1/4")
# 75%
l = self.rotate((cx, cy), ((cx, cy - r + 16), (cx, cy - r)), 60)
ctx.move_to(*l[0])
ctx.line_to(*l[1])
tx, ty = self.rotate((cx, cy), ((cx, cy - r + 30),), 60)[0]
self.draw_text_center(ctx, tx, ty, "3/4")
ctx.set_font_size(24)
tx, ty = self.rotate((cx, cy), ((cx, cy - r + 30),), -130)[0]
self.draw_text_center(ctx, tx, ty, "E")
tx, ty = self.rotate((cx, cy), ((cx, cy - r + 30),), 130)[0]
self.draw_text_center(ctx, tx, ty, "F")
ctx.stroke()
self.draw_text_center(ctx, cx, cy + r - 20, f"{level:.0f}%")
ctx.stroke()
# Skalenpunkte
# Alle 5% ein Punkt aber nur da wo noch kein Strich ist
for angle in [x for x in range(-120, 120, 12) if x not in (-120, -60, 0, 60, 120)]:
x, y = self.rotate((cx, cy), ((cx, cy - r + 10),), angle)[0]
ctx.arc(x, y, 2, 0, 2*math.pi)
ctx.fill()