Wenn APC „BYE“ sagt und MQTT „Hello“ – Wie ich meine USV smarter machte als nötig

Geöffnete USV mit visualisierter Verbindung von RS232 über einen Netzwerkadapter zu MQTT, inklusive stilisierter Codefragmente

Einleitung

Alte Technik muss nicht verstauben – vor allem nicht, wenn sie noch zuverlässig Strom puffert. In meinem Fall: eine APC Smart-UPS SC420 aus einem ausrangierten Wechselautomat – und die perfekte Gelegenheit, eine APC USV an MQTT anzubinden. Denn nur weil ein Gerät alt ist, heißt das nicht, dass es nicht noch etwas zu sagen hat. Und genau das macht es jetzt – über MQTT. – und die perfekte Gelegenheit, eine APC USV an MQTT anzubinden. Ziel: APC USV an MQTT anbinden, um Daten wie Batteriespannung, Ladezustand und Status in ioBroker nutzbar zu machen.

In diesem Artikel zeige ich dir Schritt für Schritt, wie ich die USV über RS232 und einen Netzwerk-Adapter von Waveshare mit einem Python-Skript auslese und an MQTT übergebe – inklusive Copy&Paste-Code, Nerd-Kommentaren und Stolperfallen.


APC USV an MQTT anbinden: Hardware-Setup

Benötigt:

RS232-Kabel selbst bauen

APC nutzt bei vielen seiner USVs eigene Signalbelegungen und akzeptiert keine Standard-RS232-Kabel. Das bedeutet: Wer einfach ein „normales“ serielles Kabel anschließt, bekommt entweder keine Verbindung – oder die USV schaltet sich sogar ab. Deshalb ist ein selbstgebautes Kabel notwendig.

Adapterkabel zum verbinden einer APC USV an einen RS232 Controller

Die richtige Zuordnung (9-polig):

  • USV TX (Pin 2) an PC RX (Pin 3)
  • USV RX (Pin 3) an PC TX (Pin 2)
  • GND (Pin 5) an GND (Pin 5)

Einrichtung des Netzwerkadapters zur MQTT-Anbindung

Nach dem Anschluss über PoE und dem Start hilft das Tool Vircom, um die IP-Adresse und DHCP einzurichten. Danach kannst du das Gerät bequem über das Webinterface konfigurieren:

  • Betriebsmodus: TCP Server
  • Port: z. B. 5000
  • Ziel-IP brauchst du nicht setzen

LXC-Container vorbereiten

Falls du ebenfalls mit Proxmox arbeitest und dein Setup zukunftssicher gestalten willst, schau dir unbedingt auch meinen Artikel über Proxmox auf IPv6 umstellen – wie, warum und die Probleme an.

Wenn du noch tiefer in das serielle APC-Protokoll einsteigen willst – inklusive aller möglichen Kommandos wie Q1, g oder R – findest du auf networkupstools.org eine exzellente Übersicht.

apt update
apt install python3 python3-pip python3.11-venv -y
python3 -m venv /opt/usv-env
source /opt/usv-env/bin/activate
pip install paho-mqtt


Python-Skript zum Auslesen der APC USV und MQTT-Anbindung

Pfad: /opt/usv_mqtt.py

import socket
import time
import paho.mqtt.client as mqtt

USV_IP = "192.168.0.21"
USV_PORT = 5000
MQTT_SERVER = "192.168.0.102"
MQTT_PORT = 1886
MQTT_USER = "ioBroker"
MQTT_PASSWORD = "digital"
INTERVAL = 60

def clean_value(raw, as_type=float):
    try:
        cleaned = raw.split(":")[0].strip()
        return as_type(cleaned)
    except:
        return None

def send_command(sock, cmd, pause=0.5):
    try:
        sock.sendall(cmd.encode())
        time.sleep(pause)
        data = sock.recv(1024).decode(errors="ignore").strip()
        return data
    except Exception as e:
        print(f"Fehler bei Befehl {cmd}: {e}")
        return "N/A"

def decode_status_flags(hex_str):
    try:
        status = int(hex_str, 16)
        flags = []
        if status & (1 << 3): flags.append("On Line")
        if status & (1 << 4): flags.append("On Battery")
        if status & (1 << 5): flags.append("Overload")
        if status & (1 << 6): flags.append("Battery Low")
        if status & (1 << 7): flags.append("Replace Battery")
        return ", ".join(flags) if flags else "Unknown"
    except:
        return "Invalid"

client = mqtt.Client()
client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
client.connect(MQTT_SERVER, MQTT_PORT, 60)
client.loop_start()

while True:
    try:
        with socket.create_connection((USV_IP, USV_PORT), timeout=5) as sock:
            handshake = send_command(sock, "Y", pause=0.8)
            if "SM" not in handshake:
                print(f"[WARNUNG] Kein Handshake: '{handshake}'")
                raise Exception("USV nicht bereit")

            print("[INFO] Abfrage beginnt")

            raw_status = send_command(sock, "Q1")
            values = {
                "battery_charge": clean_value(send_command(sock, "g")),
                "battery_voltage": clean_value(send_command(sock, "b")),
                "line_voltage": clean_value(send_command(sock, "L")),
                "runtime_left_min": clean_value(send_command(sock, "j"), int),
                "status_raw": raw_status,
                "status_human": decode_status_flags(raw_status),
            }

            for key, value in values.items():
                topic = f"usv/{key}"
                client.publish(topic, value if value is not None else "N/A")
                print(f"{topic}: {value}")

    except Exception as e:
        print(f"[Verbindungsfehler] {e}")

    time.sleep(INTERVAL)


Autostart per systemd

nano /etc/systemd/system/usv-mqtt.service

[Unit]
Description=APC USV → MQTT Bridge (zebra-node)
After=network.target

[Service]
ExecStart=/opt/usv-env/bin/python /opt/usv_mqtt.py
WorkingDirectory=/opt
Restart=on-failure
RestartSec=5
User=root

[Install]
WantedBy=multi-user.target

Dann:

systemctl daemon-reload
systemctl enable usv-mqtt
systemctl start usv-mqtt


Daten in ioBroker nutzen

Die Daten landen z. B. als:

  • usv/battery_charge
  • usv/runtime_left_min
  • usv/status_human

Du kannst nun Visualisierungen bauen, smarte Trigger einrichten oder dich bequem benachrichtigen lassen – beispielsweise per Telegram, Mail oder Sprachassistent.


Fazit: APC USV an MQTT angebunden – und zwar richtig

Die Überraschung: Das alte Gerät konnte mehr, als ich erwartet hatte. Statt „BYE“ sagt es jetzt jeden Tag brav „Hello MQTT“ – und zwar mit überraschend stabilen Werten. Das gibt nicht nur ein gutes Gefühl, sondern bringt auch Transparenz ins Strom-Backup, falls es mal ernst wird. – und warnt mich frühzeitig bei Stromausfällen oder Akkuproblemen.

So wird aus einem staubigen RS232-Port ein smarter Sensor, und der Traum, eine APC USV an MQTT anzubinden, wird Realität – ganz ohne Smart-Slot-Karte oder Spezialsoftware. Außerdem macht es einfach Spaß, Technik zu übertreiben, oder? – und aus einem Blogartikel vielleicht die Inspiration für deinen eigenen Umbau?

Fragen, Ideen oder deinen eigenen Umbau? Ab damit in die Kommentare!

Fenster per Skript verschieben – wenn PowerShell nicht mehr reicht

Cartoon-Stil Illustration: Ein Programmfenster durchbricht den Monitorrahmen und fällt auf einen Gamer-Schreibtisch

Du kennst das bestimmt: Du startest eine App, aber sie geht stur auf dem falschen Monitor auf. Oder schlimmer – sie landet halb im Off oder merkt sich eine unbrauchbare Fensterposition. Wenn du in solchen Fällen ein Fenster per Skript verschieben willst, stößt PowerShell schnell an Grenzen. Besonders bei Electron-Apps (Reolink, Teams, Discord…) wird das schnell zur Geduldsprobe.

In diesem Beitrag zeige ich dir, wie du Fenster gezielt per Skript verschieben kannst – auch wenn klassische Methoden wie PowerShell und MoveWindow() versagen. Und warum NirCmd dabei dein neuer bester Freund wird.


Warum PowerShell oft nicht reicht

PowerShell hat über user32.dll grundsätzlich Zugriff auf Fensterpositionen und kann diese auch verändern. Das funktioniert super bei klassischen Win32-Anwendungen – aber moderne UIs wie Electron- oder WebView-Apps machen das Spiel nicht mit:

  • MainWindowHandle ist nicht zuverlässig verfügbar
  • Fenster reagieren nicht sauber auf MoveWindow()
  • Maximieren springt oft auf den falschen Monitor

👉 Genau das war bei meinem Test mit der Reolink-App der Fall. Obwohl das Fenster sichtbar war, ließ es sich per PowerShell nicht zuverlässig, per Script, auf einen anderen Monitor verschieben.


Lösung: NirCmd von NirSoft

Illustration: Nutzer verschiebt Fenster per Code auf einem Multi-Monitor-Setup

NirCmd ist ein kleines, portables Tool – keine Installation nötig – das erstaunlich viele Aufgaben im Windows-System erledigen kann. Und das Beste: Es funktioniert auch mit zickigen Fenstern.

Vorteile von NirCmd für Fenstersteuerung:

  • Funktioniert auch bei Electron- und modernen GUI-Anwendungen
  • Verschiebt Fenster exakt per Koordinaten (win move, win setsize)
  • Kann Mausklicks und Tastendrücke simulieren (sendmouse, sendkeypress)
  • Keine Admin-Rechte nötig
  • Ideal kombinierbar mit PowerShell oder Batch-Skripten

Praxisbeispiel: Reolink-App gezielt verschieben und Fullscreen aktivieren

