Compare commits

..

8 Commits

9 changed files with 331 additions and 68 deletions

12
INSTALL
View File

@ -4,12 +4,22 @@ 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
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 obp60.conf im gleichen
Verzeichnis wie das Hauptprogramm gesteuert. Die Konfiguration wird
einmalig beim Programmstart eingelesen.
Die Schriftarten aus dem fonts-Verzeichnis müssen in /usr/local/share/fonts
abgelegt werden.
Meßdaten werden im Homeverzeichnis unter ~/.local/lib/obp60 gespeichert.
Dies betrifft momentan Luftdruckmessungen mit dem BME280.
Das Verzeichnis wird automatisch angelegt.

36
README
View File

@ -11,32 +11,52 @@ 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
- python3-serial
- python3-nmea2
Für BME280
- smbus2
- bme280
- python3-smbus2
- python3-bme280
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 800x600 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.

142
fullscreen.svg Normal file
View 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

BIN
images/front.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 B

View File

@ -4,6 +4,8 @@ loglevel = 3
deviceid = 100
simulation = on
histpath = ~/.local/lib/obp60
guistyle = fullscreen
mouseptr = off
[bme280]
enabled = true
@ -57,7 +59,7 @@ number_of_pages = 10
start_page = 1
[page1]
type=ApparentWind
type=Clock
[page2]
type=Barograph
@ -69,7 +71,7 @@ type=Anchor
type=Autobahn
[page5]
type=Clock
type=ApparentWind
[page6]
type=TwoValues

109
obp60.py
View File

