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:
- APC Smart-UPS (z. B. SC420)
- RS232-Anschluss oder serielle Erweiterung
- Waveshare RS232/485/422 to PoE ETH* (bezahlter Link)
- Patchkabel* (bezahlter Link) & PoE-Switch* (bezahlter Link)
- Selbstgebautes RS232-Kabel (Steckerbelegung siehe unten)
- Ein Proxmox LXC (hier:
zebra-node
)
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.

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!