USV für den Raspi mit der upsplus - Integration in FHEM

Begonnen von cwagner, 19 Oktober 2023, 17:01:56

Vorheriges Thema - Nächstes Thema

cwagner

Um Datenverlusten und Wiederanlaufproblemen gerade bei unvorhergesehen und kurzzeitigen Stromunterbrechungen vorzubeugen, habe ich die Haussteuerung auf einem PI-3 mit einer USV ausgestattet: Mit gefiel dieses Konzept vor allem auch wegen der flexiblen Akku-Wahl, dem Zugang zu den Daten über I2C samt Beispielcode für automatisiertes Runterfahren und Wiederanlauf sowie die Doku im Git:USPplus Wiki.

Mit zwei Lithium-Rundzellen 18650 mit je 3450 mAh Kapazität hält der PI-3 mitsamt angeschlossener USB-Peripherie (EnOcean-Funk-Stick, 1-Wire, HomeMatic-Funkstick) gerne 4 Stunden und mehr im vollen Galopp durch. Diese USV will ich von FHEM aus zu überwachen. In einem weiteren Schritt soll auch die Parametrisierung dazu kommen.

Der erste Wurf aufsetzend auf diese wertvolle Arbeit im FHEM-Wiki-Beitrag in den Grenzen meiner doch arg eingerosteten Programmierkenntnisse stelle ich hier zur Diskussion. Vielleicht haben ja schon andere sich mit dem Teil beschäftigt oder es gibt Anregungen für weitere Schritte oder mehr Eleganz im Code.

Nächster Schritt soll das Auslesen der INA-Register sein, mit denen ich die Spannungs- und Strom-Messwerte vom PI beschaffe.
Setup:
Mit dem Einbau der USV muss I2C auf dem Raspi aktiviert sein. Das ist im Hersteller-Wiki bestens beschrieben.
In Fhem ist lediglich ein Device zum ,,Lauschen" auf dem Bus notwendig.
define I2C RPII2C 1
attr I2C comment Adresse der UPSPLUS auf I2C #1 ist 0x17
attr I2C room i2c
#   .FhemMetaInternals 1
#   DEF        1
#   DeviceName /dev/i2c-1
#   ERRORCNT   2
#   FVERSION   00_RPII2C.pm:0.236640/2021-02-02
#   NAME       I2C
#   NOTIFYDEV  global
#   NR         317
#   NTFY_ORDER 50-I2C
#   STATE      Ok
#   TYPE       RPII2C
#   eventCount 271
#   ioctl_ph_exists 1
#   READINGS:
#     2023-10-11 17:54:09   state           0
#
setstate I2C Ok


Über ein simples AT werden die bisher auscodierten Adressen ausgelesen und aufbereitet. Das geschieht über eine Routine in der 99_Utils.pm

################################################################################################
#              Routinen für USV 
#   https://wiki.fhem.de/wiki/Unterbrechungsfreie_Spannungsversorgung_%22PIUSV%2B%22_direkt_ansteuern
######################################################################################################

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

my $content;
my $datagramm;
my $u_MCU; my $u_MCU_low; my $u_MCU_high; ##Register 0x01 - 0x02
my $u_PI; my $u_PI_low; my $u_PI_high;    ##0X03 - 0x04
my $u_Bat; my $u_Bat_low; my $u_Bat_high;
my $u_USB_C_low; my $u_USB_C; my $u_USB_C_high;
my $u_USB_micro; my $u_USB_micro_low; my $u_USB_micro_high;
my $u_Bat_Temp; my $u_Bat_Temp_low; my $u_Bat_Temp_high;
my $u_Bat_full; my $u_Bat_full_low; my $u_Bat_full_high;
my $u_Bat_empty; my $u_Bat_empty_low; my $u_Bat_empty_high;
my $u_Bat_protec; my $u_Bat_protec_low; my $u_Bat_protec_high;
my $Bat_remain; my $Bat_remain_low; my $Bat_remain_high;
my $countdown;
my $status;
my $usv_meldung="";

