First commit
This commit is contained in:
98
wetter.js
Normal file
98
wetter.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* 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);
|
||||
Reference in New Issue
Block a user