HomeMatic Raspberry Pi Tutorial

HomeMatic – Eine externe USV an einer RaspberryMatic betreiben

RaspberryMatic USV

Einplatinencomputer quittieren das Entfernen der Stromversorgung bei laufendem Betrieb oftmals mit einem Crash, der ein erneutes Aufsetzen des Systems erforderlich macht, insbesondere, wenn bei Wegfall der Stromversorgung gerade auf die Speicherkarte zugegriffen wurde.

Es ist daher sinnvoll, auch bei einem RaspberryMatic-System eine unabhängige Stromversorgung (USV) einzusetzen.

Nach – wenig zufriedenstellenden – Versuchen mit einem Strompi und einer längeren – sehr gut funktionierenden – Einsatzdauer einer S.USV bin ich vor einiger Zeit auf eine externe USV umgestiegen, die mittels der in RaspberryMatic bereits integrierten Network UPS Tools (NUT)-Unterstützung über einen USB Anschluss angebunden ist.

Der wesentliche Grund für den Umstieg war, dass ich neben der RaspberryMatic auch den Router mit versorgen wollte, um während eines Stomausfalls weiterhin Zugriff von außen zu haben und über das Festnetz telefonieren zu können.

Ich habe mich für eine FSP Fortron USV-Anlage EP 650 SP, 650VA entschieden, weil diese den hier benötigten Daten entspricht und erfolgreich im Zusammenwirken mit der RaspberryMatic getestet wurde.

Einrichten des NUT-Servers auf der RaspberryMatic

Hierzu wird eine Anleitung von ELV zur Verfügung gestellt, die ich hier nicht wiederholen möchte. Ergänzend kann aber noch erwähnt werden, dass in den Einstellungen der Software WinNUTClient, folgendes einzutragen ist, damit die Verbindung zum NUT Server funktioniert…

RaspberryMatic USV

Einlesen von Daten der USV in Systemvariable

Die EP 650 SP stellt verschiedene Daten zur Verfügung, die nach dem Einloggen auf die RaspberryMatic mittels Putty und Eingabe des Befehls…

upsc ep650@localhost

…gelistet werden (die Angaben können für andere NUT-fähige USV-Anlagen abweichen)…

# upsc ep650@localhost
battery.charge: 100
battery.voltage: 13.70
battery.voltage.high: 13.00
battery.voltage.low: 10.40
battery.voltage.nominal: 12.0
device.type: ups
driver.name: blazer_usb
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.synchronous: no
driver.version: 2.35.16.20180708-20-g6b5bf56
driver.version.internal: 0.12
input.current.nominal: 2.0
input.frequency: 50.1
input.frequency.nominal: 50
input.voltage: 234.9
input.voltage.fault: 237.0
input.voltage.nominal: 230
output.voltage: 237.0
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.load: 2
ups.productid: 5161
ups.status: OL
ups.type: offline / line interactive
ups.vendorid: 0665

Hiervon habe ich mir folgende Werte ausgesucht, und für diese jeweils eine Systemvariable wie folgt angelegt:

USV ParameterSystemvariableTypminmaxEinheitAnmerkung
battery.chargeUPS.CapBatterieZahl0100%Ladezustand Akku
battery.voltageUPS.VoltBatterieZahl020VSpannung des Akkus
input.voltageUPS.VoltEingangZahl0250VEingangsspannung der USV
output.voltageUPS.VoltAusgangZahl0250VAusgangsspannung der USV
ups.loadUPS.LastZahl0100%Last
ups.statusUPS.SourceZeichenkette---Spannungsquelle:
OB = USV
OL = Netz

Mit folgendem, per Zeitmodul oder CUxD-Timer ca. minütlich aufgerufenen Skript wird der Wert in die jeweilige Systemvariablen geschrieben…

RaspberryMatic USV
var vb = dom.GetObject("UPS.VoltBatterie");
string stdout;
string stderr;
system.Exec("upsc ep650@localhost battery.voltage", &stdout, &stderr);
vb.State(stdout);

Wer SystemExec nicht mag und den CUxD verwendet, kann das alternativ wie folgt erledigen lassen…

var vb = dom.GetObject("UPS.VoltBatterie");
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("upsc ep650@localhost battery.voltage");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
vb.State(dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State());

…und hier ein CUxD-Skript für alle genannten Werte…

var cb = dom.GetObject("UPS.CapBatterie");
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("upsc ep650@localhost battery.charge");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
cb.State(dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State());

var la = dom.GetObject("UPS.Last");
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("upsc ep650@localhost ups.load");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
la.State(dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State());

var us = dom.GetObject("UPS.Source");
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("upsc ep650@localhost ups.status");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
us.State(dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State());