# Werte lesen ab Register 01   anschließend get 42 Byte
fhem("set I2C writeByte 17 01");

$content=fhem("get I2C readblock 17 42",1);
$content=~ m/received : (\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+).(\d+) |/is;
$datagramm=$content;
$u_MCU_low=$1; $u_MCU_high=$2;
$u_PI_low=$3; $u_PI_high=$4;
$u_Bat_low=$5; $u_Bat_high=$6;
$u_USB_C_low=$7; $u_USB_C_high=$8;
$u_USB_micro_low=$9; $u_USB_micro_high=$10;
$u_Bat_Temp_low=$11; $u_Bat_Temp_high=$12;
$u_Bat_full_low=$13; $u_Bat_full_high=$14;
$u_Bat_empty_low=$15; $u_Bat_empty_high=$16;
$u_Bat_protec_low=$17; $u_Bat_protec_high=$18;
$Bat_remain_low=$19; $Bat_remain_high=$20;
$countdown=$24;

$u_MCU=((($u_MCU_high & 0x7F)*256+$u_MCU_low)/1000);
$u_PI=((($u_PI_high & 0x7F)*256+$u_PI_low)/1000);
$u_Bat=((($u_Bat_high & 0x3F)*256+$u_Bat_low)/1000);
$u_USB_C=((($u_USB_C_high & 0x3F)*256+$u_USB_C_low)/1000);
$u_USB_micro=((($u_USB_micro_high & 0x3F)*256+$u_USB_micro_low)/1000);
$u_Bat_Temp=(($u_Bat_Temp_high & 0x3F)*256+$u_Bat_Temp_low);
$u_Bat_full=((($u_Bat_full_high & 0x3F)*256+$u_Bat_full_low)/1000);
$u_Bat_empty=((($u_Bat_empty_high & 0x3F)*256+$u_Bat_empty_low)/1000);
$u_Bat_protec=((($u_Bat_protec_high & 0x3F)*256+$u_Bat_protec_low)/1000);
$Bat_remain=(($Bat_remain_high & 0x3F)*256+$Bat_remain_low);

$u_MCU=$u_MCU." V (2.4... 3.6 V)";
$u_PI=$u_PI." V (0 ... 5.5 V)";
$u_Bat=$u_Bat." V (0 ... 4.5 V)";
$u_USB_C=$u_USB_C." V (0 ... 13.5 V)";
$u_USB_micro=$u_USB_micro." V (0 ... 13.5 V)";
fhem("set USV_Daten $datagramm");
fhem("setReading USV_Daten MCU $u_MCU");
fhem("setReading USV_Daten PI $u_PI");
fhem("setReading USV_Daten Battery $u_Bat");
fhem("setReading USV_Daten USB_C $u_USB_C");
fhem("setReading USV_Daten USB_Micro $u_USB_micro");
fhem("setReading USV_Daten Bat_Temp $u_Bat_Temp");
fhem("setReading USV_Daten Bat_full $u_Bat_full");
fhem("setReading USV_Daten Bat_empty $u_Bat_empty");
fhem("setReading USV_Daten Bat_protec $u_Bat_protec");
fhem("setReading USV_Daten Bat_remain $Bat_remain");
fhem("setReading USV_Daten Countdown $countdown");

}
(Nochmals: Hier ist deutlich zu erkennen, dass ich beim Autoren des Wiki-Eintrages sowie hier Forumbeitrag von maddinthebrain gelernt habe)

Die aufbereiteten Daten werden in Readings eines Dummy gepackt:

