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 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 | + | **Aufbau:** APC Smart-UPS SMT1500I |
| - | **Aufbau:** APC-USV -- USB (später RS-232) -- Raspberry Pi/apcupsd -- TCP 3551 -- Home Assistant. | + | Später ist serielles RS-232-Modbus vorgesehen |
| ===== 1. Raspberry Pi und USV vorbereiten ===== | ===== 1. Raspberry Pi und USV vorbereiten ===== | ||
| - | - Raspberry Pi OS Lite passend zum Pi installieren, | + | - Raspberry Pi OS Lite installieren, |
| - | - USV per USB an den Pi anschließen. An der USV unter **Advanced / Configuration** die Option **Modbus | + | - USV zunächst |
| - | - Pakete | + | - Software |
| <code bash> | <code bash> | ||
| sudo apt update | sudo apt update | ||
| sudo apt install -y apcupsd cron | sudo apt install -y apcupsd cron | ||
| + | |||
| + | |||
| </ | </ | ||
| Zeile 20: | Zeile 22: | ||
| <code bash> | <code bash> | ||
| sudo nano / | sudo nano / | ||
| + | |||
| + | |||
| </ | </ | ||
| - | Diese Einträge | + | Folgende Werte setzen; keine doppelten aktiven |
| - | < | + | < |
| 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 | ||
| + | |||
| </ | </ | ||
| - | **Warum:** '' | + | **Begründung:** '' |
| - | Bei älteren | + | Bei älteren Installationen ggf. '' |
| + | < | ||
| + | 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 ' | + | apcaccess status | grep -E ' |
| + | |||
| </ | </ | ||
| - | Der angezeigte | + | '' |
| - | ===== 3. Home Assistant | + | ===== 3. In Home Assistant |
| - | **Einstellungen | + | **Einstellungen |
| - | Optional: Ein Leistungssensor lässt sich aus '' | + | Die HA-Integration fragt standardmäßig |
| - | ===== 4. Dienst bei Prozessfehler automatisch | + | ===== 4. Dienst bei Prozessabsturz |
| <code bash> | <code bash> | ||
| sudo systemctl edit apcupsd | sudo systemctl edit apcupsd | ||
| + | |||
| + | |||
| </ | </ | ||
| + | < | ||
| - | <code ini> | ||
| [Service] | [Service] | ||
| Restart=on-failure | Restart=on-failure | ||
| RestartSec=10s | RestartSec=10s | ||
| + | |||
| </ | </ | ||
| Zeile 74: | Zeile 85: | ||
| sudo systemctl daemon-reload | sudo systemctl daemon-reload | ||
| sudo systemctl restart apcupsd | sudo systemctl restart apcupsd | ||
| + | |||
| + | |||
| </ | </ | ||
| - | **Grenze: | + | **Grenze: |
| - | ===== 5. USB-Modbus-Freeze: automatischer Watchdog | + | ===== 5. USB-Modbus-Freeze |
| - | **Beobachteter Fehler: | + | **Beobachteter Fehler: |
| - | **Nicht die Netzspannung vergleichen!** '' | + | Der Watchdog läuft |
| + | |||
| + | Skript erstellen: | ||
| + | |||
| + | <code bash> | ||
| + | sudo nano / | ||
| + | |||
| + | |||
| + | </ | ||
| - | Skript mit **korrekter Bash-Startzeile** anlegen (den gesamten Block ausführen): | + | Den folgenden Inhalt |
| <code bash> | <code bash> | ||
| - | sudo tee / | ||
| # | # | ||
| set -u | set -u | ||
| Zeile 96: | Zeile 116: | ||
| MODE=" | MODE=" | ||
| - | if [[ -n " | + | case " |
| - | echo " | + | |
| - | | + | |
| - | fi | + | esac |
| exec 9>/ | exec 9>/ | ||
| - | if [[ " | + | if [ " |
| - | flock -w 5 9 || { echo " | + | flock -w 5 9 || { echo " |
| 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=""; | reason=""; | ||
| report=$(timeout 10s / | report=$(timeout 10s / | ||
| - | date_text=$(printf ' | + | date_text=$(printf ' |
| - | ups_status=$(printf ' | + | ups_status=$(printf ' |
| - | | + | |
| - | | + | |
| - | fi | + | *" |
| - | if [[ " | + | |
| - | | + | |
| - | | + | if [ -z " |
| - | if [[ -z " | + | reason=" |
| - | reason=" | + | |
| fi | fi | ||
| + | |||
| stamp=$(date -d " | stamp=$(date -d " | ||
| - | | + | |
| - | | + | "" |
| - | | + | |
| - | | + | |
| - | age=$((now | + | |
| - | if ((age < -60)); then | + | if [ "$age" -lt -60 ]; then |
| - | health=" | + | health=" |
| - | | + | |
| - | if ((age > MAX_AGE)); then | + | reason=" |
| - | reason=" | + | else |
| + | health=" | ||
| fi | fi | ||
| - | health=" | ||
| } | } | ||
| probe | probe | ||
| - | if [[ " | + | if [ " |
| case " | case " | ||
| - | ok) echo "OK: DATE ist ${age}s alt, STATUS=$ups_status"; | + | ok) echo "OK: DATE ${age}s alt, STATUS=$ups_status"; |
| - | protected) echo " | + | protected) echo " |
| - | clock) | + | clock) echo " |
| - | *) | + | *) echo " |
| esac | esac | ||
| fi | fi | ||
| Zeile 155: | Zeile 174: | ||
| last=0 | last=0 | ||
| - | if [[ -s " | + | if [ -s " |
| read -r last < " | read -r last < " | ||
| - | | + | |
| fi | fi | ||
| now=$(date +%s) | now=$(date +%s) | ||
| - | ((now - last >= COOLDOWN)) || exit 0 | + | if [ "$((now - last))" -lt " |
| printf ' | printf ' | ||
| - | logger -p daemon.warning -t apcupsd-watchdog | + | logger -p daemon.warning -t apcupsd-watchdog " |
| - | | + | |
| 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 " |
| - | | + | |
| exit 1 | exit 1 | ||
| fi | fi | ||
| + | |||
| sleep 35 | sleep 35 | ||
| probe | probe | ||
| - | if [[ " | + | if [ " |
| - | logger -t apcupsd-watchdog | + | logger -t apcupsd-watchdog " |
| - | | + | |
| else | else | ||
| - | logger -p daemon.err -t apcupsd-watchdog | + | logger -p daemon.err -t apcupsd-watchdog "Noch keine aktuellen Daten: $reason" |
| - | | + | |
| exit 1 | exit 1 | ||
| fi | fi | ||
| - | SCRIPT | ||
| - | sudo chmod 750 / | ||
| - | sudo bash -n / | ||
| - | sudo / | ||
| - | </ | ||
| - | **Wichtig: | ||
| - | Cronjob als **root** eintragen: | + | </ |
| + | |||
| + | **Wichtig:** Die erste Zeile der Skriptdatei muss ''# | ||
| <code bash> | <code bash> | ||
| + | sudo chmod 750 / | ||
| + | sudo bash -n / | ||
| + | sudo / | ||
| sudo crontab -e | sudo crontab -e | ||
| + | |||
| + | |||
| </ | </ | ||
| + | Dort **nur diesen einen** | ||
| < | < | ||
| + | |||
| * * * * * / | * * * * * / | ||
| + | |||
| </ | </ | ||
| - | **Keine zweite/ | + | Alte Watchdogs deaktivieren. Kontrolle: |
| <code bash> | <code bash> | ||
| - | systemctl is-active cron | ||
| sudo crontab -l | sudo crontab -l | ||
| - | sudo / | + | 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 | ||
| + | |||
| + | |||
| </ | </ | ||
| - | **Praxisnachweis | + | **Praxisnachweis:** Am 06.11.2026 |
| - | ===== 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, | + | ---- |
| - | Benötigt werden: | + | ===== Umstieg auf serielles Modbus |
| - | * APC-Originalkabel **AP940-0625A** | + | |
| - | * 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/ | + | Bei der SMT1500I sind USB-Modbus-Freezes dokumentiert. |
| - | Beim späteren Umbau USB-USV-Kabel entfernen, APC-Seriellkabel | + | Benötigt werden das passende **APC-Kabel AP940-0625A** |
| + | |||
| + | Pinout: [[https:// | ||
| + | |||
| + | Nach dem Umstecken serielle Schnittstelle | ||
| <code bash> | <code bash> | ||
| ls -l / | ls -l / | ||
| + | |||
| + | |||
| </ | </ | ||
| - | In ''/ | + | Beispiel: |
| + | |||
| + | <code bash> | ||
| + | DEVICE / | ||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | In ''/ | ||
| + | < | ||
| - | <code ini> | ||
| UPSCABLE smart | UPSCABLE smart | ||
| UPSTYPE modbus | UPSTYPE modbus | ||
| DEVICE / | DEVICE / | ||
| + | |||
| </ | </ | ||
| Zeile 236: | Zeile 270: | ||
| sudo systemctl restart apcupsd | sudo systemctl restart apcupsd | ||
| apcaccess status | grep -E ' | apcaccess status | grep -E ' | ||
| + | |||
| + | |||
| </ | </ | ||
| - | '' | + | **Port 3551, Home-Assistant-Integration und Watchdog bleiben |
| - | ===== 7. Schnelle | + | |
| + | ---- | ||
| + | |||
| + | |||
| + | ===== 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 " |
| + | |||
| </ | </ | ||
| - | * '' | + | * '' |
| - | * '' | + | * '' |
| - | * '' | + | * Im Test waren Pi-Unterspannung ('' |
| - | * Ein USB-Reset **zeitgleich mit apcupsd-Neustart** ist allein kein Beweis für einen Hardwaredefekt. | + | |
| - | ===== Quellen | + | ===== 7. Zusätzliche Netzwerk-Clients anbinden (Master/Slave-Betrieb) |
| - | * [[https:// | + | Wenn an der APC Smart-UPS 1500 mehrere Server oder Systeme |
| - | | + | |
| - | | + | |
| - | * [[https:// | + | |
| + | Die Installation von '' | ||
| + | ==== Schritt 1: Konfiguration auf dem Client-System anpassen ==== | ||
| - | ===== Bilder ===== | + | 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> | ||
| + | # 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: | ||
| + | |||
| + | < | ||
| + | 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 ===== | ||
| - | {{ : | + | {{ : |
| - | {{: | + | {{: |
| - | {{: | + | {{: |