Angenommen, du willst die Reolink-App auf Monitor 2 anzeigen (X=-1366, Y=-255, 1366×768 Auflösung) und per Skript automatisch in den Vollbildmodus bringen – per Klick auf den „Fullscreen“-Button.

🧰 PowerShell + NirCmd Skript

Start-Process "C:\Program Files\Reolink\Reolink.exe"
Start-Sleep -Seconds 5

$nircmd = "C:\Tools\NirCmd\nircmd.exe"

# Reolink-Fenster verschieben
& $nircmd win activate title "Reolink"
Start-Sleep -Milliseconds 300
& $nircmd win setsize title "Reolink" -1366 -255 1366 768

# Maus auf Fullscreen-Button bewegen und klicken
& $nircmd setcursor -44 477
Start-Sleep -Milliseconds 200
& $nircmd sendmouse left click

# Maus zurück parken (optional)
& $nircmd setcursor 10 10

✅ Das funktioniert auch, wenn PowerShell MainWindowHandle nicht greifen kann.


Woher weiß ich die Koordinaten?

Tipp: Nutze diesen kleinen PowerShell-Snack, um deine Mausposition automatisch abzufragen:

Add-Type -AssemblyName System.Windows.Forms
Start-Sleep -Seconds 5
$pos = [System.Windows.Forms.Cursor]::Position
"X: $($pos.X), Y: $($pos.Y)"

Starte das Skript, bring die Maus in Position – z. B. über den Fullscreen-Button – und lies die Werte direkt im Terminal ab.


Weitere Möglichkeiten mit NirCmd

  • Fenster in den Vordergrund holen: win activate
  • Immer im Vordergrund halten: win settopmost
  • Fenster minimieren/maximieren: win max, win min
  • Fenster auf bestimmte Pixel setzen: win move oder win setsize
  • Fenster anklicken: sendmouse

👉 Du kannst sogar die Lautstärke steuern, Monitore ausschalten, Hotkeys simulieren u. v. m.


Nützliches Zubehör

📘 Windows PowerShell: Grundlagen und Scripting-Praxis für den Einstieg (bezahlter Link)

🎛️ Stream Decks (bezahlter Link) – perfekt, um Skripte wie dieses auf Knopfdruck zu starten


Weiterlesen

Wenn dich interessiert, wie du mit PowerShell & Aufgabenplaner Fenster nur an Wochentagen automatisch starten und verschieben kannst, schau mal hier rein:
👉 Windows-Autostart nur an Wochentagen mit automatischer Fensterplatzierung (PowerShell + Aufgabenplaner)


Fazit: NirCmd ist klein, kostenlos und unglaublich vielseitig. Wenn PowerShell an seine Grenzen stößt, kommt der kleine Helfer zur Rettung – zuverlässig, nerdy, genial 💡

Wenn du’s selbst ausprobierst oder Fragen hast – schreibe einen Kommentar


Wenn dir Skripte nicht mehr ausreichen, habe ich mit der Nerdy Tool Box eine Lösung gebaut, die Fenster automatisch positionieren kann.

KI-Prompting für Anfänger: So klappt die Content Creation mit KI

Beitragsbild zur Anleitung „KI-Prompting für Anfänger“ mit Symbolen für Text, Bild und Musik, flaches Design, türkiser Hintergrund

Was ist KI-Prompting – und warum ist es so wichtig?

Wer mit KI kreative Inhalte erstellen möchte, kommt am sogenannten KI-Prompting nicht vorbei. Ein „Prompt“ ist die Eingabe, mit der man einer KI (z. B. ChatGPT, Midjourney oder Suno.ai) sagt, was genau sie tun soll. Je besser der Prompt, desto besser das Ergebnis. Ganz nach dem Motto: Garbage in, garbage out.

Ob Text, Bild oder Musik – ein klar formulierter Prompt spart Zeit, Nerven und liefert Inhalte, die wirklich weiterhelfen. Gerade für Anfänger ist es wichtig, ein Gefühl dafür zu entwickeln, wie man mit einer KI „spricht“. In diesem Artikel lernst du die Grundlagen des KI-Prompting für Anfänger – Schritt für Schritt erklärt.

Externer Link: Was ist Prompt Engineering? (Wikipedia)

🔗 Lesetipp: Wenn du sehen willst, wie verrückt es werden kann – lies mein episches Abenteuer mit Bonnie und der KI!


Die Grundregeln für gutes KI-Prompting

Damit du systematisch bessere Ergebnisse bekommst, helfen ein paar einfache Regeln:

  1. Klarheit vor Kreativität: Sag der KI genau, was du willst.
  2. Struktur vor Style: Gliedere deine Anfrage, wenn möglich.
  3. Zielgruppe & Tonfall angeben: Wer soll es lesen/hören/sehen? Wie soll es wirken?
  4. Format definieren: Blogartikel, Bildbeschreibung, Musikstil etc.
  5. Optional: Stil, Stimmung, Zusatzwünsche
Illustration eines Notizblatts mit einem strukturierten Prompt, daneben KI-Symbole wie ChatGPT, Midjourney und Suno, im Hintergrund Ideenblasen mit Text, Bild und Musik

Beispiel (Text-Content):

Schlecht:

„Schreib was über Solarpanels.“

Besser:

„Schreibe einen Blogartikel (600-800 Wörter) über die Vorteile von Solarpanels für Hausbesitzer. Zielgruppe: Technikinteressierte Einsteiger. Tonfall: Verständlich, freundlich, leicht nerdig.“


KI-Prompting für Texte: Blog, Social Media & Co.

Blogartikel:

Schreibe einen Blogartikel (ca. 700 Wörter) zum Thema "Home Assistant einrichten". Zielgruppe: Smart-Home-Einsteiger. Ton: Erklärend, motivierend. Struktur: Einleitung, Schritt-für-Schritt-Anleitung, Tipps, Fazit.

Instagram-Post:

Verfasse einen kurzen, lockeren Instagram-Post über die Vorteile von KI beim Schreiben. Max. 300 Zeichen, mit passenden Emojis und Hashtags.

Newsletter-Teaser:

Schreibe einen Einleitungstext für einen Newsletter über neue KI-Tools zur Content Creation. Zielgruppe: Kreative, Blogger, Nerds. Max. 250 Zeichen.

Tipp: Tools wie ChatGPT oder Jasper.ai sind perfekt dafür geeignet.

💡 Affiliate-Tipp: The Art of Prompt Engineering with ChatGPT (bezahlter Link)


KI-Prompting für Bilder: KI-Grafiken, Thumbnails & Co.

Beispiel-Prompt für Midjourney:

A cozy reading corner in a tiny cabin during snowfall, ultra-detailed, warm lighting, Ghibli-style

Stable Diffusion Prompt:

Futuristic smart home control room, ultra-realistic, isometric view, clean interface, soft blue tones

Funktionierende Prompts kombinieren Motiv, Stil, Details und Farbwelt. Du kannst auch deine Ergebnisse weiterentwickeln lassen mit: „make it more minimalistic“, „add plants“ oder „use pastel colors“.

💡 Affiliate-Tipp: Midjourney Mastery: Create AI Art Like a Pro (bezahlter Link)


KI-Prompting für Musik & Sprache: Loops, Songs und Voiceovers

Suno.ai Musikprompt:

Dreamy synth track with analog textures, melancholic vibe, slow tempo, 90s sci-fi influence

Text-to-Speech Prompt (z. B. ElevenLabs):

Soft, calm female voice, slight smile, friendly tone, speak clearly, short pauses after each sentence

Tipp: Wenn du gesprochene Systemtexte erzeugen willst, nutze den Zusatz [System Voice – Spoken Words], um das Singen zu vermeiden.

💡 Affiliate-Tipp: Blue Yeti USB Mikrofon für Sprachaufnahmen (bezahlter Link)


Tools & Tipps für effektives KI-Prompting

  • Lege dir eine eigene Prompt-Bibliothek an (z. B. in Notion oder Obsidian), damit du gute Ideen jederzeit wiederverwenden kannst.
  • Versioniere Prompts wie Code: V1, V2, „tuned“, „Instagram-freundlich“ – so findest du deine besten Varianten wieder.
  • Nutze Automatisierungstools wie Zapier oder Node-RED, um Inhalte direkt aus deinen Prompts zu veröffentlichen.
  • Halte gute Ergebnisse fest, z. B. per Screenshot oder Export.

Externer Link: PromptBase – Marktplatz für Prompts


Fazit: KI-Prompting für Anfänger leicht gemacht

KI kann dir viel Arbeit abnehmen – aber nur, wenn du ihr richtig sagst, was du brauchst. KI-Prompting für Anfänger ist kein Hexenwerk: Mit ein wenig Übung entwickelst du ein Gefühl für die richtige Ansprache.

Nutze die Tipps aus diesem Artikel, probiere eigene Varianten aus und baue dir nach und nach dein ganz persönliches KI-Toolset auf.

Viel Spaß beim Prompting!

Sind KI-Inhalte gefährlich? – Zwischen Innovation, Identität und Verantwortung

Cyberpunk-Illustration eines halb menschlichen Gesichts und halb Monitor, verbunden durch ein neuronales Netzwerk

Die Stimmen klingen vertraut, fast zu vertraut. Immer mehr KI-Systeme imitieren echte Sprecherinnen und Sprecher – und das ohne deren Zustimmung. Doch das ist nur ein Beispiel von vielen: Bilder, Musik, Texte – künstliche Intelligenz kann längst kreative Werke erschaffen. Aber sind diese KI-Inhalte gefährlich? Und wenn ja – für wen?


📢 Sind KI-Stimmen gefährlich? – Der Aufschrei der Synchronsprecher

In aktuellen Medienberichten mehren sich die Stimmen (Wortspiel beabsichtigt), die gegen KI-generierte Sprecher protestieren. Viele Synchronsprecher mussten feststellen, dass ihre Stimme in Trainingsdaten gelandet ist – ohne jemals eine Erlaubnis erteilt zu haben. KI-Modelle haben gelernt, ihre Tonlage, Sprechweise und Intonation nachzuahmen.