@ -3,12 +3,18 @@
"""
Virtuelles Multifunktionsgerät
Zwei Displayvarianten
1. Fliegendes OBP60 auf großem Bildschirm. 400x300 Display
2. Fullscreen Display skaliert mit 1,6 ergibt 640x480
mit Platz für große Touch-Flächen am rechten Rand
NMEA2000
deviceclass: 120 - Display
devicefunction: 130 - Display
Benötigte Pakete:
python3-cairo python3-gi python3-gi-cairo gir1.2-rsvg-2.0
python3-astral
Um transparente Darstellung unter Openbox zu erhalten muß xcompmgr
installiert und konfiguriert werden.
@ -67,7 +73,7 @@ Button 5 wird für Trend TRND verwendet
Version Datum Änderung(en) von
-------- ----------- ------------------------------------------------------ ----
0.1 2024-10-31 Entwicklung begonnen tho
0.2 2024-12-24 Veräffentlichung als Git-Repository tho
0.2 2024-12-24 Veröffentlichung als Git-Repository tho
"""
@ -274,7 +280,35 @@ def datareader(histpath, history):
class Frontend(Gtk.Window):
button = {
def __init__(self, cfg, device, boatdata, profile):
super().__init__()
self.owndev = device
self.boatdata = boatdata
self._fullscreen = cfg['guistyle'] == 'fullscreen'
self._mouseptr = cfg['mouseptr']
self.connect("destroy", self.on_destroy)
if self._fullscreen:
self.fullscreen()
#self.set_size_request(800, 480)
# Schaltflächen am unteren Bildschirmrand sind berührbar,
# zusätzlich gibt es die großen Flächen am rechten Rand
self.button_round = False
self.button = { # linke obere Ecke
1: (640, 96),
2: (640, 160),
3: (640, 224),
4: (640, 288),
5: (640, 352),
6: (640, 416)
}
self.button_w = 160
self.button_h = 64
else:
self.button_round = True
# Runde Tasten wie beim Original-Gerät
self.button = { # Mittelpunkt
1: (75, 485),
2: (150, 492),
3: (227, 496),
@ -282,15 +316,7 @@ class Frontend(Gtk.Window):
5: (382, 492),
6: (459, 485)
}
radius = 30
def __init__(self, device, boatdata, profile):
super().__init__()
self.owndev = device
self.boatdata = boatdata
self.connect("destroy", self.on_destroy)
self.button_radius = 30
self.set_position(Gtk.WindowPosition.CENTER)
self.set_size_request(530, 555)
self.set_title("OBP60 virt")
@ -304,6 +330,9 @@ class Frontend(Gtk.Window):
self.set_visual(self.visual)
handle = Rsvg.Handle()
if self._fullscreen:
self._svg = handle.new_from_file(os.path.join(sys.path[0], "fullscreen.svg"))
else:
self._svg = handle.new_from_file(os.path.join(sys.path[0], "obp60.svg"))
self.connect("draw", self.on_draw)
@ -323,6 +352,11 @@ class Frontend(Gtk.Window):
print("Wische von 2 nach 1 für Programmende")
def on_realize(self, widget):
if self._fullscreen and not self._mouseptr:
# Mauszeiger ggf. ausschalten
self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.BLANK_CURSOR))
def run(self):
GLib.timeout_add_seconds(2, self.on_timer)
self.show_all()
@ -346,13 +380,20 @@ class Frontend(Gtk.Window):
viewport = Rsvg.Rectangle()
viewport.x = 0
viewport.y = 0
if self._fullscreen:
viewport.width = 800
viewport.height = 480
else:
viewport.width = 530
viewport.height = 555
self._svg.render_document(ctx, viewport)
ctx.set_source_rgb(1.0, 0, 0)
if not self._fullscreen:
ctx.translate(64, 95) # Koordinatenursprung auf virtuellen Displaybereich setzen
ctx.rectangle(0, 0, 400, 300)
ctx.clip()
else:
ctx.scale(1.6, 1.6)
ctx.set_source_rgb(0, 0, 0) # Schwarz auf Weiß
@ -369,13 +410,26 @@ class Frontend(Gtk.Window):
# Die eigentliche Funktion wird beim Loslassen ausgelöst.
# Damit sind Wischgesten simulierbar
self.button_clicked = 0
if (event.x < self.button[1][0] - self.radius or event.x > self.button[6][0] + self.radius):
if self.button_round:
# Horizontale runde Buttons
if (event.x < self.button[1][0] - self.button_radius or event.x > self.button[6][0] + self.button_radius):
return True
if (event.y < self.button[1][1] - self.radius or event.y > self.button[3][1] + self.radius):
if (event.y < self.button[1][1] - self.button_radius or event.y > self.button[3][1] + self.button_radius):
return True
for b, v in self.button.items():
diff = math.sqrt((event.x - v[0])**2 + (event.y - v[1])**2)
if diff < self.radius:
if diff < self.button_radius:
self.button_clicked = b
break
else:
# Vertikale eckige Buttons
if (event.x < self.button[1][0]) or (event.x > self.button[1][0] + self.button_w):
return True
if (event.y < self.button[1][1]) or (event.y > self.button[6][1] + self.button_h):
return True
for b, v in self.button.items():
if event.x >= v[0] and event.x <= v[0] + self.button_w and \
event.y >= v[1] and event.y <= v[1] + self.button_h:
self.button_clicked = b
break
return True
@ -388,16 +442,30 @@ class Frontend(Gtk.Window):
# Falls der Rückgabewert "True" ist, hat die Seite die Taste
# verarbeitet, die Funktion hier wird damit unterdrückt.
# TODO
if (event.x < self.button[1][0] - self.radius or event.x > self.button[6][0] + self.radius):
print("release")
if self.button_round:
if (event.x < self.button[1][0] - self.button_radius or event.x > self.button[6][0] + self.button_radius):
return True
if (event.y < self.button[1][1] - self.radius or event.y > self.button[3][1] + self.radius):
if (event.y < self.button[1][1] - self.button_radius or event.y > self.button[3][1] + self.button_radius):
return True
selected = 0
for b, v in self.button.items():
diff = math.sqrt((event.x - v[0])**2 + (event.y - v[1])**2)
if diff < self.radius:
if diff < self.button_radius:
selected = b
break
else:
if event.x < self.button[1][0] or event.x > self.button[6][0] + self.button_w:
return True
if event.y < self.button[1][1] or event.y > self.button[6][1] + self.button_h:
return True
selected = 0
for b, v in self.button.items():
if event.x >= v[0] and event.x <= v[0] + self.button_w and \
event.y >= v[1] and event.y <= v[1] + self.button_h:
selected = b
break
if self.keylock:
# Bei Tastensperre einzige Möglichkeit: Tastensperre ausschalten
if selected == 6 and self.button_clicked == 1:
@ -523,6 +591,9 @@ if __name__ == "__main__":
cfg['deviceid'] = config.getint('system', 'deviceid')
cfg['simulation'] = config.getboolean('system', 'simulation')
cfg['histpath'] = os.path.expanduser(config.get('system', 'histpath'))
cfg['guistyle'] = config.get('system', 'guistyle')
cfg['mouseptr'] = config.getboolean('system', 'mouseptr')
print("Setting GUI style to '{}'".format(cfg['guistyle']))
cfg['gps'] = config.getboolean('gps', 'enabled')
if cfg['gps']:
@ -544,6 +615,7 @@ if __name__ == "__main__":
profile = init_profile(config, cfg, boatdata)
if not cfg['simulation']:
t_rxd_n2k = threading.Thread(target=rxd_n2k)
t_rxd_n2k.start()
t_rxd_0183 = threading.Thread(target=rxd_0183, args=(cfg['ocpn_port'],))
@ -552,9 +624,10 @@ if __name__ == "__main__":
t_data = threading.Thread(target=datareader, args=(cfg['histpath'], history))
t_data.start()
app = Frontend(owndevice, boatdata, profile)
app = Frontend(cfg, owndevice, boatdata, profile)
app.run()
shutdown = True
if not cfg['simulation']:
t_rxd_n2k.join()
t_rxd_0183.join()
t_data.join()

