Vollbildmodus eingebaut

This commit is contained in:
Thomas Hooge 2025-06-21 19:45:08 +02:00
parent 81836bc5f1
commit ea82d5731e
8 changed files with 316 additions and 49 deletions

View File

@ -4,12 +4,15 @@ erforderlich. Die unten angegebenen Abhängigkeiten müssen erfüllt sein.
Python muß mindestens Version 3.10 sein. Python muß mindestens Version 3.10 sein.
apt-get install python3-cairo python3-gi python3-gi-cairo gir1.2-rsvg-2.0 \ apt-get install python3-cairo python3-gi python3-gi-cairo gir1.2-rsvg-2.0 \
python-serial python3-nmea2 python3-smbus2 python3-bme280 python-serial python3-nmea2 python3-smbus2 python3-bme280 python3-astral
Das Programm wird über eine Konfigurationsdatei obp60.conf im gleichen Das Programm wird über eine Konfigurationsdatei obp60.conf im gleichen
Verzeichnis wie das Hauptprogramm gesteuert. Die Konfiguration wird Verzeichnis wie das Hauptprogramm gesteuert. Die Konfiguration wird
einmalig beim Programmstart eingelesen. 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. Meßdaten werden im Homeverzeichnis unter ~/.local/lib/obp60 gespeichert.
Dies betrifft momentan Luftdruckmessungen mit dem BME280. Dies betrifft momentan Luftdruckmessungen mit dem BME280.
Das Verzeichnis wird automatisch angelegt. Das Verzeichnis wird automatisch angelegt.

4
README
View File

@ -11,13 +11,14 @@ Für Informationen zum OBP60 in Hardware siehe:
Fehlermeldungen und Patches gerne an thomas@hoogi.de senden. Fehlermeldungen und Patches gerne an thomas@hoogi.de senden.
Basishardware Basishardware
- Raspberry Pi 4 - Raspberry Pi 4 / 4GB
Zusatzhardware: Zusatzhardware:
- NMEA2000 Interface - NMEA2000 Interface
- PiCAN-M (hiermit wird entwickelt) - PiCAN-M (hiermit wird entwickelt)
- Waveshare RS485 CAN HAT (ungetestet) - Waveshare RS485 CAN HAT (ungetestet)
- BME280-Sensor über I2C - BME280-Sensor über I2C
- RTC mit DS3231 über I2C
- GPS über USB/seriell angeschlossen - GPS über USB/seriell angeschlossen
Zusatzsoftware: Zusatzsoftware:
@ -26,6 +27,7 @@ Zusatzsoftware:
Abhängigkeiten Abhängigkeiten
- python-can - python-can
- heapdict - heapdict
- python3-astral
Für GPS Für GPS
- python-serial - python-serial

181
fullscreen.svg Normal file
View File