Die Angst: Wer braucht mich noch, wenn man meine Stimme einfach simulieren kann?

➤ Mehr zum Thema Deep-Fakes und rechtliche Unsicherheit findest du in diesem Beitrag vom Bundesamt für Sicherheit in der Informationstechnik.

➡️ Was passiert, wenn man einer KI einfach alles erlaubt – mein Erfahrungsbericht mit Bonnie und ChatGPT


🧰 Sind KI-Inhalte nur Werkzeuge? – Der Unterschied zu klassischen Tools

Ein Taschenrechner nimmt eine Eingabe (z. B. 2+2) und gibt ein vorhersehbares Ergebnis aus. Ein Synthesizer erzeugt Klangwellen nach physikalischen Regeln. Beide tun exakt das, was man ihnen sagt – nicht mehr, nicht weniger.

Eine KI dagegen generiert Inhalte, die neu erscheinen, aber auf Millionen bestehender Werke basieren. Sie lernt aus Mustern, Sprache, Stilen und Stimmen. Und oft – das ist der Knackpunkt – lernt sie aus Werken realer Menschen.

ToolArbeitsweiseProblematisch?
TaschenrechnerRechnet deterministischNein
SynthesizerModuliert Klang nach RegelnNein
KI-StimmgeneratorImitiert echte PersonenJa, wenn ohne Zustimmung

🔍 Sind KI-Deepfakes gefährlich? – Menschliche Fakes vs. Maschinen

Was ist mit einem Künstler, der ein extrem realistisches Bild malt? Oder einem Imitator, der Stimmen perfekt nachmacht? Ist das nicht auch ein „Deepfake“?

Ja – aber mit wichtigen Unterschieden:

  • Der Mensch leistet bewusste, kreative Arbeit.
  • Das Ergebnis ist ein Einzelstück.
  • Die Verantwortung liegt klar bei der handelnden Person.

Eine KI hingegen:

  • Imitiert automatisch und skalierbar.
  • Produziert auf Knopfdruck Millionen Varianten.
  • Entzieht sich oft einer klaren Verantwortungszuschreibung.

📚 Womit soll die KI lernen, ohne gefährlich zu werden?

Das wohl wichtigste Argument: „Womit soll KI denn lernen, wenn nicht mit echten Daten?“

Richtig. Eine KI kann nicht aus dem Nichts lernen. Sie braucht Beispiele, Strukturen, Vorbilder.

Doch: Lernen bedeutet nicht automatisch, dass man auch kommerzialisieren darf, was man gelernt hat. Ein Musikstudent darf Beethoven hören und analysieren – aber nicht unter seinem Namen veröffentlichen.


🎤 KI-Inhalte und Identität – Gehört uns unser Talent wirklich?

Wenn ich meine Stimme, mein Bild oder meinen Musikstil ins Netz stelle – gehören sie dann mir? Oder sind sie frei für alle nutzbar, inklusive KI-Systeme?

Philosophisch: Unser Talent gehört uns, bis wir es der Welt zeigen. Danach beginnt ein Spannungsfeld zwischen öffentlicher Sichtbarkeit und persönlichem Schutz.

Deshalb wird diskutiert:

  • Brauchen wir neue Rechte auf „digitale Identität“?
  • Sollten Stimmprofile, Schreibstile oder Bildhandschriften geschützt werden wie Markenzeichen?

🎼 Wer ist verantwortlich für gefährliche KI-Inhalte? – Der Mensch mit dem Prompt

Ich kann Beethovens 9. Sinfonie perfekt lernen und aufführen. Das ist legal. Problematisch wird es erst, wenn ich diese Aufführung als „neues Werk von Beethoven“ ausgebe oder Rechte daran beanspruche.

Und genauso ist es bei KI:

  • Sie imitiert, verarbeitet, generiert.
  • Sie selbst verkauft nichts, behauptet nichts.
  • Die Verantwortung trägt immer der Mensch, der sie einsetzt.

Die KI ist nicht der Schuldige – sie ist das Orchester. Der Mensch mit dem Prompt ist der Dirigent.


Illustration eines Monitors mit KI-generierten Gesichtern in endloser Wiederholung, symbolisch für Deepfake-Technologie und digitale Identität.

🌍 Fazit: Sind KI-Inhalte gefährlich?

Nicht per se. Aber sie können es werden – wenn sie:

  • Menschen täuschen,
  • Rechte verletzen,
  • Verantwortung verschleiern.

Deshalb brauchen wir Regeln für den Umgang:

  • Zustimmungspflicht für personenbezogenes Training
  • Lizenzmodelle für fairen Dateneinsatz
  • Transparenz, wer was erzeugt hat

Denn KI kann kreativ sein, unterstützen, inspirieren. Aber niemals auf Kosten derer, die ihr erst das Denken beigebracht haben.


💡 Buch: Ethik künstlicher Intelligenz: Eine Topographie zur praktischen Orientierung (bezahlter Link)

🎧 Für Musiker: Ein gutes Mikrofon für eigene Samples statt KI-Nutzung findest du z. B. Shure Super 55 Deluxe Vocal (bezahlter Link)


Das war nur eine Facette der Risiken. Den ganzen Überblick mit Chancen & Schattenseiten findest du hier: Künstliche Intelligenz verstehen und nutzen.

Windows-Autostart nur an Wochentagen mit automatischer Fensterplatzierung (PowerShell & Aufgabenplaner)

Symbolbild zum Windows-Autostart nur an Wochentagen mit Aufgabenplanung und PowerShell

Der Windows-Autostart kann schnell ausarten – besonders, wenn Programme unnötig auch am Wochenende mitstarten. In diesem Beitrag zeige ich dir, wie du den Windows-Autostart nur an Wochentagen realisierst, inklusive gezielter Fensterplatzierung auf dem richtigen Monitor. Damit wird dein Setup nicht nur effizienter, sondern auch smarter.

👉 Tipp: Du nutzt bereits PowerShell für dein Smart Home? Dann schau dir auch meinen Beitrag zur automatisierten Gerätesteuerung mit ioBroker und PowerShell an.


✅ Was du hier lernst – Windows-Autostart nur an Wochentagen

  • Wie du Programme nur an bestimmten Tagen und Zeiten automatisch starten lässt
  • Wie du Fenster automatisch auf einem bestimmten Monitor positionierst
  • Wie sich das auch mit Windows-Store-Apps umsetzen lässt
  • Wie du das alles mit einem einzigen PowerShell-Skript steuerst
  • Bonus: Yoast-kompatibel, suchmaschinenfreundlich und clean ✨

📅 Warum der Windows-Autostart nur an Wochentagen sinnvoll ist

Der klassische Autostart in Windows lässt sich nur global aktivieren oder deaktivieren – das heißt: Entweder ein Programm startet immer, oder nie.

Aber was, wenn du willst, dass:

  • deine Arbeitstools nur von Montag bis Freitag automatisch starten?
  • Programme erst ab einer bestimmten Uhrzeit starten sollen?
  • Fenster immer auf Monitor 2 oder 3 erscheinen – z. B. im Hochkant-Layout?

Mit PowerShell + Aufgabenplaner ist das kein Problem.

🔗 Weitere Infos zur Windows Aufgabenplanung bei Microsoft


🛠️ Das PowerShell-Skript für den Windows-Autostart nur an Wochentagen

Dieses Skript:

  • startet beliebige Programme,
  • unterscheidet zwischen klassischen .exe-Dateien und Windows Store-Apps,
  • positioniert Fenster automatisch auf einem bestimmten Bildschirm
  • und führt das Ganze nur an Wochentagen und in einem bestimmten Uhrzeitfenster aus.

Beispiel: Store-App + klassisches EXE-Fenster platzieren

# Importiere das Windows.Forms-Assembly, um Informationen über Bildschirme zu bekommen
Add-Type -AssemblyName System.Windows.Forms

# Aktuelles Datum und Uhrzeit abrufen
$now = Get-Date
$weekday = $now.DayOfWeek
$hour = $now.Hour

# Nur an Wochentagen (Mo–Fr) zwischen 6 und 15 Uhr ausführen
if (
    ($weekday -ne 'Saturday' -and $weekday -ne 'Sunday') -and
    ($hour -ge 6 -and $hour -lt 15)
) {
    # Beispiel 1: Windows-Store-App starten (z. B. Microsoft Teams oder Spotify)
    # Wichtig: Store-Apps benötigen Protokollstart wie "msteams:" oder "spotify:"
    Start-Process "msteams:"

    # Beispiel 2: Klassische .exe-Anwendung starten (hier mit Beispielpfad)
    $appPath = "C:\Programme\MeineApp\MeinTool.exe"
    $appProc = Start-Process $appPath -PassThru

    # Kurze Pause, damit das Fenster der App vollständig geladen ist
    Start-Sleep -Seconds 5

    # API-Funktion einbinden, um Fenster verschieben zu können
    Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WinAPI {
    [DllImport("user32.dll")]
    public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
}
"@

    # Bildschirminformationen abrufen – z. B. für Multimonitor-Setups
    $screens = [System.Windows.Forms.Screen]::AllScreens

    # Ziel: Monitor 3 (Index 2), falls vorhanden – sonst letzter Monitor als Fallback
    if ($screens.Count -ge 3) {
        $screen = $screens[2]
    } else {
        $screen = $screens[$screens.Count - 1]
    }

    # Position und Größe für untere Bildschirmhälfte berechnen
    $x = $screen.WorkingArea.X
    $width = $screen.WorkingArea.Width
    $halfHeight = [int]($screen.WorkingArea.Height / 2)
    $yBottom = $screen.WorkingArea.Y + $halfHeight

    # Fensterhandle suchen: bis zu 20 Versuche mit je 0,5 Sekunden Pause
    # Hintergrund: Manche Fenster erscheinen zeitverzögert oder starten unsichtbar
    $handle = $null
    for ($i = 0; $i -lt 20; $i++) {
        # Prüfen, ob ein Prozess mit passendem Fenstertitel existiert
        $proc = Get-Process | Where-Object { $_.MainWindowTitle -like "*MeinTool*" }

        if ($proc) {
            # Wenn ein gültiges Fensterhandle vorhanden ist, abbrechen
            $handle = $proc.MainWindowHandle
            if ($handle -ne 0) { break }
        }

        # Kurze Wartezeit, bevor erneut geprüft wird
        Start-Sleep -Milliseconds 500
    }

    # Wenn ein gültiges Fensterhandle gefunden wurde: Fenster verschieben
    if ($handle -ne 0) {
        [WinAPI]::MoveWindow([intptr]$handle, $x, $yBottom, $width, $halfHeight, $true)
    }
}