var va = dom.GetObject("UPS.VoltAusgang");
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("upsc ep650@localhost output.voltage");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
va.State(dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State());

var vb = dom.GetObject("UPS.VoltBatterie");
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("upsc ep650@localhost battery.voltage");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
vb.State(dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State());

var ve = dom.GetObject("UPS.VoltEingang");
dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("upsc ep650@localhost input.voltage");
dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
ve.State(dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State());

Netzbetrieb:

RaspberryMatic USV

USV-Betrieb:

RaspberryMatic USV

Integration der Daten in aio NEO

Um eine Übersicht der USV-Parameter im aio NEO Frontend zu erhalten, wurden diese wie folgt integriert…

Netzbetrieb:

RaspberryMatic USV

USV-Betrieb:

RaspberryMatic USV

Dabei wurde dem Ladestand des Akkus „UPS.CapBatterie“ diese Stausregel hinterlegt…

RaspberryMatic USV

Für die Betriebsart der USV (Netz/USV) wurde der Wert „UPS.VoltEingang“ mit dieser Stausregel verwendet…

RaspberryMatic USV

…, da die Eingangsspannung der EP 650 SP im USV-Betrieb ca. 10 V beträgt…

RaspberryMatic USV

Man kann alternativ auch den Wert „UPS.Source“ benutzen.

Nachricht per Pushover verschicken

Da mit jedem Wechsel von Netz- in USV-Betrieb und vice versa die „Alarmzone 1“ der RaspberryMatic aktiviert wird…

RaspberryMatic USV
RaspberryMatic USV

…, lasse ich mir mit folgendem Programm…

RaspberryMatic USV

…über dieses Skript…

