Tide: Anzeige erster Testdaten
This commit is contained in:
parent
e9d473fd10
commit
e7a2f4bb54
|
@ -4,6 +4,7 @@ Generische Applikationsdaten
|
|||
"""
|
||||
|
||||
import os
|
||||
from web import WebInterface
|
||||
from tracker import Tracker
|
||||
from navtex import NAVTEX
|
||||
|
||||
|
@ -14,6 +15,13 @@ class AppData():
|
|||
self.log = logger
|
||||
if cfg['navtex']:
|
||||
self.navtex = NAVTEX(logger, cfg)
|
||||
else:
|
||||
self.navtex = None
|
||||
if cfg['tide']:
|
||||
self.web = WebInterface(logger, cfg)
|
||||
self.web.refresh()
|
||||
else:
|
||||
self.web = None
|
||||
self.track = Tracker(logger, cfg)
|
||||
self.frontend = None
|
||||
self.bv_lat = None
|
||||
|
|
|
@ -26,6 +26,9 @@ B2: Subject indicator character
|
|||
Y Special services — allocation by IMO NAVTEX Panel
|
||||
Z No message on hand
|
||||
|
||||
Für Konfiguration: subjects = ABCDEFGHIJKLTVWXYZ
|
||||
|
||||
|
||||
B3, B4: Serial number 01-99, 00: immediate printout
|
||||
|
||||
Timecode: DDHHmm UTC MMM YY
|
||||
|
@ -38,6 +41,7 @@ Sqlite database schema
|
|||
content TEXT
|
||||
received TEXT
|
||||
|
||||
siehe auch: https://www.icselectronics.co.uk/support/info/navtexdb
|
||||
"""
|
||||
import os
|
||||
import http.client
|
||||
|
|
|
@ -36,6 +36,8 @@ port = /dev/ttyACM0
|
|||
[navtex]
|
||||
enabled = false
|
||||
source = net
|
||||
navarea = I
|
||||
subjects = ABDEFKLXYZ
|
||||
housekeeping = 72
|
||||
refresh = 30
|
||||
|
||||
|
|
18
obp60v.py
18
obp60v.py
|
@ -6,7 +6,7 @@ Virtuelles Multifunktionsgerät OBP60v
|
|||
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
|
||||
mit Platz für große Touch-Flächen (160px) am rechten Rand
|
||||
|
||||
Das Gerät kann Daten von NMEA2000 und NMEA0183 empfangen, sowie von
|
||||
einem lokal angeschlossenen GPS-Empfänger.
|
||||
|
@ -141,6 +141,7 @@ cfg = {
|
|||
'gps': False,
|
||||
'bme280': False,
|
||||
'tracker': { 'type': 'NONE' },
|
||||
'tide': False,
|
||||
'boat': { }
|
||||
}
|
||||
|
||||
|
@ -798,13 +799,21 @@ if __name__ == "__main__":
|
|||
config.write(fh)
|
||||
log.info("Created new boat UUID: {}".format(cfg['boat']['uuid']))
|
||||
|
||||
# Globale Daten, u.a. auch Shutdown-Indikator
|
||||
appdata = AppData(log, cfg)
|
||||
|
||||
# Ggf. Simulationsdaten einschalten
|
||||
if cfg['simulation']:
|
||||
boatdata.enableSimulation()
|
||||
|
||||
# Tide wird aktiviert wenn mindestens eine Tidenseite angezeigt wird
|
||||
for s in config.sections():
|
||||
if s == 'pages':
|
||||
continue
|
||||
if s.startswith('page'):
|
||||
if config.get(s, "type") == 'Tide':
|
||||
cfg['tide'] = True
|
||||
|
||||
# Globale Daten, u.a. auch Shutdown-Indikator
|
||||
appdata = AppData(log, cfg)
|
||||
|
||||
# Gerät initialisieren u.a. mit den genutzten Seiten
|
||||
profile = init_profile(config, cfg, boatdata)
|
||||
|
||||
|
@ -834,6 +843,7 @@ if __name__ == "__main__":
|
|||
elif cfg['tracker']['type'] in ['LOCAL', 'SDCARD']:
|
||||
t_tracker = threading.Thread(target=appdata.track.local_tracker, args=(cfg,appdata,boatdata))
|
||||
t_tracker.start()
|
||||
|
||||
if not cfg['simulation']:
|
||||
if cfg['bme280']:
|
||||
log.info("Environment sensor enabled")
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""
|
||||
|
||||
NAVTEX
|
||||
- Meldungen anzeigen
|
||||
Tide Vorausschau
|
||||
|
||||
"""
|
||||
|
||||
|
@ -25,6 +24,9 @@ class Tide(Page):
|
|||
ctx.set_font_size(16)
|
||||
ctx.set_line_width(2)
|
||||
|
||||
ctx.move_to(220, 40)
|
||||
ctx.show_text("Schulau, Elbe")
|
||||
|
||||
x0 = 40 # links unten
|
||||
y0 = 250
|
||||
x1 = 380 # rechts oben
|
||||
|
@ -48,3 +50,28 @@ class Tide(Page):
|
|||
self.draw_text_center(ctx, x0 + (x1 - x0) / 2, y0 + 12, "Zeit, h")
|
||||
ctx.stroke()
|
||||
|
||||
ymin, ymax = self.app.web.get_tide_minmax()
|
||||
rawdata = self.app.web.get_tide()
|
||||
|
||||
ctx.move_to(x0 - 32, y0 + 8)
|
||||
ctx.show_text(str(ymin))
|
||||
|
||||
ctx.move_to(x0 - 32, y1 + 8)
|
||||
ctx.show_text(str(ymax))
|
||||
|
||||
ctx.move_to(x0 + 16, y0 + 16)
|
||||
ctx.show_text(f"n = {len(rawdata)}")
|
||||
|
||||
dx = (x1 - x0) / len(rawdata)
|
||||
x = x0
|
||||
while rawdata[0][0] is None:
|
||||
x += dx
|
||||
del rawdata[0]
|
||||
y = (rawdata[0][0] - ymin) / (ymax - ymin) * (y0 - y1)
|
||||
ctx.move_to(x, y0 - (rawdata[0][0] - ymin))
|
||||
del rawdata[0]
|
||||
x += dx
|
||||
for val in rawdata:
|
||||
y = (val[0] - ymin) / (ymax - ymin) * (y0 - y1)
|
||||
ctx.line_to(x, y0 - y)
|
||||
x += dx
|
||||
|
|
46
web.py
46
web.py
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
Web Interface
|
||||
|
||||
Regelmäßiges Abfragen von Daten im Internet
|
||||
Regelmäßiges Abfragen von Daten aus dem Internet
|
||||
- NAVTEX
|
||||
- DWD
|
||||
- Pegelstände
|
||||
|
@ -13,7 +13,7 @@ Regelmäßiges Abfragen von Daten im Internet
|
|||
import os
|
||||
import http.client
|
||||
import ssl
|
||||
import re
|
||||
import json
|
||||
import sqlite3
|
||||
import datetime
|
||||
from gi.repository import GLib
|
||||
|
@ -35,7 +35,14 @@ class WebInterface():
|
|||
if self.cur.fetchone() == None:
|
||||
sql = ("CREATE TABLE IF NOT EXISTS station ("
|
||||
"uuid TEXT PRIMARY KEY NOT NULL,"
|
||||
"name TEXT"
|
||||
"name TEXT)"
|
||||
)
|
||||
self.cur.execute(sql)
|
||||
sql = ("CREATE TABLE IF NOT EXISTS data ("
|
||||
"timestamp TEXT PRIMARY KEY NOT NULL,"
|
||||
"astro NUMBER NOT NULL,"
|
||||
"forecast NUMBER,"
|
||||
"measurement NUMBER)"
|
||||
)
|
||||
self.cur.execute(sql)
|
||||
self.log.info(f"Created tide database: {dbpath}")
|
||||
|
@ -44,6 +51,7 @@ class WebInterface():
|
|||
#GLib.timeout_add_seconds(cfg['tide_refresh'] * 60, self.on_timer)
|
||||
GLib.timeout_add_seconds(60 * 60, self.on_timer)
|
||||
self.running = True
|
||||
self.log.info(f"Web interface started")
|
||||
|
||||
def __del__(self):
|
||||
self.conn.close()
|
||||
|
@ -62,7 +70,7 @@ class WebInterface():
|
|||
"""
|
||||
if local:
|
||||
# Für Tests um nicht permanent die Webseite abzufragen
|
||||
with open("DE__714P.json", "r") as fh:
|
||||
with open("/tmp/DE__714P.json", "r") as fh:
|
||||
content = fh.read()
|
||||
else:
|
||||
ssl_context = ssl.create_default_context()
|
||||
|
@ -88,18 +96,26 @@ class WebInterface():
|
|||
|
||||
def refresh(self):
|
||||
self.log.info("Data refresh")
|
||||
data = self.bsh_get_data(True)
|
||||
"""
|
||||
sql = "INSERT INTO message (msgid, station, content) VALUES (?, ?, ?)"
|
||||
for m in messages:
|
||||
msg = self.parse_message(m)
|
||||
self.cur.execute("SELECT COUNT(*) FROM message WHERE msgid=?", (msg['id'],))
|
||||
result = self.cur.fetchone()
|
||||
if result[0] == 0:
|
||||
self.log.debug(f"NAVTEX: insert new message '{msg['id']}'")
|
||||
self.cur.execute(sql, (msg['id'], msg['station'], m))
|
||||
data = self.bsh_get_data(False)
|
||||
#tmpfile = open("/tmp/DE__714P.json", "w")
|
||||
#tmpfile.write(data)
|
||||
#tmpfile.close()
|
||||
wvdata = json.loads(data)
|
||||
sql = "INSERT OR REPLACE INTO data (timestamp, astro, forecast, measurement) VALUES (?, ?, ?, ?)"
|
||||
for wv in wvdata["curve_forecast"]["data"]:
|
||||
self.cur.execute(sql, (wv['timestamp'], wv['astro'], wv['curveforecast'], wv['measurement']))
|
||||
self.conn.commit()
|
||||
"""
|
||||
|
||||
def housekeeping(self):
|
||||
self.log.info("Housekeeping")
|
||||
|
||||
def get_tide(self):
|
||||
# 12 Stunden
|
||||
sql = "select forecast from data where timestamp > '2025-10-05 12:00' and timestamp < '2025-10-06 22:00'"
|
||||
self.cur.execute(sql)
|
||||
return self.cur.fetchall()
|
||||
|
||||
def get_tide_minmax(self):
|
||||
sql = "select min(forecast), max(forecast) from data where timestamp > '2025-10-05 12:00' and timestamp < '2025-10-06 22:00'"
|
||||
self.cur.execute(sql)
|
||||
return self.cur.fetchone()
|
||||
|
|
Loading…
Reference in New Issue