Metainformationen zur Seite
  •  

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
home_assistant:home_assistant_rezepte:apcusv_einbinden [06.11.2026] – koljahome_assistant:home_assistant_rezepte:apcusv_einbinden [07.11.2026] (aktuell) – kolja
Zeile 1: Zeile 1:
 ====== Raspberry Pi als APC-USV-Server für Home Assistant ====== ====== Raspberry Pi als APC-USV-Server für Home Assistant ======
  
-Diese Anleitung nutzt **apcupsd mit Modbus** für eine APC Smart-UPS SMT1500I und einen Raspberry Pi (getestet: Pi 1 Model B+, Raspberry Pi OS Legacy Lite 32 Bit). Home Assistant liest die USV über das Netzwerk aus. Ein Watchdog behebt das bei USB-Modbus beobachtete Einfrieren der Messwerte. Mittelfristig ist der Wechsel auf **serielles RS-232-Modbus** vorgesehen.+**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.
  
-**Aufbau:** APC-USV -- USB (später RS-232) -- Raspberry Pi/apcupsd -- TCP 3551 -- Home Assistant.+Später ist serielles RS-232-Modbus vorgesehen (Stabilere Verbindung)
  
 ===== 1. Raspberry Pi und USV vorbereiten ===== ===== 1. Raspberry Pi und USV vorbereiten =====
  
-  - Raspberry Pi OS Lite passend zum Pi installieren, Netzwerk/SSH einrichten und dem Pi eine feste IP bzw. DHCP-Reservierung geben. Pi und Netzwerkverbindung für die gewünschte USV-Überwachung ebenfalls notstromversorgen. +  - Raspberry Pi OS Lite installieren, SSH und Netzwerk einrichten; eine feste IP/DHCP-Reservierung verwenden. Pi und Netzwerk für einen Stromausfall ebenfalls über die USV versorgen. 
-  - USV per USB an den Pi anschließen. An der USV unter **Advanced / Configuration** die Option **Modbus = Enabled** setzen. +  - USV zunächst per USB mit dem Pi verbinden. Im USV-Menü **Advanced / Configuration / Modbus**  aktivieren. 
-  - Pakete installieren:+  - Software installieren:
  
 <code bash> <code bash>
 sudo apt update sudo apt update
 sudo apt install -y apcupsd cron sudo apt install -y apcupsd cron
 +
 +
 </code> </code>
  
Zeile 20: Zeile 22:
 <code bash> <code bash>
 sudo nano /etc/apcupsd/apcupsd.conf sudo nano /etc/apcupsd/apcupsd.conf
 +
 +
 </code> </code>
  
-Diese Einträge setzen (andere gleichnamige aktive Einträge nicht doppelt stehen lassen):+Folgende Werte setzen; keine doppelten aktiven Einträge stehen lassen:
  
-<code ini>+<code>
 UPSCABLE usb UPSCABLE usb
 UPSTYPE modbus UPSTYPE modbus
 DEVICE DEVICE
 POLLTIME 30 POLLTIME 30
- 
 NETSERVER on NETSERVER on
 NISIP 0.0.0.0 NISIP 0.0.0.0
 NISPORT 3551 NISPORT 3551
- 
 ONBATTERYDELAY 6 ONBATTERYDELAY 6
 BATTERYLEVEL 10 BATTERYLEVEL 10
Zeile 39: Zeile 41:
 TIMEOUT 0 TIMEOUT 0
 KILLDELAY 0 KILLDELAY 0
 +
 </code> </code>
  
-**Warum:** ''DEVICE'' bleibt bei USB-Modbus leer; ''POLLTIME 30'' fragt die USV ungefähr alle 30 s ab. ''NISIP 0.0.0.0'' erlaubt den Zugriff über das LAN (Port 3551 nur für vertrauenswürdige Geräte freigeben). Die Batteriegrenzen betreffen die lokale apcupsd-Abschaltung des Pi; sie fahren nicht automatisch andere Server herunter.+**Begründung:**  ''DEVICE''  bleibt bei USB-Modbus leer. ''POLLTIME 30''  liest die USV ungefähr alle 30 Sekunden aus. ''NISIP 0.0.0.0''  erlaubt Netzwerkzugriffe: Port 3551 nur im vertrauenswürdigen LAN freigeben. Die Batteriegrenzen betreffen apcupsd auf dem Pi; andere Geräte werden dadurch nicht automatisch heruntergefahren.
  