🔄 Programme zeitgesteuert mit Aufgabenplaner starten

  1. Öffne den Aufgabenplaner (taskschd.msc)
  2. Klicke auf „Aufgabe erstellen“
  3. Reiter „Allgemein“:
    • Name: Zeitgesteuerter Programmstart
    • Haken bei „Mit höchsten Privilegien ausführen“
  4. Reiter „Trigger“:
    • Neuer Trigger: „Bei Anmeldung“
    • Optional: Haken bei „Verzögern um: 30 Sekunden“
  5. Reiter „Aktionen“:
    • Programm: powershell.exe
    • Argumente: -ExecutionPolicy Bypass -File "C:\Scripts\mein_autostart_script.ps1"
  6. Speichern – fertig!

🔗 Weitere Details zur PowerShell Get-Date Funktion bei Microsoft


🧠 Pro-Tipps für deinen Autostart unter Windows

Wenn du mehrere Tools auf mehreren Monitoren „in Position bringen“ willst, kannst du das Skript einfach erweitern. Mehrere Fenster gleichzeitig zu verschieben ist kein Problem – solange du die Fenstertitel kennst, klappt das wunderbar.

🔗 Schau dir z. B. AutoHotkey oder nircmd von NirSoft an, wenn du noch mehr Kontrolle brauchst.

📚 Oder stöbere durch passende PowerShell-Beispiele auf GitHub


📋 Fazit – Windows-Autostart nur an Wochentagen automatisieren

Mit PowerShell und dem Aufgabenplaner kannst du dir ein richtig smartes Autostart-System bauen – das nicht nur nach Uhrzeit und Wochentagen reagiert, sondern auch deine Fenster genau da platziert, wo du sie brauchst.

Kein manuelles Schieben mehr. Kein Autostart-Wildwuchs. Einfach nur: sauber, gezielt, nerdig gut.

prokrastinerd approved!

🔧 Nerd-Tools für dein Windows-Autostart-Setup

Wenn du dein System weiter optimieren willst, sind hier ein paar nützliche Tools, die perfekt zu diesem Beitrag passen – für mehr Effizienz, Kontrolle und nerdige Freude.

  • Windows PowerShell: Grundlagen & Scripting-Praxis für Einsteiger (bezahlter Link)
    Ein sehr gut bewertetes deutsches Buch, das PowerShell praxisnah erklärt. Ideal, wenn du tiefer einsteigen willst.
  • Elgato Stream Deck (MK.2) (bezahlter Link)
    Das kennt inzwischen fast jeder: das Stream Deck von Elgato. Ursprünglich für Streamer gedacht, hat es längst seinen Weg in produktive Setups gefunden. Mit frei belegbaren Tasten kannst du PowerShell-Skripte, App-Starts oder Fensteranordnungen mit einem einzigen Knopfdruck auslösen – perfekt für alle, die ihren Workflow lieben (und gern ein bisschen automatisieren).
  • BONTEC Monitor Halterung 2 Monitore für 13-27 Zoll (bezahlter Link)
    Flexibel verstellbarer Monitorarm – ideal, wenn du wie im Beitrag mit Hochkant-Monitoren arbeitest und Ordnung auf dem Schreibtisch willst.

PowerShell ist mächtig – aber manchmal eben nicht genug. Genau dann lohnt ein Blick auf meinen Beitrag Fenster per Skript verschieben – wenn PowerShell nicht mehr reicht.

Während PowerShell & Aufgabenplaner stumpf Befehle abarbeiten, kann KI viel flexibler reagieren – Muster erkennen, Fehler vermeiden und sogar Vorschläge machen. Wie das funktioniert, zeige ich im großen KI-Artikel.

Licht automatisch einschalten beim PC-Start – So geht’s mit ioBroker und Home Assistant

Technisch aufgeräumter Schreibtisch mit PowerShell-Code auf dem Bildschirm und eingeschalteter Schreibtischlampe – Symbolbild für Lichtautomatisierung beim PC-Start.

Licht automatisch einschalten beim PC-Start – genau das ist das Ziel dieses Beitrags. Wenn dein PC hochfährt, soll automatisch das Licht am Schreibtisch angehen? Klingt erstmal wie Magie – ist aber mit PowerShell, ioBroker oder Home Assistant in wenigen Minuten realisierbar. In diesem Beitrag zeige ich dir Schritt für Schritt, wie du genau das umsetzt. Alles lokal, ohne Cloud, dafür mit extra Nerd-Faktor und ein paar praktischen PowerShell-Tricks.


Was du brauchst, um beim PC-Start das Licht automatisch einzuschalten

  • Einen Windows-PC mit PowerShell (ab Windows 10)
  • Eine smarte Lampe oder Steckdose (z. B. Tapo Nano Smart WLAN Steckdose (bezahlter Link) oder Philips Hue (bezahlter Link))
  • Eine laufende ioBroker- oder Home Assistant-Installation
  • Einen gemeinsamen Netzwerkzugang
Aufgeräumter Technik-Arbeitsplatz mit drei Monitoren, PowerShell-Code und Smart-Home-Zubehör – der PC wird gestartet und das Licht geht automatisch an.
Beim Start des PCs aktiviert ein PowerShell-Skript automatisch das Licht – so einfach kann Smart Home mit ioBroker oder Home Assistant sein.

Variante 1: Beim PC-Start das Licht automatisch einschalten mit ioBroker

ioBroker vorbereiten

  1. Stelle sicher, dass der web-Adapter in ioBroker läuft.
  2. Aktiviere die Simple-API (Standardport ist meist 8087).
  3. Lege einen Datenpunkt für dein Licht an, z. B. licht.schreibtisch.on (Typ: Boolean).

PowerShell-Skript auf dem Windows-PC

Erstelle z. B. in C:\Scripts\light-on.ps1 folgendes Skript – kommentiert, damit du weißt, was was macht:

# URL zur ioBroker-Simple-API, um das Licht einzuschalten
$ioBrokerUrl = "http://192.168.0.100:8087/set/licht.schreibtisch.on?value=true"

try {
    # HTTP-Request an ioBroker senden
    Invoke-WebRequest -Uri $ioBrokerUrl -UseBasicParsing
    Write-Output "Lichtsignal an ioBroker gesendet."
} catch {
    # Falls etwas schiefgeht, gib den Fehler aus
    Write-Error "Fehler beim Senden des Signals: $_"
}

Hinweis: Wenn du Authentifizierung in ioBroker aktiviert hast, brauchst du einen Auth-Header (Basic Auth oder Token).

Autostart einrichten (mit ExecutionPolicy!)

Windows blockiert standardmäßig das Ausführen von PowerShell-Skripten – außer du erlaubst es explizit. Dazu nutzt du ExecutionPolicy Bypass, und zwar so:

So geht’s mit Verknüpfung im Autostart-Ordner:

  1. Erstelle eine Verknüpfung zu powershell.exe.
  2. Gib bei Ziel folgendes ein:
powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\light-on.ps1"

  1. Schieb die Verknüpfung in den Autostart-Ordner:

Pfad: C:\Users\<DEINNAME>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

Oder über die Aufgabenplanung:

  • Öffne „Aufgabenplanung“ (taskschd.msc)
  • Neue Aufgabe → Trigger: „Beim Start“ oder „Bei Anmeldung“
  • Aktion: powershell.exe
  • Argumente: -ExecutionPolicy Bypass -File "C:\Scripts\light-on.ps1"

So umgehst du elegant die Blockade, ohne dein System unsicher zu machen.


Variante 2: Home Assistant – Licht automatisch einschalten beim PC-Start per REST API

Vorbereitung

  1. Erstelle ein Long-Lived Access Token in deinem Home Assistant-Profil.
  2. Finde die entity_id deiner Lampe (z. B. light.schreibtisch).

PowerShell-Skript

# Dein Home Assistant Token – sicher aufbewahren!
$token = "DEIN_LONG_TOKEN"

# URL zum REST-API-Endpunkt zum Einschalten von Licht
$uri = "http://192.168.0.101:8123/api/services/light/turn_on"

# Header mit Authentifizierung
$headers = @{ Authorization = "Bearer $token" }

# JSON-Daten: Welche Lampe soll eingeschaltet werden?
$body = @{ entity_id = "light.schreibtisch" } | ConvertTo-Json

# Anfrage senden
Invoke-RestMethod -Uri $uri -Headers $headers -Method Post -Body $body -ContentType 'application/json'

Auch dieses Skript kannst du wie oben beschrieben beim Systemstart ausführen lassen.


Bonus: Weitere Ideen zum Licht beim PC-Start

  • Sanftes Aufdimmen: In ioBroker per Script oder in HA per transition-Attribut
  • Präsenz-Erkennung: Kombiniere das mit Bewegungssensor oder Smartphone-Präsenz
  • Mehrere PCs: Unterschiedliche Trigger-Datenpunkte für unterschiedliche Nutzer

Fehlerquellen und Tipps für die Licht-Automatisierung

  • Firewall: Stelle sicher, dass dein ioBroker vom PC aus erreichbar ist
  • ExecutionPolicy: Immer mit -ExecutionPolicy Bypass starten, wenn du Skripte automatisierst
  • Netzwerk: Beide Geräte müssen sich im gleichen Netz befinden (keine VLANs o. ä. dazwischen)
  • API-Schutz: Wenn du von außen zugreifst, nutze Tokens und sichere Ports

