/** * wetter.js – Hauptprogramm * * Ablauf beim Start: * 1. SQLite-Datenbank öffnen (wetter.db) * 2. Letzten archivierten Zeitstempel lesen → Archiv nachladen * 3. Archivdaten in DB schreiben * 4. LOOP-Schleife starten: alle 30 s Echtzeit-Daten holen & in DB schreiben */ import "dotenv/config"; import path from "path"; import { fileURLToPath } from "url"; import { openDb, getLatestTs, insertRecords, insertRecord } from "./db.js"; import { readArchiveSince, connectStation, fetchLoopData } from "./davis.js"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const DB_PATH = process.env.DB_PATH ?? path.join(__dirname, "wetter.db"); const LOOP_INTERVAL_MS = Number(process.env.LOOP_INTERVAL_MS ?? 30_000); // ── Hilfsfunktionen ──────────────────────────────────────────────────────── const fmt24h = (d) => d.toLocaleTimeString("de-DE", { hour12: false }); const fmtDateTime = (d) => d.toLocaleString("de-DE", { hour12: false }); function log(msg) { console.log (`[${fmt24h(new Date())}] ${msg}`); } function warn(msg) { console.warn(`[${fmt24h(new Date())}] WARN ${msg}`); } function err(msg) { console.error(`[${fmt24h(new Date())}] ERROR ${msg}`); } // ── Archiv nachladen ─────────────────────────────────────────────────────── async function catchUpArchive(db) { const latestTs = getLatestTs(db); const since = latestTs ? new Date(latestTs * 1000) // ab letztem DB-Eintrag : new Date(Date.now() - 24 * 60 * 60 * 1000); // Fallback: letzte 24 h log(`Lade Archiv ab ${fmtDateTime(since)} ...`); let lastPct = -1; const records = await readArchiveSince(since, (cur, total) => { const pct = Math.floor(cur / total * 100); if (pct !== lastPct) { process.stdout.write(`\r Archiv: ${pct}% (Seite ${cur}/${total})`); lastPct = pct; } }); process.stdout.write("\r\x1b[K"); // Fortschrittszeile löschen if (records.length === 0) { log("Archiv: keine neuen Datensätze."); return; } const inserted = insertRecords(db, records, "archive"); log(`Archiv: ${inserted} neue Datensätze gespeichert (${records.length} empfangen).`); } // ── LOOP-Schleife ────────────────────────────────────────────────────────── async function runLoop(db) { let station = null; async function connect() { station = await connectStation(); log("Verbunden mit Wetterstation."); } async function tick() { try { const data = await fetchLoopData(station); insertRecord(db, data, "loop"); log( `Außen: ${data.tempOut?.toFixed(1)}°C ` + `Feuchte: ${data.humOut}% ` + `Wind: ${data.windAvg} km/h ` + `Druck: ${data.pressure} hPa` ); } catch (e) { warn("LOOP-Fehler: " + e.message + " – Verbindung wird neu aufgebaut."); try { await station?.disconnect(); } catch {} station = null; try { await connect(); } catch (ce) { err("Reconnect fehlgeschlagen: " + ce.message); } } setTimeout(tick, LOOP_INTERVAL_MS); } await connect(); tick(); } // ── Hauptprogramm ────────────────────────────────────────────────────────── const db = openDb(DB_PATH); log(`Datenbank: ${DB_PATH}`); await catchUpArchive(db); await runLoop(db);