@ -0,0 +1,181 @@
<?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="obp60.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
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="215.82343"
inkscape:cy="482.77859"
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" /><g
id="g911"
transform="translate(-33.720303,-39.612621)"><rect
style="fill:#383838;fill-opacity:0.995886;stroke:#000000;stroke-width:0.264583;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
id="rect5580"
width="439.73541"
height="339.73541"
x="64.710724"
y="66.951721" /><circle
style="fill:#5f6d9b;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
id="path5526"
cx="95.418182"
cy="77.421028"
r="4.8677087" /><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="399.73541"
height="299.73541"
x="84.710724"
y="86.951721" /></g><g
id="g11079"
transform="matrix(4.0148294,0,0,4.0148294,649.70895,-97.900583)"
style="stroke-width:0.249077"><circle
style="fill:#2a2a2a;fill-opacity:1;stroke:#000000;stroke-width:0.0659014;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
id="path8373"
cx="24.618317"
cy="130.36757"
r="7.9375" /><path
sodipodi:type="star"
style="fill:#525252;fill-opacity:1;stroke:#000000;stroke-width:0.153617;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
id="path9879"
inkscape:flatsided="true"
sodipodi:sides="6"
sodipodi:cx="16.355543"
sodipodi:cy="150.80168"
sodipodi:r1="7.745985"
sodipodi:r2="4.8291588"
sodipodi:arg1="1.0332539"
sodipodi:arg2="1.5568527"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 20.321693,157.45525 -7.745232,0.108 -3.9661499,-6.65356 3.7790819,-6.76157 7.745232,-0.10801 3.96615,6.65357 z"
inkscape:transform-center-x="-0.093238378"
inkscape:transform-center-y="-0.22711284"
transform="matrix(0.4296957,0,0,0.42830241,17.59041,65.778845)" /></g><use
x="0"
y="0"
xlink:href="#g11079"
id="use11081"
transform="rotate(-15.936104,611.29401,1406.0778)" /><use
x="0"
y="0"
xlink:href="#g11079"
id="use11083"
transform="rotate(-5.080918,679.92065,1972.247)" /><use
x="0"
y="0"
xlink:href="#g11079"
id="use11085"
transform="rotate(17.398182,542.66737,-920.07115)" /><use
x="0"
y="0"
xlink:href="#g11079"
id="use11087"
transform="translate(-549.01314)" /><use
x="0"
y="0"
xlink:href="#g11079"
id="use11089"
transform="rotate(-15.814908,405.41409,2895.9699)" /><text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:42.6667px;line-height:1.25;font-family:Ubuntu;-inkscape-font-specification:'Ubuntu, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-decoration-color:#000000;fill:#000000;stroke-width:0.999999;-inkscape-stroke:none;stop-color:#000000"
x="554.66705"
y="189.20534"
id="text975"><tspan
sodipodi:role="line"
id="tspan973"
x="554.66705"
y="189.20534">OBP60v</tspan></text><g
id="layer1"
transform="matrix(3.7795276,0,0,3.7795276,628.88195,27.206809)"><path
style="display:inline;fill:#102c99;fill-opacity:1;stroke:none;stroke-width:0.264584px;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.264584px;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)"><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.261839" /><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.261839" /><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.261839" /><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.261839" /><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.261839" /><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.261839" /><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.261839" /><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.261839" /><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.261839" /><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.261839" /><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.261839" /><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.261839" /></g></g><text
xml:space="preserve"
style="font-size:26.6667px;line-height:1.25;font-family:osifont;-inkscape-font-specification:osifont;text-decoration-color:#000000;fill:#000000;stroke-width:0.999999;-inkscape-stroke:none;stop-color:#000000"
x="557.21405"
y="226.21376"
id="text1017"><tspan
sodipodi:role="line"
id="tspan1015"
x="557.21405"
y="226.21376"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:26.6667px;font-family:Ubuntu;-inkscape-font-specification:'Ubuntu, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal">Vorabstudie</tspan></text></g></svg>

After

Width:  |  Height:  |  Size: 16 KiB

BIN
images/front.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 B

View File

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

144
obp60.py
View File