-Bei älteren Debian-/Pi-OS-Installationen ggf. in ''/etc/default/apcupsd'' zusätzlich ''ISCONFIGURED=yes'' setzen.+Bei älteren Installationen ggf. ''ISCONFIGURED=yes''  in ''/etc/default/apcupsd''  setzen.    
 + <font inherit/inherit;;#e74c3c;;inherit>**ACHTUNG:**</font>  Die Zeiten unbeding an die eigenen Bedürfnisse anpassen. Einige Proxmox Server brauchen realtiv lange zum sicheren Herunterfahren.  
 +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.
  
 <code bash> <code bash>
 sudo systemctl enable --now apcupsd sudo systemctl enable --now apcupsd
 sudo systemctl restart apcupsd sudo systemctl restart apcupsd
-apcaccess status | grep -E '^(DATE|STATUS|LINEV|LOADPCT|END APC)'+apcaccess status | grep -E '^(DATE|STATUS|END APC)' 
 + 
 </code> </code>
  
-Der angezeigte ''DATE''-Zeitpunkt muss aktuell sein, ''STATUS'' normalerweise ''ONLINE''.+''DATE''  muss aktuell sein; ''STATUS''  lautet normalerweise ''ONLINE''.
  
-===== 3. Home Assistant anbinden =====+===== 3. In Home Assistant einbinden =====
  
-**Einstellungen -> Geräte & Dienste -> Integration hinzufügen -> APC UPS Daemon**. IP-Adresse des Pi und Port **3551** eintragen. Die HA-Integration fragt standardmäßig **alle 60 s** ab; ''POLLTIME 30'' auf dem Pi bedeutet also **keine** 30-s-Aktualisierung in HA. Vor Abschaltautomationen stets die Aktualität der Werte berücksichtigen.+**Einstellungen → Geräte & Dienste → Integration hinzufügen → APC UPS Daemon**. IP des Pi und Port **3551**  eintragen.
  
-Optional: Ein Leistungssensor lässt sich aus ''LOADPCT'' und der **Wirkleistungs-Nennleistung** der jeweiligen USV abschätzen, z. B. bei 1.000 W Nennleistung: ''Last in % * 10 = ungefähr W''. Das ist kein echter Wirkleistungs- oder Energiezähler; bei fehlenden Werten **nicht** automatisch 0 W annehmen.+Die HA-Integration fragt standardmäßig **alle 60 Sekunden**  ab. Die 30 Sekunden ''POLLTIME''  auf dem Pi bedeuten daher keine 30-Sekunden-Aktualisierung in HA. Bei einem Freeze können Werte kurzzeitig deutlich älter werden. Für Abschaltautomationen die Datenaktualität und das Ausfallverhalten berücksichtigen.
  
-===== 4. Dienst bei Prozessfehler automatisch neu starten =====+===== 4. Dienst bei Prozessabsturz neu starten =====
  
 <code bash> <code bash>
 sudo systemctl edit apcupsd sudo systemctl edit apcupsd
 +
 +
 </code> </code>
 +<code>
  
-<code ini> 
 [Service] [Service]
 Restart=on-failure Restart=on-failure
 RestartSec=10s RestartSec=10s
 +
 </code> </code>
  
Zeile 74: Zeile 85:
 sudo systemctl daemon-reload sudo systemctl daemon-reload
 sudo systemctl restart apcupsd sudo systemctl restart apcupsd
 +
 +
 </code> </code>
  
-**Grenze:** ''Restart=on-failure'' hilft nur bei Prozessfehlern. Ein laufender Daemon kann trotzdem **eingefrorene Modbus-Daten** liefern.+**Grenze:**  Ein eingefrorener USB-Modbus-Datenstrom stoppt den Prozess nicht zwingend. Deshalb ist zusätzlich ein Watchdog nötig.
  
