116 lines
3.1 KiB
Python
116 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Wetterstation Web-Interface - Visualisierung und API
|
|
Stellt das Web-Interface und Lese-APIs für historische Daten bereit
|
|
"""
|
|
|
|
import sqlite3
|
|
import json
|
|
import os
|
|
from datetime import datetime, timedelta
|
|
from flask import Flask, render_template, jsonify
|
|
from dotenv import load_dotenv
|
|
|
|
# Lade Umgebungsvariablen aus .env Datei
|
|
load_dotenv()
|
|
|
|
# Konfiguration aus Umgebungsvariablen
|
|
DB_FILE = os.getenv("DB_FILE", "wetterdaten.db")
|
|
HTTP_PORT = int(os.getenv("HTTP_PORT", 5003))
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
class WetterDB:
|
|
"""Klasse für Datenbankoperationen (nur Lesezugriff)"""
|
|
|
|
def __init__(self, db_file):
|
|
self.db_file = db_file
|
|
|
|
def get_data(self, hours=24):
|
|
"""Daten der letzten X Stunden abrufen"""
|
|
conn = sqlite3.connect(self.db_file)
|
|
conn.row_factory = sqlite3.Row
|
|
cursor = conn.cursor()
|
|
|
|
time_threshold = (datetime.now() - timedelta(hours=hours)).strftime('%Y-%m-%d %H:%M:%S')
|
|
|
|
cursor.execute('''
|
|
SELECT * FROM wetterdaten
|
|
WHERE dateTime >= ?
|
|
ORDER BY dateTime ASC
|
|
''', (time_threshold,))
|
|
|
|
rows = cursor.fetchall()
|
|
conn.close()
|
|
|
|
return [dict(row) for row in rows]
|
|
|
|
def get_hourly_rain(self, hours=24):
|
|
"""Regenmenge pro Stunde berechnen"""
|
|
conn = sqlite3.connect(self.db_file)
|
|
cursor = conn.cursor()
|
|
|
|
time_threshold = (datetime.now() - timedelta(hours=hours)).strftime('%Y-%m-%d %H:%M:%S')
|
|
|
|
cursor.execute('''
|
|
SELECT
|
|
strftime('%Y-%m-%d %H:00:00', dateTime) as hour,
|
|
SUM(rainRate) as total_rain
|
|
FROM wetterdaten
|
|
WHERE dateTime >= ?
|
|
GROUP BY hour
|
|
ORDER BY hour ASC
|
|
''', (time_threshold,))
|
|
|
|
rows = cursor.fetchall()
|
|
conn.close()
|
|
|
|
return [{'hour': row[0], 'rain': row[1] or 0} for row in rows]
|
|
|
|
|
|
# Globale Datenbankinstanz
|
|
db = WetterDB(DB_FILE)
|
|
|
|
|
|
# Flask Routes
|
|
@app.route('/')
|
|
def index():
|
|
"""Hauptseite"""
|
|
return render_template('index.html')
|
|
|
|
|
|
@app.route('/health')
|
|
def health():
|
|
"""Health-Check Endpoint"""
|
|
return jsonify({'status': 'ok', 'service': 'web'}), 200
|
|
|
|
|
|
@app.route('/api/data/<period>')
|
|
def get_historical_data(period):
|
|
"""API Endpoint für historische Wetterdaten"""
|
|
hours = 24 if period == 'day' else 168 # 168h = 1 Woche
|
|
data = db.get_data(hours)
|
|
rain_data = db.get_hourly_rain(hours)
|
|
|
|
return jsonify({
|
|
'data': data,
|
|
'rain_hourly': rain_data
|
|
})
|
|
|
|
|
|
def main():
|
|
"""Hauptprogramm"""
|
|
print("Wetterstation Web-Interface wird gestartet...")
|
|
print(f"\nWeb-Interface verfügbar unter: http://0.0.0.0:{HTTP_PORT}")
|
|
print(f"API Endpoints:")
|
|
print(f" - http://0.0.0.0:{HTTP_PORT}/api/data/day")
|
|
print(f" - http://0.0.0.0:{HTTP_PORT}/api/data/week")
|
|
print(f"Health-Check: http://0.0.0.0:{HTTP_PORT}/health")
|
|
print("Drücke CTRL+C zum Beenden\n")
|
|
app.run(host='0.0.0.0', port=HTTP_PORT, debug=False)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|