string tmpN;
string tmpO = system.Date("%d.%m.%Y, %T");
tmpN = "%C3%84nderung bei der Stromversorgung seit (" # tmpO # ")!!";
string tmpP;
string tmpQ = "";
foreach(tmpP, tmpN.Split(" ")) {
tmpQ = tmpQ # "+" # tmpP;
}
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State("extra/curl -s -d token=TOKEN -d user=USER -d message='"#tmpQ#"' -d priority=2 -d retry=30 -d  expire=3600 -d sound=persistent  http://api.pushover.net/1/messages.json");

eine Pushover-Nachricht senden…

RaspberryMatic USV

Bitte beachten...

SMART WOHNEN in Stern's Haus ist ein rein privates Projekt. Support kann ich daher nur im Rahmen meiner begrenzten Freizeit leisten, hierfür bitte ich um Verständnis. Meine Hinweise, Anleitungen, Schaltungen und Software werden so angeboten, „wie sie sind“. Die Verwendung erfolgt auf eigenes Risiko, ich übernehme hierfür keinerlei Gewährleistung bzw. Haftung! Für die Einhaltung der einschlägigen technischen Vorschriften ist jeder Anwender selbst verantwortlich!
Creative Commons Lizenzvertrag
Copyright © Jens-Peter Stern | SMART WOHNEN in Stern's Haus | smart-wohnen.org
  1. Hallo, versuche dies super Anleitung umzusetzen. Alle Eingaben werden akzeptiert.
    Leider bekomme ich bei:
    upsc ep650@localhost
    # Error: Connection failure: Connection refused
    diese Medung.

    was mache ich falsch ?
    MfG
    KHK

    • Hallo KHK,
      ich verstehe dich so, dass du die Fehlermeldung bekommst, wenn du dich über Putty an der RaspberryMatic anmeldest.
      Hast du dich als root angemeldet und in der Firewall der CCU die IP des Gerätes, von dem aus du zugreifst, freigegeben?
      Hast du Zugriff auf andere Befehle der RaspberryMatic über Putty?
      Grüße Jens

      • Peter Arens

        Hallo Jens,
        auf Grund des entspannten Umgangs hier erlaube ich mir die persönliche Anrede.
        Ich hoffe das ist so ok.
        Im Grunde habe ich das gleiche Problem wie KHK. Leider gibt es noch keine Rückmeldung zu
        Deiner Antwort.
        Ich kann mich in Putty einloggen und auch in den Verzeichnissen wechseln. Da ich ein neues
        Verzeichnis anlegen konnte, gehe ich davon aus, dass meine Berechtigungen ausreichend sind.
        Gestern habe ich die aktuelle RaspMatic-Version (3.47.18.20190918) eingespielt. Anschließend wollte ich dann endlich die USV verbinden. Mit meinem Laptop habe ich die USV, ein-schließlich USB-Kabel, erfolgreich getestet. Die Einstellungen habe ich anhand der ELV-Anleitung vorgenommen und dann den Rasp neu gestartet. Die Alarmmeldung sieht etwas anders aus als in der Anleitung, aber ich denke das liegt an der RaspMatic-Version.
        Leider kann ich hier keinen Screenshot einfügen:
        Alarmname : ep650@localhost.Alarm
        Alarmmeldung : NOCOMM
        Damit scheitern leider auch die Scripte zum Auslesen der Werte.
        Hast Du eine Idee was hier nicht korrekt sein könnte?
        Vielen Dank schon einmal im Voraus
        Peter (Anfänger)

  2. Peter Arens

    Hallo Jens,
    kaum macht man(n), in diesem Falle ich, alles richtig und schon klappt es.
    Nicht nur mit dem Nachbarn sondern auch mit der USV.
    In der usp.conf hatte ich eine Tippfehler {ep650] statt [ep650]. Nach Korrektur läuft auch das Script hervorragend.
    Vielen Dank für die ausführliche Anleitung.
    Gruß
    Peter

  3. Hallo Jens,
    ich möchte dieses Projekt mit der FSP PPF4800114 Fortron EP850 850VA/480W umsetzen (deine vorgeschlagene Variante ist aktuell nicht lieferbar) und damit meine Raspberrymatic (ELV-Charly) und mein Modem/Router (ConnextBox) damit versorgen.
    Wie lange (geschätzt) würden die beiden Geräte in etwa bei einem Stromausfall „durchhalten“?
    Deine Meinung wäre mir wichtig, bevor ich diese USV bestelle!
    Vielen Dank im Voraus
    LG
    Wolfgang

    • Hallo Wolfgang,

      leider kann ich dir da keine wirklich verlässliche Aussage liefern, da das Ganze sehr von der individuellen Last deiner Geräte abhängt und anscheinend auch der individuell eingebaute Typ/Hersteller des USV-Akkus eine Rolle spielt.

      Zum Vergleich kann ich aber aus Erfahrung berichten, dass meine EP-650 mit einer RaspberryMatic mit dem neuen Funkmodul und einer Fritzbox 7590 mit einem USB-Stick und einer externen Festplatte (als Last wird bei der EP-650 insgesamt 2 % angezeigt) schon einen Stromausfall von 35 Minuten problemlos überstanden hat. Die EP-850 sollte das bei deiner Konfiguration also mindestens auch schaffen. Diese Einschätzung ist natürlich ohne Gewähr 😉 .

      Einen längeren Stromausfall hatte ich bisher nicht und habe ihn auch noch nicht simuliert.

      Ich bin mir übrigens nicht ganz sicher, ob der EP-850 vom NUT-Server des RaspberryMatic unterstützt wird. Gelistet sind nur die beiden Modelle EP-650 und EP-1000. Vielleicht fragst du vor einer Bestellung zur Sicherheit mal im RaspberryMatic Forum nach.

      Liebe Grüße Jens

  4. Tobias Möller

    Hallo,
    ich versuche Deine Ableitung für eine APC Back-UPS BX1400UI zu verwenden.
    wenn ich mich mit WinSCP auf meiner Raspberrymatic einwähle und den Befehl upsc apcbx1400ui@localhost ausführe, erhalte ich die nachfolgenden Ausgaben. Soweit so gut.

    battery.charge: 100
    battery.charge.low: 10
    battery.charge.warning: 50
    battery.date: 2001/09/25
    battery.mfr.date: 2019/10/30
    battery.runtime: 6332
    battery.runtime.low: 120
    battery.type: PbAc
    battery.voltage: 27.1
    battery.voltage.nominal: 24.0
    device.mfr: American Power Conversion
    device.model: Back-UPS XS 1400U
    device.serial: 4B1944P12313
    device.type: ups
    driver.name: usbhid-ups
    driver.parameter.pollfreq: 30
    driver.parameter.pollinterval: 2
    driver.parameter.port: auto
    driver.parameter.synchronous: no
    driver.version: 3.49.17.20200131-35-gcc1bc83d
    driver.version.data: APC HID 0.96
    driver.version.internal: 0.41
    input.sensitivity: medium
    input.transfer.high: 280
    input.transfer.low: 155
    input.voltage: 228.0
    input.voltage.nominal: 230
    ups.beeper.status: enabled
    ups.delay.shutdown: 20
    ups.firmware: 926.T2 .I
    ups.firmware.aux: T2
    ups.load: 5
    ups.mfr: American Power Conversion
    ups.mfr.date: 2019/10/30
    ups.model: Back-UPS XS 1400U
    ups.productid: 0002
    ups.realpower.nominal: 700
    ups.serial: 4B1944P12313
    ups.status: OL
    ups.test.result: No test initiated
    ups.timer.reboot: 0
    ups.timer.shutdown: -1
    ups.vendorid: 051d

    Ich habe versucht das Script auf meine USV anzuwenden. Es werden keine Daten abgerufen

    var bc = dom.GetObject("USV Batterieladezustand");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost battery.charge");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    bc.State(dom.GetObject("CUxD. CUX2800001:16.CMD_RETS").State());

    var ul = dom.GetObject("USV Last");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost ups.load");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    ul.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var bcl = dom.GetObject("USV Batterieladezustand leer");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost battery.charge.low");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    bcl.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var bcw = dom.GetObject("USV Batterieladezustand Warnung");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost battery.charge.warning");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    bcw.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var brt = dom.GetObject("USV Akkulaufzeit");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost battery.runtime");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    brt.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var brtl = dom.GetObject("USV Akkulaufzeit leere Batterie");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost battery.runtime.low");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    brtl.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var bv = dom.GetObject("USV Akkuspannung");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost battery.voltage");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    bv.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var bvn = dom.GetObject("USV Akkuspannung nominal");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost battery.voltage.nominal");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    bvn.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var bt = dom.GetObject("USV Akkutyp");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost battery.type");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    bt.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var um = dom.GetObject("USV Modell");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost ups.load");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    um.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var inputsensitivity = dom.GetObject("USV Eingangsempfindlichkeit");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost input.sensitivity");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    inputsensitivity.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var iv = dom.GetObject("USV Eingangsspannung");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost input.voltage");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    iv.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var ivn = dom.GetObject("USV Eingangsspannung nominal");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost input.voltage.nominal");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    ivn.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var rp = dom.GetObject("USV Wirkleistung");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost ups.realpower.nominal");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    rp.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var status = dom.GetObject("USV Status");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost ups.status");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    status.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var mfr = dom.GetObject("USV Hersteller");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost ups.mfr");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    mfr.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    var mfrdate = dom.GetObject("USV Herstellungsdatum");
    dom.GetObject("CUxD.CUX2800001:16.CMD_SETS").State("upsc apcbx1400ui@localhost ups.mfr.date");
    dom.GetObject("CUxD.CUX2800001:16.CMD_QUERY_RET").State(1);
    mfrdate.State(dom.GetObject("CUxD.CUX2800001:16.CMD_RETS").State());

    Was muss ggf. angepasst werden, damit es auch für mein USV funktioniert.

  5. Hallo Tobias,

    ich meine mich zu erinnern, damals mehrfach gelesen zu haben, dass das mit APC USVen – warum auch immer – nicht so einfach umzusetzen ist, weswegen ich mich gegen eine APC und für die FSP entschieden hatte.

    Aber ich schaue mit das gerne mal in Ruhe an und melde mich bei dir per Mail, kann aber etwas dauern.

    Liebe Grüße
    Jens

    • Hallo Tobias,

      wie bereits per Mail übermittelt, vermute ich, dass es sich bei deinem speziellen APC-Problem um ein NUT-Treiber bzw. herstellerspezifisches Phänomen handelt, da werden dir andere APC-Nutzer und NUT-Experten wohl eher helfen können als ich.
      Ich würde zunächst mal die Hinweise der anderen Nutzer auf deine themengleiche Frage im Homematic-Forum ausprobieren.

      Viel Erfolg und liebe Grüße Jens

  6. Sascha

    Hallo,

    super Anleitung. Jedoch 2 Sachen habe ich anderst gemacht.
    Beim ups.status schneide ich auf die ersten 2 Buchstaben, damit das \r nicht mit drin ist.
    Sonst kann man auf die Variable nicht sauber triggern.

    var ve = dom.GetObject("ups.Source");
    dom.GetObject("CUxD.CUX2801001:2.CMD_SETS").State("upsc myups@localhost ups.status");
    dom.GetObject("CUxD.CUX2801001:2.CMD_QUERY_RET").State(1);
    ve.State(dom.GetObject("CUxD.CUX2801001:2.CMD_RETS").State().Substr(0,2););

    Und habe die runtime abgefragt, damit ich weis wie lange ich noch Power habe.
    Da es in Sekunden ist /60, damit ich es als Minuten habe.

    var ve = dom.GetObject("ups.Laufzeit");
    dom.GetObject("CUxD.CUX2801001:2.CMD_SETS").State("upsc myups@localhost battery.runtime");
    dom.GetObject("CUxD.CUX2801001:2.CMD_QUERY_RET").State(1);
    var resp = dom.GetObject("CUxD.CUX2801001:2.CMD_RETS").State();
    ve.State(resp.ToInteger()/60);

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.