Unterbrechungsfreie Spannungsversorgung "PIUSV+" direkt ansteuern: Unterschied zwischen den Versionen

Aus FHEMWiki
 
(58 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
[[Datei:Piusvplus.jpg|mini|400px|rechts|Unterbrechungsfreie Spannungsversorgung "PIUSV+<br>Foto: RITTER Elektronik GmbH]]


== Idee ==
== Idee ==


Hier wird der direkten Zugriff auf die Unterbrechungsfreien Spannungsversorgung PIUSV+, die früher von CW2 und aktuell über Reichelt vertrieben wird, beschrieben.   
Hier wird der direkte FHEM-Zugriff auf die unterbrechungsfreien Spannungsversorgung PIUSV+, die früher von CW2 und aktuell von Ritter Elektronik hergestellt wird, beschrieben. Die PIUSV+ wird über Reichelt Elektronik vertrieben (https://www.reichelt.de/raspberry-pi-usv-rpi-usv-p169883.html).<br>    
Direkter Zugriff bedeutet, dass die Kommunikation vollständig über die I2C-Schnittstelle erfolgt, wie es die Originalsoftware "piusmon" auch bewerkstelligt.
Der direkte Zugriff bedeutet, dass die Kommunikation vollständig über die I2C-Schnittstelle erfolgt, wie es die Originalsoftware "piupsmon" auch bewerkstelligt.


Der direkte Zugriff hat folgenden Vorteile:
Der direkte Zugriff hat folgenden Vorteile:
* Die Installation der Originalsoftware "piusmon", die für den Betrieb der USV vorgesehen ist, wird nicht mehr nötig (ggf. sollte diese deinstalliert werden). Die Originalsoftware, die nicht mehr vom ursprünglichen Hersteller supportet wird, arbeitet nicht immer zuverlässig.
* Die Originalsoftware "piupsmon", die für den Betrieb der USV vorgesehen ist, wird nicht bzw. nicht mehr benötig (ggf. sollte diese mit <code>sudo apt-get --purge piupsmon</code> deinstalliert werden). Die Originalsoftware, die vom ursprünglichen Hersteller CW2 stammt und nicht mehr supportet wird, arbeitet nicht immer zuverlässig.
* Es muss kein zusätzliches Skript in die piusmon-Software zum sauberen Runterfahren des FHEM-Servers eingebunden werden.
* Es muss kein zusätzliches Skript in die piupsmon-Software zum sauberen Runterfahren des FHEM-Servers eingebunden werden.
* Die direkte Ansteuerung bietet mehr Möglichkeiten (auch für eigene Erweiterungen). So wird beispielsweise wie hier beschrieben der Shutdown nicht nach einer festen Zeit ausgelöst, sondern abhängig von einer bestimmten Akkusspannung.
* Die direkte Ansteuerung bietet mehr Möglichkeiten (auch für eigene Erweiterungen). So wird beispielsweise nach einem Spannungsausfall wie hier beschrieben der Shutdown nicht nach einer festen Zeit ausgelöst, sondern beim Unterschreiten einer bestimmten Akkusspannung.
* Es können diverse Werte wie Versorgungspannung, Pi-Spannung, Pi-Strom, Pi-Leistung und Akku-Status ausgelesen bzw. angezeigt werden.
* Es können diverse Werte wie Versorgungspannung, Pi-Spannung, Pi-Strom, Pi-Leistung, Akku-Spannung und Akku-Status ausgelesen bzw. angezeigt werden.
* Durch die eigene Kontrolle über die USV wird die Sicherheit erhöht, wodurch ein Crash des Betriebssystems auf dem Systemspeicher (SD-Karte oder externer USB-Speicher) effektiv verhindert wird.
* Durch die eigene Kontrolle über die USV wird die Sicherheit erhöht, wodurch ein Crash des Betriebssystems auf dem Systemspeicher (SD-Karte oder externer USB-Speicher) noch effektiv verhindert werden kann.
* Der Raspberry Pi kann vom FHEM-Server aus komplett (spannungslos) abgeschaltet werden.


== Umsetzung ==
== Umsetzung ==


I2C-Daten werden über ein I2C Interface Modul wie beispielsweise RPII2C, FRM oder NetzerI2C gesendet. Daher muss eines dieser Module zuvor definiert werden (siehe Commandref).
Die hier vorgestellte Lösung ist als Beispiel zu verstehen. Je nach Anforderung können/müssen entsprechend Anpassungen durchgefüht werden.
Hier wurde der Zugriff auf die I2C-Schnittstelle über das Modul RPII2C realisiert.


In der Datei "99_myUtils.pm" müssen die folgende Funktionen kopiert werden:
Da die Kommunikation über die I2C-Schnittstelle des Raspberry Pi's erfolgt, muss das I2C-Interface Modul „RPII2C“ zuvor definiert werden (siehe Commandref).


<syntaxhighlight lang=pl>
In die Datei "99_myUtils.pm" müssen die folgende Funktionen kopiert werden:
 
<syntaxhighlight lang="pl">
sub USV_Werte_auslesen($$)
sub USV_Werte_auslesen($$)
{
{
Zeile 25: Zeile 29:


my $content;
my $content;
my $datagramm;
my $u_akku_high;
my $u_akku_high;
my $u_akku_low;
my $u_akku_low;
Zeile 38: Zeile 43:
my $i_pi;
my $i_pi;
my $p_pi;
my $p_pi;
my $usv_meldung
my $s_pi;
my $status;
my $usv_meldung="";


# TWI_CMD_GETVOLTAGE
# Werte lesen
fhem("set PIi2c_1 writeByte 18 02");
fhem("set PIi2c_1 writeByte 18 02");


$content=fhem("get PIi2c_1 readblock 18 10",1);
$content=fhem("get PIi2c_1 readblock 18 10",1);
$content=~ m/received : (\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+) |/is;
$content=~ m/received : (\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+) |/is;
$datagramm=$content;
$u_akku_high=$1;
$u_akku_high=$1;
$u_akku_low=$2;
$u_akku_low=$2;
Zeile 65: Zeile 73:
{
{
$USV_Netzteilspannung_Error_Counter++;
$USV_Netzteilspannung_Error_Counter++;
if ($USV_Netzteilspannung_Error_Counter==2) { $usv-meldung="FHEM: USV-Netzspannung fehlt!"; }
if ($USV_Netzteilspannung_Error_Counter==2) { $usv_meldung="FHEM: USV-Netzspannung fehlt!"; }
fhem("set USV_Netzteilspannung_Error_Counter $USV_Netzteilspannung_Error_Counter");
fhem("set USV_Netzteilspannung_Error_Counter $USV_Netzteilspannung_Error_Counter");
}
}
Zeile 77: Zeile 85:
{
{
$USV_Akkuspannung_Error_Counter++;
$USV_Akkuspannung_Error_Counter++;
if ($USV_Akkuspannung_Error_Counter==2) { $usv-meldung="FHEM: USV-Akkuspannung zu niedrig!"; }
if ($USV_Akkuspannung_Error_Counter==2) { $usv_meldung="FHEM: USV-Akkuspannung zu niedrig!"; }
fhem("set USV_Akkuspannung_Error_Counter $USV_Akkuspannung_Error_Counter");
fhem("set USV_Akkuspannung_Error_Counter $USV_Akkuspannung_Error_Counter");
}
}
Zeile 88: Zeile 96:
if (($u_netz<0.1) && ($u_akku>3.0) && ($u_akku<3.5)) # shutdown-Bedingung ermitteln
if (($u_netz<0.1) && ($u_akku>3.0) && ($u_akku<3.5)) # shutdown-Bedingung ermitteln
{
{
$usv-meldung="Raspberry Pi und USV wurden wegen Stromausfall abgeschaltet!";
$usv_meldung="Raspberry Pi und USV wurden wegen Stromausfall abgeschaltet!";
USV_abschalten();
USV_abschalten();
rasp_shutdown();
rasp_shutdown();
Zeile 98: Zeile 106:
$i_pi=$i_pi." A";
$i_pi=$i_pi." A";
$p_pi=$p_pi." W";
$p_pi=$p_pi." W";
fhem("set USV_Datagramm $content");
fhem("set USV_Datagramm $datagramm");
fhem("set USV_Akkuspannung $u_akku");
fhem("set USV_Akkuspannung $u_akku");
fhem("set USV_Netzteilspannung $u_netz");
fhem("set USV_Netzteilspannung $u_netz");
Zeile 104: Zeile 112:
fhem("set USV_Strom $i_pi");
fhem("set USV_Strom $i_pi");
fhem("set USV_Leistung $p_pi");
fhem("set USV_Leistung $p_pi");
fhem("set USV_Meldung $usv_meldung")
if ($usv_meldung ne "") {
fhem("set USV_Meldung $usv_meldung");
}
}
 
fhem("set PIi2c_1 writeByte 18 00");
$content=fhem("get PIi2c_1 read 18",1);
$content=~ m/received : (\d+) |/is;
$s_pi = $1;
if ($s_pi != 0xFF)
{
$status=$s_pi & 0x3F;
fhem("set USV_Statusregister $status");
}
}
}
}
Zeile 111: Zeile 131:
sub USV_abschalten()
sub USV_abschalten()
{
{
# TWI_CMD_SHUTDOWN
# USV-Abschaltung auslösen (Abschaltung erfolgt hier nach 21 Sekunden)
fhem("set PIi2c_1 writeByte 18 10");
fhem("set PIi2c_1 writeByte 18 10");
fhem("set PIi2c_1 writeByte 18 15");
fhem("set PIi2c_1 writeByte 18 15");
Zeile 123: Zeile 143:


Anmerkung:
Anmerkung:
Um den Raspberry wie hier direkt vom FHEM aus über den Befehl "sudo shutdown -h now" auszuschalten, muss in die Datei "/etc/sudoers.d/010_pi-nopasswd" hinter dem Eintrag
Um den Raspberry wie hier direkt vom FHEM aus über den Befehl "sudo shutdown -h now" auszuschalten, muss in die Datei <code>/etc/sudoers.d/010_pi-nopasswd</code> hinter dem Eintrag


<pre>
<pre>
Zeile 141: Zeile 161:
#i2C-Schnittstelle einrichten
#i2C-Schnittstelle einrichten
define PIi2c_1 RPII2C 1
define PIi2c_1 RPII2C 1
# PI USV+ Datagramm
define USV_Datagramm dummy


# PI USV+ Netzteilspannung
# PI USV+ Netzteilspannung
define USV_Netzteilspannung dummy
define USV_Netzteilspannung dummy
attr USV_Netzteilspannung fp_Raspberry 25,460,2,USV Netzteilspannung:
define USV_Netzteilspannung_Error_Counter dummy
define USV_Netzteilspannung_Error_Counter dummy
define USV_Netzteilspannung_Error_Counter_Init notify global:INITIALIZED set USV_Netzteilspannung_Error_Counter 0
define USV_Netzteilspannung_Error_Counter_Init notify global:INITIALIZED set USV_Netzteilspannung_Error_Counter 0
Zeile 150: Zeile 172:
# PI USV+ Akkuspannung
# PI USV+ Akkuspannung
define USV_Akkuspannung dummy
define USV_Akkuspannung dummy
attr USV_Akkuspannung fp_Raspberry 75,460,2,USV Akkuspannung:
define USV_Akkuspannung_Error_Counter dummy
define USV_Akkuspannung_Error_Counter dummy
define USV_Akkuspannung_Error_Counter_Init notify global:INITIALIZED set USV_Akkuspannung_Error_Counter 0
define USV_Akkuspannung_Error_Counter_Init notify global:INITIALIZED set USV_Akkuspannung_Error_Counter 0
Zeile 156: Zeile 177:
# PI USV+ Spannung
# PI USV+ Spannung
define USV_Spannung dummy
define USV_Spannung dummy
attr USV_Spannung fp_Raspberry 125,460,2,USV PI-Spannung:


# PI USV+ Strom
# PI USV+ Strom
define USV_Strom dummy
define USV_Strom dummy
attr USV_Strom fp_Raspberry 175,460,2,USV PI-Strom:


# PI USV+ Leistung
# PI USV+ Leistung
define USV_Leistung dummy
define USV_Leistung dummy
attr USV_Leistung fp_Raspberry 225,460,2,USV PI-Leistung:


# PI USV+ Leistung
# PI USV+ Statusregister
define USV_Statusregister dummy
 
# PI USV+ Meldung
define USV_Meldung dummy
define USV_Meldung dummy
attr USV_Leistung fp_Raspberry 225,460,2,USV Meldung:


# PI USV+ werte aktualisieren und ggf. Abschalten auslösen
# PI USV+ Werte aktualisieren und ggf. Abschaltung auslösen
define USV_Werte_auslesen at +*00:00:05 { USV_Werte_auslesen(Value("USV_Netzteilspannung_Error_Counter"),Value("USV_Akkuspannung_Error_Counter")) }
define USV_Werte_auslesen at +*00:00:05 { USV_Werte_auslesen(Value("USV_Netzteilspannung_Error_Counter"),Value("USV_Akkuspannung_Error_Counter")) }
</pre>
</pre>
Anmerkung:<br>
Der Wert des Statusregister wird hier als Dezimalzahl dargestellt und muss zur weiteren Verarbeitung ggf. noch binär ausdekodiert werden.


== Registerbeschreibung (für eigene Erweiterungen) ==
== Registerbeschreibung (für eigene Erweiterungen) ==


Die PIUSV+ kann direkt über die I2C Schnittstelle über die Adresse "0x18" angesprochen und angesteuert werden.  
Die PIUSV+ kann per I2C-Schnittstelle über die Adresse "0x18" angesprochen werden.<br>
Achtung: lt. Foren wurde bei älteren PIUSV+ teilweise auch die Adresse "0X30" verwendet.
Achtung: lt. Foren wurde bei älteren PIUSV+ teilweise auch die Adresse "0x30" verwendet.<br>
Der nächste Wert, der hinter der Adresse an die piusv+ gesendet werden muss, ist als Befehl zu verstehen.
Das nächste Byte, das hinter der Adresse an die PIUSV+ gesendet werden muss, ist als Befehl zu verstehen.


Folgende Befehle sind möglich:
Folgende Befehle sind möglich:
Zeile 185: Zeile 208:
"Status lesen"              0x00  danach muss 1 Byte (Statusregister) gelesen werden
"Status lesen"              0x00  danach muss 1 Byte (Statusregister) gelesen werden
                                   Die einzelnen Bits des Statusregister haben folgende Bedeutung:
                                   Die einzelnen Bits des Statusregister haben folgende Bedeutung:
                                     Bit0:  Primäre Spannungsversorgung aktiv
                                     Bit0:  Primäre Spannungsversorgung (5V) aktiv
                                     Bit1:  Sekundäre Spannungsversorgung aktiv
                                     Bit1:  Sekundäre Spannungsversorgung (5V...25V) aktiv
                                     Bit2:  Akkuspannung zu niedrig
                                     Bit2:  Akkuspannung zu niedrig
                                     Bit3:  Akku wird geladen
                                     Bit3:  Akku wird geladen
Zeile 192: Zeile 215:
                                     Bit5:  Taster S1 an der USV betätigt
                                     Bit5:  Taster S1 an der USV betätigt


"Firmare Version lesen"    0x01  danach müssen 12 Zeichen gelesen werden
"Firmare Version lesen"    0x01  danach müssen 12 Bytes (Zeichen) gelesen werden


"Werte lesen"              0x02  danach müssen 10 Byte gelesen werden
"Werte lesen"              0x02  danach müssen 10 Byte gelesen werden
Zeile 214: Zeile 237:
                                               dass ein zuvor ausgelöster Shutdown des Raspberry Pi abgeschlossen ist.
                                               dass ein zuvor ausgelöster Shutdown des Raspberry Pi abgeschlossen ist.
</pre>
</pre>
== PIUSV+ und Raspberry Pi 4 ==
Obwohl die PIUSV+ nur 2 A liefern kann, ist der Betrieb mit einem Raspberry Pi 4 durchaus möglich, sofern auf dem Raspberry hauptsächlich der FHEM-Server und keine sonstige hochperformante Software installiert ist.
Bei einer FHEM-Beispielinstallation (Raspian Buster, FHEM 6.0) mit USB-SSD-Platte (32GB), 3x USB/232-Konverter, einem Homematic-Sender/Empfängermodul (HM-MOD-PRI-PCB) und Nutzung der 1-Wire-, I²C- und 2xGPIO-Schnittstellen am 40pol. Pfostenverbinder beträgt der 5V-Versorgungsstrom ca. 0,9A (entspricht 4,5W).


== Ausblick ==
== Ausblick ==
Es wäre sinvoll, das hier beschriebene in einem eigenen Modul z.B. "52_I2C_PIUPS_PLUS.pm" unterzubringen, um den Zugriff noch eleganter zu realisieren.
Es wäre sinnvoll, das hier Beschriebene in einem eigenen Modul z.B. "52_I2C_PIUPS_PLUS.pm" unterzubringen, um den Zugriff noch eleganter und vollständiger zu realisieren.<br>
 
<br>
[[Kategorie:Examples]]
[[Kategorie:Examples]]
[[Kategorie:Code Snippets]]
[[Kategorie:Code Snippets]]
[[Kategorie:USV]]
[[Kategorie:Raspberry Pi]]

Aktuelle Version vom 31. Mai 2020, 15:38 Uhr

Unterbrechungsfreie Spannungsversorgung "PIUSV+
Foto: RITTER Elektronik GmbH

Idee

Hier wird der direkte FHEM-Zugriff auf die unterbrechungsfreien Spannungsversorgung PIUSV+, die früher von CW2 und aktuell von Ritter Elektronik hergestellt wird, beschrieben. Die PIUSV+ wird über Reichelt Elektronik vertrieben (https://www.reichelt.de/raspberry-pi-usv-rpi-usv-p169883.html).
Der direkte Zugriff bedeutet, dass die Kommunikation vollständig über die I2C-Schnittstelle erfolgt, wie es die Originalsoftware "piupsmon" auch bewerkstelligt.

Der direkte Zugriff hat folgenden Vorteile:

  • Die Originalsoftware "piupsmon", die für den Betrieb der USV vorgesehen ist, wird nicht bzw. nicht mehr benötig (ggf. sollte diese mit sudo apt-get --purge piupsmon deinstalliert werden). Die Originalsoftware, die vom ursprünglichen Hersteller CW2 stammt und nicht mehr supportet wird, arbeitet nicht immer zuverlässig.
  • Es muss kein zusätzliches Skript in die piupsmon-Software zum sauberen Runterfahren des FHEM-Servers eingebunden werden.
  • Die direkte Ansteuerung bietet mehr Möglichkeiten (auch für eigene Erweiterungen). So wird beispielsweise nach einem Spannungsausfall wie hier beschrieben der Shutdown nicht nach einer festen Zeit ausgelöst, sondern beim Unterschreiten einer bestimmten Akkusspannung.
  • Es können diverse Werte wie Versorgungspannung, Pi-Spannung, Pi-Strom, Pi-Leistung, Akku-Spannung und Akku-Status ausgelesen bzw. angezeigt werden.
  • Durch die eigene Kontrolle über die USV wird die Sicherheit erhöht, wodurch ein Crash des Betriebssystems auf dem Systemspeicher (SD-Karte oder externer USB-Speicher) noch effektiv verhindert werden kann.
  • Der Raspberry Pi kann vom FHEM-Server aus komplett (spannungslos) abgeschaltet werden.

Umsetzung

Die hier vorgestellte Lösung ist als Beispiel zu verstehen. Je nach Anforderung können/müssen entsprechend Anpassungen durchgefüht werden.

Da die Kommunikation über die I2C-Schnittstelle des Raspberry Pi's erfolgt, muss das I2C-Interface Modul „RPII2C“ zuvor definiert werden (siehe Commandref).

In die Datei "99_myUtils.pm" müssen die folgende Funktionen kopiert werden:

sub USV_Werte_auslesen($$)
{
my ($USV_Netzteilspannung_Error_Counter, $USV_Akkuspannung_Error_Counter) = @_;

my $content;
my $datagramm;
my $u_akku_high;
my $u_akku_low;
my $u_akku;
my $u_netz_high;
my $u_netz_low;
my $u_netz;
my $u_pi_high;
my $u_pi_low;
my $u_pi;
my $i_pi_high;
my $i_pi_low;
my $i_pi;
my $p_pi;
my $s_pi;
my $status;
my $usv_meldung="";

# Werte lesen
fhem("set PIi2c_1 writeByte 18 02");

$content=fhem("get PIi2c_1 readblock 18 10",1);
$content=~ m/received : (\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+) |/is;
$datagramm=$content;
$u_akku_high=$1;
$u_akku_low=$2;
$u_netz_high=$7;
$u_netz_low=$8;
$u_pi_high=$5;
$u_pi_low=$6;
$i_pi_high=$3;
$i_pi_low=$4;

$u_akku=((($u_akku_high & 0x7F)*256+$u_akku_low)/1000);
$u_netz=((($u_netz_high & 0x7F)*256+$u_netz_low)/1000);
$u_pi=((($u_pi_high & 0x3F)*256+$u_pi_low)/1000);
$i_pi=((($i_pi_high & 0x3F)*256+$i_pi_low)/1000);
$p_pi=floor($u_pi*$i_pi*1000+0.5)/1000;

if ($u_akku<5 && $u_akku>2.5 && $u_netz<6 && $u_pi<6 && $i_pi<3 && not($u_pi==0 && $i_pi>0) && not($i_pi==0 && $u_pi>0))
	{
	if ($u_netz<0.1)
		{
		$USV_Netzteilspannung_Error_Counter++;
		if ($USV_Netzteilspannung_Error_Counter==2) { $usv_meldung="FHEM: USV-Netzspannung fehlt!"; }
		fhem("set USV_Netzteilspannung_Error_Counter $USV_Netzteilspannung_Error_Counter");
		}
	else
		{
		$USV_Netzteilspannung_Error_Counter=0;
		fhem("set USV_Netzteilspannung_Error_Counter $USV_Netzteilspannung_Error_Counter");
		}
	
	if ($u_akku<3.0)
		{
		$USV_Akkuspannung_Error_Counter++;
		if ($USV_Akkuspannung_Error_Counter==2) { $usv_meldung="FHEM: USV-Akkuspannung zu niedrig!"; }
		fhem("set USV_Akkuspannung_Error_Counter $USV_Akkuspannung_Error_Counter");
		}
	else
		{
		$USV_Akkuspannung_Error_Counter=0;
		fhem("set USV_Akkuspannung_Error_Counter $USV_Akkuspannung_Error_Counter");
		}
	
	if (($u_netz<0.1) && ($u_akku>3.0) && ($u_akku<3.5)) # shutdown-Bedingung ermitteln
		{
		$usv_meldung="Raspberry Pi und USV wurden wegen Stromausfall abgeschaltet!";
		USV_abschalten();
		rasp_shutdown();
		}
		
	$u_akku=$u_akku." V (3.0 ... 4.2 V)";
	$u_netz=$u_netz." V (5V)";
	$u_pi=$u_pi." V (5V)";
	$i_pi=$i_pi." A";
	$p_pi=$p_pi." W";
	fhem("set USV_Datagramm $datagramm");
	fhem("set USV_Akkuspannung $u_akku");
	fhem("set USV_Netzteilspannung $u_netz");
	fhem("set USV_Spannung $u_pi");
	fhem("set USV_Strom $i_pi");
	fhem("set USV_Leistung $p_pi");
	if ($usv_meldung ne "") {
		fhem("set USV_Meldung $usv_meldung");
		}
	}

fhem("set PIi2c_1 writeByte 18 00");
$content=fhem("get PIi2c_1 read 18",1);
$content=~ m/received : (\d+) |/is;
$s_pi = $1;
if ($s_pi != 0xFF)
	{
	$status=$s_pi & 0x3F;
	fhem("set USV_Statusregister $status");
	}
}


sub USV_abschalten()
{
# USV-Abschaltung auslösen (Abschaltung erfolgt hier nach 21 Sekunden)
fhem("set PIi2c_1 writeByte 18 10");
fhem("set PIi2c_1 writeByte 18 15");
}

sub rasp_shutdown()
{
my @processes = `sudo shutdown -h now`;
}

Anmerkung: Um den Raspberry wie hier direkt vom FHEM aus über den Befehl "sudo shutdown -h now" auszuschalten, muss in die Datei /etc/sudoers.d/010_pi-nopasswd hinter dem Eintrag

pi ALL=(ALL) NOPASSWD: ALL

folgendes ergänzt werden

pi ALL=(ALL) NOPASSWD: ALL
fhem ALL=(ALL) NOPASSWD: /sbin/reboot, /sbin/shutdown, /sbin/halt

In der Datei "fhem.cfg" kann dann die Anzeige der USV-Parameter und die Abschaltung der USV beispielsweise folgendermaßen realisiert werden:

#i2C-Schnittstelle einrichten
define PIi2c_1 RPII2C 1

# PI USV+ Datagramm
define USV_Datagramm dummy

# PI USV+ Netzteilspannung
define USV_Netzteilspannung dummy
define USV_Netzteilspannung_Error_Counter dummy
define USV_Netzteilspannung_Error_Counter_Init notify global:INITIALIZED set USV_Netzteilspannung_Error_Counter 0

# PI USV+ Akkuspannung
define USV_Akkuspannung dummy
define USV_Akkuspannung_Error_Counter dummy
define USV_Akkuspannung_Error_Counter_Init notify global:INITIALIZED set USV_Akkuspannung_Error_Counter 0

# PI USV+ Spannung
define USV_Spannung dummy

# PI USV+ Strom
define USV_Strom dummy

# PI USV+ Leistung
define USV_Leistung dummy

# PI USV+ Statusregister
define USV_Statusregister dummy

# PI USV+ Meldung
define USV_Meldung dummy

# PI USV+ Werte aktualisieren und ggf. Abschaltung auslösen
define USV_Werte_auslesen at +*00:00:05 { USV_Werte_auslesen(Value("USV_Netzteilspannung_Error_Counter"),Value("USV_Akkuspannung_Error_Counter")) }

Anmerkung:
Der Wert des Statusregister wird hier als Dezimalzahl dargestellt und muss zur weiteren Verarbeitung ggf. noch binär ausdekodiert werden.

Registerbeschreibung (für eigene Erweiterungen)

Die PIUSV+ kann per I2C-Schnittstelle über die Adresse "0x18" angesprochen werden.
Achtung: lt. Foren wurde bei älteren PIUSV+ teilweise auch die Adresse "0x30" verwendet.
Das nächste Byte, das hinter der Adresse an die PIUSV+ gesendet werden muss, ist als Befehl zu verstehen.

Folgende Befehle sind möglich:

"Status lesen"              0x00   danach muss 1 Byte (Statusregister) gelesen werden
                                   Die einzelnen Bits des Statusregister haben folgende Bedeutung:
                                     Bit0:  Primäre Spannungsversorgung (5V) aktiv
                                     Bit1:  Sekundäre Spannungsversorgung (5V...25V) aktiv
                                     Bit2:  Akkuspannung zu niedrig
                                     Bit3:  Akku wird geladen
                                     Bit4:  Akku ist voll
                                     Bit5:  Taster S1 an der USV betätigt

"Firmare Version lesen"     0x01   danach müssen 12 Bytes (Zeichen) gelesen werden

"Werte lesen"               0x02   danach müssen 10 Byte gelesen werden
                                   Die zu lesenden Bytes haben folgende Reihenfolge und Bedeutung:
	                             HIGH_BYTE (UINT) Akku-Spannung in mV	
	                             LOW_BYTE  (UINT) Akku-Spannung in mV
                                     HIGH_BYTE (UINT) Strom in mA, der zum Raspberry Pi fließt
                                     LOW_BYTE  (UINT) Strom in mA, der zum Raspberry Pi fließt
                                     HIGH_BYTE (UINT) 5V-Versorgungsspannung in mV (USV-Spannungversorung für Raspberry Pi)
                                     LOW_BYTE  (UINT) 5V-Versorgungsspannung in mV (USV-Spannungversorung für Raspberry Pi)
                                     HIGH_BYTE (UINT) Spannung in mV am Micro USB-Stecker der USV (primäre Spannungsversorgung)
                                     LOW_BYTE  (UINT) Spannung in mV am Micro USB-Stecker der USV (primäre Spannungsversorgung)
                                     HIGH_BYTE (UINT) Spannung in mV externe Spannungsversorgung (sekundäre Spannungsversorgung)
                                     LOW_BYTE  (UINT) Spannung in mV externe Spannungsversorgung (sekundäre Spannungsversorgung)

"USV-Abschaltung auslösen"  0x10   danach muss 1 Byte geschrieben werden
                                   Folgende Werte sind möglich:
                                     0x00 (default Wert): USV wird nach einer Zeit von 30sec. abgeschaltet
                                     0x01...0xFF:	  USV wird nach einer Zeit von 1...255 Sekunden abgeschaltet
                                   Anmerkung: Durch das zeitverzögerte Auschalten der USV kann sichergestellt werden,
                                              dass ein zuvor ausgelöster Shutdown des Raspberry Pi abgeschlossen ist.

PIUSV+ und Raspberry Pi 4

Obwohl die PIUSV+ nur 2 A liefern kann, ist der Betrieb mit einem Raspberry Pi 4 durchaus möglich, sofern auf dem Raspberry hauptsächlich der FHEM-Server und keine sonstige hochperformante Software installiert ist. Bei einer FHEM-Beispielinstallation (Raspian Buster, FHEM 6.0) mit USB-SSD-Platte (32GB), 3x USB/232-Konverter, einem Homematic-Sender/Empfängermodul (HM-MOD-PRI-PCB) und Nutzung der 1-Wire-, I²C- und 2xGPIO-Schnittstellen am 40pol. Pfostenverbinder beträgt der 5V-Versorgungsstrom ca. 0,9A (entspricht 4,5W).

Ausblick

Es wäre sinnvoll, das hier Beschriebene in einem eigenen Modul z.B. "52_I2C_PIUPS_PLUS.pm" unterzubringen, um den Zugriff noch eleganter und vollständiger zu realisieren.