const express = require('express'); const path = require('path'); const cors = require('cors'); const fs = require('fs'); const bodyParser = require('body-parser'); const mqtt = require('mqtt'); const app = express(); const port = process.env.PORT || 3000; const mqttBroker = process.env.MQTT_BROKER || 'mqtt://192.168.1.100:1883'; const mqttTopic = process.env.MQTT_TOPIC || 'iobroker/pickupCheck/config'; const mqttUser = process.env.MQTT_USER || 'iobroker'; const mqttPassword = process.env.MQTT_PASSWORD || 'password'; const configPath = './config/pickup-config.json'; // Logger mit Timestamp function logWithTimestamp(...args) { const timestamp = new Date().toISOString(); console.log(`[${timestamp}]`, ...args); } function errorWithTimestamp(...args) { const timestamp = new Date().toISOString(); console.error(`[${timestamp}]`, ...args); } // MQTT-Client mit Authentifizierung initialisieren const mqttClient = mqtt.connect(mqttBroker, { clientId: 'pickup-config-web-' + Math.random().toString(16).substring(2, 8), clean: true, username: mqttUser, password: mqttPassword }); // MQTT-Events mqttClient.on('connect', () => { logWithTimestamp('Verbunden mit MQTT-Broker:', mqttBroker); mqttClient.subscribe(mqttTopic, (err) => { if (!err) { logWithTimestamp('Abonniert auf Topic:', mqttTopic); mqttClient.publish(mqttTopic + '/get', 'true'); } }); }); mqttClient.on('error', (error) => { errorWithTimestamp('MQTT-Fehler:', error); }); mqttClient.on('message', (topic, message) => { logWithTimestamp('Nachricht erhalten auf Topic:', topic); if (topic === mqttTopic) { try { const config = JSON.parse(message.toString()); logWithTimestamp('Konfiguration vom MQTT-Broker erhalten'); fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); } catch (error) { errorWithTimestamp('Fehler beim Verarbeiten der MQTT-Nachricht:', error); } } }); // Middleware app.use(cors()); app.use(bodyParser.json()); app.use(express.static(path.join(__dirname, 'build'))); // Sicherstellen, dass Konfigurationsordner existiert const configDir = path.dirname(configPath); if (!fs.existsSync(configDir)) { fs.mkdirSync(configDir, { recursive: true }); } // Initiale Konfigurationsdatei erstellen, falls nicht vorhanden if (!fs.existsSync(configPath)) { const initialConfig = [ { id: "63448", active: false, checkProfileId: true, onlyNotify: true, label: "Penny Baden-Oos" }, { id: "44975", active: false, checkProfileId: true, onlyNotify: false, label: "Aldi Kuppenheim", desiredWeekday: "Samstag" }, { id: "44972", active: false, checkProfileId: true, onlyNotify: false, label: "Aldi Biblisweg", desiredWeekday: "Dienstag" }, { id: "44975", active: false, checkProfileId: true, onlyNotify: false, label: "Aldi Kuppenheim", desiredDate: "2025-05-18" }, { id: "33875", active: false, checkProfileId: true, onlyNotify: false, label: "Cap Markt", desiredWeekday: "Donnerstag" }, { id: "42322", active: false, checkProfileId: false, onlyNotify: false, label: "Edeka Haueneberstein" }, { id: "51450", active: false, checkProfileId: true, onlyNotify: false, label: "Hornbach Grünwinkel" } ]; fs.writeFileSync(configPath, JSON.stringify(initialConfig, null, 2)); mqttClient.publish(mqttTopic, JSON.stringify(initialConfig)); logWithTimestamp('Initiale Konfiguration erstellt und an MQTT gesendet'); } // API: Konfiguration abrufen app.get('/api/iobroker/pickup-config', (req, res) => { try { const configData = fs.readFileSync(configPath, 'utf8'); res.json(JSON.parse(configData)); } catch (error) { errorWithTimestamp('Error reading configuration:', error); res.status(500).json({ error: 'Failed to read configuration' }); } }); // API: Konfiguration speichern app.post('/api/iobroker/pickup-config', (req, res) => { try { const newConfig = req.body; fs.writeFileSync(configPath, JSON.stringify(newConfig, null, 2)); mqttClient.publish(mqttTopic, JSON.stringify(newConfig)); logWithTimestamp('Konfiguration über MQTT gesendet'); res.json({ success: true }); } catch (error) { errorWithTimestamp('Error saving configuration:', error); res.status(500).json({ error: 'Failed to save configuration' }); } }); // React-App ausliefern app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'build', 'index.html')); }); // Server starten app.listen(port, () => { logWithTimestamp(`Server läuft auf Port ${port}`); });