define USV_Daten dummy
attr USV_Daten event-on-change-reading Bat_.*
attr USV_Daten room i2c
#   FUUID      652ff96a-f33f-e1df-7c62-1c746145b17b827c
#   NAME       USV_Daten
#   NR         469
#   STATE      received : 219 12 105 19 78 16 217 35 3 0 43 0 117 17 116 14 84 11 87 0 2 0 1 0 1 0 0 113 198 4 0 1 11 5 0 89 34 3 0 14 0 0 | transmission: Ok
#   TYPE       dummy
#   eventCount 1726
#   .attraggr:
#   .attreocr:
#     Bat_.*
#   .attrminint:
#   OLDREADINGS:
#   READINGS:
#     2023-10-19 16:48:54   Bat_Temp        43
#     2023-10-19 16:48:54   Bat_empty       3.7
#     2023-10-19 16:48:54   Bat_full        4.469
#     2023-10-19 16:48:54   Bat_protec      2.9
#     2023-10-19 16:48:54   Bat_remain      87
#     2023-10-19 16:48:54   Battery         4.174 V (0 ... 4.5 V)
#     2023-10-19 16:48:54   Countdown       0
#     2023-10-19 16:48:54   MCU             3.291 V (2.4... 3.6 V)
#     2023-10-19 16:48:54   PI              4.969 V (0 ... 5.5 V)
#     2023-10-19 16:48:54   USB_C           9.177 V (0 ... 13.5 V)
#     2023-10-19 16:48:54   USB_Micro       0.003 V (0 ... 13.5 V)
#     2023-10-19 16:48:54   state           received : 219 12 105 19 78 16 217 35 3 0 43 0 117 17 116 14 84 11 87 0 2 0 1 0 1 0 0 113 198 4 0 1 11 5 0 89 34 3 0 14 0 0 | transmission: Ok
#
setstate USV_Daten received : 219 12 105 19 78 16 217 35 3 0 43 0 117 17 116 14 84 11 87 0 2 0 1 0 1 0 0 113 198 4 0 1 11 5 0 89 34 3 0 14 0 0 | transmission: Ok
setstate USV_Daten 2023-10-19 16:48:54 Bat_Temp 43
setstate USV_Daten 2023-10-19 16:48:54 Bat_empty 3.7
setstate USV_Daten 2023-10-19 16:48:54 Bat_full 4.469
setstate USV_Daten 2023-10-19 16:48:54 Bat_protec 2.9
setstate USV_Daten 2023-10-19 16:48:54 Bat_remain 87
setstate USV_Daten 2023-10-19 16:48:54 Battery 4.174 V (0 ... 4.5 V)
setstate USV_Daten 2023-10-19 16:48:54 Countdown 0
setstate USV_Daten 2023-10-19 16:48:54 MCU 3.291 V (2.4... 3.6 V)
setstate USV_Daten 2023-10-19 16:48:54 PI 4.969 V (0 ... 5.5 V)
setstate USV_Daten 2023-10-19 16:48:54 USB_C 9.177 V (0 ... 13.5 V)
setstate USV_Daten 2023-10-19 16:48:54 USB_Micro 0.003 V (0 ... 13.5 V)
setstate USV_Daten 2023-10-19 16:48:54 state received : 219 12 105 19 78 16 217 35 3 0 43 0 117 17 116 14 84 11 87 0 2 0 1 0 1 0 0 113 198 4 0 1 11 5 0 89 34 3 0 14 0 0 | transmission: Ok


Das ist der Stand noch während des Trainings des Lade-Schaltung, der jetzt eine Woche läuft. Ich freue mich über konstruktive Kritik und Hinweise, vielleicht ist ja jemand schon viel weiter als ich. Das Ergebnis unserer Arbeit werde ich dann im Abschnitt USV des WIKIs dokumentieren.

Christian
PI 2B+/3B+ Raspbian 12, Perl 5.36.0, FHEM 6.3: 295 Module in ConfigDB: Steuerung Heizkessel, FBH, Solarthermie, kontr. Lüftung mit WRG. Smarthome u.a. HMCUL, 1-Wire (FT232RL ; DS2480B), EnOcean (TCM EPS3), MQTT2. DOIF, PID20, Threshold, OWX; Micropelt IRTV, Volkszähler, SolarForecast; MariaDB