MQTT Visualisierte Steuerung Sensor: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
Die Seite wurde neu angelegt: „=== Voraussetzungen === *Voraussetzungen für Node.js-Projekt ==== Neues Verzeichnis für den Steuerungsserver erstellen ==== *'''mkdir /usr/local/contr…“ |
Keine Bearbeitungszusammenfassung |
||
| (8 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
=== Voraussetzungen === | === Voraussetzungen === | ||
*[[ | ==== Installation von Node.js und npm ==== | ||
==== Entferne, falls vorhanden, die alte Node.js-Version ==== | |||
*sudo apt update && sudo apt upgrade | |||
*sudo apt install curl | |||
*sudo apt remove nodejs | |||
==== Füge das Repository für die neueste LTS-Version von Node.js hinzu ==== | |||
*curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - | |||
==== Installiere Node.js (Version 20.x) und npm ==== | |||
*sudo apt install -y nodejs | |||
==== Überprüfe die Installation ==== | |||
*node -v | |||
*npm -v | |||
[[KATEGORIE:Node.js]] | |||
*apt install mosquitto-clients | |||
==== Neues Verzeichnis für den Steuerungsserver erstellen ==== | ==== Neues Verzeichnis für den Steuerungsserver erstellen ==== | ||
* | *mkdir /usr/local/control-switch | ||
* | *cd /usr/local/control-switch | ||
==== Initialisiere das Node.js-Projekt ==== | ==== Initialisiere das Node.js-Projekt ==== | ||
* | *npm init -y | ||
==== Installiere die benötigten Pakete ==== | ==== Installiere die benötigten Pakete ==== | ||
* | *npm install mqtt express | ||
==== Konfiguration des Steuerungsservers ==== | ==== Konfiguration des Steuerungsservers ==== | ||
| Zeile 17: | Zeile 34: | ||
<pre> | <pre> | ||
const mqtt = require('mqtt'); | const mqtt = require('mqtt'); | ||
const express = require('express'); | const express = require('express'); | ||
const path = require('path'); | const path = require('path'); | ||
const app = express(); | const app = express(); | ||
const port = 3000; | const port = 3000; | ||
const fs = require('fs'); | |||
let status = { | let status = { | ||
livingRoom: 'off', | |||
bedroom: 'off', | |||
kitchen: 'off', | |||
frontDoor: 'closed' | |||
}; | }; | ||
// MQTT-Verbindung herstellen | // MQTT-Verbindung herstellen | ||
const options = { | const options = { | ||
// username: 'xinux', | |||
// password: '123Start$', | |||
// port: 8883, | |||
// protocol: 'mqtts', | |||
// ca: fs.readFileSync('./ca.crt'), | |||
port: 1883, | port: 1883, | ||
host: 'mqtt.dkbi.int' | host: 'mqtt.dkbi.int' | ||
}; | }; | ||
| Zeile 43: | Zeile 60: | ||
client.on('connect', () => { | client.on('connect', () => { | ||
console.log(' | console.log('Connected to the broker'); | ||
client.subscribe('home/+/status', (err) => { | client.subscribe('home/+/status', (err) => { | ||
if (!err) { | if (!err) { | ||
console.log(' | console.log('Subscribed to all topics'); | ||
} | } | ||
}); | }); | ||
| Zeile 54: | Zeile 71: | ||
const room = topic.split('/')[1]; | const room = topic.split('/')[1]; | ||
status[room] = message.toString(); | status[room] = message.toString(); | ||
console.log(`Status | console.log(`Status of ${room}: ${status[room]}`); | ||
}); | }); | ||
// API | // API route to get the status of the lights and front door | ||
app.get('/status', (req, res) => { | app.get('/status', (req, res) => { | ||
res.send(status); | res.send(status); | ||
}); | }); | ||
// | // Serve static directory for the web interface | ||
app.use(express.static(path.join(__dirname))); | app.use(express.static(path.join(__dirname))); | ||
// | // Start the web server | ||
app.listen(port, () => { | app.listen(port, () => { | ||
console.log(` | console.log(`Control Center is running at http://0.0.0.0:${port}`); | ||
}); | }); | ||
</pre> | </pre> | ||
| Zeile 74: | Zeile 92: | ||
==== Die HTML Datei index.html==== | ==== Die HTML Datei index.html==== | ||
<pre> | <pre> | ||
<!DOCTYPE html> | <!DOCTYPE html> | ||
<html lang=" | <html lang="en"> | ||
<head> | <head> | ||
<meta charset="UTF-8"> | <meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title> | <title>Control Center</title> | ||
<style> | <style> | ||
.device { | .device { | ||
| Zeile 89: | Zeile 105: | ||
text-align: center; | text-align: center; | ||
font-size: 1.5em; | font-size: 1.5em; | ||
cursor: pointer; | |||
} | } | ||
.on { | .on { | ||
background-color: | background-color: yellow; | ||
color: | color: black; | ||
} | } | ||
.off { | .off { | ||
background-color: | background-color: gray; | ||
color: white; | color: white; | ||
} | } | ||
.open { | .open { | ||
background-color: | background-color: red; | ||
color: white; | color: white; | ||
} | } | ||
| Zeile 108: | Zeile 125: | ||
</style> | </style> | ||
<script> | <script> | ||
// Fetch and display the status of devices | |||
function fetchStatus() { | function fetchStatus() { | ||
fetch('/status') | fetch('/status') | ||
.then(response => response.json()) | .then(response => response.json()) | ||
.then(data => { | .then(data => { | ||
document.getElementById(' | // Update the class and text for each device | ||
document.getElementById(' | document.getElementById('livingRoom').className = 'device ' + (data.livingRoom === 'on' ? 'on' : 'off'); | ||
document.getElementById(' | document.getElementById('livingRoom').textContent = 'Living Room Light: ' + (data.livingRoom === 'on' ? 'On' : 'Off'); | ||
document.getElementById(' | |||
document.getElementById('bedroom').className = 'device ' + (data.bedroom === 'on' ? 'on' : 'off'); | |||
document.getElementById('bedroom').textContent = 'Bedroom Light: ' + (data.bedroom === 'on' ? 'On' : 'Off'); | |||
document.getElementById('kitchen').className = 'device ' + (data.kitchen === 'on' ? 'on' : 'off'); | |||
document.getElementById('kitchen').textContent = 'Kitchen Light: ' + (data.kitchen === 'on' ? 'On' : 'Off'); | |||
document.getElementById('frontDoor').className = 'device ' + (data.frontDoor === 'open' ? 'open' : 'closed'); | |||
document.getElementById('frontDoor').textContent = 'Front Door: ' + (data.frontDoor === 'open' ? 'Open' : 'Closed'); | |||
}); | }); | ||
} | } | ||
setInterval(fetchStatus, 1000); | // Toggle a device and update its status | ||
function toggleDevice(device) { | |||
fetch(`/toggle/${device}`, { method: 'POST' }) | |||
.then(fetchStatus); | |||
} | |||
// Fetch status every second | |||
setInterval(fetchStatus, 1000); | |||
</script> | </script> | ||
</head> | </head> | ||
<body> | <body> | ||
<h1> | <h1>Control Center</h1> | ||
<div id=" | <div id="livingRoom" class="device off" onclick="toggleDevice('livingRoom')">Living Room Light: Off</div> | ||
<div id=" | <div id="bedroom" class="device off" onclick="toggleDevice('bedroom')">Bedroom Light: Off</div> | ||
<div id=" | <div id="kitchen" class="device off" onclick="toggleDevice('kitchen')">Kitchen Light: Off</div> | ||
<div id=" | <div id="frontDoor" class="device closed" onclick="toggleDevice('frontDoor')">Front Door: Closed</div> | ||
</body> | </body> | ||
</html> | </html> | ||
| Zeile 152: | Zeile 186: | ||
==== Steuerungsserver starten und beim Booten aktivieren ==== | ==== Steuerungsserver starten und beim Booten aktivieren ==== | ||
* | *systemctl start control-switch.service | ||
* | *systemctl enable control-switch.service | ||
Aktuelle Version vom 20. Juni 2026, 12:24 Uhr
Voraussetzungen
Installation von Node.js und npm
Entferne, falls vorhanden, die alte Node.js-Version
- sudo apt update && sudo apt upgrade
- sudo apt install curl
- sudo apt remove nodejs
Füge das Repository für die neueste LTS-Version von Node.js hinzu
- curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
Installiere Node.js (Version 20.x) und npm
- sudo apt install -y nodejs
Überprüfe die Installation
- node -v
- npm -v
- apt install mosquitto-clients
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 express = require('express');
const path = require('path');
const app = express();
const port = 3000;
const fs = require('fs');
let status = {
livingRoom: 'off',
bedroom: 'off',
kitchen: 'off',
frontDoor: 'closed'
};
// MQTT-Verbindung herstellen
const options = {
// username: 'xinux',
// password: '123Start$',
// port: 8883,
// protocol: 'mqtts',
// ca: fs.readFileSync('./ca.crt'),
port: 1883,
host: 'mqtt.dkbi.int'
};
const client = mqtt.connect(options);
client.on('connect', () => {
console.log('Connected to the broker');
client.subscribe('home/+/status', (err) => {
if (!err) {
console.log('Subscribed to all topics');
}
});
});
client.on('message', (topic, message) => {
const room = topic.split('/')[1];
status[room] = message.toString();
console.log(`Status of ${room}: ${status[room]}`);
});
// API route to get the status of the lights and front door
app.get('/status', (req, res) => {
res.send(status);
});
// Serve static directory for the web interface
app.use(express.static(path.join(__dirname)));
// Start the web server
app.listen(port, () => {
console.log(`Control Center is running at http://0.0.0.0:${port}`);
});
Die HTML Datei index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Control Center</title>
<style>
.device {
margin: 20px;
padding: 10px;
border-radius: 10px;
text-align: center;
font-size: 1.5em;
cursor: pointer;
}
.on {
background-color: yellow;
color: black;
}
.off {
background-color: gray;
color: white;
}
.open {
background-color: red;
color: white;
}
.closed {
background-color: gray;
color: white;
}
</style>
<script>
// Fetch and display the status of devices
function fetchStatus() {
fetch('/status')
.then(response => response.json())
.then(data => {
// Update the class and text for each device
document.getElementById('livingRoom').className = 'device ' + (data.livingRoom === 'on' ? 'on' : 'off');
document.getElementById('livingRoom').textContent = 'Living Room Light: ' + (data.livingRoom === 'on' ? 'On' : 'Off');
document.getElementById('bedroom').className = 'device ' + (data.bedroom === 'on' ? 'on' : 'off');
document.getElementById('bedroom').textContent = 'Bedroom Light: ' + (data.bedroom === 'on' ? 'On' : 'Off');
document.getElementById('kitchen').className = 'device ' + (data.kitchen === 'on' ? 'on' : 'off');
document.getElementById('kitchen').textContent = 'Kitchen Light: ' + (data.kitchen === 'on' ? 'On' : 'Off');
document.getElementById('frontDoor').className = 'device ' + (data.frontDoor === 'open' ? 'open' : 'closed');
document.getElementById('frontDoor').textContent = 'Front Door: ' + (data.frontDoor === 'open' ? 'Open' : 'Closed');
});
}
// Toggle a device and update its status
function toggleDevice(device) {
fetch(`/toggle/${device}`, { method: 'POST' })
.then(fetchStatus);
}
// Fetch status every second
setInterval(fetchStatus, 1000);
</script>
</head>
<body>
<h1>Control Center</h1>
<div id="livingRoom" class="device off" onclick="toggleDevice('livingRoom')">Living Room Light: Off</div>
<div id="bedroom" class="device off" onclick="toggleDevice('bedroom')">Bedroom Light: Off</div>
<div id="kitchen" class="device off" onclick="toggleDevice('kitchen')">Kitchen Light: Off</div>
<div id="frontDoor" class="device closed" onclick="toggleDevice('frontDoor')">Front Door: Closed</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