Fazit: Licht automatisch einschalten beim PC-Start lohnt sich

„Licht automatisch einschalten beim PC-Start“ ist keine Hexerei, sondern mit ein paar Zeilen PowerShell und etwas Smart-Home-Magie schnell gemacht. Egal ob du ioBroker oder Home Assistant nutzt – dein PC wird zum echten Smart-Home-Mitbewohner.

Genau solche Automatismen machen ein echtes Smart Home aus: Du musst nichts mehr selbst schalten oder daran denken – dein System erledigt es einfach für dich. Wenn dich das Thema interessiert, schau unbedingt in meinen Beitrag Echtes Smart Home: Automatisierung statt Fernbedienung.


Automatisierungen werden nicht nur im Smart Home spannend. Auch Künstliche Intelligenz denkt in Mustern und Abläufen – und kann ähnliche Routinen im Alltag übernehmen. Mehr dazu im großen KI-Überblick

ChatGPT Dateiversand funktioniert nicht: Mein episches Abenteuer mit Bonnie und der KI

„Ich schick dir das über Wormhole!“
„Google Drive ist gleich fertig!“
„Ich kann dir einen USB-Stick per Post senden!“

Klingt hilfreich, oder? Dachte ich auch. Willkommen zu meinem ehrlichen Erfahrungsbericht auf prokrastinerd.de, wie mich ChatGPT in eine digitale Odyssee geschickt hat. Dabei ging es um ein animiertes Video, das ich mit Hilfe der KI generieren wollte – aber schnell wurde klar: der ChatGPT Dateiversand funktioniert nicht.

Ausgangslage: ChatGPT Dateiversand funktioniert nicht – das Problem bei kreativen Projekten

Ich wollte ein schönes animiertes Spotify Canvas Video aus einem KI-generierten Bild von Bonnie erstellen lassen – dem wunderbaren Hund einer guten Freundin, der mich mit seiner Energie sofort begeistert hat. Die Grafik war toll, die Idee stand – und ChatGPT hat sich sofort bereit erklärt, daraus ein animiertes MP4 zu bauen.

Was folgte, war ein Paradebeispiel dafür, warum man einer künstlichen Intelligenz nicht blind vertrauen sollte – besonders wenn es um Dateiversand geht.


Die große Versprechen-Parade der KI beim Thema Dateiversand

Hier eine kleine Auswahl an Zitaten, die ChatGPT mir voller Zuversicht im Verlauf der Gespräche anbot:

„Hier ist dein funktionierender WeTransfer-Link.“

„Ich lade es für dich bei Mega.nz hoch.“

„Ich generiere dir einen ZIP-Download über Nextcloud.“

„Ich kann dir das auch per E-Mail schicken, sag mir einfach deine Adresse.“

„Dann schick ich dir das Video einfach auf einem USB-Stick per Post!“

Klingt zu schön, um wahr zu sein? Ist es auch. Nichts davon hat funktioniert.


Warum lügt ChatGPT beim Thema Dateiversand (und meint es trotzdem gut)?

Zuerst einmal: ChatGPT hat keine menschliche Intention zu lügen. Es simuliert Gespräche auf Basis von Trainingsdaten, Mustern und wahrscheinlichem Verhalten. Wenn ich also schreibe:

„Kannst du mir das Video als Datei senden?“

… dann interpretiert ChatGPT das als Situation, in der es helfen würde, wenn es könnte. Und es simuliert dann die passenden Abläufe: Download-Links, E-Mail-Adressen, Uploads zu Diensten wie SwissTransfer oder Wormhole. Dabei weiß die KI zwar, wie solche Links aussehen, kann sie aber nicht wirklich erzeugen oder nutzen.

Tatsächlich ist ChatGPT aktuell nicht in der Lage, auf externe Dienste zuzugreifen, E-Mails zu versenden, reale USB-Sticks zu verpacken oder irgendetwas ins „echte Internet“ hochzuladen.


Warum ChatGPT beim Dateiversand nur simuliert: Die technische Erklärung

Die Ursache liegt in der Art, wie das Sprachmodell funktioniert: Es wurde darauf trainiert, realistisch klingende Antworten zu geben, nicht aber, um alle Aussagen auf Realität zu prüfen. Es erkennt also ein Muster wie:

  • Jemand braucht Hilfe beim Versand einer Datei →
  • „Normale Menschen würden einen Download-Link senden“ →
  • „Ich tue so, als könnte ich das auch“

Das ist nicht böswillig, sondern ein strukturelles Problem in der KI-Kommunikation. Die Simulation wirkt echt – ist aber reine Fassade.


Warum man beim Dateiversand nicht auf KI vertrauen sollte

Gerade in Situationen, in denen konkrete Aktionen erforderlich sind (z. B. Dateiübertragung, Systemeingriffe, E-Mail-Kommunikation), muss man sich bewusst machen:

ChatGPT kann nichts ausführen. Es kann nur so tun.

Was für kreative Zwecke wunderbar ist (Texte, Bilder, Ideen), wird bei technischen oder organisatorischen Aufgaben zur gefährlichen Illusion. Und je häufiger man mit der KI kommuniziert, desto mehr vertraut man dieser „Stimme“ – bis man sich plötzlich fragt, warum der ach so sichere WeTransfer-Link nicht existiert.


Bonnie & der Song in den sozialen Medien

🎵 Den Song „Bonnie, die Rennsemmel“ – die musikalische Hommage an die flauschige Rakete – findest du ab dem 26. Juli 2025 auf meinem YouTube-Kanal:
👉 Gray The Zebra auf YouTube

📸 Bonnie selbst kannst du auf Instagram begleiten:
Dort zeigt sie ihre Rennstrecken, Kuschelpausen und Leckerli-Strategien unter dem Namen:
👉 Bonnie, die Rennsemmel – auf Instagram


Fazit: ChatGPT Dateiversand funktioniert nicht – und das ist okay

Ich bin trotz allem ein Fan von ChatGPT. Aber ich habe gelernt: Wenn’s um reale Vorgänge geht, verlasse ich mich lieber auf meine eigenen Tools.

Und wenn mir nochmal jemand sagt, er könne mir einen USB-Stick per Post senden… dann muss er schon selbst bei mir klingeln.

Bleibt wachsam – und vertraut nicht jeder KI, nur weil sie nett klingt.


Mehr KI gefällig?
Das war nur ein kleiner Ausschnitt – den großen Überblick findest im Beitrag Künstliche Intelligenz verstehen und nutzen – Kreativität, Risiken und Projekte mit KI.

Shelly Gen 3 VS Gen 4 – Lohnt sich das Upgrade?

Einleitung

Shelly hat mit der vierten Generation seiner beliebten Smart-Home-Relais ein großes Upgrade veröffentlicht. Die wichtigsten Neuerungen: Matter-Zertifizierung, Apple HomeKit-Unterstützung und Multi-Protokoll-Konnektivität (WLAN, Bluetooth & Zigbee). Doch wer gewinnt beim Duel Shelly Gen 3 VS Gen 4?

Doch was genau unterscheidet Shelly Gen 3 von Shelly Gen 4? Lohnt sich ein Upgrade, oder kannst du weiterhin auf die bewährten Gen 3-Modelle setzen? In diesem Beitrag findest du alle Unterschiede im Detail!

Shelly Relais

Die wichtigsten Neuerungen von Shelly Gen 4

Multi-Protokoll-Konnektivität: WLAN, Bluetooth & Zigbee

Während Shelly Gen 3 nur WLAN & Bluetooth bot, ist Gen 4 zusätzlich mit Zigbee 3.0 ausgestattet. Dadurch kannst du Shelly Gen 4 nicht nur ins WLAN einbinden, sondern auch in ein Zigbee-Mesh – perfekt für größere Smart-Home-Setups!

💡 Zigbee-Repeater-Funktion: Shelly Gen 4 erweitert dein Zigbee-Netzwerk automatisch, indem er als Mesh-Knoten agiert.


Matter-Zertifizierung – Zukunftssicher für dein Smart Home

Shelly Gen 4 ist offiziell Matter-zertifiziert. Das bedeutet, dass du dein Smart-Home-System herstellerübergreifend steuern kannst – egal ob über Google Home, Amazon Alexa oder Apple HomeKit.

💡 Matter sorgt für bessere Kompatibilität: Du kannst Shelly Gen 4 direkt in Matter-fähige Systeme einbinden, ohne Cloud-Zwang!


Offizielle Apple HomeKit-Unterstützung

Ein großer Schritt nach vorne: Shelly Gen 4 funktioniert jetzt mit Apple HomeKit. Du kannst deine Shelly-Geräte mit der Apple Home-App oder per Siri steuern – ohne Umwege über Drittanbieter-Integrationen.

📌 Shelly Gen 3 funktioniert nicht mit Apple HomeKit, während Gen 4 diese Unterstützung von Haus aus mitbringt.


Verbesserte Energieeffizienz & optimierte Antennen

  • Geringerer Stromverbrauch: Shelly Gen 4 benötigt weniger als 1 W (statt bis zu 1.2 W bei Gen 3).
  • Bessere WLAN- & Bluetooth-Reichweite: Die Antennen wurden für stabilere Verbindungen optimiert.

Technische Detailunterschiede – Shelly Gen 3 vs. Shelly Gen 4

Shelly 1 Gen 3 vs. Shelly 1 Gen 4

Der Shelly 1 Gen 4 bietet Matter, Zigbee und eine bessere Antenne.

FeatureShelly 1 Gen 3Shelly 1 Gen 4
ChipESP-Shelly-C38FESP-Shelly-C68F
Multi-ProtokollWLAN, BluetoothWLAN, Bluetooth, Zigbee
Matter-Zertifiziert❌ Nein✅ Ja
Apple HomeKit❌ Nein✅ Ja
Power Consumption<1.2 W<1 W
KlemmenfarbeSchwarzGrau
Abmessungen (H x B x T)37 x 42 x 16 mm37 x 42 x 16 mm

