Compare commits
73 Commits
81836bc5f1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| ba43c3147e | |||
| 1661c81dfa | |||
| cd04a5560d | |||
| 9ffb28d65b | |||
| 7613a5b7cb | |||
| f969df8cb8 | |||
| e7a2f4bb54 | |||
| e9d473fd10 | |||
| fb7c688a99 | |||
| 99dcf00242 | |||
| 2572d156e0 | |||
| de1cff974d | |||
| 8d75782ae8 | |||
| d4ac504e08 | |||
| fd5b2c96b9 | |||
| adb1b4e63a | |||
| a5baea524e | |||
| f6f515ea14 | |||
| f47379b6d3 | |||
| e7a96390f2 | |||
| f0ebdd0201 | |||
| e5646b6f27 | |||
| 84a99a747e | |||
| bcbaa25cf5 | |||
| 65335e3c91 | |||
| eab6cdf4c9 | |||
| d3a984075e | |||
| fc87a5959d | |||
| 9b4811a11d | |||
| eb41bdafa4 | |||
| ebb7b42d48 | |||
| 766b191109 | |||
| f3c9ced477 | |||
| 20882feeca | |||
| defe4e3c03 | |||
| 5b000f4f1f | |||
| 612783454e | |||
| b1d0687952 | |||
| acbcfac425 | |||
| fd673d5e55 | |||
| 4ba75b5686 | |||
| e738438a94 | |||
| 14108b1165 | |||
| 7d8ce221fd | |||
| be20826ab5 | |||
| d7136e38bf | |||
| dafcfaca6b | |||
| 986d222a98 | |||
| 664d6c7d49 | |||
| 5d8b33b086 | |||
| ae38d2b681 | |||
| 7f0a0f280b | |||
| 658806446e | |||
| 7d3a113ba3 | |||
| 46295f8139 | |||
| f7337a0c6c | |||
| 9e4622aeef | |||
| df04c9ad8e | |||
| b1fdb592b0 | |||
| 6214d08174 | |||
| aefd01e0f9 | |||
| b06d88d0ec | |||
| bae459c4d4 | |||
| 8b5168a83e | |||
| 5c2f058888 | |||
| e94f6df408 | |||
| 013cd5f5e9 | |||
| b85cfa1467 | |||
| baf19fb024 | |||
| 0114f25689 | |||
| 2992fed56b | |||
| 624534bff1 | |||
| ea82d5731e |
2
.gitignore
vendored
@@ -1,2 +1,4 @@
|
||||
*~
|
||||
__pycache__
|
||||
nmea2000
|
||||
obp60v.conf
|
||||
|
||||
26
INSTALL
@@ -4,12 +4,30 @@ erforderlich. Die unten angegebenen Abhängigkeiten müssen erfüllt sein.
|
||||
Python muß mindestens Version 3.10 sein.
|
||||
|
||||
apt-get install python3-cairo python3-gi python3-gi-cairo gir1.2-rsvg-2.0 \
|
||||
python-serial python3-nmea2 python3-smbus2 python3-bme280
|
||||
python3-serial python3-nmea2 python3-smbus2 python3-bme280 python3-astral \
|
||||
python3-can python3-paho-mqtt python3-setproctitle gir1.2-gtk-3.0
|
||||
|
||||
Das Programm wird über eine Konfigurationsdatei obp60.conf im gleichen
|
||||
Zusätzlich zu diesem Programm muß auch die zugehörige NMEA2000-Bibliothek
|
||||
für Python vorhanden sein. Diese kann momentan am besten parallel zu dem
|
||||
OBP60v-Verzeichnis installiert werden:
|
||||
git clone https://git.hoogi.de/thooge/nmea2000
|
||||
cd OBP60v
|
||||
ln -s ../nmea2000 .
|
||||
|
||||
Das Programm wird über eine Konfigurationsdatei obp60v.conf im gleichen
|
||||
Verzeichnis wie das Hauptprogramm gesteuert. Die Konfiguration wird
|
||||
einmalig beim Programmstart eingelesen.
|
||||
einmalig beim Programmstart eingelesen. Dazu kann die Vorlage kopiert
|
||||
werden:
|
||||
cp obp60v.conf-sample obp60v.conf
|
||||
|
||||
Meßdaten werden im Homeverzeichnis unter ~/.local/lib/obp60 gespeichert.
|
||||
Die Schriftarten aus dem fonts-Verzeichnis müssen in /usr/local/share/fonts
|
||||
abgelegt werden.
|
||||
sudo cp -a fonts/* /usr/local/share/fonts
|
||||
|
||||
Meßdaten werden im Homeverzeichnis unter ~/.local/lib/obp60v gespeichert.
|
||||
Dies betrifft momentan Luftdruckmessungen mit dem BME280.
|
||||
Das Verzeichnis wird automatisch angelegt.
|
||||
|
||||
Wenn das GUI-Fenster an den Ecken schwarze Stellen hat, dann ist vermutlich
|
||||
kein Kompositor vorhanden. Nachinstallieren z.B.:
|
||||
apt-get install xcompmgr
|
||||
|
||||
46
README
@@ -11,32 +11,58 @@ Für Informationen zum OBP60 in Hardware siehe:
|
||||
Fehlermeldungen und Patches gerne an thomas@hoogi.de senden.
|
||||
|
||||
Basishardware
|
||||
- Raspberry Pi 4
|
||||
- Raspberry Pi 4 / 4GB
|
||||
|
||||
Zusatzhardware:
|
||||
- NMEA2000 Interface
|
||||
- PiCAN-M (hiermit wird entwickelt)
|
||||
- Waveshare RS485 CAN HAT (ungetestet)
|
||||
oder
|
||||
- Waveshare RS485 CAN HAT (getestet)
|
||||
- BME280-Sensor über I2C
|
||||
- RTC mit DS3231 über I2C
|
||||
- GPS über USB/seriell angeschlossen
|
||||
|
||||
Zusatzsoftware:
|
||||
- OpenCPN
|
||||
|
||||
Abhängigkeiten
|
||||
- python-can
|
||||
- heapdict
|
||||
- python3-can für das N2K-Interface
|
||||
- python3-astral für Sonnenauf- und -untergang
|
||||
- python3-heapdict
|
||||
- python3-setproctitle
|
||||
|
||||
Für GPS
|
||||
- python-serial
|
||||
Für GPS und/oder NMEA0183
|
||||
- python3-serial
|
||||
- python3-nmea2
|
||||
Achtung: in Debian ist Version 1.15, die aktuelle Version 1.19 hat
|
||||
weitere Satzarten implementiert. Allerdings ist dort auch kein AIS
|
||||
vorhanden.
|
||||
|
||||
Für BME280
|
||||
- smbus2
|
||||
- bme280
|
||||
- python3-smbus2
|
||||
- python3-bme280
|
||||
|
||||
Für den Tracker
|
||||
- python3-paho-mqtt
|
||||
|
||||
Die Konfiguration des virtuellen Geräts erfolgt über die Datei "obp60.conf".
|
||||
Die Einstellungen sollten vor dem ersten Start überprüft und ggf. angepaßt
|
||||
werden.
|
||||
|
||||
Es gibt zwei Darstellungsmodi: Standard und Vollbild
|
||||
Der Standardmodus sollte im Design möglichst nahme am Original OBP60 liegen.
|
||||
Es ist ein Fenster was immer im Vordergrund liegt, sich jedoch auf dem
|
||||
Bildschirm positionieren läßt.
|
||||
Der Vollbildmodus ist für das Display des OBP60P gedacht und setzt eine
|
||||
physische Bildschirmauflösung von 800x480 Pixeln voraus.
|
||||
Der Modus kann vor dem Programmstart in der Konfigurationsdatei obp60.conf
|
||||
eingestellt werden:
|
||||
[system]
|
||||
guistyle = default | fullscreen
|
||||
|
||||
Zur Steuerung des Geräts sind 6 Tasten vorhanden. Numeriert von 1 bis 6 von
|
||||
links nach rechts. Die Tasten können angeklickt werden und führen dann direkt
|
||||
links nach rechts bzw. von oben nach unten im Vollbildmodus.
|
||||
Die Tasten können angeklickt werden und führen dann direkt
|
||||
eine von der jeweiligen Seite abhängige Funktion aus.
|
||||
Die jeweilige Funktion wird durch ein Symbol oberhalb der Taste dargestellt.
|
||||
Die Tasten 3 und 4 sind für die Seitennavigation vorgesehen: zurück und vor.
|
||||
@@ -53,7 +79,7 @@ Folgende Wischfunktionen sind implementiert:
|
||||
|
||||
Routen und Wegepunkte können von OpenCPN empfangen werden. Dazu muß eine
|
||||
passende serielle Schnittstelle für den NMEA0183-Ausgang definiert werden.
|
||||
Im System kann diese in der Datei rc.local aktiviert werden:
|
||||
Im System kann diese in der Datei z.B. rc.local aktiviert werden:
|
||||
# Create virtual serial connection
|
||||
socat pty,rawer,echo=0,group-late=dialout,mode=0660,link=/dev/ttyV0 \
|
||||
pty,rawer,echo=0,group-late=dialout,mode=0660,link=/dev/ttyV1 &
|
||||
|
||||
38
TODO
@@ -1,4 +1,26 @@
|
||||
Aufgaben- und Planungs- und Ideenliste
|
||||
Aufgaben, Planungs- und Ideenliste
|
||||
|
||||
- Tracker
|
||||
a) Regatta Hero
|
||||
python3-paho-mqtt benötigt
|
||||
b) lokal
|
||||
c) Server
|
||||
|
||||
- Internationalisierung
|
||||
1. EN (Standardsprache)
|
||||
2. DE
|
||||
3. FR
|
||||
4. ES
|
||||
5. IT
|
||||
|
||||
- Satelliten: SatelliteList verwenden und dieses auch in
|
||||
nmea2000 implementieren
|
||||
- Satellitenübersicht / SkyView
|
||||
Kreis mit Sats
|
||||
Rechtecke mit SNR (Signal/Noise)
|
||||
|
||||
- datareader für mehrere I²C-Sensoren. History muß entsprechend
|
||||
eine Liste sein.
|
||||
|
||||
- Barograph
|
||||
|
||||
@@ -6,8 +28,14 @@ Aufgaben- und Planungs- und Ideenliste
|
||||
Kreis um Position, Liste letzter Positionen
|
||||
Tasten: Set/Clear, Radius+, Radius-
|
||||
|
||||
- Satellitenübersicht / SkyView
|
||||
Kreis mit Sats
|
||||
Rechtecke mit SNR (Signal/Noise)
|
||||
|
||||
- Sea wave recorder (siehe Steamrock)
|
||||
|
||||
- Datenübertragung über Ethernet
|
||||
Achtung: Fast Packets
|
||||
- SeaSmart
|
||||
NMEA2000 in NMEA0183 gekapselt
|
||||
- Yacht Devices ASCII Raw Protokoll
|
||||
https://www.yachtd.com/downloads/ydnr02.pdf
|
||||
- Actisense?
|
||||
|
||||
- AIS
|
||||
|
||||
80
appdata.py
Normal file
@@ -0,0 +1,80 @@
|
||||
"""
|
||||
Generische Applikationsdaten
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
from web import WebInterface
|
||||
from tracker import Tracker
|
||||
from navtex import NAVTEX
|
||||
from mapservice import MapService
|
||||
|
||||
class AppData():
|
||||
|
||||
def __init__(self, logger, cfg):
|
||||
self.shutdown = False # Globaler Ausschalter
|
||||
self.log = logger
|
||||
if cfg['navtex']:
|
||||
self.navtex = NAVTEX(logger, cfg)
|
||||
else:
|
||||
self.navtex = None
|
||||
if cfg['tide']:
|
||||
self.web = WebInterface(logger, cfg)
|
||||
else:
|
||||
self.web = None
|
||||
self.track = Tracker(logger, cfg)
|
||||
self.mapsrv = MapService(logger, cfg)
|
||||
self.frontend = None
|
||||
self.bv_lat = None
|
||||
self.bv_lon = None
|
||||
|
||||
# Für u.a. Header-Indikatoren
|
||||
# TODO
|
||||
self.status = {
|
||||
'AP': False, # Accesspoint
|
||||
'WIFI': False, # Wireless Client
|
||||
'TCP': False, # TCP Network
|
||||
'N2K': False, # NMEA2000
|
||||
'183': False, # NMEA0183
|
||||
'USB': False, # USB Datenverbindung
|
||||
'GPS': False, # GPS-Fix und -daten
|
||||
'TRK': False # Tracker
|
||||
}
|
||||
|
||||
def setFrontend(self, frontend):
|
||||
self.frontend = frontend # Referenz zur GUI
|
||||
self.bv_lat = frontend.boatdata.getRef("LAT")
|
||||
self.bv_lon = frontend.boatdata.getRef("LON")
|
||||
|
||||
def refreshStatus(self):
|
||||
self.status['AP'] = False # nicht implementiert
|
||||
|
||||
self.status['TCP'] = False
|
||||
self.status['WIFI'] = False
|
||||
for intf in os.listdir('/sys/class/net'):
|
||||
statefile = os.path.join('/sys/class/net', intf, 'operstate')
|
||||
wififile = os.path.join('/sys/class/net', intf, 'wireless')
|
||||
if os.path.exists(statefile):
|
||||
with open(statefile) as fh:
|
||||
state = fh.read().strip()
|
||||
if state == 'up':
|
||||
if os.path.exists(wififile):
|
||||
self.status['WIFI'] = True
|
||||
else:
|
||||
self.status['TCP'] = True
|
||||
|
||||
# TODO NMEA2000
|
||||
# can-Interface can0 im Netzwerk. Identifikation?
|
||||
|
||||
# TODO NMEA0183 tty auf Konfiguration
|
||||
# enabled in Konfiguration
|
||||
# port muß gültige Schnittstelle sein
|
||||
|
||||
# TODO USB /dev/ttyUSB0?
|
||||
|
||||
# GPS
|
||||
# Kann ein Empfänger am USB sein. Siehe Konfiguration
|
||||
self.status['GPS'] = self.bv_lat and self.bv_lon and self.bv_lat.valid and self.bv_lon.valid
|
||||
|
||||
# Tracker
|
||||
self.status['TRK'] = self.track.is_active()
|
||||
BIN
audio/30sek_alerter.mp3
Normal file
BIN
audio/30sek_alerter_en.mp3
Normal file
BIN
audio/abbruch.mp3
Normal file
BIN
audio/abbruch_en.mp3
Normal file
BIN
audio/acht.mp3
Normal file
BIN
audio/acht_en.mp3
Normal file
BIN
audio/alive.mp3
Normal file
BIN
audio/allgmRueck.mp3
Normal file
BIN
audio/allgmRueck_en.mp3
Normal file
BIN
audio/bahnVerk.mp3
Normal file
BIN
audio/bahnVerk_en.mp3
Normal file
BIN
audio/bahnmarke.mp3
Normal file
BIN
audio/bahnmarke_en.mp3
Normal file
BIN
audio/batteryLevel.mp3
Normal file
BIN
audio/batteryLevel_en.mp3
Normal file
BIN
audio/cellback.mp3
Normal file
BIN
audio/cellback_en.mp3
Normal file
BIN
audio/drei.mp3
Normal file
BIN
audio/dreiMin.mp3
Normal file
BIN
audio/dreiMin_en.mp3
Normal file
BIN
audio/drei_en.mp3
Normal file
BIN
audio/dreissig.mp3
Normal file
BIN
audio/dreissig_en.mp3
Normal file
BIN
audio/eineMin.mp3
Normal file
BIN
audio/eineMin_en.mp3
Normal file
BIN
audio/eins.mp3
Normal file
BIN
audio/eins_en.mp3
Normal file
BIN
audio/einzelRueck.mp3
Normal file
BIN
audio/einzelRueck_en.mp3
Normal file
BIN
audio/endeEineMinute.mp3
Normal file
BIN
audio/endeEineMinute_en.mp3
Normal file
BIN
audio/endeWettfahrt.mp3
Normal file
BIN
audio/endeWettfahrt_en.mp3
Normal file
BIN
audio/endstartVerschiebung.mp3
Normal file
BIN
audio/endstartVerschiebung_en.mp3
Normal file
BIN
audio/fuenf.mp3
Normal file
BIN
audio/fuenfMin.mp3
Normal file
BIN
audio/fuenfMin_en.mp3
Normal file
BIN
audio/fuenf_en.mp3
Normal file
BIN
audio/fuenfzehn.mp3
Normal file
BIN
audio/fuenfzehn_en.mp3
Normal file
BIN
audio/fuenfzig.mp3
Normal file
BIN
audio/fuenfzig_en.mp3
Normal file
BIN
audio/jumping.mp3
Normal file
BIN
audio/jumping_en.mp3
Normal file
BIN
audio/neueAnsage.mp3
Normal file
BIN
audio/neueAnsage_en.mp3
Normal file
BIN
audio/neun.mp3
Normal file
BIN
audio/neun_en.mp3
Normal file
BIN
audio/noconnection.mp3
Normal file
BIN
audio/noconnection_en.mp3
Normal file
BIN
audio/runde.mp3
Normal file
BIN
audio/runde_en.mp3
Normal file
BIN
audio/sechs.mp3
Normal file
BIN
audio/sechs_en.mp3
Normal file
BIN
audio/sieben.mp3
Normal file
BIN
audio/sieben_en.mp3
Normal file
BIN
audio/startErfolgt.mp3
Normal file
BIN
audio/startErfolgt_en.mp3
Normal file
BIN
audio/startVerschiebung.mp3
Normal file
BIN
audio/startVerschiebung_en.mp3
Normal file
BIN
audio/startlinie.mp3
Normal file
BIN
audio/startlinie_en.mp3
Normal file
BIN
audio/startnotready.mp3
Normal file
BIN
audio/startnotready_en.mp3
Normal file
BIN
audio/startready.mp3
Normal file
BIN
audio/startready_en.mp3
Normal file
BIN
audio/vier.mp3
Normal file
BIN
audio/vierMin.mp3
Normal file
BIN
audio/vierMin_en.mp3
Normal file
BIN
audio/vier_en.mp3
Normal file
BIN
audio/vierzig.mp3
Normal file
BIN
audio/vierzig_en.mp3
Normal file
BIN
audio/wartenAnkuend.mp3
Normal file
BIN
audio/wartenAnkuend_en.mp3
Normal file
BIN
audio/zehn.mp3
Normal file
BIN
audio/zehn_en.mp3
Normal file
BIN
audio/ziellinie.mp3
Normal file
BIN
audio/ziellinie_en.mp3
Normal file
BIN
audio/zwanzig.mp3
Normal file
BIN
audio/zwanzig_en.mp3
Normal file
BIN
audio/zwei.mp3
Normal file
BIN
audio/zweiMin.mp3
Normal file
BIN
audio/zweiMin_en.mp3
Normal file
BIN
audio/zwei_en.mp3
Normal file
98
cfgmenu.py
Normal file
@@ -0,0 +1,98 @@
|
||||
"""
|
||||
Menüsystem für Konfiguration(en)
|
||||
|
||||
"""
|
||||
|
||||
class MenuItem():
|
||||
|
||||
def __init__(self, valtype, label, value=None, unit=''):
|
||||
validtypes = ('int', 'bool')
|
||||
valtype = valtype.lower() # Groß- und Kleinschreibung lassen wir gemischt zu
|
||||
if valtype not in validtypes:
|
||||
raise TypeError(f"Invalid value type: '{valtype}'. Only supported: {validtypes}")
|
||||
self.label = label # Anzeigetext des Menüeintrag
|
||||
self.value = value # Zugeordneter Wert für diesen Eintrag
|
||||
self.unit = unit
|
||||
self._type = valtype
|
||||
self._min = 0
|
||||
self._max = 99999
|
||||
self.steps = (1, 10, 100, 1000) # Sprungmöglichkeiten für +/- Tasten
|
||||
self.step = 0 # index into tuple above
|
||||
self.position = None # Menüposition gezählt von 0 an
|
||||
|
||||
def setRange(self, valmin, valmax, steps):
|
||||
self.min = valmin
|
||||
self.max = valmax
|
||||
self.steps = steps
|
||||
|
||||
def setValue(self, val):
|
||||
if self._type == 'int':
|
||||
if val >= self._min and val <= self._max:
|
||||
self.value = val
|
||||
return True
|
||||
elif self.type == 'bool':
|
||||
self.value = val
|
||||
return True
|
||||
return False
|
||||
|
||||
class Menu():
|
||||
|
||||
def __init__(self, title, x, y):
|
||||
self.title = title
|
||||
self.items = {} # Items über Schlüssel zugreifbar
|
||||
self.activeitem = -1 # Noch nichts aktiv
|
||||
self._x = x
|
||||
self._y = y
|
||||
self._w = 100
|
||||
self._h = 20
|
||||
self._index = [] # Mapping zwischen Index(Position) und Schlüssel
|
||||
self._iter_index = 0
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if self._iter_index < len(self.items):
|
||||
itm = self.items[self._index[self._iter_index]]
|
||||
self._iter_index += 1
|
||||
return itm
|
||||
self._iter_index = 0
|
||||
raise StopIteration
|
||||
|
||||
def addItem(self, key, label, valtype, value=None, unit=''):
|
||||
if key in self.items.keys():
|
||||
raise KeyError(f"Duplicate menu item key: '{key}'")
|
||||
itm = MenuItem(valtype, label, value, unit)
|
||||
self.items[key] = itm
|
||||
self._index.append(key)
|
||||
itm.position = self._index.index(key)
|
||||
return itm
|
||||
|
||||
def setItemActive(self, key):
|
||||
self.activeitem = self._index.index(key)
|
||||
|
||||
def getActiveItem(self):
|
||||
return self.items[self._index[self.activeitem]]
|
||||
|
||||
def getItemByIndex(self, index):
|
||||
return self.items[self._index[index]]
|
||||
|
||||
def getItemByKey(self, key):
|
||||
return self.items[key]
|
||||
|
||||
def getItemCount(self):
|
||||
return len(self.items)
|
||||
|
||||
def setItemDimension(self, w, h):
|
||||
self._w = w
|
||||
self._h = h
|
||||
|
||||
def getXY(self):
|
||||
return (self._x, self._y)
|
||||
|
||||
def getRect(self):
|
||||
return (self._x, self._y, self._w, self._h * len(self.items))
|
||||
|
||||
def getItemRect(self, index):
|
||||
y = self._y + index * self._h
|
||||
return (self._x, y, self._w, self._h)
|
||||
142
fullscreen.svg
Normal file
@@ -0,0 +1,142 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="800"
|
||||
height="480"
|
||||
viewBox="0 0 800 480"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xml:space="preserve"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="fullscreen2.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="px"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.84096521"
|
||||
inkscape:cx="303.81756"
|
||||
inkscape:cy="386.4607"
|
||||
inkscape:current-layer="layer2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1149"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1" /><defs
|
||||
id="defs2" /><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Rahmen"
|
||||
style="display:inline"><rect
|
||||
style="fill:#a2a2a2;fill-opacity:1;stroke:none;stroke-width:7.55905;stroke-opacity:1;stop-color:#000000"
|
||||
id="rect352"
|
||||
width="800"
|
||||
height="480"
|
||||
x="0"
|
||||
y="0" /><ellipse
|
||||
style="fill:#5f6d9b;fill-opacity:1;stroke:#000000;stroke-width:0.264582;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path5526"
|
||||
cx="658.65332"
|
||||
cy="19.676636"
|
||||
rx="7.8677087"
|
||||
ry="7.8677092" /><rect
|
||||
style="fill:#dcdcdc;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6475"
|
||||
width="639.73541"
|
||||
height="479.73541"
|
||||
x="0.1322915"
|
||||
y="0.1322915" /><rect
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1;stop-color:#000000"
|
||||
id="rect405"
|
||||
width="159"
|
||||
height="64"
|
||||
x="640.5"
|
||||
y="96" /><rect
|
||||
style="display:inline;fill:none;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1;stop-color:#000000"
|
||||
id="rect405-4"
|
||||
width="159"
|
||||
height="64"
|
||||
x="640.5"
|
||||
y="160" /><rect
|
||||
style="display:inline;fill:none;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1;stop-color:#000000"
|
||||
id="rect405-43"
|
||||
width="159"
|
||||
height="64"
|
||||
x="640.5"
|
||||
y="224" /><rect
|
||||
style="display:inline;fill:none;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1;stop-color:#000000"
|
||||
id="rect405-0"
|
||||
width="159"
|
||||
height="64"
|
||||
x="640.5"
|
||||
y="288" /><rect
|
||||
style="display:inline;fill:none;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1;stop-color:#000000"
|
||||
id="rect405-7"
|
||||
width="159"
|
||||
height="64"
|
||||
x="640.5"
|
||||
y="352" /><rect
|
||||
style="display:inline;fill:none;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1;stop-color:#000000"
|
||||
id="rect405-8"
|
||||
width="159"
|
||||
height="64"
|
||||
x="640.5"
|
||||
y="416" /><g
|
||||
id="layer1"
|
||||
transform="matrix(3.224819,0,0,3.224819,674.77992,9.0078049)"
|
||||
style="stroke-width:1.17201"><path
|
||||
style="display:inline;fill:#102c99;fill-opacity:1;stroke:none;stroke-width:0.310095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 0.00582151,19.103043 13.427616,2.594e-5 V 19.108558 Z"
|
||||
id="path3736" /><path
|
||||
id="path3738"
|
||||
style="display:inline;fill:#102c99;fill-opacity:1;stroke:none;stroke-width:0.310095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 34.998815,0 16.6293,0.0015279 16.628,19.108557 h 18.370774 z m -12.47283,1.7484273 c 1.061943,0 1.890855,0.3043204 2.48681,0.9129571 0.599128,0.6086381 0.898693,1.4439109 0.898693,2.5058558 0,0.6973958 -0.137894,1.3107928 -0.413684,1.8401801 -0.275788,0.5293873 -0.670454,0.9351717 -1.183992,1.2172996 -0.513538,0.2789589 -1.112671,0.4183914 -1.797385,0.4183914 -1.052436,0 -1.878197,-0.3090753 -2.477326,-0.9272217 -0.595954,-0.6213181 -0.893913,-1.4708555 -0.893913,-2.5486494 0,-1.074625 0.297959,-1.9131151 0.893913,-2.5154125 0.595958,-0.6022973 1.424936,-0.9034004 2.486884,-0.9034004 z m 4.445889,0.099855 h 3.009906 c 0.802007,0 1.418546,0.1854463 1.849665,0.5563333 0.434289,0.367718 0.651482,0.8891621 0.651482,1.5643681 0,0.4311171 -0.09832,0.8162728 -0.294858,1.1554617 -0.196539,0.3391875 -0.478625,0.6023222 -0.846339,0.7893515 -0.364549,0.183859 -0.798861,0.2757416 -1.30289,0.2757416 h -1.664221 v 2.3584967 h -1.402745 z m -4.445889,1.0032552 c -0.627659,0 -1.112668,0.2044657 -1.455028,0.6133929 -0.342355,0.4057583 -0.513538,0.9732134 -0.513538,1.7023101 0,0.735436 0.17433,1.3155463 0.523025,1.7403254 0.351869,0.4216073 0.830513,0.6324358 1.435983,0.6324358 0.627657,0 1.111129,-0.2060737 1.450319,-0.6181713 0.342355,-0.4120976 0.513538,-0.9969641 0.513538,-1.7545899 0,-0.7227574 -0.171183,-1.2886031 -0.513538,-1.6975304 C 23.624385,3.0576111 23.14413,2.8515375 22.525985,2.8515375 Z m 5.848634,0.08559 v 2.1730517 h 1.488262 c 0.386741,0 0.684766,-0.0951 0.893986,-0.2852982 0.20922,-0.1933687 0.313829,-0.4707693 0.313829,-0.8321466 0,-0.7037366 -0.415297,-1.0556069 -1.24583,-1.0556069 z m -8.670744,7.5100735 h 5.26855 v 1.084137 h -3.865804 v 1.683265 h 3.575726 v 1.084137 h -3.575726 v 1.764076 h 4.060735 v 1.084138 h -5.463481 z m 6.495337,0 h 1.602384 L 30.764,15.649133 c -0.05706,-0.478668 -0.08559,-0.91452 -0.08559,-1.307598 v -3.894334 h 1.245829 v 6.699753 h -1.645248 l -2.919609,-5.159137 c 0.05706,0.500858 0.08559,0.903424 0.08559,1.207743 v 3.951394 h -1.245759 z" /><g
|
||||
id="g1985"
|
||||
transform="translate(-0.08213509)"
|
||||
style="stroke-width:1.17201"><path
|
||||
d="m 3.5322255,23.272579 q 0,0.525843 -0.3862392,0.813413 -0.3862392,0.287573 -1.0728873,0.287573 H 0.18213509 V 20.51464 H 1.9121655 q 0.6920129,0 1.0460654,0.246489 0.3567342,0.243751 0.3567342,0.723035 0,0.328651 -0.1797087,0.55597 -0.1770255,0.224579 -0.5418078,0.304002 0.4586593,0.05477 0.6973765,0.295788 0.2414004,0.238273 0.2414004,0.632655 z M 2.5183467,21.593715 q 0,-0.260183 -0.1636153,-0.369735 Q 2.1937992,21.11443 1.8746152,21.11443 H 0.97338997 v 0.95583 H 1.8799787 q 0.3352774,0 0.4854811,-0.117767 0.1528869,-0.120505 0.1528869,-0.358778 z m 0.2199421,1.615872 q 0,-0.542275 -0.7617499,-0.542275 H 0.97338997 v 1.106462 H 2.0060438 q 0.3808743,0 0.5552181,-0.139677 0.1770269,-0.142416 0.1770269,-0.42451 z"
|
||||
id="path39641"
|
||||
style="fill:#102c99;stroke-width:0.306879" /><path
|
||||
d="m 6.922548,22.889151 q 0,0.720297 -0.3916038,1.131111 -0.3916037,0.408078 -1.0836157,0.408078 -0.6786011,0 -1.0648405,-0.410815 -0.3862393,-0.410816 -0.3862393,-1.128374 0,-0.714817 0.3862393,-1.122895 0.3862394,-0.410815 1.0809337,-0.410815 0.7107875,0 1.0836158,0.397122 0.3755105,0.394382 0.3755105,1.136588 z m -0.788572,0 q 0,-0.528581 -0.1689797,-0.766855 -0.1689796,-0.238271 -0.4908458,-0.238271 -0.6866477,0 -0.6866477,1.005126 0,0.495719 0.1662975,0.755901 0.1689797,0.257444 0.4854813,0.257444 0.6946944,0 0.6946944,-1.013345 z"
|
||||
id="path39643"
|
||||
style="fill:#102c99;stroke-width:0.306879" /><path
|
||||
d="m 8.1912368,24.42834 q -0.421108,0 -0.6571433,-0.232796 Q 7.2980584,23.96001 7.2980584,23.5355 q 0,-0.460111 0.2923618,-0.701123 0.2950438,-0.241012 0.852945,-0.24649 l 0.6249564,-0.01094 v -0.150633 q 0,-0.290309 -0.099242,-0.429986 -0.099242,-0.142416 -0.3245481,-0.142416 -0.2092129,0 -0.308455,0.0986 -0.09656,0.09586 -0.1206998,0.320436 L 7.429487,22.234608 q 0.07242,-0.432726 0.3862393,-0.654566 0.3165016,-0.22458 0.8609918,-0.22458 0.5498538,0 0.8475809,0.276617 0.2977257,0.276615 0.2977257,0.786025 v 1.079076 q 0,0.249228 0.053645,0.345086 0.056325,0.09312 0.1850723,0.09312 0.08583,0 0.166297,-0.01643 v 0.416294 q -0.06705,0.01643 -0.120699,0.03013 -0.05364,0.01369 -0.1072883,0.02191 -0.053645,0.0082 -0.1153353,0.01369 -0.05901,0.0055 -0.1394753,0.0055 -0.2843155,0 -0.421109,-0.142417 Q 9.1890218,24.121607 9.1622,23.844991 H 9.1461066 Q 8.8296045,24.42835 8.1912368,24.42835 Z m 0.8770848,-1.426898 -0.3862389,0.0055 q -0.2628574,0.01096 -0.3728283,0.06025 -0.1099711,0.04656 -0.1689797,0.145153 -0.056327,0.0986 -0.056327,0.262922 0,0.210886 0.093878,0.314958 0.09656,0.101335 0.2548105,0.101335 0.1770264,0 0.3218662,-0.09859 0.147522,-0.0986 0.2306705,-0.271139 0.083149,-0.175281 0.083149,-0.369733 z"
|
||||
id="path39645"
|
||||
style="fill:#102c99;stroke-width:0.306879" /><path
|
||||
d="m 11.318704,24.422861 q -0.332597,0 -0.512304,-0.183496 -0.17971,-0.186237 -0.17971,-0.561449 v -1.747332 h -0.367463 v -0.520368 h 0.405015 l 0.236035,-0.695646 h 0.472071 v 0.695646 h 0.549854 v 0.520368 h -0.549854 v 1.539187 q 0,0.216362 0.08047,0.320434 0.08047,0.101335 0.249445,0.101335 0.08851,0 0.252129,-0.03834 v 0.476546 q -0.27895,0.09312 -0.635685,0.09312 z"
|
||||
id="path39647"
|
||||
style="fill:#102c99;stroke-width:0.306879" /><path
|
||||
d="m 17.02378,21.736131 q 0,0.372472 -0.166297,0.66552 -0.166299,0.293048 -0.477436,0.454635 -0.308454,0.158849 -0.734927,0.158849 h -0.938776 v 1.35843 H 13.91509 V 20.51464 h 1.697844 q 0.678601,0 1.043382,0.320436 0.367464,0.317697 0.367464,0.901055 z m -0.796618,0.01369 q 0,-0.608007 -0.702742,-0.608007 h -0.818076 v 1.251617 h 0.839533 q 0.327232,0 0.504258,-0.164325 0.177027,-0.167065 0.177027,-0.479285 z"
|
||||
id="path39649"
|
||||
style="fill:#102c99;stroke-width:0.306879" /><path
|
||||
d="m 17.595093,24.373565 v -2.2677 q 0,-0.243751 -0.008,-0.405339 -0.0054,-0.164325 -0.01342,-0.29031 h 0.718835 q 0.008,0.0493 0.02146,0.301265 0.01342,0.249227 0.01342,0.331392 h 0.01072 q 0.10997,-0.31222 0.195801,-0.438203 0.08583,-0.128724 0.203848,-0.188976 0.118018,-0.06299 0.295045,-0.06299 0.14484,0 0.233352,0.04108 v 0.64361 q -0.182391,-0.04108 -0.321866,-0.04108 -0.281632,0 -0.439884,0.232796 -0.155569,0.232795 -0.155569,0.690169 v 1.454286 z"
|
||||
id="path39651"
|
||||
style="fill:#102c99;stroke-width:0.306879" /><path
|
||||
d="m 22.49014,22.889151 q 0,0.720297 -0.391604,1.131111 -0.391604,0.408078 -1.083616,0.408078 -0.678601,0 -1.06484,-0.410815 -0.38624,-0.410816 -0.38624,-1.128374 0,-0.714817 0.38624,-1.122895 0.386239,-0.410815 1.080934,-0.410815 0.710788,0 1.083615,0.397122 0.375511,0.394382 0.375511,1.136588 z m -0.788573,0 q 0,-0.528581 -0.168979,-0.766855 -0.168979,-0.238271 -0.490846,-0.238271 -0.686647,0 -0.686647,1.005126 0,0.495719 0.166297,0.755901 0.168979,0.257444 0.485482,0.257444 0.694693,0 0.694693,-1.013345 z"
|
||||
id="path39653"
|
||||
style="fill:#102c99;stroke-width:0.306879" /><path
|
||||
d="m 23.090956,20.876158 v -0.566925 h 0.753704 v 0.566925 z m -0.01609,4.661383 q -0.268222,0 -0.455976,-0.02465 v -0.542275 l 0.136792,0.01096 q 0.19312,0 0.262857,-0.08764 0.07242,-0.0849 0.07242,-0.35604 V 21.41022 h 0.753704 v 3.313911 q 0,0.391643 -0.195802,0.602528 -0.19312,0.210886 -0.573995,0.210886 z"
|
||||
id="path39655"
|
||||
style="fill:#102c99;stroke-width:0.306879" /><path
|
||||
d="m 25.802678,24.42834 q -0.654462,0 -1.005832,-0.394384 -0.351371,-0.39712 -0.351371,-1.155759 0,-0.73399 0.356736,-1.128372 0.356735,-0.394384 1.011195,-0.394384 0.624956,0 0.954869,0.42451 0.329912,0.421771 0.329912,1.237922 v 0.02191 H 25.23673 q 0,0.432725 0.155568,0.654565 0.158251,0.219102 0.44793,0.219102 0.399651,0 0.504257,-0.3533 l 0.710789,0.06299 q -0.308456,0.805199 -1.252596,0.8052 z m 0,-2.588137 q -0.265541,0 -0.41038,0.188975 -0.142157,0.188976 -0.150203,0.528583 h 1.126531 q -0.02146,-0.358779 -0.168981,-0.536799 -0.147522,-0.180759 -0.396967,-0.180759 z"
|
||||
id="path39657"
|
||||
style="fill:#102c99;stroke-width:0.306879" /><path
|
||||
d="m 28.879182,24.42834 q -0.659826,0 -1.019242,-0.39986 -0.359417,-0.402599 -0.359417,-1.120156 0,-0.73399 0.362097,-1.142068 0.362101,-0.410815 1.027291,-0.410815 0.512304,0 0.84758,0.262922 0.335277,0.262922 0.421109,0.725773 l -0.759068,0.03834 q -0.03219,-0.227317 -0.160932,-0.361518 -0.128747,-0.136937 -0.364781,-0.136937 -0.582043,0 -0.582043,0.994172 0,1.024299 0.59277,1.024299 0.214578,0 0.359417,-0.136938 0.14484,-0.139677 0.179709,-0.413554 l 0.756386,0.0356 q -0.04023,0.304004 -0.214578,0.542277 -0.171662,0.238272 -0.453295,0.369733 -0.281632,0.128723 -0.633003,0.128723 z"
|
||||
id="path39659"
|
||||
style="fill:#102c99;stroke-width:0.306879" /><path
|
||||
d="m 31.46752,24.422861 q -0.332594,0 -0.512303,-0.183496 -0.179707,-0.186237 -0.179707,-0.561449 v -1.747332 h -0.367464 v -0.520368 h 0.405014 l 0.236035,-0.695646 h 0.472069 v 0.695646 h 0.549856 v 0.520368 h -0.549856 v 1.539187 q 0,0.216362 0.08047,0.320434 0.08047,0.101335 0.249447,0.101335 0.08851,0 0.252128,-0.03834 v 0.476546 q -0.278949,0.09312 -0.635685,0.09312 z"
|
||||
id="path39661"
|
||||
style="fill:#102c99;stroke-width:0.306879" /><path
|
||||
d="m 34.999999,23.508112 q 0,0.429987 -0.346005,0.676477 -0.343324,0.243751 -0.952187,0.243751 -0.598135,0 -0.917319,-0.191715 -0.316501,-0.194452 -0.421109,-0.602528 l 0.662509,-0.101334 q 0.05633,0.210884 0.193119,0.298525 0.139476,0.08764 0.4828,0.08764 0.3165,0 0.461341,-0.08216 0.14484,-0.08216 0.14484,-0.257442 0,-0.142417 -0.118019,-0.22458 -0.115335,-0.0849 -0.394285,-0.142416 -0.638368,-0.128722 -0.860991,-0.238272 -0.222625,-0.11229 -0.340642,-0.28757 -0.115335,-0.178021 -0.115335,-0.435466 0,-0.424508 0.319184,-0.660043 0.321864,-0.238271 0.90927,-0.238271 0.517668,0 0.831488,0.205407 0.316501,0.205408 0.394286,0.594312 l -0.667871,0.07121 q -0.03219,-0.180757 -0.158252,-0.268398 -0.126064,-0.09038 -0.399651,-0.09038 -0.268221,0 -0.402332,0.07121 -0.134111,0.06847 -0.134111,0.232795 0,0.128722 0.101925,0.205408 0.104606,0.07395 0.348689,0.123246 0.34064,0.07121 0.603497,0.147893 0.26554,0.07395 0.423791,0.178019 0.160933,0.104074 0.25481,0.268399 0.09656,0.161588 0.09656,0.416292 z"
|
||||
id="path39663"
|
||||
style="fill:#102c99;stroke-width:0.306879" /></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 14 KiB |
21
graph.py
Normal file
@@ -0,0 +1,21 @@
|
||||
"""
|
||||
Generische Klasse zum Diagramme-Zeichnen
|
||||
"""
|
||||
|
||||
class Graph():
|
||||
|
||||
def __init__(self):
|
||||
self.title = "Title"
|
||||
self.subtitle = "Subtitle"
|
||||
self.title_x = "Title X"
|
||||
self.title_y = "Title Y"
|
||||
self.has_arrows = False
|
||||
|
||||
def paint(self, ctx):
|
||||
"""
|
||||
Output Graph to Cairo context
|
||||
"""
|
||||
pass
|
||||
|
||||
def add_series(self):
|
||||
pass
|
||||
BIN
images/arrow_dn.png
Normal file
|
After Width: | Height: | Size: 135 B |
BIN
images/arrow_up.png
Normal file
|
After Width: | Height: | Size: 138 B |
BIN
images/exclamation.png
Normal file
|
After Width: | Height: | Size: 203 B |
BIN
images/flags/alpha.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
images/flags/answer.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
images/flags/black.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
images/flags/blue.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |