First Commit - sieht schon gut aus
This commit is contained in:
214
server.js
Normal file
214
server.js
Normal file
@@ -0,0 +1,214 @@
|
||||
const express = require('express');
|
||||
const { MongoClient, ObjectId } = require('mongodb');
|
||||
const path = require('path');
|
||||
|
||||
const app = express();
|
||||
const PORT = 3000;
|
||||
|
||||
// MongoDB-Verbindung
|
||||
const MONGO_URL = 'mongodb://nuccy:27017';
|
||||
const DB_NAME = 'smarthome';
|
||||
|
||||
// Konfiguration für verschiedene Collections
|
||||
const COLLECTION_CONFIG = {
|
||||
'maschinen': {
|
||||
verbraucherFeld: 'maschine',
|
||||
arbeitsFeld: 'arbeit',
|
||||
zeitFeld: 'datetime',
|
||||
faktor: 1, // Wh
|
||||
einheit: 'Wh',
|
||||
// Verbraucher-spezifische Faktoren
|
||||
verbraucherFaktoren: {
|
||||
'spuelmaschine': 1000 // kWh -> Wh
|
||||
}
|
||||
},
|
||||
'auto': {
|
||||
verbraucherFeld: null, // kein Verbraucher-Feld
|
||||
verbraucherName: 'Auto', // fester Name
|
||||
arbeitsFeld: 'gesamt',
|
||||
zeitFeld: '_id', // Zeitstempel aus ObjectId
|
||||
faktor: 100, // 0.1 kWh = 100 Wh
|
||||
einheit: 'Wh'
|
||||
}
|
||||
};
|
||||
|
||||
let db;
|
||||
|
||||
// Verbindung zur MongoDB herstellen
|
||||
MongoClient.connect(MONGO_URL)
|
||||
.then(client => {
|
||||
console.log('Erfolgreich mit MongoDB verbunden');
|
||||
db = client.db(DB_NAME);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('MongoDB Verbindungsfehler:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// View-Engine konfigurieren
|
||||
app.set('view engine', 'pug');
|
||||
app.set('views', path.join(__dirname, 'views'));
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
app.use(express.static('public'));
|
||||
|
||||
// Hauptseite rendern
|
||||
app.get('/', (req, res) => {
|
||||
res.render('index');
|
||||
});
|
||||
|
||||
// Hilfsfunktion: Zeitstempel aus Dokument extrahieren
|
||||
function getTimestamp(doc, zeitFeld) {
|
||||
if (zeitFeld === '_id') {
|
||||
// Zeitstempel aus ObjectId extrahieren
|
||||
return doc._id.getTimestamp();
|
||||
}
|
||||
return doc[zeitFeld];
|
||||
}
|
||||
|
||||
// Hilfsfunktion: Query für Zeitbereich erstellen
|
||||
function createTimeQuery(start, end, zeitFeld) {
|
||||
if (zeitFeld === '_id') {
|
||||
// Bei ObjectId: IDs im Zeitbereich generieren
|
||||
const startId = ObjectId.createFromTime(Math.floor(start.getTime() / 1000));
|
||||
const endId = ObjectId.createFromTime(Math.floor(end.getTime() / 1000));
|
||||
return { _id: { $gte: startId, $lte: endId } };
|
||||
}
|
||||
return { [zeitFeld]: { $gte: start, $lte: end } };
|
||||
}
|
||||
|
||||
// Hilfsfunktion: Daten für eine Collection abrufen
|
||||
async function fetchCollectionData(collectionName, start, end) {
|
||||
const config = COLLECTION_CONFIG[collectionName];
|
||||
if (!config) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const coll = db.collection(collectionName);
|
||||
const timeQuery = createTimeQuery(start, end, config.zeitFeld);
|
||||
|
||||
let verbraucherList;
|
||||
|
||||
if (config.verbraucherFeld) {
|
||||
// Alle Verbraucher im Zeitraum finden
|
||||
verbraucherList = await coll.distinct(config.verbraucherFeld, timeQuery);
|
||||
} else {
|
||||
// Nur ein Verbraucher mit festem Namen
|
||||
verbraucherList = [config.verbraucherName];
|
||||
}
|
||||
|
||||
// Für jeden Verbraucher den ersten und letzten Wert im Zeitraum holen
|
||||
const verbrauchsData = await Promise.all(
|
||||
verbraucherList.map(async (verbraucher) => {
|
||||
let query = { ...timeQuery };
|
||||
|
||||
// Verbraucher-Filter hinzufügen, falls vorhanden
|
||||
if (config.verbraucherFeld) {
|
||||
query[config.verbraucherFeld] = verbraucher;
|
||||
}
|
||||
|
||||
// Sortierfeld festlegen
|
||||
const sortFeld = config.zeitFeld;
|
||||
|
||||
// Erster Wert im Zeitraum
|
||||
const ersterWert = await coll
|
||||
.find(query)
|
||||
.sort({ [sortFeld]: 1 })
|
||||
.limit(1)
|
||||
.toArray();
|
||||
|
||||
// Letzter Wert im Zeitraum
|
||||
const letzterWert = await coll
|
||||
.find(query)
|
||||
.sort({ [sortFeld]: -1 })
|
||||
.limit(1)
|
||||
.toArray();
|
||||
|
||||
// Verbraucher-spezifischen Faktor prüfen
|
||||
let faktor = config.faktor;
|
||||
if (config.verbraucherFaktoren && config.verbraucherFaktoren[verbraucher]) {
|
||||
faktor = config.verbraucherFaktoren[verbraucher];
|
||||
}
|
||||
|
||||
const anfangsWert = (ersterWert[0][config.arbeitsFeld] || 0) * faktor;
|
||||
const endWert = (letzterWert[0][config.arbeitsFeld] || 0) * faktor;
|
||||
const verbrauch = endWert - anfangsWert;
|
||||
|
||||
return {
|
||||
verbraucher: verbraucher,
|
||||
collection: collectionName,
|
||||
anfangsWert: anfangsWert,
|
||||
anfangsZeit: getTimestamp(ersterWert[0], config.zeitFeld),
|
||||
endWert: endWert,
|
||||
endZeit: getTimestamp(letzterWert[0], config.zeitFeld),
|
||||
verbrauch: verbrauch,
|
||||
einheit: 'Wh' // Normalisiert auf Wh
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
// Null-Werte filtern (Verbraucher ohne Daten)
|
||||
return verbrauchsData.filter(item => item !== null);
|
||||
}
|
||||
|
||||
// API-Endpoint zum Abrufen der Verbrauchsdaten
|
||||
app.get('/api/verbrauch', async (req, res) => {
|
||||
try {
|
||||
const { collections, startDate, endDate } = req.query;
|
||||
|
||||
if (!collections || !startDate || !endDate) {
|
||||
return res.status(400).json({
|
||||
error: 'Parameter fehlen: collections, startDate, endDate erforderlich'
|
||||
});
|
||||
}
|
||||
|
||||
const start = new Date(startDate);
|
||||
const end = new Date(endDate);
|
||||
|
||||
// Ende auf 23:59:59 setzen
|
||||
end.setHours(23, 59, 59, 999);
|
||||
|
||||
// Collections-Parameter kann kommaseparierte Liste sein
|
||||
const collectionList = typeof collections === 'string'
|
||||
? collections.split(',').map(c => c.trim())
|
||||
: [collections];
|
||||
|
||||
// Daten für alle Collections abrufen
|
||||
const allResults = await Promise.all(
|
||||
collectionList.map(collectionName =>
|
||||
fetchCollectionData(collectionName, start, end)
|
||||
)
|
||||
);
|
||||
|
||||
// Alle Ergebnisse zusammenführen
|
||||
const alleVerbraucher = allResults.flat();
|
||||
|
||||
res.json({
|
||||
zeitraum: { von: start, bis: end },
|
||||
collections: collectionList,
|
||||
verbraucher: alleVerbraucher
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Abrufen der Daten:', error);
|
||||
res.status(500).json({ error: 'Serverfehler: ' + error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// API-Endpoint zum Abrufen verfügbarer Collections
|
||||
app.get('/api/collections', async (req, res) => {
|
||||
try {
|
||||
const collections = await db.listCollections().toArray();
|
||||
const collectionNames = collections.map(c => c.name);
|
||||
res.json({ collections: collectionNames });
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Abrufen der Collections:', error);
|
||||
res.status(500).json({ error: 'Serverfehler: ' + error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Server starten
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Server läuft auf http://localhost:${PORT}`);
|
||||
});
|
||||
Reference in New Issue
Block a user