@ -3,12 +3,18 @@
""" """
Virtuelles Multifunktionsgerät 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 NMEA2000
deviceclass: 120 - Display deviceclass: 120 - Display
devicefunction: 130 - Display devicefunction: 130 - Display
Benötigte Pakete: Benötigte Pakete:
python3-cairo python3-gi python3-gi-cairo gir1.2-rsvg-2.0 python3-cairo python3-gi python3-gi-cairo gir1.2-rsvg-2.0
python3-astral
Um transparente Darstellung unter Openbox zu erhalten muß xcompmgr Um transparente Darstellung unter Openbox zu erhalten muß xcompmgr
installiert und konfiguriert werden. installiert und konfiguriert werden.
@ -67,7 +73,7 @@ Button 5 wird für Trend TRND verwendet
Version Datum Änderung(en) von Version Datum Änderung(en) von
-------- ----------- ------------------------------------------------------ ---- -------- ----------- ------------------------------------------------------ ----
0.1 2024-10-31 Entwicklung begonnen tho 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,25 +280,44 @@ def datareader(histpath, history):
class Frontend(Gtk.Window): class Frontend(Gtk.Window):
button = { def __init__(self, cfg, device, boatdata, profile):
1: (75, 485),
2: (150, 492),
3: (227, 496),
4: (306, 496),
5: (382, 492),
6: (459, 485)
}
radius = 30
def __init__(self, device, boatdata, profile):
super().__init__() super().__init__()
self.owndev = device self.owndev = device
self.boatdata = boatdata self.boatdata = boatdata
self._fullscreen = cfg['guistyle'] == 'fullscreen'
self.connect("destroy", self.on_destroy) self.connect("destroy", self.on_destroy)
self.set_position(Gtk.WindowPosition.CENTER) if self._fullscreen:
self.set_size_request(530, 555) 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),
4: (306, 496),
5: (382, 492),
6: (459, 485)
}
self.button_radius = 30
self.set_position(Gtk.WindowPosition.CENTER)
self.set_size_request(530, 555)
self.set_title("OBP60 virt") self.set_title("OBP60 virt")
self.set_app_paintable(True) self.set_app_paintable(True)
self.set_decorated(False) self.set_decorated(False)
@ -304,7 +329,10 @@ class Frontend(Gtk.Window):
self.set_visual(self.visual) self.set_visual(self.visual)
handle = Rsvg.Handle() handle = Rsvg.Handle()
self._svg = handle.new_from_file(os.path.join(sys.path[0], "obp60.svg")) if self._fullscreen:
self._svg = handle.new_from_file(os.path.join(sys.path[0], "fullscreen2.svg"))
else:
self._svg = handle.new_from_file(os.path.join(sys.path[0], "obp60.svg"))
self.connect("draw", self.on_draw) self.connect("draw", self.on_draw)
@ -346,13 +374,20 @@ class Frontend(Gtk.Window):
viewport = Rsvg.Rectangle() viewport = Rsvg.Rectangle()
viewport.x = 0 viewport.x = 0
viewport.y = 0 viewport.y = 0
viewport.width = 530 if self._fullscreen:
viewport.height = 555 viewport.width = 800
viewport.height = 480
else:
viewport.width = 530
viewport.height = 555
self._svg.render_document(ctx, viewport) self._svg.render_document(ctx, viewport)
ctx.set_source_rgb(1.0, 0, 0) ctx.set_source_rgb(1.0, 0, 0)
ctx.translate(64, 95) # Koordinatenursprung auf virtuellen Displaybereich setzen if not self._fullscreen:
ctx.rectangle(0, 0, 400, 300) ctx.translate(64, 95) # Koordinatenursprung auf virtuellen Displaybereich setzen
ctx.clip() 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ß ctx.set_source_rgb(0, 0, 0) # Schwarz auf Weiß
@ -369,15 +404,28 @@ class Frontend(Gtk.Window):
# Die eigentliche Funktion wird beim Loslassen ausgelöst. # Die eigentliche Funktion wird beim Loslassen ausgelöst.
# Damit sind Wischgesten simulierbar # Damit sind Wischgesten simulierbar
self.button_clicked = 0 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:
return True # Horizontale runde Buttons
if (event.y < self.button[1][1] - self.radius or event.y > self.button[3][1] + self.radius): if (event.x < self.button[1][0] - self.button_radius or event.x > self.button[6][0] + self.button_radius):
return True return True
for b, v in self.button.items(): if (event.y < self.button[1][1] - self.button_radius or event.y > self.button[3][1] + self.button_radius):
diff = math.sqrt((event.x - v[0])**2 + (event.y - v[1])**2) return True
if diff < self.radius: for b, v in self.button.items():
self.button_clicked = b diff = math.sqrt((event.x - v[0])**2 + (event.y - v[1])**2)
break 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 return True
def da_button_release(self, widget, event): def da_button_release(self, widget, event):
@ -388,16 +436,30 @@ class Frontend(Gtk.Window):
# Falls der Rückgabewert "True" ist, hat die Seite die Taste # Falls der Rückgabewert "True" ist, hat die Seite die Taste
# verarbeitet, die Funktion hier wird damit unterdrückt. # verarbeitet, die Funktion hier wird damit unterdrückt.
# TODO # TODO
if (event.x < self.button[1][0] - self.radius or event.x > self.button[6][0] + self.radius): print("release")
return True if self.button_round:
if (event.y < self.button[1][1] - self.radius or event.y > self.button[3][1] + self.radius): if (event.x < self.button[1][0] - self.radius or event.x > self.button[6][0] + self.radius):
return True return True
selected = 0 if (event.y < self.button[1][1] - self.radius or event.y > self.button[3][1] + self.radius):
for b, v in self.button.items(): return True
diff = math.sqrt((event.x - v[0])**2 + (event.y - v[1])**2) selected = 0
if diff < self.radius: for b, v in self.button.items():
selected = b diff = math.sqrt((event.x - v[0])**2 + (event.y - v[1])**2)
break if diff < self.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: if self.keylock:
# Bei Tastensperre einzige Möglichkeit: Tastensperre ausschalten # Bei Tastensperre einzige Möglichkeit: Tastensperre ausschalten
if selected == 6 and self.button_clicked == 1: if selected == 6 and self.button_clicked == 1:
@ -523,6 +585,8 @@ if __name__ == "__main__":
cfg['deviceid'] = config.getint('system', 'deviceid') cfg['deviceid'] = config.getint('system', 'deviceid')
cfg['simulation'] = config.getboolean('system', 'simulation') cfg['simulation'] = config.getboolean('system', 'simulation')
cfg['histpath'] = os.path.expanduser(config.get('system', 'histpath')) cfg['histpath'] = os.path.expanduser(config.get('system', 'histpath'))
cfg['guistyle'] = config.get('system', 'guistyle')
print("Setting GUI style to '{}'".format(cfg['guistyle']))
cfg['gps'] = config.getboolean('gps', 'enabled') cfg['gps'] = config.getboolean('gps', 'enabled')
if cfg['gps']: if cfg['gps']:
@ -552,7 +616,7 @@ if __name__ == "__main__":
t_data = threading.Thread(target=datareader, args=(cfg['histpath'], history)) t_data = threading.Thread(target=datareader, args=(cfg['histpath'], history))
t_data.start() t_data.start()
app = Frontend(owndevice, boatdata, profile) app = Frontend(cfg, owndevice, boatdata, profile)
app.run() app.run()
shutdown = True shutdown = True
t_rxd_n2k.join() t_rxd_n2k.join()

View File

@ -9,7 +9,11 @@ class ApparentWind(Page):
super().__init__(pageno, cfg, boatdata) super().__init__(pageno, cfg, boatdata)
self.buttonlabel[1] = 'MODE' self.buttonlabel[1] = 'MODE'
self.mode = 'L' # (W)ind (L)ens self.mode = 'L' # (W)ind (L)ens
self.symbol = cairo.ImageSurface.create_from_png(os.path.join(cfg['imgpath'], "front.png")) 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): def handle_key(self, buttonid):
if buttonid == 1: if buttonid == 1:
@ -27,10 +31,11 @@ class ApparentWind(Page):
ctx.show_text("Apparent Wind") ctx.show_text("Apparent Wind")
def draw_lens(self, ctx): def draw_lens(self, ctx):
ctx.save() if self.symbol:
ctx.set_source_surface(self.symbol, 140, 30) ctx.save()
ctx.paint() ctx.set_source_surface(self.symbol, 140, 30)
ctx.restore() ctx.paint()
ctx.restore()
ctx.set_line_width(2) ctx.set_line_width(2)

View File

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