-===== 5. USB-Modbus-Freeze: automatischer Watchdog =====+===== 5. USB-Modbus-Freeze automatisch beheben =====
  
-**Beobachteter Fehler:** ''apcaccess'' liefert weiter einen neuen Statusbericht (''END APC''), aber ''DATE'' bleibt stundenlang stehen. ''DATE'' ist der Zeitpunkt der letzten Datenaktualisierung von der USV; ''END APC'' nur der Berichtzeitpunkt. Ein manueller ''systemctl restart apcupsd'' hat die Daten jeweils wiederhergestellt.+**Beobachteter Fehler:**''END APC''  zeigt die aktuelle Abfragezeit, aber ''DATE''  bleibt auf der letzten erfolgreichen USV-Datenübertragung stehen. Ein Neustart von ''apcupsd''  stellte die Kommunikation wieder her. **Nicht**  die Netzspannung ''LINEV''  vergleichen: Ein konstanter Messwert ist kein Fehlernachweis.
  
-**Nicht die Netzspannung vergleichen!** ''LINEV'' darf im Normalbetrieb unverändert bleiben. Der Watchdog prüft deshalb jede Minute, ob ''DATE'' mehr als **120 s** alt ist, bestätigt den Fehler nach 10 s und startet ''apcupsd'' neu. Neustarts sind auf **höchstens einen Versuch pro 15 Minuten** begrenzt; ''LOWBATT'' und ''SHUTTING DOWN'' werden geschützt. Fehler und Erfolge landen im Journal.+Der Watchdog läuft **jede Minute**, meldet ein ''DATE''-Alter über **120 Sekunden**, bestätigt den Fehler nach **10 Sekunden**  und startet ''apcupsd''  neu. Zwischen zwei Neustarts liegen mindestens **15 Minuten**. ''LOWBATT''  und ''SHUTTING DOWN''  sind geschützt. Ereignisse werden im Journal protokolliert. 
 + 
 +Skript erstellen: 
 + 
 +<code bash> 
 +sudo nano /usr/local/sbin/apcupsd-watchdog.sh 
 + 
 + 
 +</code>
  
-Skript mit **korrekter Bash-Startzeile** anlegen (den gesamten Block ausführen):+Den folgenden Inhalt **ab der ersten Zeile**  einfügen. Der komplette Skriptinhalt steht in einem einzigen DokuWiki-Codeblock:
  
 <code bash> <code bash>
-sudo tee /usr/local/sbin/apcupsd-watchdog.sh >/dev/null <<'SCRIPT' 
 #!/usr/bin/env bash #!/usr/bin/env bash
 set -u set -u
Zeile 96: Zeile 116:
 MODE="${1:-}" MODE="${1:-}"
  
-if [[ -n "$MODE" && "$MODE" != "--check" ]]; then +case "$MODE" in 
-    echo "Aufruf: $0 [--check]" >&2 +    ""|--check) ;; 
-    exit 2 +    *) echo "Aufruf: $0 [--check]" >&2; exit 2 ;; 
-fi+esac
  
 exec 9>/run/apcupsd-watchdog.lock exec 9>/run/apcupsd-watchdog.lock
-if [[ "$MODE" == "--check" ]]; then +if [ "$MODE" = "--check" ]; then 
-    flock -w 5 9 || { echo "BELEGT: Watchdog laeuft bereits."; exit 2; }+    flock -w 5 9 || { echo "BELEGT: Watchdog laeuft."; exit 2; }
 else else
     flock -n 9 || exit 0     flock -n 9 || exit 0
