#!/usr/bin/env python3 """ Wetterstation - HTTP-POST Datenempfang und Web-Visualisierung """ import sqlite3 import json import os from datetime import datetime, timedelta from flask import Flask, render_template, jsonify, request 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""" def __init__(self, db_file): self.db_file = db_file self.init_db() def init_db(self): """Datenbank initialisieren""" conn = sqlite3.connect(self.db_file) cursor = conn.cursor() cursor.execute(''' CREATE TABLE IF NOT EXISTS wetterdaten ( id INTEGER PRIMARY KEY AUTOINCREMENT, dateTime TEXT NOT NULL, barometer REAL, outTemp REAL, outHumidity INTEGER, windSpeed REAL, windDir REAL, windGust REAL, rainRate REAL, rain REAL ) ''') cursor.execute(''' CREATE INDEX IF NOT EXISTS idx_dateTime ON wetterdaten(dateTime) ''') conn.commit() conn.close() def save_data(self, data): """Wetterdaten speichern""" conn = sqlite3.connect(self.db_file) cursor = conn.cursor() cursor.execute(''' INSERT INTO wetterdaten (dateTime, barometer, outTemp, outHumidity, windSpeed, windDir, windGust, rainRate, rain) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ''', ( data.get('dateTime'), data.get('barometer'), data.get('outTemp'), data.get('outHumidity'), data.get('windSpeed'), data.get('windDir'), data.get('windGust'), data.get('rainRate'), data.get('rain') )) conn.commit() conn.close() print(f"Daten gespeichert: {data.get('dateTime')}") 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('/api/data/upload', methods=['POST']) def upload_data(): """HTTP-POST Endpoint für Wetterdaten""" try: data = request.get_json() if not data: return jsonify({'error': 'Keine Daten empfangen'}), 400 # Daten speichern (unverändert) db.save_data(data) return jsonify({ 'status': 'success', 'message': 'Daten empfangen und gespeichert' }), 200 except Exception as e: print(f"Fehler beim Verarbeiten der POST-Anfrage: {e}") return jsonify({'error': str(e)}), 400 @app.route('/api/data/') 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 wird gestartet...") print("\nWeb-Interface verfügbar unter: http://localhost:5003") print("HTTP-POST Endpoint: http://localhost:5003/api/data/upload") print("Drücke CTRL+C zum Beenden\n") app.run(host='0.0.0.0', port=HTTP_PORT, debug=False) if __name__ == '__main__': main()