Tide weiterprogrammiert

This commit is contained in:
2025-10-09 20:12:54 +02:00
parent 7613a5b7cb
commit 9ffb28d65b
4 changed files with 159 additions and 35 deletions

103
web.py
View File

@@ -6,20 +6,48 @@ Regelmäßiges Abfragen von Daten aus dem Internet
- DWD
- Pegelstände
- pegelonline
- WSV
- BSH
- Wetterinformationen
TODO
- Datenbanktabelle um feld bshid erweitern um mehrere Pegel gleichzeitig
verarbeiten zu können
"""
import os
import http.client
import ssl
import json
import sqlite3
import datetime
from datetime import datetime, timedelta
from gi.repository import GLib
class WebInterface():
pegeldata = {
'Amrum': '631P',
'Borkum': '101P',
'Büsum': '505P',
'Cuxhaven': '506P',
'Dagebüll': '635P',
'Dwarsgat': '737P',
'Eider Sperrwerk': '664P',
'Emden': '507P',
'Helgoland': '509A',
'Hörnum, Sylt': '624P',
'Hooksiel': '764B',
'Hooge': '636F',
'Husum': '510P',
'Leer': '806P',
'List, Sylt': '617P',
'Norderney': '111P',
'Papenburg': '814P',
'Scharhörn': '677C',
'Schulau': '714P',
'St. Pauli': '508P',
'Wangerooge': '754P'
}
def __init__(self, logger, cfg):
self.log = logger
dbpath = os.path.join(cfg['histpath'], "tidedata.db")
@@ -47,6 +75,19 @@ class WebInterface():
self.cur.execute(sql)
self.log.info(f"Created tide database: {dbpath}")
self.pegelid = 'Schulau'
self.bshid = self.pegeldata[self.pegelid]
# Tidendaten (Rahmen)
self.tide = {
'station': None,
'area': None,
'MHW': None,
'MNW': None,
'warning': None,
'forecast_ts': None
}
# In der Konfiguration werden Minuten angegeben
#GLib.timeout_add_seconds(cfg['tide_refresh'] * 60, self.on_timer)
GLib.timeout_add_seconds(60 * 60, self.on_timer)
@@ -70,12 +111,12 @@ class WebInterface():
"""
if local:
# Für Tests um nicht permanent die Webseite abzufragen
with open("/tmp/DE__714P.json", "r") as fh:
with open(f"/tmp/DE__{self.bshid}.json", "r") as fh:
content = fh.read()
else:
ssl_context = ssl.create_default_context()
conn = http.client.HTTPSConnection("wasserstand-nordsee.bsh.de", 443, context=ssl_context)
url = "https://wasserstand-nordsee.bsh.de/data/DE__714P.json"
url = f"https://wasserstand-nordsee.bsh.de/data/DE__{self.bshid}.json"
try:
conn.request("GET", url)
@@ -91,31 +132,65 @@ class WebInterface():
except ssl.SSLError as ssl_error:
self.log.warning(f"SSL error occurred: {ssl_error}")
return []
finally:
conn.close()
return content
def refresh(self):
self.log.info("Data refresh")
data = self.bsh_get_data(False)
#tmpfile = open("/tmp/DE__714P.json", "w")
#tmpfile.write(data)
#tmpfile.close()
tmpfile = open(f"/tmp/DE__{self.bshid}.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()
self.tide['station'] = wvdata["station_name"]
self.tide['area'] = wvdata["area"]
self.tide['MHW'] = wvdata["MHW"] # Mittleres Hochwasser
self.tide['MNW'] = wvdata["MNW"] # Mittleres Niedrigwasser
self.tide['warning'] = wvdata["warning"]
self.tide['forecast_ts'] = wvdata["creation_forecast"]
# Zeitpunkte und Höhen der beiden nächsten Hoch- und Niedrigwasser
# wvdata["hwnwforecast"]["data"]["event"] HW / NW
# wvdata["hwnwforecast"]["data"]["timestamp"]
# wvdata["hwnwforecast"]["data"]["value"]
def housekeeping(self):
self.log.info("Housekeeping")
def set_pegel(self, pegelid):
self.pegelid = pegelid
self.bshid = self.pegeldata[self.pegelid]
def set_timestamp(self, vorlauf, dauer):
"""
Manuell setzen, damit verschiedene Aufrufe nacheinander auch
auf den selben Zeitstempel zurückgreifen
"""
self.current_ts = datetime.now().replace(minute=0, second=0, microsecond=0)
self.start_ts = self.current_ts - timedelta(hours=vorlauf)
self.end_ts = self.current_ts + timedelta(hours=dauer)
# TODO
# Stationsdaten
# Berechnungszeitpunkt
# Warnhinweise (z.B. Sturmflut)
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()
# 12 Stunden Vorhersage ab der aktuelle Stunde
# Vorlauf sind 4 Stunden
# TODO Aufbereiten, daß nur eine einfache Liste zurückgeliefert wird
sql = "select forecast from data where timestamp > ? and timestamp < ?"
self.cur.execute(sql, (self.start_ts, self.end_ts))
return [x[0] for x in 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)
# Liefert ein Tupel mit min, max zurück
sql = "select min(forecast), max(forecast) from data where timestamp > ? and timestamp < ?"
self.cur.execute(sql, (self.start_ts, self.end_ts))
return self.cur.fetchone()