MQTT Visualisierte Schaltzentrale von Lichtern und Haustüröffner: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „=== Voraussetzungen === Ein separater Node.js-Server wird für die Steuerung der MQTT-Nachrichten verwendet, um das Ein- und Ausschalten der Geräte unabhän…“)
 
 
(15 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
 
=== Voraussetzungen ===   
 
=== Voraussetzungen ===   
Ein separater Node.js-Server wird für die Steuerung der MQTT-Nachrichten verwendet, um das Ein- und Ausschalten der Geräte unabhängig steuern zu können.
+
*[[Voraussetzungen für Node.js-Projekt]]
  
 
==== Neues Verzeichnis für den Steuerungsserver erstellen ====
 
==== Neues Verzeichnis für den Steuerungsserver erstellen ====
*'''mkdir /usr/local/home-control-switch'''
+
*'''mkdir /usr/local/control-switch'''
*'''cd /usr/local/home-control-switch'''
+
*'''cd /usr/local/control-switch'''
  
 
==== Initialisiere das Node.js-Projekt ====
 
==== Initialisiere das Node.js-Projekt ====
Zeile 13: Zeile 13:
  
 
==== Konfiguration des Steuerungsservers ====
 
==== Konfiguration des Steuerungsservers ====
Erstelle die Datei '''switch-server.js''' im Verzeichnis '''/usr/local/home-control-switch''' mit folgendem Inhalt:
+
Erstelle die Datei '''switch-server.js''' im Verzeichnis '''/usr/local/control-switch''' mit folgendem Inhalt:
  
 
<pre>
 
<pre>
 
const mqtt = require('mqtt');
 
const mqtt = require('mqtt');
 +
const fs = require('fs');
 
const express = require('express');
 
const express = require('express');
 +
const path = require('path');
 
const app = express();
 
const app = express();
const port = 3001;
+
const port = 3000;
  
// MQTT-Konfiguration
+
let status = {
const client = mqtt.connect('mqtt://10.0.10.97:1883', {
+
  wohnzimmer: 'off',
   username: 'xinux',
+
  schlafzimmer: 'off',
   password: 'geheim'
+
  kueche: 'off',
});
+
  haustuer: 'geschlossen'
 +
};
 +
 
 +
// MQTT-Verbindung herstellen über TLS
 +
const options = {
 +
  port: 1883,
 +
  host: 'mqtt.dkbi.int',
 +
  //protocol: 'mqtts',
 +
   //username: 'xinux',
 +
   //password: 'geheim',
 +
  //ca: fs.readFileSync('./ca.crt')  // Pfad zur ca.crt
 +
};
 +
 
 +
const client = mqtt.connect(options);
  
 
client.on('connect', () => {
 
client.on('connect', () => {
 
   console.log('Verbunden mit dem Broker');
 
   console.log('Verbunden mit dem Broker');
 +
  client.subscribe('home/+/status', (err) => {
 +
    if (!err) {
 +
      console.log('Alle Topics abonniert');
 +
    }
 +
  });
 
});
 
});
  
// Funktion zum Senden von MQTT-Nachrichten
+
client.on('message', (topic, message) => {
function toggleDevice(topic, state) {
+
   const room = topic.split('/')[1];
   client.publish(topic, state);
+
  status[room] = message.toString();
}
+
  console.log(`Status von ${room}: ${status[room]}`);
 +
});
  
// API-Endpunkte zum Steuern der Geräte
+
// API-Route für den Status der Lichter und Haustür
app.get('/toggle/wohnzimmer', (req, res) => {
+
app.get('/status', (req, res) => {
  toggleDevice('home/wohnzimmer/status', 'on');
+
   res.send(status);
   res.send('Wohnzimmer Licht eingeschaltet');
 
 
});
 
});
  
app.get('/toggle/schlafzimmer', (req, res) => {
+
// Statisches Verzeichnis für die Webseite
   toggleDevice('home/schlafzimmer/status', 'on');
+
app.use(express.static(path.join(__dirname)));
  res.send('Schlafzimmer Licht eingeschaltet');
+
 
 +
// Starte den Webserver
 +
app.listen(port, () => {
 +
   console.log(`Webserver läuft auf http://localhost:${port}`);
 
});
 
});
  
app.get('/toggle/kueche', (req, res) => {
+
</pre>
  toggleDevice('home/kueche/status', 'on');
+
 
  res.send('Küchen Licht eingeschaltet');
+
==== Die HTML Datei index.html====
});
+
<pre>
 +
 
 +
 +
<!DOCTYPE html>
 +
<html lang="de">
 +
<head>
 +
  <meta charset="UTF-8">
 +
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 +
  <title>Haussteuerung</title>
 +
  <style>
 +
    .device {
 +
      margin: 20px;
 +
      padding: 10px;
 +
      border-radius: 10px;
 +
      text-align: center;
 +
      font-size: 1.5em;
 +
    }
 +
    .on {
 +
      background-color: green;
 +
      color: white;
 +
    }
 +
    .off {
 +
      background-color: red;
 +
      color: white;
 +
    }
 +
    .open {
 +
      background-color: blue;
 +
      color: white;
 +
    }
 +
    .closed {
 +
      background-color: gray;
 +
      color: white;
 +
    }
 +
  </style>
 +
  <script>
 +
    function fetchStatus() {
 +
      fetch('/status')
 +
        .then(response => response.json())
 +
        .then(data => {
 +
          document.getElementById('wohnzimmer').className = 'device ' + (data.wohnzimmer === 'on' ? 'on' : 'off');
 +
          document.getElementById('schlafzimmer').className = 'device ' + (data.schlafzimmer === 'on' ? 'on' : 'off');
 +
          document.getElementById('kueche').className = 'device ' + (data.kueche === 'on' ? 'on' : 'off');
 +
          document.getElementById('haustuer').className = 'device ' + (data.haustuer === 'offen' ? 'open' : 'closed');
 +
        });
 +
    }
 +
 
 +
    setInterval(fetchStatus, 1000); // Alle 1 Sekunde den Status abrufen
 +
  </script>
 +
</head>
 +
<body>
 +
  <h1>Haussteuerung</h1>
 +
  <div id="wohnzimmer" class="device off">Wohnzimmer Licht: Aus</div>
 +
  <div id="schlafzimmer" class="device off">Schlafzimmer Licht: Aus</div>
 +
  <div id="kueche" class="device off">Küchen Licht: Aus</div>
 +
  <div id="haustuer" class="device closed">Haustür: Geschlossen</div>
 +
</body>
 +
</html>
  
app.get('/toggle/haustuer', (req, res) => {
 
  toggleDevice('home/haustuer/status', 'offen');
 
  res.send('Haustür geöffnet');
 
});
 
  
// Server starten
 
app.listen(port, () => {
 
  console.log(`Schalt-Server läuft auf http://localhost:${port}`);
 
});
 
 
</pre>
 
</pre>
  
 
==== systemd-Unit für den Steuerungsserver erstellen ====
 
==== systemd-Unit für den Steuerungsserver erstellen ====
Erstelle die Datei '''/etc/systemd/system/home-control-switch.service''' mit folgendem Inhalt:
+
Erstelle die Datei '''/etc/systemd/system/control-switch.service''' mit folgendem Inhalt:
  
 
<pre>
 
<pre>
Zeile 72: Zeile 143:
 
[Service]
 
[Service]
 
Type=simple
 
Type=simple
WorkingDirectory=/usr/local/home-control-switch
+
WorkingDirectory=/usr/local/control-switch
ExecStart=/usr/bin/node switch-server.js
+
ExecStart=/usr/bin/node server.js
 
ExecStartPost=/bin/echo "Schalt-Server gestartet"
 
ExecStartPost=/bin/echo "Schalt-Server gestartet"
  
Zeile 81: Zeile 152:
  
 
==== Steuerungsserver starten und beim Booten aktivieren ====
 
==== Steuerungsserver starten und beim Booten aktivieren ====
*'''systemctl start home-control-switch.service'''
+
*'''systemctl start control-switch.service'''
*'''systemctl enable home-control-switch.service'''
+
*'''systemctl enable control-switch.service'''
  
 
==== Steuerung der Geräte über HTTP ====
 
==== Steuerung der Geräte über HTTP ====

Aktuelle Version vom 29. Oktober 2024, 11:50 Uhr

Voraussetzungen

Neues Verzeichnis für den Steuerungsserver erstellen

  • mkdir /usr/local/control-switch
  • cd /usr/local/control-switch

Initialisiere das Node.js-Projekt

  • npm init -y

Installiere die benötigten Pakete

  • npm install mqtt express

Konfiguration des Steuerungsservers

Erstelle die Datei switch-server.js im Verzeichnis /usr/local/control-switch mit folgendem Inhalt:

const mqtt = require('mqtt');
const fs = require('fs');
const express = require('express');
const path = require('path');
const app = express();
const port = 3000;

let status = {
  wohnzimmer: 'off',
  schlafzimmer: 'off',
  kueche: 'off',
  haustuer: 'geschlossen'
};

// MQTT-Verbindung herstellen über TLS
const options = {
  port: 1883,
  host: 'mqtt.dkbi.int',
  //protocol: 'mqtts',
  //username: 'xinux',
  //password: 'geheim',
  //ca: fs.readFileSync('./ca.crt')  // Pfad zur ca.crt
};

const client = mqtt.connect(options);

client.on('connect', () => {
  console.log('Verbunden mit dem Broker');
  client.subscribe('home/+/status', (err) => {
    if (!err) {
      console.log('Alle Topics abonniert');
    }
  });
});

client.on('message', (topic, message) => {
  const room = topic.split('/')[1];
  status[room] = message.toString();
  console.log(`Status von ${room}: ${status[room]}`);
});

// API-Route für den Status der Lichter und Haustür
app.get('/status', (req, res) => {
  res.send(status);
});

// Statisches Verzeichnis für die Webseite
app.use(express.static(path.join(__dirname)));

// Starte den Webserver
app.listen(port, () => {
  console.log(`Webserver läuft auf http://localhost:${port}`);
});

Die HTML Datei index.html


 
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Haussteuerung</title>
  <style>
    .device {
      margin: 20px;
      padding: 10px;
      border-radius: 10px;
      text-align: center;
      font-size: 1.5em;
    }
    .on {
      background-color: green;
      color: white;
    }
    .off {
      background-color: red;
      color: white;
    }
    .open {
      background-color: blue;
      color: white;
    }
    .closed {
      background-color: gray;
      color: white;
    }
  </style>
  <script>
    function fetchStatus() {
      fetch('/status')
        .then(response => response.json())
        .then(data => {
          document.getElementById('wohnzimmer').className = 'device ' + (data.wohnzimmer === 'on' ? 'on' : 'off');
          document.getElementById('schlafzimmer').className = 'device ' + (data.schlafzimmer === 'on' ? 'on' : 'off');
          document.getElementById('kueche').className = 'device ' + (data.kueche === 'on' ? 'on' : 'off');
          document.getElementById('haustuer').className = 'device ' + (data.haustuer === 'offen' ? 'open' : 'closed');
        });
    }

    setInterval(fetchStatus, 1000); // Alle 1 Sekunde den Status abrufen
  </script>
</head>
<body>
  <h1>Haussteuerung</h1>
  <div id="wohnzimmer" class="device off">Wohnzimmer Licht: Aus</div>
  <div id="schlafzimmer" class="device off">Schlafzimmer Licht: Aus</div>
  <div id="kueche" class="device off">Küchen Licht: Aus</div>
  <div id="haustuer" class="device closed">Haustür: Geschlossen</div>
</body>
</html>


systemd-Unit für den Steuerungsserver erstellen

Erstelle die Datei /etc/systemd/system/control-switch.service mit folgendem Inhalt:

[Unit]
Description=Home Control Switch Server

[Service]
Type=simple
WorkingDirectory=/usr/local/control-switch
ExecStart=/usr/bin/node server.js
ExecStartPost=/bin/echo "Schalt-Server gestartet"

[Install]
WantedBy=multi-user.target

Steuerungsserver starten und beim Booten aktivieren

  • systemctl start control-switch.service
  • systemctl enable control-switch.service

Steuerung der Geräte über HTTP

Nun können die Geräte über den separaten Server gesteuert werden:

- Wohnzimmerlicht einschalten: `http://localhost:3001/toggle/wohnzimmer` - Schlafzimmerlicht einschalten: `http://localhost:3001/toggle/schlafzimmer` - Küchenlicht einschalten: `http://localhost:3001/toggle/kueche` - Haustür öffnen: `http://localhost:3001/toggle/haustuer`

Der Server ist für die Steuerung der Geräte per HTTP zuständig und sendet die entsprechenden MQTT-Nachrichten.