Metainformationen zur Seite
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
| home_assistant:home_assistant_rezepte:apcusv_einbinden [06.11.2026] – kolja | home_assistant:home_assistant_rezepte:apcusv_einbinden [07.11.2026] (aktuell) – kolja | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| - | ====== Raspberry Pi als USV-Server für Home Assistant ====== | + | ====== Raspberry Pi als APC-USV-Server für Home Assistant ====== |
| - | Diese Dokumentation beschreibt die Einrichtung eines Raspberry Pi 1 Model B+ (mit Raspberry Pi OS Legacy Lite 32-Bit) als ressourcenschonenden USV-Server für eine **APC Smart-UPS 1500**. | + | **Aufbau:** APC Smart-UPS SMT1500I → USB → Raspberry Pi mit apcupsd → TCP 3551 → Home Assistant. Getestet mit Raspberry Pi B+ und Raspberry Pi OS Legacy Lite. |
| - | In dieser Konfiguration wurde bewusst **auf den Standard-Dienst NUT verzichtet**, | + | Später ist serielles RS-232-Modbus |
| - | ===== 1. USV-Hardware | + | ===== 1. Raspberry Pi und USV vorbereiten ===== |
| - | 1. Die APC Smart-UPS 1500 per USB-Kabel | + | - Raspberry Pi OS Lite installieren, |
| - | 2. **Wichtig: | + | |
| + | - Software installieren: | ||
| - | ===== 2. apcupsd | + | <code bash> |
| + | sudo apt update | ||
| + | sudo apt install -y apcupsd | ||
| - | Dienst installieren: | ||
| - | < | ||
| - | Konfiguration für den USB-Modbus-Betrieb und den Netzwerkzugriff anpassen: | + | </ |
| - | < | + | |
| - | Folgende | + | ===== 2. apcupsd konfigurieren ===== |
| - | < | + | |
| + | <code bash> | ||
| + | sudo nano / | ||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | Folgende | ||
| + | |||
| + | < | ||
| UPSCABLE usb | UPSCABLE usb | ||
| UPSTYPE modbus | UPSTYPE modbus | ||
| - | DEVICE | + | DEVICE |
| + | POLLTIME 30 | ||
| NETSERVER on | NETSERVER on | ||
| NISIP 0.0.0.0 | NISIP 0.0.0.0 | ||
| NISPORT 3551 | NISPORT 3551 | ||
| + | ONBATTERYDELAY 6 | ||
| + | BATTERYLEVEL 10 | ||
| + | MINUTES 5 | ||
| + | TIMEOUT 0 | ||
| + | KILLDELAY 0 | ||
| + | |||
| </ | </ | ||
| - | *(Hinweis: Hinter '' | ||
| - | Dienst aktivieren und starten: | + | **Begründung:** '' |
| - | < | + | |
| - | sudo systemctl restart | + | |
| - | Erfolgstest auf dem Pi ausführen: | + | Bei älteren Installationen ggf. '' |
| - | <code>apcaccess status</code> | + | <font inherit/ |
| - | *Die Ausgabe liefert nun alle Live-Werte der USV (z. B. LINEV, LOADPCT, ITEMP).* | + | Dort müssen BATTERYLEVEL und MINUTES erhöht werden. |
| + | Diese beiden sind eine ODER Entscheidung. Je nachdem, welche Kondition zuerst eintritt, also wie hier 10% Batterielevel oder 5 Minuten Restlaufzeit. | ||
| - | ==== Wichtig: Echtzeit-Erkennung bei Stromausfall (POLLTIME) ==== | + | <code bash> |
| - | Standardmäßig ist das Abfrage-Intervall | + | sudo systemctl enable |
| + | sudo systemctl restart apcupsd | ||
| + | apcaccess status | grep -E '^(DATE|STATUS|END APC)' | ||
| - | Datei öffnen: | ||
| - | < | ||
| - | Nach der Zeile **POLLTIME** suchen (ggf. die Raute ''#'' | ||
| - | <code ini> | ||
| - | # POLLTIME <rate in seconds> | ||
| - | POLLTIME 20 | ||
| </ | </ | ||
| - | Dienst neu starten, um die Änderung zu übernehmen: | + | '' |
| - | < | + | |
| - | * **Ergebnis: | + | ===== 3. In Home Assistant |
| + | **Einstellungen → Geräte & Dienste → Integration hinzufügen → APC UPS Daemon**. IP des Pi und Port **3551** | ||
| - | ===== 3. Integration in Home Assistant ===== | + | Die HA-Integration |
| - | 1. In Home Assistant zu **Einstellungen** -> **Geräte & Dienste** navigieren. | + | ===== 4. Dienst bei Prozessabsturz neu starten ===== |
| - | 2. Auf **Integration hinzufügen** klicken und nach **APC UPS Daemon (apcupsd)** suchen. | + | |
| - | 3. Die IP-Adresse des Raspberry Pi (z. B. '' | + | |
| - | 4. Das Gerät listet nun über 20 Sensoren direkt auf. | + | |
| - | ===== 4. Leistungstrick: | + | <code bash> |
| + | sudo systemctl edit apcupsd | ||
| - | Da die USV die Last nur in Prozent ('' | ||
| - | 1. In HA zu **Einstellungen** -> **Geräte & Dienste** -> Reiter **Helfer** wechseln. | + | </code> |
| - | 2. Auf **Helfer erstellen** -> **Template** -> **Template für einen Sensor** klicken. | + | < |
| - | 3. Folgende Daten eintragen: | + | |
| - | * **Name:** USV Aktueller Verbrauch Watts | + | |
| - | * **Zustandstemplate: | + | |
| - | < | + | |
| - | {{ (states(' | + | |
| - | </code> | + | |
| - | | + | |
| - | * **Maßeinheit: | + | |
| - | * **Geräteklasse: | + | |
| - | * **Zustandsklasse: | + | |
| - | Der Sensor steht nun für Dashboards und das Home Assistant Energie-Dashboard zur Verfügung. | + | [Service] |
| + | Restart=on-failure | ||
| + | RestartSec=10s | ||
| - | ===== 5. Automatische Selbstheilung (Dienst-Überwachung) ===== | + | </ |
| - | Falls sich der USB-Treiber oder der Dienst aufgrund von hoher Last verschluckt oder einfriert, wurde eine automatische systemd-Überwachung eingerichtet. Diese startet den Dienst im Fehlerfall ohne manuelles Eingreifen nach 10 Sekunden automatisch neu. | + | <code bash> |
| + | sudo systemctl daemon-reload | ||
| + | sudo systemctl restart apcupsd | ||
| - | Erweiterungskonfiguration öffnen: | ||
| - | < | ||
| - | Folgenden Block einfügen und speichern: | ||
| - | <code ini> | ||
| - | [Service] | ||
| - | Restart=on-failure | ||
| - | RestartSec=10s | ||
| </ | </ | ||
| - | Konfigurations-Manager neu laden: | + | **Grenze:** Ein eingefrorener USB-Modbus-Datenstrom stoppt den Prozess nicht zwingend. Deshalb ist zusätzlich ein Watchdog nötig. |
| - | < | + | |
| - | ===== 6. Modbus-Freeze-Überwachung (Watchdog-Skript) | + | ===== 5. USB-Modbus-Freeze |
| - | Bei APC Smart-UPS Modellen kann es im USB-Modbus-Betrieb nach einigen Stunden dazu kommen, dass die Messwerte einfrieren (obwohl der Zeitstempel aktuell | + | **Beobachteter Fehler: |
| - | ==== Schritt 1: Überwachungs-Skript erstellen ==== | + | Der Watchdog läuft **jede Minute**, meldet ein '' |
| - | Datei anlegen: | + | Skript erstellen: |
| - | < | + | |
| - | Folgenden Inhalt einfügen und speichern: | ||
| <code bash> | <code bash> | ||
| - | #!/bin/bash | + | sudo nano /usr/local/sbin/apcupsd-watchdog.sh |
| - | CACHE_FILE="/ | + | |
| - | CURRENT_LINEV=$(/sbin/apcaccess status | grep " | + | |
| - | if [ -z "$CURRENT_LINEV" ]; then | + | |
| - | exit 0 | + | </ |
| + | |||
| + | Den folgenden Inhalt **ab der ersten Zeile** | ||
| + | |||
| + | <code bash> | ||
| + | # | ||
| + | set -u | ||
| + | |||
| + | MAX_AGE=120 | ||
| + | COOLDOWN=900 | ||
| + | STATE=/ | ||
| + | MODE=" | ||
| + | |||
| + | case " | ||
| + | "" | ||
| + | *) echo " | ||
| + | esac | ||
| + | |||
| + | exec 9>/ | ||
| + | if [ "$MODE" = " | ||
| + | | ||
| + | else | ||
| + | flock -n 9 || exit 0 | ||
| fi | fi | ||
| - | if [ -f "$CACHE_FILE" | + | probe() { |
| - | | + | reason=""; |
| - | | + | |
| - | | + | date_text=$(printf ' |
| - | | + | |
| + | |||
| + | case " | ||
| + | | ||
| + | | ||
| + | esac | ||
| + | |||
| + | if [ -z "$date_text" | ||
| + | reason=" | ||
| fi | fi | ||
| + | |||
| + | stamp=$(date -d " | ||
| + | case " | ||
| + | "" | ||
| + | esac | ||
| + | |||
| + | age=$(($(date +%s) - stamp)) | ||
| + | if [ " | ||
| + | health=" | ||
| + | elif [ " | ||
| + | reason=" | ||
| + | else | ||
| + | health=" | ||
| + | fi | ||
| + | } | ||
| + | |||
| + | probe | ||
| + | if [ " | ||
| + | case " | ||
| + | ok) echo "OK: DATE ${age}s alt, STATUS=$ups_status"; | ||
| + | protected) echo " | ||
| + | clock) echo " | ||
| + | *) echo " | ||
| + | esac | ||
| fi | fi | ||
| - | echo "$CURRENT_LINEV" > "$CACHE_FILE" | + | case "$health" |
| + | sleep 10 | ||
| + | probe | ||
| + | case " | ||
| + | |||
| + | last=0 | ||
| + | if [ -s " | ||
| + | read -r last < " | ||
| + | case " | ||
| + | fi | ||
| + | now=$(date +%s) | ||
| + | if [ " | ||
| + | printf ' | ||
| + | |||
| + | logger -p daemon.warning -t apcupsd-watchdog " | ||
| + | if ! timeout 30s systemctl restart apcupsd; then | ||
| + | logger -p daemon.err -t apcupsd-watchdog " | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | sleep 35 | ||
| + | probe | ||
| + | if [ " | ||
| + | logger -t apcupsd-watchdog " | ||
| + | else | ||
| + | logger -p daemon.err -t apcupsd-watchdog "Noch keine aktuellen Daten: $reason" | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| </ | </ | ||
| - | Skript ausführbar machen: | + | **Wichtig:** Die erste Zeile der Skriptdatei muss ''# |
| - | < | + | |
| - | ==== Schritt 2: Automatischen Zeitplan einrichten (Cronjob) ==== | + | <code bash> |
| + | sudo chmod 750 / | ||
| + | sudo bash -n / | ||
| + | sudo / | ||
| + | sudo crontab -e | ||
| - | Die System-Zeitschaltuhr als Root öffnen: | ||
| - | < | ||
| - | Ganz unten am Ende der Datei folgende Zeile einfügen, damit der Check alle 15 Minuten läuft: | + | </ |
| + | |||
| + | Dort **nur diesen einen** | ||
| + | < | ||
| + | |||
| + | * * * * * / | ||
| + | |||
| + | </ | ||
| + | |||
| + | Alte Watchdogs deaktivieren. Kontrolle: | ||
| + | |||
| + | <code bash> | ||
| + | sudo crontab -l | ||
| + | systemctl is-active cron | ||
| + | sudo journalctl -t apcupsd-watchdog --since "24 hours ago" --no-pager | ||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | **Praxisnachweis: | ||
| + | |||
| + | . | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Umstieg auf serielles Modbus (RS-232) ===== | ||
| + | |||
| + | Bei der SMT1500I sind USB-Modbus-Freezes dokumentiert. **RS-232-Modbus** | ||
| + | |||
| + | Benötigt werden das passende **APC-Kabel AP940-0625A** | ||
| + | |||
| + | Pinout: [[https:// | ||
| + | |||
| + | Nach dem Umstecken serielle Schnittstelle ermitteln: | ||
| + | |||
| + | <code bash> | ||
| + | ls -l / | ||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | Beispiel: | ||
| + | |||
| + | <code bash> | ||
| + | DEVICE / | ||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | In ''/ | ||
| + | < | ||
| + | |||
| + | UPSCABLE smart | ||
| + | UPSTYPE modbus | ||
| + | DEVICE / | ||
| + | |||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | sudo systemctl restart apcupsd | ||
| + | apcaccess status | grep -E ' | ||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | **Port 3551, Home-Assistant-Integration und Watchdog bleiben gleich.** | ||
| + | |||
| + | |||
| + | ---- | ||
| + | |||
| + | |||
| + | ===== 6. Fehlersuche ===== | ||
| + | |||
| + | <code bash> | ||
| + | apcaccess status | grep -E ' | ||
| + | sudo systemctl status apcupsd --no-pager | ||
| + | sudo journalctl -u apcupsd -n 40 --no-pager | ||
| + | sudo journalctl -t apcupsd-watchdog -n 30 --no-pager | ||
| + | sudo journalctl -u apcupsd --since " | ||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * Im Test waren Pi-Unterspannung ('' | ||
| + | |||
| + | ===== 7. Zusätzliche Netzwerk-Clients anbinden (Master/ | ||
| + | |||
| + | Wenn an der APC Smart-UPS 1500 mehrere Server oder Systeme (z. B. ein Proxmox-Server, | ||
| + | |||
| + | Die Installation von '' | ||
| + | |||
| + | ==== Schritt 1: Konfiguration auf dem Client-System anpassen ==== | ||
| + | |||
| + | Datei auf dem zusätzlichen Server öffnen: | ||
| + | < | ||
| + | |||
| + | sudo nano / | ||
| + | |||
| + | </ | ||
| + | |||
| + | Folgende Werte setzen und darauf achten, dass keine doppelten, aktiven Einträge in der Datei stehen bleiben (alte USB-Einträge mit ''#'' | ||
| <code ini> | <code ini> | ||
| - | */15 * * * * / | + | # Verbindungstyp auf Netzwerk (Ethernet) umstellen |
| + | UPSCABLE ether | ||
| + | UPSTYPE net | ||
| + | |||
| + | # IP-Adresse und Port des Raspberry Pi (Masters) eintragen | ||
| + | DEVICE 192.168.10.248: | ||
| + | |||
| + | # Abfrage-Intervall zum Master (in Sekunden) | ||
| + | POLLTIME 30 | ||
| + | |||
| + | # Erhöhte Sicherheits-Grenzwerte für den Client | ||
| + | BATTERYLEVEL 20 | ||
| + | MINUTES 10 | ||
| </ | </ | ||
| + | Dienst auf dem Client neu starten: | ||
| - | ===== Bilder ===== | + | < |
| + | sudo systemctl restart apcupsd | ||
| + | </ | ||
| + | |||
| + | ==== Erklärung der Sicherheits-Grenzwerte (Wichtig!) ==== | ||
| + | |||
| + | Die Werte '' | ||
| + | |||
| + | * **BATTERYLEVEL 20:** Der Client fährt bereits bei **20 % Restkapazität** | ||
| + | |||
| + | **Der Kaskaden-Ablauf im Ernstfall: | ||
| + | |||
| + | ^Parameter^Einstellung^Einfache Erklärung| | ||
| + | |||
| + | |**UPSCABLE** |'' | ||
| + | |**UPSTYPE** |'' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | Dokumentation bei Kolja [[: | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Quellen und weiterführende Links ===== | ||
| + | |||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | |||
| + | ===== Bilder ===== | ||
| - | {{ : | + | {{ : |
| - | {{: | + | {{: |
| - | {{: | + | {{: |