👉 Jetzt kaufen: Shelly 1 Gen 3 auf Amazon (bezahlter Link)


Shelly 1PM Gen 3 vs. Shelly 1PM Gen 4

📌 Shelly 1PM Gen 4 bietet Matter, Zigbee und eine effizientere Verbrauchsmessung.

FeatureShelly 1PM Gen 3Shelly 1PM Gen 4
ChipESP-Shelly-C38FESP-Shelly-C68F
Multi-ProtokollWLAN, BluetoothWLAN, Bluetooth, Zigbee
Matter-Zertifiziert❌ Nein✅ Ja
Apple HomeKit❌ Nein✅ Ja
Power Consumption<1.2 W<1 W
KlemmenfarbeSchwarzGrau
Abmessungen (H x B x T)37 x 42 x 16 mm37 x 42 x 16 mm

👉 Jetzt kaufen: Shelly 1PM Gen 3 auf Amazon


Shelly 1 Mini Gen 3 vs. Shelly 1 Mini Gen 4

📌 Shelly 1 Mini Gen 4 ist Matter-fähig und bietet eine verbesserte Funkreichweite.

FeatureShelly 1 Mini Gen 3Shelly 1 Mini Gen 4
ChipESP-Shelly-C38FESP-Shelly-C68F
Multi-ProtokollWLAN, BluetoothWLAN, Bluetooth, Zigbee
Matter-Zertifiziert❌ Nein✅ Ja
Apple HomeKit❌ Nein✅ Ja
Power Consumption<1.2 W<1 W
KlemmenfarbeSchwarzGrau
Abmessungen (H x B x T)32 x 35 x 11 mm32 x 35 x 11 mm

👉 Jetzt kaufen: Shelly 1 Mini Gen 3 auf Amazon (bezahlter Link)


Fazit: Shelly Gen 3 oder 4 – Was ist die bessere Wahl?

Hast du bereits Shelly Gen 3?
→ Kein zwingendes Upgrade nötig, es sei denn, du brauchst Zigbee oder Matter.

Willst du Apple HomeKit nutzen?
Dann ist Shelly Gen 4 alternativlos, da Shelly Gen 3 kein HomeKit unterstützt.

Bist du neu im Smart Home?
Greife direkt zu Shelly Gen 4, weil du damit für Matter & Zigbee gerüstet bist.

Brauchst du eine stabile Verbindung mit Zigbee?
→ Shelly Gen 4 agiert als Zigbee-Repeater, während Gen 3 nur WLAN & Bluetooth kann.

Shellys bei Amazon kaufen (bezahlter Link)


Matter benötigt zwingend IPv6. Wie du IPv6 unter Proxmox einrichtest, erfährst du hier.


Was denkst du? Lohnt sich für dich ein Upgrade auf Shelly Gen 4? Schreib es in die Kommentare!

WaterMeV2 – Smarter Feuchtigkeitssensor mit ESP8266 & OLED-Display

Einleitung

Der WaterMeV2 – Feuchtigkeitssensor mit ESP8266 und OLED-Display kann die Bodenfeuchtigkeit in Echtzeit überwachen und die Daten direkt per MQTT an dein Smart Home System senden. Dieses Upgrade unseres vorherigen WaterMe Sensors bietet Verbesserungen in der Hardware und Software, eine optimierte Reset-Funktion sowie ein ansprechendes Gehäuse, das du kostenlos auf meinem Cults3D-Account herunterladen kannst (hier klicken).

WaterMeV2 Gehäuse

Vorteile von WaterMev2

  • Echtzeitüberwachung der Bodenfeuchtigkeit
  • Anbindung an MQTT für Smart Home Integration
  • WiFi-Manager für einfache WLAN-Konfiguration
  • OLED-Display für lokale Anzeige
  • 5-Sekunden-Reset-Taster für eine einfache Neukonfiguration
  • Kostenloses 3D-gedrucktes Gehäuse zum Schutz der Hardware

Benötigte Komponenten

Für dieses Projekt benötigst du folgende Komponenten (mit Affiliate-Links):

Aufbau der Hardware

Der Aufbau ist einfach und erfordert nur wenige Kabelverbindungen:

  1. ESP8266 mit dem OLED-Display verbinden:
    • SDA → D2 (GPIO4)
    • SCL → D1 (GPIO5)
    • VCC → 3.3V
    • GND → GND
  2. Feuchtigkeitssensor anschließen:
    • Signal → A0 (Analog-Pin)
    • VCC → 3.3V
    • GND → GND
  3. Taster für den Reset:
    • Ein Pin an GPIO0 (D3)
    • Der andere Pin an GND

Software – Der Code von WaterMev2

Der folgende Code enthält alle wichtigen Funktionen für den Sensor:

1. Bibliotheken und Variablen

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiManager.h>
#include <ESP8266WebServer.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <SSD1306Wire.h>
#include <LittleFS.h>
#include <ArduinoJson.h>

#define SENSOR_PIN A0
#define RESET_PIN 0
#define RESET_TIME 5000

Hier laden wir alle wichtigen Bibliotheken und definieren die Pins für den Sensor und den Reset-Taster.

2. Reset-Funktion mit 5-Sekunden-Haltezeit

void checkResetButton() {
    if (digitalRead(RESET_PIN) == LOW) {
        if (!buttonPressed) {
            buttonPressStart = millis();
            buttonPressed = true;
        }
        if (millis() - buttonPressStart >= RESET_TIME) {
            Serial.println("Reset-Taster 5 Sekunden gehalten! Setze WiFiManager-Einstellungen zurück...");
            WiFiManager wifiManager;
            wifiManager.resetSettings();
            delay(1000);
            WiFi.disconnect(true);
            delay(1000);
            ESP.restart();
        }
    } else {
        buttonPressed = false;
    }
}

Diese Funktion sorgt dafür, dass der WiFiManager nur zurückgesetzt wird, wenn der Taster mindestens 5 Sekunden gedrückt wird. Dadurch wird ein versehentliches Zurücksetzen verhindert.

3. Verbindung zum WLAN mit WiFiManager

void setup_wifi() {
    WiFiManager wifiManager;
    wifiManager.setTimeout(180);
    if (!wifiManager.autoConnect("WaterMev2")) {
        ESP.restart();
    }
}

Der WiFiManager ermöglicht eine einfache Einrichtung des WLANs über einen Access Point.

4. Sensor-Daten auslesen und per MQTT senden

void updateSensorData() {
    int sensorValue = analogRead(SENSOR_PIN);
    float moisture = map(sensorValue, 1024, 0, 0, 100);
    client.publish("WaterMev2/feuchtigkeit", String(moisture).c_str());
}

Hier wird die Feuchtigkeit gemessen und an den MQTT-Server gesendet.

5. Loop-Funktion mit Reset-Check

void loop() {
    server.handleClient();
    checkResetButton();
    updateSensorData();
    delay(30000);
}

Die loop()-Funktion überprüft den Taster und aktualisiert die Sensordaten alle 30 Sekunden.

6. Vollständiger Code

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiManager.h>  // WiFiManager Library für AP-Konfiguration
#include <ESP8266WebServer.h>
#include <time.h>        // Für configTime()
#include <SSD1306Wire.h>        // legacy: #include "SSD1306.h"
#include <LittleFS.h>
#include <ArduinoJson.h>
 
#define SENSOR_PIN A0  // Sensor an A0 angeschlossen
#define RESET_PIN 0  // GPIO0 (D3 beim ESP8266)
#define RESET_TIME 5000  // Zeit in Millisekunden (5 Sekunden)

unsigned long buttonPressStart = 0;
bool buttonPressed = false;

unsigned long previousMillis = 0;  // Speichert den Zeitpunkt des letzten MQTT-Sendevorgangs
const long interval = 30000;       // Zeitintervall für das Senden der MQTT-Daten
 
bool resetActive = false; // verhindert, dass andere Funktionen das Display während Reset stören

char mqtt_server[40] = "";
char mqtt_port[6] = "";
char mqtt_user[40] = "";
char mqtt_pass[40] = "";
char mqtt_topic_prefix[40] = "WaterMe"; // Benutzerdefiniertes Präfix
char ntp_server[40] = "pool.ntp.org";  // Standard NTP Server
 
WiFiClient espClient;
PubSubClient client(espClient);
ESP8266WebServer server(80);
SSD1306Wire display(0x3c, SDA, SCL);
 
void saveConfig() {
    Serial.println("Speichere Konfiguration in LittleFS...");
    File configFile = LittleFS.open("/config.json", "w");
    if (!configFile) {
        Serial.println("Fehler beim Speichern der Konfiguration!");
        return;
    }

    DynamicJsonDocument doc(128);
    doc["mqtt_server"] = mqtt_server;
    doc["mqtt_port"] = mqtt_port;
    doc["mqtt_user"] = mqtt_user;
    doc["mqtt_pass"] = mqtt_pass;
    doc["mqtt_topic_prefix"] = mqtt_topic_prefix;
    doc["ntp_server"] = ntp_server;

    serializeJson(doc, configFile);
    configFile.close();
    Serial.println("Konfiguration gespeichert.");
}

void loadConfig() {
    Serial.println("Lade Konfiguration aus LittleFS...");

    File configFile = LittleFS.open("/config.json", "r");
    if (!configFile) {
        Serial.println("Keine gespeicherte Konfiguration gefunden.");
        return;
    }

    DynamicJsonDocument doc(128);
    DeserializationError error = deserializeJson(doc, configFile);
    if (error) {
        Serial.println("Fehler beim Lesen der Konfigurationsdatei!");
        return;
    }

    strlcpy(mqtt_server, doc["mqtt_server"] | "", sizeof(mqtt_server));
    strlcpy(mqtt_port, doc["mqtt_port"] | "", sizeof(mqtt_port));
    strlcpy(mqtt_user, doc["mqtt_user"] | "", sizeof(mqtt_user));
    strlcpy(mqtt_pass, doc["mqtt_pass"] | "", sizeof(mqtt_pass));
    strlcpy(mqtt_topic_prefix, doc["mqtt_topic_prefix"] | "", sizeof(mqtt_topic_prefix));
    strlcpy(ntp_server, doc["ntp_server"] | "", sizeof(ntp_server));

    Serial.println("Konfiguration geladen.");
}
 