Zeile 109: Zeile 129:
  
 probe() { probe() {
-    local report date_text stamp now 
     reason=""; age=""; ups_status=""; health="fault"     reason=""; age=""; ups_status=""; health="fault"
     report=$(timeout 10s /usr/sbin/apcaccess status 2>/dev/null) || report=""     report=$(timeout 10s /usr/sbin/apcaccess status 2>/dev/null) || report=""
-    date_text=$(printf '%s\n' "$report" | awk '/^DATE[[:space:]]*:/ {sub(/^[^:]*:[[:space:]]*/, ""); print; exit}') +    date_text=$(printf '%s\n' "$report" | awk '$1 == "DATE" {sub(/^[^:]*:[ \t]*/, ""); print; exit}') 
-    ups_status=$(printf '%s\n' "$report" | awk '/^STATUS[[:space:]]*:/ {sub(/^[^:]*:[[:space:]]*/, ""); print; exit}')+    ups_status=$(printf '%s\n' "$report" | awk '$1 == "STATUS" {sub(/^[^:]*:[ \t]*/, ""); print; exit}')
  
-    if [[ "$ups_status" == *"SHUTTING DOWN"* || "$ups_status" == *"LOWBATT"* ]]; then +    case "$ups_status" in 
-        health="protected"; return 0 +        *"SHUTTING DOWN"*|*"LOWBATT"*) health="protected"; return ;; 
-    fi +        *"COMMLOST"*) reason="STATUS=COMMLOST"; return ;; 
-    if [[ "$ups_status" == *"COMMLOST"* ]]; then +    esac 
-        reason="STATUS=COMMLOST"; return 1 + 
-    fi +    if [ -z "$date_text" ] || [ -z "$ups_status" ]; then 
-    if [[ -z "$date_text" || -z "$ups_status" ]]; then +        reason="DATE oder STATUS fehlt"; return
-        reason="DATE oder STATUS fehlt"; return 1+
     fi     fi
 +
     stamp=$(date -d "$date_text" +%s 2>/dev/null) || stamp=""     stamp=$(date -d "$date_text" +%s 2>/dev/null) || stamp=""
-    if [[ ! "$stamp" =~ ^[0-9]+$ ]]; then +    case "$stamp" in 
-        reason="DATE nicht auswertbar"; return 1 +        ""|*[!0-9]*) reason="DATE ungueltig"; return ;; 
-    fi +    esac 
-    now=$(date +%s) + 
-    age=$((now - stamp)) +    age=$(($(date +%s) - stamp)) 
-    if ((age < -60)); then +    if [ "$age" -lt -60 ]; then 
-        health="clock"; reason="DATE liegt in der Zukunft: Systemzeit pruefen"; return 2 +        health="clock"; reason="Systemzeit pruefen" 
-    fi +    elif [ "$age" -gt "$MAX_AGE" ]; then 
-    if ((age > MAX_AGE)); then +        reason="DATE ist ${age}s alt (Grenze ${MAX_AGE}s)" 
-        reason="DATE ist ${age}s alt (Grenzwert ${MAX_AGE}s)"; return 1+    else 
 +        health="ok"
     fi     fi
-    health="ok"; return 0 
 } }
  
 probe probe
-if [[ "$MODE" == "--check" ]]; then+if [ "$MODE" = "--check" ]; then
     case "$health" in     case "$health" in
-        ok)        echo "OK: DATE ist ${age}s alt, STATUS=$ups_status"; exit 0 ;; +        ok) echo "OK: DATE ${age}s alt, STATUS=$ups_status"; exit 0 ;; 
-        protected) echo "GESCHUETZT: STATUS=$ups_status, kein Neustart"; exit 0 ;; +        protected) echo "GESCHUETZT: $ups_status"; exit 0 ;; 
-        clock)     echo "WARNUNG: $reason"; exit 2 ;; +        clock) echo "WARNUNG: $reason"; exit 2 ;; 
-        *)         echo "FEHLER: $reason (Testmodus: kein Neustart)"; exit 1 ;;+        *) echo "FEHLER: $reason (kein Neustart im Testmodus)"; exit 1 ;;
     esac     esac
 fi fi
Zeile 155: Zeile 174:
  
 last=0 last=0
-if [[ -s "$STATE" ]]; then+if [ -s "$STATE" ]; then
     read -r last < "$STATE"     read -r last < "$STATE"
-    [[ "$last" =~ ^[0-9]+$ ]] || last=0+    case "$last" in ""|*[!0-9]*) last=0 ;; esac
 fi fi
 now=$(date +%s) now=$(date +%s)
-((now - last >= COOLDOWN)) || exit 0+if [ "$((now - last))" -lt "$COOLDOWN" ]; then exit 0; fi
 printf '%s\n' "$now" > "$STATE" printf '%s\n' "$now" > "$STATE"
  
