OBP60v/pages/voltage.py

217 lines
5.9 KiB
Python

"""
Integrierte Spannungsmessung
Ideen:
- Umschaltung Datenquelle: intern, N2K
- Umschaltung analog / digital / Graphik
- Historische Werte vom YD-Batteriemonitor
"""
import cairo
import math
from .page import Page
class Voltage(Page):
avg = (1, 10, 60, 300);
def __init__(self, pageno, cfg, boatdata):
super().__init__(pageno, cfg, boatdata)
self.trend = True
self.mode = 'A'
self.avgindex = 0
self.buttonlabel[1] = 'AVG'
self.buttonlabel[2] = 'MODE'
self.buttonlabel[5] = 'TRD'
self.lastvalue = self.bd.voltage.value
def handle_key(self, buttonid):
if buttonid == 1:
if self.avgindex < len(self.avg) -1:
self.avgindex += 1
else:
self.avgindex = 0
elif buttonid == 2:
if self.mode == 'A':
self.mode = 'D'
else:
self.mode = 'A'
elif buttonid == 5:
self.trend = not self.trend
def setBoatValue(self, boatvalue):
# Einstellen welcher Wert dargestellt werden soll
self.value1 = boatvalue
def draw(self, ctx):
ctx.select_font_face("Ubuntu", cairo.FontSlant.NORMAL, cairo.FontWeight.BOLD)
if self.mode == 'A':
self.draw_analog(ctx)
else:
self.draw_digital(ctx)
def draw_analog(self, ctx):
# TODO schönes Viertelkreis-Instrument
# Skala von 9V bis 15V
# d.h. 90° entsprechend unterteilen in 6 Stücke je 15°
# Beschriftung 10, 11, 12, 13, 14
# Datenquelle
ctx.set_font_size(16)
ctx.move_to(300, 40)
ctx.show_text("Source:")
ctx.move_to(300, 60)
ctx.show_text("VBat")
# Batterietyp
ctx.move_to(300, 90)
ctx.show_text("Type:")
ctx.move_to(300, 110)
ctx.show_text("AGM")
# Glättung
ctx.move_to(300, 140)
ctx.show_text("Avg:")
ctx.move_to(300, 160)
ctx.show_text("1s")
ctx.stroke()
# Gleichstromsymbol
ctx.set_font_size(32)
ctx.move_to(20, 80)
ctx.show_text("V")
ctx.set_line_width(3)
ctx.move_to(20, 86.5) # obere Linie
ctx.line_to(40, 86.5)
ctx.move_to(20, 91.5) # untere drei kurzen Linien
ctx.line_to(25, 91.5)
ctx.move_to(27, 91.5)
ctx.line_to(33, 91.5)
ctx.move_to(35, 91.5)
ctx.line_to(40, 91.5)
ctx.stroke()
# Kreis-segment 90°
# Rotationszentrum
cx = 260
cy = 270
# Radius des Instruments
r = 240
ctx.set_source_rgb(*self.fgcolor)
ctx.set_line_width(2)
ctx.arc(cx, cy, r, math.pi, 1.5*math.pi)
ctx.stroke()
# Beschriftung
ctx.set_font_size(20)
label = {285: "10", 300: "11", 315: "12", 330: "13", 345: "14"}
for angle in label:
x, y = self.rotate((cx, cy), ((cx, cy - r + 30),), angle)[0]
self.draw_text_center(ctx, x, y, label[angle])
# grobe Skala
p = ((cx, cy-r), (cx, cy - r + 12))
ctx.set_line_width(2)
for angle in label:
line = self.rotate((cx, cy), p, angle)
ctx.move_to(*line[0])
ctx.line_to(*line[1])
ctx.stroke()
# feine Skala
p = ((cx, cy-r), (cx, cy - r + 5))
ctx.set_line_width(1)
for angle in [x for x in range(273, 360, 3)]:
if angle in label:
continue
line = self.rotate((cx, cy), p, angle)
ctx.move_to(*line[0])
ctx.line_to(*line[1])
ctx.stroke()
# Zeiger auf 0-Position
val = float(self.bd.voltage.format())
if not val:
angle = -0.5
elif val > 15:
angle = 91
elif val <= 9:
angle = -0.5
else:
angle = (val - 9) * 15
p = ((cx - 2, cy + 4),
(cx - r + 35, cy + 2),
(cx - r + 35, cy + 1),
(cx - r + 5, cy + 1),
(cx - r + 5, cy - 1),
(cx - r + 35, cy - 1),
(cx - r + 35, cy - 2),
(cx - 2, cy - 4))
zeiger = self.rotate((cx, cy), p, angle)
# Zeiger zeichnen
ctx.set_line_width(1)
ctx.move_to(*zeiger[0])
for point in zeiger[1:]:
ctx.line_to(*point)
ctx.fill()
# Zeigerbasis
ctx.arc(cx, cy, 6, 0, 2*math.pi)
ctx.set_source_rgb(*self.bgcolor)
ctx.fill_preserve()
ctx.set_line_width(2)
ctx.set_source_rgb(*self.fgcolor)
ctx.stroke()
def draw_digital(self, ctx):
# Name
ctx.set_font_size(60)
ctx.move_to(20, 100)
ctx.show_text("VBat")
# Unit
ctx.set_font_size(40)
ctx.move_to(270, 100)
ctx.show_text("V")
# Battery type
ctx.set_font_size(16)
ctx.move_to(294, 100)
ctx.show_text("AGM")
# Mittelwert
ctx.move_to(320, 84)
ctx.show_text("Avg: {}s".format(self.avg[self.avgindex]))
ctx.stroke()
ctx.select_font_face("DSEG7 Classic")
ctx.set_font_size(100)
ctx.move_to(40, 240)
ctx.show_text(self.bd.voltage.format())
ctx.stroke()
# Trendanzeige
if self.trend and self.bd.voltage.value and self.lastvalue:
ctx.rectangle(315, 183, 35, 4)
ctx.fill()
size = 11
if self.lastvalue < self.bd.voltage.value:
ctx.move_to(320, 174)
ctx.line_to(320+size*2, 174)
ctx.line_to(320+size, 174-size*2)
ctx.line_to(320, 174)
ctx.fill()
elif self.lastvalue > self.bd.voltage.value:
ctx.move_to(320, 195)
ctx.line_to(320+size*2, 195)
ctx.line_to(320+size, 195+size*2)
ctx.line_to(320, 195)
ctx.fill()
self.lastvalue = self.bd.voltage.value