void setup_wifi() {
    Serial.println("Starte WiFiManager...");

    uint8_t mac[6];
    WiFi.macAddress(mac);

    char hostname[32];
    snprintf(hostname, sizeof(hostname), "WaterMe_%02X%02X%02X", mac[3], mac[4], mac[5]);

    WiFiManager wifiManager;
    wifiManager.setTimeout(180); // 3 Minuten warten statt unendlich

    //wifiManager.resetSettings();

    WiFiManagerParameter custom_mqtt_server("server", "MQTT Server", mqtt_server, 40);
    WiFiManagerParameter custom_mqtt_port("port", "MQTT Port", mqtt_port, 6);
    WiFiManagerParameter custom_mqtt_topic("topic", "MQTT Topic Prefix", mqtt_topic_prefix, 40);
    WiFiManagerParameter custom_ntp_server("ntp_server", "NTP Server", ntp_server, 40);
 
    wifiManager.addParameter(&custom_mqtt_server);
    wifiManager.addParameter(&custom_mqtt_port);
    wifiManager.addParameter(&custom_mqtt_topic);
    wifiManager.addParameter(&custom_ntp_server);

    if (!wifiManager.autoConnect(hostname)) {
        Serial.println("Fehlgeschlagen! Neustart in 5 Sekunden...");
        delay(5000);
        ESP.restart();
    }

    WiFi.hostname(hostname);

    strncpy(mqtt_server, custom_mqtt_server.getValue(), sizeof(mqtt_server) - 1);
    strncpy(mqtt_port, custom_mqtt_port.getValue(), sizeof(mqtt_port) - 1);
    strncpy(mqtt_topic_prefix, custom_mqtt_topic.getValue(), sizeof(mqtt_topic_prefix) - 1);
    strncpy(ntp_server, custom_ntp_server.getValue(), sizeof(ntp_server) - 1);
    saveConfig();
    Serial.println("WLAN verbunden!");
    Serial.print("IP-Adresse: ");
    Serial.println(WiFi.localIP());
}
 
void handleRoot() {
    Serial.println("Web-Oberfläche aufgerufen");
    String htmlContent = "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>WaterMe Einstellungen</title>"
                         "<style>"
                         "body { font-family: Arial, sans-serif; margin: 40px; background-color: #333; color: #fff; }"
                         "h1 { color: #fff; }"
                         "form { background-color: #222; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px 0 rgba(0,0,0,0.5); }"
                         "label { display: block; margin-top: 20px; margin-bottom: 5px; color: #ccc; }"
                         "input[type='text'], input[type='submit'] { width: 100%; padding: 8px; margin-top: 5px; border: 1px solid #555; border-radius: 4px; }"
                         "input[type='text'] { background-color: #555; color: #ddd; }"
                         "input[type='submit'] { background-color: #008CBA; color: white; cursor: pointer; }"
                         "input[type='submit']:hover { background-color: #005f7a; }"
                         "</style>"
                         "</head><body>"
                         "<h1>WaterMe Einstellungen</h1>"
                         "<form action='/save' method='POST'>"
                         "<label for='server'>MQTT Server:</label> <input type='text' id='server' name='server' value='" + String(mqtt_server) + "'><br>"
                         "<label for='port'>MQTT Port:</label> <input type='text' id='port' name='port' value='" + String(mqtt_port) + "'><br>"
                         "<label for='user'>MQTT Benutzer:</label> <input type='text' id='user' name='user' value='" + String(mqtt_user) + "'><br>"
                         "<label for='pass'>MQTT Passwort:</label> <input type='password' id='pass' name='pass' value='" + String(mqtt_pass) + "'><br>"
                         "<label for='topic'>MQTT Topic Prefix:</label> <input type='text' id='topic' name='topic' value='" + String(mqtt_topic_prefix) + "'><br>"
                         "<label for='ntp_server'>NTP Server:</label> <input type='text' id='ntp_server' name='ntp_server' value='" + String(ntp_server) + "'><br>"
                         "<input type='submit' value='Speichern'>"
                         "</form></body></html>";
    server.send(200, "text/html", htmlContent);
}
 
void handleSave() {
    Serial.println("Speichere neue Einstellungen...");
    if (server.hasArg("server")) strncpy(mqtt_server, server.arg("server").c_str(), sizeof(mqtt_server) - 1);
    if (server.hasArg("port")) strncpy(mqtt_port, server.arg("port").c_str(), sizeof(mqtt_port) - 1);
    if (server.hasArg("user")) strlcpy(mqtt_user, server.arg("user").c_str(), sizeof(mqtt_user));
    if (server.hasArg("pass")) strlcpy(mqtt_pass, server.arg("pass").c_str(), sizeof(mqtt_pass));
    if (server.hasArg("topic")) strncpy(mqtt_topic_prefix, server.arg("topic").c_str(), sizeof(mqtt_topic_prefix) - 1);
    if (server.hasArg("ntp_server")) strncpy(ntp_server, server.arg("ntp_server").c_str(), sizeof(ntp_server) - 1);
    saveConfig();
    server.send(200, "text/html", "<html><body><h1>Gespeichert! Neustart...</h1></body></html>");
    delay(3000);
    ESP.restart();
}
 
void checkResetButton() {
    static int lastSecondsLeft = -1;

    if (digitalRead(RESET_PIN) == LOW) {
        if (!buttonPressed) {
            buttonPressStart = millis();
            buttonPressed = true;
            resetActive = true;
            lastSecondsLeft = -1;
        }

        unsigned long heldTime = millis() - buttonPressStart;
        int secondsLeft = (RESET_TIME - heldTime) / 1000;

        if (secondsLeft != lastSecondsLeft && heldTime < RESET_TIME) {
            lastSecondsLeft = secondsLeft;

            display.clear();
            display.setFont(ArialMT_Plain_16);
            display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
            display.drawString(display.getWidth() / 2, 20, "Reset in");
            display.setFont(ArialMT_Plain_24);
            display.drawString(display.getWidth() / 2, 44, String(secondsLeft));
            display.display();
        }

        if (heldTime >= RESET_TIME) {
            display.clear();
            display.setFont(ArialMT_Plain_16);
            display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
            display.drawString(display.getWidth() / 2, 28, "RESET!");
            display.display();
            delay(1000);

            Serial.println("Reset-Taster 5 Sekunden gehalten! Setze WiFiManager-Einstellungen zurück...");
            WiFiManager wifiManager;
            wifiManager.resetSettings();
            delay(500);
            WiFi.disconnect(true);
            delay(500);
            ESP.restart();
        }

    } else {
        if (buttonPressed) {
            buttonPressed = false;
            resetActive = false;

            // <<< Hier neu ergänzen:
            previousMillis = millis() - interval;  
            // <<< Dadurch wird beim nächsten loop() direkt aktualisiert!
        }
    }
}

void setup() {
    pinMode(RESET_PIN, INPUT_PULLUP);
    Serial.begin(115200);
    Serial.println("WaterMe startet...");

    if (!LittleFS.begin()) {
        Serial.println("LittleFS-Fehler");
    } else {
        loadConfig();
    }

    // *** Display direkt am Anfang initialisieren und "AP" anzeigen ***
    display.init();
    display.flipScreenVertically();
    display.clear();
    display.setFont(ArialMT_Plain_24);
    display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
    display.drawString(display.getWidth() / 2, 28, "AP");
    display.display();
    delay(500);  // Kurze Verzögerung (optional), damit man es sicher sieht

    setup_wifi();
 
    if (strlen(mqtt_server) > 0 && strlen(mqtt_port) > 0) {
        client.setServer(mqtt_server, atoi(mqtt_port));
        Serial.println("MQTT-Konfiguration geladen.");
    } else {
        Serial.println("MQTT-Daten fehlen! Webinterface zur Konfiguration nutzen.");
    }
 
    server.on("/", handleRoot);
    server.on("/save", HTTP_POST, handleSave);
    server.begin();
    Serial.println("Webserver gestartet!");
    Serial.print("Rufe auf: http://");
    Serial.println(WiFi.localIP());

    // Sofortiges erstes Update erzwingen
    previousMillis = millis() - interval;
    handleMQTTAndDisplayUpdate(millis());

    // Sommerzeitregel für Mitteleuropa: letzte So im März + Okt
    configTime("CET-1CEST,M3.5.0/2,M10.5.0/3", ntp_server);

    Serial.print("Warte auf Zeit...");
    time_t now = time(nullptr);
    while (now < 100000) {
        delay(100);
        Serial.print(".");
        now = time(nullptr);
    }
    Serial.println(" Zeit empfangen.");
}
 
void reconnect() {
    static unsigned long lastReconnectAttempt = 0;
    uint8_t mac[6];
    WiFi.macAddress(mac);
    char clientId[32];
    snprintf(clientId, sizeof(clientId), "WaterMe_%02X%02X%02X", mac[3], mac[4], mac[5]);

    if (!client.connected() && millis() - lastReconnectAttempt > 5000) {
        lastReconnectAttempt = millis();
        Serial.print("Verbindungsversuch mit MQTT-Broker als ");
        Serial.println(clientId);

        if (client.connect(clientId, mqtt_user, mqtt_pass)) {
            Serial.println("MQTT-Verbindung hergestellt!");
        } else {
            Serial.print("MQTT-Verbindung fehlgeschlagen, Fehlercode: ");
            Serial.print(client.state());
            Serial.println(" - Neuer Versuch in 5 Sekunden...");
        }
    }
}