-logger -p daemon.warning -t apcupsd-watchdog \ +logger -p daemon.warning -t apcupsd-watchdog "Datenfehler: $reason; Neustart."
-    "USV-Datenfehler bestaetigt: $reason. Starte apcupsd neu."+
 if ! timeout 30s systemctl restart apcupsd; then if ! timeout 30s systemctl restart apcupsd; then
-    logger -p daemon.err -t apcupsd-watchdog \ +    logger -p daemon.err -t apcupsd-watchdog "Neustart fehlgeschlagen."
-        "Neustart von apcupsd fehlgeschlagen!"+
     exit 1     exit 1
 fi fi
 +
 sleep 35 sleep 35
 probe probe
-if [[ "$health" == "ok" ]]; then +if [ "$health" = "ok" ]; then 
-    logger -t apcupsd-watchdog \ +    logger -t apcupsd-watchdog "Wiederhergestellt: DATE ${age}s alt, STATUS=$ups_status."
-        "Wiederhergestellt: DATE ${age}s alt, STATUS=$ups_status."+
 else else
-    logger -p daemon.err -t apcupsd-watchdog \ +    logger -p daemon.err -t apcupsd-watchdog "Noch keine aktuellen Daten: $reason"
-        "Nach Neustart noch keine aktuellen Daten ($reason; STATUS=$ups_status)."+
     exit 1     exit 1
 fi fi
-SCRIPT 
-sudo chmod 750 /usr/local/sbin/apcupsd-watchdog.sh 
-sudo bash -n /usr/local/sbin/apcupsd-watchdog.sh 
-sudo /usr/local/sbin/apcupsd-watchdog.sh --check 
-</code> 
  
-**Wichtig:** Das Skript muss mit ''#!/usr/bin/env bash'' **in der ersten Zeile** beginnen. Fehlermeldungen wie ''not found'' bei Bash-Bedingungen deuten auf eine Ausführung mit ''sh'' hin. Den Interpreter mit ''sudo head -n 2 /usr/local/sbin/apcupsd-watchdog.sh'' prüfen. ''[[: not found'' bedeutet, dass es fälschlich mit ''sh'' ausgeführt wurde. Den Interpreter mit ''sudo head -n 2 /usr/local/sbin/apcupsd-watchdog.sh'' prüfen. 
  
-Cronjob als **root** eintragen:+</code> 
 + 
 +**Wichtig:**  Die erste Zeile der Skriptdatei muss ''#!/usr/bin/env bash''  sein, ohne Leerzeile davor. Danach testen und Cronjob anlegen:
  
 <code bash> <code bash>
 +sudo chmod 750 /usr/local/sbin/apcupsd-watchdog.sh
 +sudo bash -n /usr/local/sbin/apcupsd-watchdog.sh
 +sudo /usr/local/sbin/apcupsd-watchdog.sh --check
 sudo crontab -e sudo crontab -e
 +
 +
 </code> </code>
  
 +Dort **nur diesen einen**  Watchdog eintragen:
 <code> <code>
 +
 * * * * * /usr/local/sbin/apcupsd-watchdog.sh * * * * * /usr/local/sbin/apcupsd-watchdog.sh
 +
 </code> </code>
  
-**Keine zweite/altere Freeze-Überwachung parallel laufen lassen.** Prüfen:+Alte Watchdogs deaktivieren. Kontrolle:
  
 <code bash> <code bash>
-systemctl is-active cron 
 sudo crontab -l sudo crontab -l
-sudo /usr/local/sbin/apcupsd-watchdog.sh --check+systemctl is-active cron
 sudo journalctl -t apcupsd-watchdog --since "24 hours ago" --no-pager sudo journalctl -t apcupsd-watchdog --since "24 hours ago" --no-pager
 +
 +
 </code> </code>
  