View File

@ -9,7 +9,11 @@ class ApparentWind(Page):
super().__init__(pageno, cfg, boatdata)
self.buttonlabel[1] = 'MODE'
self.mode = 'L' # (W)ind (L)ens
try:
self.symbol = cairo.ImageSurface.create_from_png(os.path.join(cfg['imgpath'], "front.png"))
except:
self.symbol = None
print("Warning: Missing image: {}".format(os.path.join(cfg['imgpath'], "front.png")))
def handle_key(self, buttonid):
if buttonid == 1:
@ -27,6 +31,7 @@ class ApparentWind(Page):
ctx.show_text("Apparent Wind")
def draw_lens(self, ctx):
if self.symbol:
ctx.save()
ctx.set_source_surface(self.symbol, 140, 30)
ctx.paint()

View File

@ -63,12 +63,12 @@ class Clock(Page):
ctx.show_text("RTC")
ctx.select_font_face("DSEG7 Classic")
ctx.set_font_size(80)
ctx.set_font_size(72)
# Zentrieren funktioniert nicht richtig, da der Leerraum vor der "1"
# mitgerechnet wird. Dafür muß ggf. der Zeichensatz angepaßt werden.
# self.draw_text_center(ctx, 200, 150, ts.strftime("%H:%M:%S"))
ctx.move_to(-30, 200)
ctx.show_text(ts.strftime("%H:%M:%S"))
ctx.move_to(0, 200)
ctx.show_text(ts.strftime("%-H:%M:%S"))
def draw_timer(self, ctx):
ts = datetime.now()

View File

@ -145,6 +145,11 @@ class Page():
ctx.set_font_size(16)
x = (35, 101, 167, 233, 299, 365)
y = 294
# Fullscreen-Buttons
bx = 400
by = (128, 192, 256, 320, 384, 448)
bw = 160
bh = 64
for i in range(6):
if len(self.buttonlabel[i+1]) > 0 :
if self.buttonlabel[i+1][0] == "#":
@ -153,12 +158,18 @@ class Page():
key = self.buttonlabel[i+1][1:]
ctx.set_source_surface(self.icon[key], x[i]-8, y-13)
ctx.paint()
ctx.set_source_surface(self.icon[key], bx + bw / 3.2 - 8, by[i] / 1.6 - 6)
ctx.paint()
ctx.restore()
else:
text = "[ {} ]".format(self.buttonlabel[i+1])
w = ctx.text_extents(text).width
ctx.move_to(x[i] - w/2, y)
ctx.show_text(text)
# Fullscreen
w = ctx.text_extents(self.buttonlabel[i+1]).width
ctx.move_to(bx + bw/3.2 - w/2, by[i] / 1.6 + 8)
ctx.show_text(self.buttonlabel[i+1])
ctx.stroke()
def clear(self):