""" Web Interface Regelmäßiges Abfragen von Daten aus dem Internet - NAVTEX - DWD - Pegelstände - pegelonline - WSV - Wetterinformationen """ import os import http.client import ssl import json import sqlite3 import datetime from gi.repository import GLib class WebInterface(): def __init__(self, logger, cfg): self.log = logger dbpath = os.path.join(cfg['histpath'], "tidedata.db") try: self.conn = sqlite3.connect(dbpath) self.cur = self.conn.cursor() except: self.log.error(f"Failed to open tide database: {dbpath}") return # Datenbank erstellen wenn nicht vorhanden sql = "SELECT name FROM sqlite_master WHERE type='table' AND name='station'" self.cur.execute(sql) if self.cur.fetchone() == None: sql = ("CREATE TABLE IF NOT EXISTS station (" "uuid TEXT PRIMARY KEY NOT NULL," "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}") # 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) self.running = True self.log.info(f"Web interface started") def __del__(self): self.conn.close() def on_timer(self): """ Data handling """ self.refresh() self.housekeeping() return True def bsh_get_data(self, local=False): """ Webseite auslesen """ if local: # Für Tests um nicht permanent die Webseite abzufragen with open("/tmp/DE__714P.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" try: conn.request("GET", url) response = conn.getresponse() if response.status == 200: content = response.read().decode() else: print(f"Error: {response.status}") return [] except http.client.HTTPException as e: self.log.warning(f"HTTP error occurred: {e}") return [] except ssl.SSLError as ssl_error: self.log.warning(f"SSL error occurred: {ssl_error}") return [] 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() 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()