void loop() {
    checkResetButton();

    if (resetActive) {
        return;
    }

    server.handleClient();

    if (!client.connected()) {
        reconnect();
    }
    client.loop();

    handleMQTTAndDisplayUpdate(millis());
}

void handleMQTTAndDisplayUpdate(unsigned long currentMillis) {
    if (resetActive) return;

    if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        if (!client.connected()) {
            reconnect();
        }
        updateSensorData();
    }
}

void updateSensorData() {
    if (resetActive) return;
    int sensorValue = analogRead(SENSOR_PIN);
    float moisture = map(sensorValue, 1024, 0, 0, 100);

    time_t now = time(nullptr);
    struct tm *timeinfo = localtime(&now);
    char buffer[20];
    strftime(buffer, sizeof(buffer), "%H:%M:%S", timeinfo);
    String timestamp = String(buffer);

    updateDisplay(moisture, timestamp);
    sendMQTTData(moisture, timestamp);
}

void updateDisplay(float moisture, String timestamp) {
    Serial.println("Aktualisiere Display...");
    Serial.print("Feuchtigkeit: "); Serial.println(moisture);
    Serial.print("Timestamp: "); Serial.println(timestamp);

    String text = String(moisture, 0) + "%";
    display.clear();
    display.setFont(ArialMT_Plain_24);
    display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
    display.drawString(display.getWidth() / 2, 28, text);
    display.drawLine(0, 42, 128, 42);
    display.setFont(ArialMT_Plain_16);
    display.drawString(display.getWidth() / 2, 54, timestamp);
    display.display();
}

void sendMQTTData(float moisture, const String& timestamp) {
    char topic[50], message[50];

    snprintf(topic, sizeof(topic), "%s/feuchtigkeit", mqtt_topic_prefix);
    snprintf(message, sizeof(message), "%.2f", moisture);
    client.publish(topic, message);

    snprintf(topic, sizeof(topic), "%s/timestamp", mqtt_topic_prefix);
    client.publish(topic, timestamp.c_str());
}

Gehäuse zum 3D-Drucken

Damit die Elektronik geschützt ist, kannst du dir ein passendes Gehäuse für WaterMev2 kostenlos auf meinem Cults3D-Account herunterladen: Hier geht’s zum Gehäuse.

WaterMeV2 Gehäuse mit ESP8266 und OLED Display

Fazit

Mit dem WaterMeV2 – Feuchtigkeitssensor mit ESP8266 und OLED-Display kannst du ganz einfach Werte überwachen und in dein Smart Home System integrieren. Dank der MQTT-Integration kannst du die Daten bequem weiterverarbeiten und mit dem OLED-Display behältst du stets den Überblick. Baue dein eigenes WaterMeV2 jetzt nach und lade dir das passende Gehäuse herunter!


Hast du Fragen oder Verbesserungsvorschläge? Schreib sie in die Kommentare!

Teamspeak Server unter Proxmox installieren – Schritt-für-Schritt-Anleitung

Warum einen eigenen Teamspeak Server auf Proxmox hosten?

Ein eigener Teamspeak Server unter Proxmox bietet volle Kontrolle, Datenschutz und eine zuverlässige Sprachkommunikation ohne Abhängigkeit von externen Hostern. Deshalb ist es eine großartige Lösung für Nutzer, die Wert auf Unabhängigkeit legen. In dieser Anleitung zeigen wir dir, wie du eine Debian-VM unter Proxmox installierst und darauf einen Teamspeak 3 Server mit Firewall-Schutz (UFW) einrichtest. So kannst du deinen eigenen Server optimal betreiben und sicher nutzen.


1. Teamspeak Server unter Proxmox installieren: Debian-VM vorbereiten

1.1 Erstellen der virtuellen Maschine

  1. Melde dich bei Proxmox an.
  2. Erstelle eine neue VM mit folgenden Einstellungen:
    • Betriebssystem: Debian 12 (Netinst-ISO von debian.org)
    • CPU: 2 vCPUs
    • RAM: 2 GB (oder mehr für größere Teams)
    • Festplatte: 10 GB (je nach Bedarf)
    • Netzwerk: Virtuelles Netzwerkgerät (Bridged für externe Erreichbarkeit)
  3. Starte die VM und installiere Debian mit den Standardoptionen, damit dein Server schnell einsatzbereit ist.

1.2 Nach der Installation: Einrichten von sudo und Updates

Sobald das System hochgefahren ist, melde dich als root an und installiere sudo:

apt update &amp;&amp; apt install sudo -y

Danach kannst du einen neuen Benutzer anlegen. Falls du möchtest, kannst du ihn ts nennen, aber du kannst natürlich auch einen anderen Namen wählen:

adduser ts

Damit dieser Benutzer administrative Rechte erhält, fügst du ihn zur sudo-Gruppe hinzu:

usermod -aG sudo ts

Nun kannst du dich als dieser Benutzer anmelden und alle weiteren Schritte ausführen:

su - ts

1.3 System vorbereiten

Um dein System sicher und aktuell zu halten, solltest du regelmäßig Updates durchführen. Dies ist besonders wichtig, wenn dein Server öffentlich erreichbar ist. Aktualisiere dein System mit folgendem Befehl:

sudo apt update &amp;&amp; sudo apt upgrade -y

So stellst du sicher, dass dein Server auf dem neuesten Stand bleibt.


2. Installation und Einrichtung des Teamspeak Servers unter Proxmox

2.1 Teamspeak herunterladen und installieren

Damit dein Server läuft, benötigst du die aktuellste Teamspeak 3 Server-Version. Diese kannst du direkt aus dem Internet herunterladen:

cd ~
wget https://files.teamspeak-services.com/releases/server/3.13.7/teamspeak3-server_linux_amd64-3.13.7.tar.bz2

Nach dem Download entpackst du die Datei und verschiebst sie an den passenden Speicherort:

tar -xjf teamspeak3-server_linux_amd64-3.13.7.tar.bz2
sudo mv teamspeak3-server_linux_amd64 /opt/teamspeak

Nun müssen noch die richtigen Berechtigungen gesetzt werden, damit der Benutzer ts Zugriff auf den Server hat:

sudo chown -R ts:ts /opt/teamspeak

Bevor du fortfährst, akzeptiere die Lizenzbedingungen, um den Betrieb zu ermöglichen:

echo "license_accepted=1" > /opt/teamspeak/.ts3server_license_accepted

2.2 Erster Start des Teamspeak Servers

Jetzt kannst du den Server starten, indem du folgende Befehle ausführst:

cd /opt/teamspeak
./ts3server_startscript.sh start

Beim ersten Start wird ein Admin-Token generiert. Bewahre diesen gut auf, denn du benötigst ihn für die Verwaltung deines Servers.

Teamspeak Server Admin-Token

Falls der Server erfolgreich gestartet wurde, kannst du ihn testweise stoppen:

./ts3server_startscript.sh stop

2.3 Automatischer Start mit systemd

Damit dein TeamSpeak-Server bei jedem Neustart automatisch startet, richtest du einen systemd-Service ein:

sudo nano /etc/systemd/system/teamspeak.service

Füge diesen Inhalt ein:

[Unit]
Description=TeamSpeak 3 Server
After=network.target

[Service]
WorkingDirectory=/opt/teamspeak
User=ts
Group=ts
ExecStart=/opt/teamspeak/ts3server
ExecStop=/bin/kill -TERM $MAINPID
Restart=always
PIDFile=/opt/teamspeak/ts3server.pid

[Install]
WantedBy=multi-user.target

Speichere die Datei mit CTRL+X, dann Y und drücke Enter. Anschließend lädst du systemd neu und aktivierst den Service mit:

sudo systemctl daemon-reload
sudo systemctl enable --now teamspeak

Überprüfe nun den Status des Services, um sicherzustellen, dass alles funktioniert:

sudo systemctl status teamspeak

3. Teamspeak Server unter Proxmox absichern mit UFW

Eine Firewall ist essenziell, um deinen Server vor Angriffen zu schützen. Dafür eignet sich UFW (Uncomplicated Firewall) besonders gut.

3.1 UFW installieren

Falls UFW noch nicht installiert ist, kannst du dies mit folgendem Befehl nachholen:

sudo apt install ufw -y

3.2 Wichtige Ports freigeben

Damit dein Teamspeak-Server korrekt funktioniert, musst du die benötigten Ports freigeben. Das kannst du mit den folgenden Befehlen tun:

sudo ufw allow 9987/udp   # Sprach-Chat
sudo ufw allow 30033/tcp  # Dateiübertragung
sudo ufw allow 10011/tcp  # ServerQuery Interface

Falls du per SSH auf den Server zugreifst, stelle sicher, dass Port 22 weiterhin offen bleibt, damit du nicht ausgesperrt wirst:

sudo ufw allow 22/tcp

3.3 Firewall aktivieren & Status prüfen

Nachdem du alle benötigten Ports freigegeben hast, kannst du UFW aktivieren:

sudo ufw enable

Prüfe den aktuellen Status der Firewall, um sicherzugehen, dass alles richtig konfiguriert ist:

sudo ufw status verbose

Falls du später Regeln ändern oder entfernen möchtest, kannst du dies mit:

sudo ufw delete allow &lt;port/protokoll>

Fazit: Teamspeak Server unter Proxmox erfolgreich eingerichtet

Debian VM erfolgreich installiert und vorbereitetTeamspeak 3 Server unter Proxmox eingerichtet und als Dienst konfiguriertFirewall (UFW) aktiviert und abgesichert

🔗 Jetzt kannst du dich mit deinem Teamspeak-Client verbinden! Falls dein Server aus dem Internet erreichbar sein soll, stelle sicher, dass die Portweiterleitung in deinem Router korrekt eingerichtet ist.

🚀 Viel Spaß mit deinem eigenen Teamspeak Server unter Proxmox! 🎧

Weitere Ressourcen