-**Praxisnachweis (06.11.2026):** ''DATE'' war 164 s alt; Watchdog startete ''apcupsd'' automatisch neu und meldete nach 21 s wieder aktuelle Daten mit ''STATUS=ONLINE''. Das ist eine **Wiederherstellung**, keine Beseitigung der USB-Modbus-Ursache. Während des Neustarts sind auch die HA-Daten kurz unterbrochen. Bei batteriebetriebenen Systemen darf die Abschaltlogik nicht ausschließlich auf einen möglicherweise eingefrorenen Status vertrauen.+**Praxisnachweis:**  Am 06.11.2026 erkannte der Watchdog ein ''DATE''-Alter von 164 s, startete ''apcupsd''  neu und stellte die Daten wieder her. Das umgeht den Freeze, beseitigt aber nicht dessen USB-Modbus-Ursache. Die USV-Abschaltung darf nicht allein von möglicherweise veralteten HA-Sensorwerten abhängen.
  
-===== 6. Geplanter Umstieg auf serielles RS-232-Modbus =====+.
  
-Bei SMT1500I wurde wiederholt ein Einfrieren über **USB-Modbus** berichtet. **Modbus über RS-232** umgeht diesen USB-Kommunikationspfad und ist deshalb eine vielversprechende, voraussichtlich stabilere Alternative – aber keine garantierte Fehlerfreiheit.+----
  
-Benötigt werden: +===== Umstieg auf serielles Modbus (RS-232) =====
-  * APC-Originalkabel **AP940-0625A** (USV-Anschluss in RJ45-/RJ50-Bauform auf DB9, Smart Signaling). +
-  * Ein Linux-kompatibler **USB-auf-RS-232-Adapter** (vorzugsweise mit stabilem USB-Serial-Treiber), falls der Pi keine echte RS-232-Schnittstelle besitzt.+
  
-**Achtung:** Der APC-RJ45-Anschluss ist **kein Ethernet/LAN-Anschluss** und **kein RS485**. Kein gewöhnliches Netzwerkkabel oder beliebiges serielles Kabel verwenden: APC warnt wegen der speziellen Pinbelegung vor unbeabsichtigtem Abschalten der USV.+Bei der SMT1500I sind USB-Modbus-Freezes dokumentiert. **RS-232-Modbus**  vermeidet den betroffenen USB-Modbus-Kommunikationsweg und ist voraussichtlich stabiler, ohne eine absolute Garantie zu bieten.
  
-Beim späteren Umbau USB-USV-Kabel entfernen, APC-Seriellkabel und Adapter verbinden. Serielles Gerät ermitteln:+Benötigt werden das passende **APC-Kabel AP940-0625A**  (USV-Buchse mit RJ45/RJ50-Bauform auf DB9) und ein Linux-kompatibler **USB-RS232-Adapter**. Der APC-Anschluss ist **kein Ethernet und kein RS485**. Wegen der speziellen Pinbelegung kein beliebiges Kabel verwenden. 
 + 
 +Pinout: [[https://pinoutguide.com/UPS/apc_0625_cable_pinout.shtml|APC Smart-UPS 5G cable pins and signals]] 
 + 
 +Nach dem Umstecken serielle Schnittstelle ermitteln:
  
 <code bash> <code bash>
 ls -l /dev/serial/by-id/ ls -l /dev/serial/by-id/
 +
 +
 </code> </code>
  
-In ''/etc/apcupsd/apcupsd.conf'' **nur die Verbindung** ändern (Beispiel, Gerätenamen anpassen):+Beispiel: 
 + 
 +<code bash> 
 +DEVICE /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 
 + 
 + 
 +</code> 
 + 
 +In ''/etc/apcupsd/apcupsd.conf''  nur die Verbindung ändern (Gerätepfad anpassen): 
 +<code>
  
-<code ini> 
 UPSCABLE smart UPSCABLE smart
 UPSTYPE modbus UPSTYPE modbus
 DEVICE /dev/serial/by-id/usb-DEIN_ADAPTER DEVICE /dev/serial/by-id/usb-DEIN_ADAPTER
 +
 </code> </code>
  
Zeile 236: Zeile 270:
 sudo systemctl restart apcupsd sudo systemctl restart apcupsd
 apcaccess status | grep -E '^(DATE|STATUS|END APC)' apcaccess status | grep -E '^(DATE|STATUS|END APC)'
 +
 +
 </code> </code>
  
-''NETSERVER'', ''NISPORT'', HA-Integration und Watchdog können **unverändert** bleiben. Die Dokumentation beschreibt den späteren Umbau; er ist noch nicht vor Ort getestet.+**Port 3551, Home-Assistant-Integration und Watchdog bleiben gleich.**  Die serielle Variante muss nach dem Umbau noch praktisch getestet werden.
  
-===== 7. Schnelle Fehlersuche =====+ 
 +---- 
 + 
 + 
 +===== 6. Fehlersuche =====
  
 <code bash> <code bash>
Zeile 247: Zeile 287:
 sudo journalctl -u apcupsd -n 40 --no-pager sudo journalctl -u apcupsd -n 40 --no-pager
 sudo journalctl -t apcupsd-watchdog -n 30 --no-pager sudo journalctl -t apcupsd-watchdog -n 30 --no-pager
-lsusb+sudo  journalctl -u apcupsd --since "today" 
 + 
 </code> </code>
  
-  * ''DATE'' alt, ''END APC'' aktuell: **Modbus-Daten eingefroren**, Watchdog sollte eingreifen. +  * ''DATE''  alt, ''END APC''  aktuell: USB-Modbus-Daten eingefroren. 
-  * ''DATE'' aktuell, HA-Werte alt: HA-Abfrage oder Netzwerk prüfen. +  * ''DATE''  aktuell, HA-Werte alt: Netzwerk oder HA-Integration prüfen. 
-  * ''throttled=0x0'' (Pi) und USB ''power/control=on'' waren beim Test unauffällig; USB-Autosuspend war nicht aktiv. +  * Im Test waren Pi-Unterspannung (''throttled=0x0'') und USB-Autosuspend (''power/control=on'') unauffällig.
-  * Ein USB-Reset **zeitgleich mit apcupsd-Neustart** ist allein kein Beweis für einen Hardwaredefekt.+
  
-===== Quellen / Hinweise =====+===== 7. Zusätzliche Netzwerk-Clients anbinden (Master/Slave-Betrieb) =====
  
-  * [[https://www.home-assistant.io/integrations/apcupsd/|Home Assistant: APC UPS Daemon (60-s-Polling)]] +Wenn an der APC Smart-UPS 1500 mehrere Server oder Systeme (z. B. ein Proxmox-Server, ein PC oder ein zweites NAS) betrieben werden, müssen auch diese über einen Stromausfall informiert werden. Da das USB-Kabel physisch im Raspberry Pi (**Master**) steckt, können weitere Systeme als **Netzwerk-Clients (Slaves)**  eingerichtet werden. Diese lauschen über das Netzwerk dem Pi.
-  * [[https://manpages.debian.org/trixie/apcupsd/apcaccess.8.en.html|apcaccess: DATE / END APC]] +
-  * [[https://sourceforge.net/p/apcupsd/mailman/apcupsd-users/thread/51b686c6-487b-df5e-bdba-c289cc1fcd19%40sci1.com/|Bekannter Freeze bei SMT1500I mit USB-Modbus]] +
-  * [[https://www.se.com/us/en/faqs/FA156800/|Schneider Electric: Warnung vor falschen seriellen Kabeln]]+
  
 +Die Installation von ''apcupsd''  auf dem Ziel-Client erfolgt analog zu den Schritten 1 und 2. In der Konfigurationsdatei des Clients müssen jedoch die Netzwerk-Parameter angepasst werden.
  
 +==== Schritt 1: Konfiguration auf dem Client-System anpassen ====
  
-===== Bilder =====+Datei auf dem zusätzlichen Server öffnen: 
 +<code>
  
 +sudo nano /etc/apcupsd/apcupsd.conf
 +
 +</code>
 +
 +Folgende Werte setzen und darauf achten, dass keine doppelten, aktiven Einträge in der Datei stehen bleiben (alte USB-Einträge mit ''#''  auskommentieren):
 +
 +<code ini>
 +# Verbindungstyp auf Netzwerk (Ethernet) umstellen
 +UPSCABLE ether
 +UPSTYPE net
 +
 +# IP-Adresse und Port des Raspberry Pi (Masters) eintragen
 +DEVICE 192.168.10.248:3551
 +
 +# Abfrage-Intervall zum Master (in Sekunden)
 +POLLTIME 30
 +
 +# Erhöhte Sicherheits-Grenzwerte für den Client
 +BATTERYLEVEL 20
 +MINUTES 10
 +
 +</code>
 +
 +Dienst auf dem Client neu starten:
 +
 +<code>
 +sudo systemctl restart apcupsd
 +
 +</code>
 +
 +==== Erklärung der Sicherheits-Grenzwerte (Wichtig!) ====
 +
 +Die Werte ''BATTERYLEVEL''  und ''MINUTES''  wurden auf dem Client bewusst **höher angesetzt**  als auf dem Raspberry Pi (Master):
 +
 +* **BATTERYLEVEL 20:**  Der Client fährt bereits bei **20 % Restkapazität**  kontrolliert herunter. * **MINUTES 10:**  Der Client fährt herunter, sobald die verbleibende Akkulaufzeit unter **10 Minuten**  fällt.
 +
 +**Der Kaskaden-Ablauf im Ernstfall:**  Durch diese Staffelung wird verhindert, dass der Raspberry Pi (Master) zeitgleich mit den Clients herunterfährt. Der Pi bleibt länger aktiv und stellt sicher, dass er die Abschalt-Befehle im Netzwerk erfolgreich an alle Clients senden kann. Erst wenn die Clients sicher ausgeschaltet sind und die USV weiter gegen die kritische 5-%-Marke sinkt, fährt sich der Pi als allerletztes Gerät im Rack herunter.
 +
 +^Parameter^Einstellung^Einfache Erklärung|
 +
 +|**UPSCABLE** |''ether'' |Sagt dem System, dass die USV nicht per Kupferdraht (USB), sondern virtuell über das Netzwerk-Kabel (Ethernet) erreichbar ist.|
 +|**UPSTYPE** |''net'' |Stellt den Treiber in den Client-Modus. Das System sucht nicht nach physikalischer Hardware, sondern lauscht auf USV-Daten aus dem Netzwerk.|
 +
 +----
 +
 +Dokumentation bei Kolja [[:blackout_shutdown_doku_bei_kolja|Link]]
 +
 +----
 +
 +===== Quellen und weiterführende Links =====
 +
 +  * [[https://www.home-assistant.io/integrations/apcupsd/|Home Assistant – APC UPS Daemon Integration]]
 +  * [[https://manpages.debian.org/trixie/apcupsd/apcaccess.8.en.html|Debian – apcaccess, DATE und END APC]]
 +  * [[https://man.uex.se/5/apcupsd.conf|apcupsd – Konfigurationsreferenz]]
 +  * [[https://sourceforge.net/p/apcupsd/mailman/message/37873478/|apcupsd – Bekannter USB-Modbus-Freeze bei SMT1500I]]
 +  * [[https://abcdocz.com/doc/296400/apcupsd-user-manual|apcupsd – Benutzerhandbuch mit serieller Modbus-Konfiguration]]
 +  * [[https://www.se.com/us/en/faqs/FA163632/|Schneider Electric – Kompatible APC-Kommunikationskabel]]
 +  * [[https://www.se.com/de/de/product/AP940-0625A/|Schneider Electric – Serielles Kabel AP940-0625A]]
 +  * [[https://www.se.com/ph/en/faqs/FA156800/|Schneider Electric – Warnung vor falschen seriellen Kabeln]]
 +
 +===== Bilder =====
  
-{{ :home_assistant:apc_ha_integration.jpeg?direct&600 |}}+{{  :home_assistant:apc_ha_integration.jpeg?direct&600  |ASCII���Screenshot}}
  
-{{:home_assistant:apc_ha_sensoren.jpeg?direct&400 |}}+{{:home_assistant:apc_ha_sensoren.jpeg?direct&400  |ASCII���Screenshot}}
  
-{{:home_assistant:apc_ha_diagnose.jpeg?direct&400 |}}+{{:home_assistant:apc_ha_diagnose.jpeg?direct&400  |ASCII���Screenshot}}