(Zurück zum Inhaltsverzeichnis)
Einleitung:
Die PIUSV+ ist eine USV die von der Fa. Ritter Elektronik hergestellt wird.
Hier geht es darum, die elektrischen Werte der PIUSV+ mittels Diagramme grafisch darzustellen.
Es lassen sich 5 Werte aus der PIUSV+ auslesen: U_Batt, U_Rasp, I_Rasp, U_USB, und U_Ext.
Die Diagramme werden alle 5 min automatisch aktualisiert.
Voraussetzung ist, das SNMP, MRTG und die PIUSV+ bereits eingerichtet sind.
Der Client ist hier mit einer PIUSV+ ausgerüstet, die mit einem Python-Script ausgelesen wird.
Die Daten werden dann mittels SNMP über Bash-Scripte abgefragt.
Ein anderer Raspberry (Server) ruft die Daten mittels MRTG ab und liefert sie über einen Webserver (Apache) aus.
Das Auslesen der PIUSV+
Zum Einsatz kommt eine modifizierte Python-Software aus dem Raspberry-Forum:<br />
Raspberry-Forum: (Beitrag 4) und einer Modifikation (Beitrag 14)
Hier bereits zusammengefügt:
#!/usr/bin/python
import smbus
import sys
import time
import os
class PiUSV(object):
def __init__(self):
# Adresse
self.address = 0x18
# StatusByte
self.data_0 = 1
# Version
self.data_1 = 12
# Parameter
self.data_2 = 10
# Variablen
self.par = [0,0,0,0,0,0,0,0,0,0]
self.par_2 = [0,0,0,0,0]
self.par_3 = [0,0,0,0,0]
self.par_name = ["U_Batt (V)", "I_Rasp (A)", "U_Rasp (V)", "U_USB (V)", "U_ext (V)"]
self.piusv = smbus.SMBus(1)
# Firmware Version auslesen und in eine lesbare Zeile umwandeln
def version(self):
self.version = ""
self.piusv.write_byte(self.address, 0x01)
for i in range (self.data_1):
try:
self.version = self.version + chr(self.piusv.read_byte(self.address))
except IOError, err:
print "Fehler beim Lesen von Device 0x%02X" % self.address
return self.version
# Statusbyte auslesen
def get_status(self):
self.piusv.write_byte(self.address, 0x00)
try:
self.status = (self.piusv.read_byte(self.address))
except IOError, err:
print "Fehler beim Lesen von Device 0x%02X" % self.address
return self.status
# Die Parameter der PIUSV+ byteweise auslesen
def get_parameter(self):
self.piusv.write_byte(self.address, 0x02)
for i in range (self.data_2):
try:
self.par[i] = self.piusv.read_byte(self.address)
except IOError, err:
print "Fehler beim Lesen von Device 0x%02X" % self.address
return self.par
# Umwandlung der Parameter in lesbare Werte(V,A)
def word2float(self):
for i in range (self.data_2/2):
self.par_2[i] = (256*float(self.par[i*2])+(float(self.par[1+(i*2)])))/1000
return self.par_2
# Umwandlung der Parameter in lesbare Werte(mV,.A)
def word2int(self):
for i in range (self.data_2/2):
self.par_2[i] = int(256*float(self.par[i*2])+(float(self.par[1+(i*2)])))
return self.par_2
# Werte mit Namen versehen
def line(self):
self.log = ""
for i in range (self.data_2/2):
self.log = self.log + " |"+"% 2.3f"% (self.par_2[i])+" "+self.par_name[i]
self.log = ("%02s"% self.get_status())+self.log
return self.log
# Statusbyte auswerten, Mehrfachnennung moeglich
def status2sent(self):
stati = "StatusByte Bedeutung \n"
status = self.get_status()
if status&0x01==0x01:
stati = stati + " 0000.0001 Spannungsversorgung von Micro-USB-Buchse" + "\n"
if status&0x02==0x02:
stati = stati + " 0000.0010 Spannungsversorgung von Uext" + "\n"
if status&0x04==0x04:
stati = stati + " 0000.0100 (Zu?) niedrige Batteriespannung" + "\n"
if status&0x08==0x08:
stati = stati + " 0000.1000 Akku wird geladen" + "\n"
if status&0x10==0x10:
stati = stati + " 0001.0000 Akku ist voll" + "\n"
if status&0x20==0x20:
stati = stati + " 0010.0000 Taster S1 betaetigt" + "\n"
return (stati)
def U_Batt(self):
self.get_parameter()
self.word2int()
return self.par_2[0]
def I_Rasp(self):
self.get_parameter()
self.word2int()
return self.par_2[1]
def U_Rasp(self):
self.get_parameter()
self.word2int()
return self.par_2[2]
def U_USB(self):
self.get_parameter()
self.word2int()
return self.par_2[3]
def U_ext(self):
self.get_parameter()
self.word2int()
return self.par_2[4]
def main():
optionen = "Moegliche Optionen:\n version \n status \n all \n log \n U_Batt \n I_Rasp \n U_Rasp \n U_USB \n U_ext \n snmp \n SNMP"
# Script mit diversen Optionen abarbeiten
# Ohne Option wird eine Hilfe-Seite ausgegeben
try:
option = sys.argv[1]
except:
print optionen
sys.exit(1)
piusv = PiUSV()
# Firmwareversion
if option == "version":
print piusv.version()
# Status und Bedeutung
elif option == "status":
print piusv.status2sent()
# Logdatei schreiben
elif option == "log":
piusv.get_parameter()
piusv.word2float()
log = time.strftime("%Y%m%d-%H%M%S")+" |"+ piusv.line(piusv.par_2, piusv.data_2) + "\n"
with open('/var/log/PIUSV.log', 'a') as fh:
fh.write(log)
# SNMP-Abfrage
elif option == "snmp":
piusv.get_parameter()
piusv.word2int()
op = open ('/tmp/U_Batt.snmp', 'w')
op.write ('{0:0.0f}\n'.format (piusv.par_2[0]))
op.close ()
op = open ('/tmp/I_Rasp.snmp', 'w')
op.write ('{0:0.0f}\n'.format (piusv.par_2[1]))
op.close ()
op = open ('/tmp/U_Rasp.snmp', 'w')
op.write ('{0:0.0f}\n'.format (piusv.par_2[2]))
op.close ()
op = open ('/tmp/U_USB.snmp', 'w')
op.write ('{0:0.0f}\n'.format (piusv.par_2[3]))
op.close ()
op = open ('/tmp/U_ext.snmp', 'w')
op.write ('{0:0.0f}\n'.format (piusv.par_2[4]))
op.close ()
elif option == "SNMP":
piusv.get_parameter()
piusv.word2int()
print (piusv.par_2[0])
print (piusv.par_2[1])
print (piusv.par_2[2])
print (piusv.par_2[3])
print (piusv.par_2[4])
# Kommandozeilenausgabe komplett
elif option == "all":
piusv.get_parameter()
piusv.word2float()
all = piusv.line()
print all + "\n" + piusv.status2sent()
# Nur eine Zahl zur Weiterverarbeitung
elif option == "U_Batt":
print piusv.U_Batt()
elif option == "I_Rasp":
print piusv.I_Rasp()
elif option == "U_Rasp":
print piusv.U_Rasp()
elif option == "U_USB":
print piusv.U_USB()
elif option == "U_ext":
print piusv.U_ext()
# Falsche Option, Hilfeseite ausgeben
else:
print optionen
if __name__ == '__main__':
main()
#EOF
Alles anzeigen
Die Modifikation ist der Abschnitt zwischen "# SNMP-Abfrage" und "# Kommandozeilenausgabe komplett"
Sie bewirkt, das die PIUSV+ nur einmal über den I2C-Bus ausgelesen wird, aber alle benötigten Werte liefert.
Nun noch ausführbar machen und das Script mit:
aufrufen. Danach sollten sich 5 Dateien in /tmp befinden:
Die Angaben in diesen Files sind in mV bzw. in mA.
Der Aufruf "pisuv.py SNMP" gibt diese Werte auch im Terminal aus.
Der Cronjob
Dieses Script sollte alle 5 min. aufgerufen werden:
Mit diesem Inhalt:
Die Bash-Scripte für SNMP
Die Abfrage vom MRTG-Server greift auf die in /tmp abgespeicherten Dateien mittels dieser Bash-Scripte zu:
Der Vorteil von dieser Vorgehensweise:
a) Die Werte werden immer zu einem bestimmten Zeitpunkt ermittelt.
b) Wann die Werte abgefragt werden ist ziemlich egal.
Nachteil: Wenn die Abfrage der PIUSV+ schiefgeht, ändern sich die Werte nicht mehr.
#!/bin/bash
tmp=`cat /tmp/U_Batt.snmp`
if test $tmp -gt 5000
then
tmp=5000
fi
echo .1.3.6.1.2.1.25.1.20
echo gauge
echo $tmp
exit 0
#!/bin/bash
tmp=`cat /tmp/U_Rasp.snmp`
if test $tmp -gt 6000
then
tmp=6000
fi
echo .1.3.6.1.2.1.25.1.21
echo gauge
echo $tmp
exit 0
!/bin/bash
tmp=`cat /tmp/I_Rasp.snmp`
if test $tmp -gt 1500
then
tmp=1500
fi
echo .1.3.6.1.2.1.25.1.22
echo gauge
echo $tmp
exit 0
#!/bin/bash
tmp=`cat /tmp/U_USB.snmp`
if test $tmp -gt 6000
then
tmp=6000
fi
echo .1.3.6.1.2.1.25.1.23
echo gauge
echo $tmp
exit 0
!/bin/bash
tmp=`cat /tmp/U_ext.snmp`
if test $tmp -gt 26000
then
tmp=26000
fi
echo .1.3.6.1.2.1.25.1.24
echo gauge
echo $tmp
exit 0
Es sind hier mehrere "If Then" Abfragen zu sehen, sie begrenzen die $tmp Variable mit einen plausiblen Maximalwert.
Hier ist es schon vorgekommen, das der Raspberry sich 56A genehmigt hatte und damit das Diagramm von MRTG wegen der dynamischen Anpassung unleserlich gemacht hatte.
Ich vermute mal, das das Python-Script die PIUSV+ abgefragt hatte, während der Prozessor der PIUSV+ neue Daten in die Register abgelegt hat.
SNMP-Erweiterung
In der:
wird der pass-Abschnitt um folgende Einträge ergänzt:
pass .1.3.6.1.2.1.25.1.20 /bin/sh /usr/local/bin/snmp-piusv_U_Batt.sh
pass .1.3.6.1.2.1.25.1.21 /bin/sh /usr/local/bin/snmp-piusv_U_Rasp.sh
pass .1.3.6.1.2.1.25.1.22 /bin/sh /usr/local/bin/snmp-piusv_I_Rasp.sh
pass .1.3.6.1.2.1.25.1.23 /bin/sh /usr/local/bin/snmp-piusv_U_USB.sh
pass .1.3.6.1.2.1.25.1.24 /bin/sh /usr/local/bin/snmp-piusv_U_ext.sh
Die OID-Liste befinden sich in einem anderen Beitrag, aber Achtung, es handelt sich zum Teil um selbst definierte OIDs, nicht um offizielle.
Die Software des Servers (MRTG-Erweiterung)
Folgende Ergänzung fehlt noch zur in der /etc/mrtg/raspiXX_mrtg.cfg (raspiXX durch eigenen Namen oder IP-Adresse ersetzen).
#---------------------------------------------------------------
# Raspberry Pi - PIUSV U_rasp
#---------------------------------------------------------------
Target[raspi_PIUSV_-_U_rasp]: .1.3.6.1.2.1.25.1.21&.1.3.6.1.2.1.25.1.7.0:public@raspiXX
Title[raspi_PIUSV_-_U_rasp]: raspiXX - PIUSV+ U rasp
PageTop[raspi_PIUSV_-_U_rasp]: <H1>raspiXX - PIUSV+ U rasp</H1>
Include: raspi_PIUSV_-_U_rasp.inc
#---------------------------------------------------------------
# Raspberry Pi - PIUSV+ I_rasp
#---------------------------------------------------------------
Target[raspi_PIUSV_-_I_rasp]: .1.3.6.1.2.1.25.1.22&.1.3.6.1.2.1.25.1.7.0:public@raspiXX
Title[raspi_PIUSV_-_I_rasp]: raspiXX - PIUSV+ I rasp
PageTop[raspi_PIUSV_-_I_rasp]: <H1>raspiXX - PIUSV+ I rasp</H1>
Include: raspi_PIUSV_-_I_rasp.inc
#---------------------------------------------------------------
# Raspberry Pi - PIUSV+ U_USB
#---------------------------------------------------------------
Target[raspi_PIUSV_-_U_USB]: .1.3.6.1.2.1.25.1.23&.1.3.6.1.2.1.25.1.7.0:public@raspiXX
Title[raspi_PIUSV_-_U_USB]: raspiXX - PIUSV+ U_USB
PageTop[raspi_PIUSV_-_U_USB]: <H1>raspiXX - PIUSV+ U_USB</H1>
Include: raspi_PIUSV_-_U_USB.inc
#---------------------------------------------------------------
# Raspberry Pi - PIUSV+ U_ext
#---------------------------------------------------------------
Target[raspi_PIUSV_-_U_ext]: .1.3.6.1.2.1.25.1.24&.1.3.6.1.2.1.25.1.7.0:public@raspiXX
Title[raspi_PIUSV_-_U_ext]: raspiXX - PIUSV+ U_ext
PageTop[raspi_PIUSV_-_U_ext]: <H1>raspiXX - PIUSV+ U_ext</H1>
Include: raspi_PIUSV_-_U_ext.inc
#---------------------------------------------------------------
# Raspberry Pi - PIUSV+ U_batt
#---------------------------------------------------------------
Target[raspi_PIUSV_-_U_batt]: .1.3.6.1.2.1.25.1.20&.1.3.6.1.2.1.25.1.7.0:public@raspiXX
Title[raspi_PIUSV_-_U_batt]: raspiXX - PIUSV+ U_batt
PageTop[raspi_PIUSV_-_U_batt]: <H1>raspiXX - PIUSV+ U_batt</H1>
Include: raspi_PIUSV_-_U_batt.inc
Alles anzeigen
Und nun noch die Include-Dateien
AbsMax[raspi_PIUSV_-_U_rasp]: 6000
MaxBytes1[raspi_PIUSV_-_U_rasp]: 5100
MaxBytes2[raspi_PIUSV_-_U_rasp]: 4900
Options[raspi_PIUSV_-_U_rasp]: gauge, nopercent, unknaszero, noo, pngdate, growright, nobanner
YLegend[raspi_PIUSV_-_U_rasp]: PIUSV+ U rasp (V)
ShortLegend[raspi_PIUSV_-_U_rasp]: V
kMG[raspi_PIUSV_-_U_rasp]: ,
Factor[raspi_PIUSV_-_U_rasp]: 0.001
YTicsFactor[raspi_PIUSV_-_U_rasp]: 0.001
LegendI[raspi_PIUSV_-_U_rasp]: U RASP (V)
LegendO[raspi_PIUSV_-_U_rasp]: U RASP (V)
Legend1[raspi_PIUSV_-_U_rasp]: U RASP (V)
Legend2[raspi_PIUSV_-_U_rasp]: U RASP (V)
Legend3[raspi_PIUSV_-_U_rasp]: Max. U RASP (V)
Legend4[raspi_PIUSV_-_U_rasp]: Max. U RASP (V)
Alles anzeigen
AbsMax[raspi_PIUSV_-_I_rasp]: 2000
MaxBytes1[raspi_PIUSV_-_I_rasp]: 250
MaxBytes2[raspi_PIUSV_-_I_rasp]: 500
Options[raspi_PIUSV_-_I_rasp]: gauge, nopercent, unknaszero, noo, pngdate, growright, nobanner
YLegend[raspi_PIUSV_-_I_rasp]: PIUSV+ I rasp (mA)
ShortLegend[raspi_PIUSV_-_I_rasp]: mA
kMG[raspi_PIUSV_-_I_rasp]: ,
Factor[raspi_PIUSV_-_I_rasp]: 1
YTicsFactor[raspi_PIUSV_-_I_rasp]: 1
LegendI[raspi_PIUSV_-_I_rasp]: I rasp (mA):
LegendO[raspi_PIUSV_-_I_rasp]: I rasp (mA):
Legend1[raspi_PIUSV_-_I_rasp]: I rasp (mA):
Legend2[raspi_PIUSV_-_I_rasp]: I rasp (mA):
Legend3[raspi_PIUSV_-_I_rasp]: Max. I rasp (mA):
Legend4[raspi_PIUSV_-_I_rasp]: Max. I rasp (mA):
Alles anzeigen
AbsMax[raspi_PIUSV_-_U_USB]: 6000
MaxBytes1[raspi_PIUSV_-_U_USB]: 5100
MaxBytes2[raspi_PIUSV_-_U_USB]: 4900
Options[raspi_PIUSV_-_U_USB]: gauge, nopercent, unknaszero, noo, pngdate, growright, nobanner
YLegend[raspi_PIUSV_-_U_USB]: PIUSV+ U USB (V)
ShortLegend[raspi_PIUSV_-_U_USB]: V
kMG[raspi_PIUSV_-_U_USB]: ,
Factor[raspi_PIUSV_-_U_USB]: 0.001
YTicsFactor[raspi_PIUSV_-_U_USB]: 0.001
LegendI[raspi_PIUSV_-_U_USB]: U USB (V)
LegendO[raspi_PIUSV_-_U_USB]: U USB (V)
Legend1[raspi_PIUSV_-_U_USB]: U USB (V)
Legend2[raspi_PIUSV_-_U_USB]: U USB (V)
Legend3[raspi_PIUSV_-_U_USB]: Max. U USB (V)
Legend4[raspi_PIUSV_-_U_USB]: Max. U USB (V)
Alles anzeigen
AbsMax[raspi_PIUSV_-_U_ext]: 30000
MaxBytes1[raspi_PIUSV_-_U_ext]: 26000
MaxBytes2[raspi_PIUSV_-_U_ext]: 5000
Options[raspi_PIUSV_-_U_ext]: gauge, nopercent, unknaszero, noo, pngdate, growright, nobanner
YLegend[raspi_PIUSV_-_U_ext]: PIUSV+ U ext (V)
ShortLegend[raspi_PIUSV_-_U_ext]: V
kMG[raspi_PIUSV_-_U_ext]: ,
Factor[raspi_PIUSV_-_U_ext]: 0.001
YTicsFactor[raspi_PIUSV_-_U_ext]: 0.001
LegendI[raspi_PIUSV_-_U_ext]: U ext (V)
LegendO[raspi_PIUSV_-_U_ext]: U ext (V)
Legend1[raspi_PIUSV_-_U_ext]: U ext (V)
Legend2[raspi_PIUSV_-_U_ext]: U ext (V)
Legend3[raspi_PIUSV_-_U_ext]: Max. U ext (V)
Legend4[raspi_PIUSV_-_U_ext]: Max. U ext (V)
Alles anzeigen
AbsMax[raspi_PIUSV_-_U_batt]: 5000
MaxBytes1[raspi_PIUSV_-_U_batt]: 3000
MaxBytes2[raspi_PIUSV_-_U_batt]: 4200
Options[raspi_PIUSV_-_U_batt]: gauge, nopercent, unknaszero, noo, pngdate, growright, nobanner
YLegend[raspi_PIUSV_-_U_batt]: PIUSV+ U batt (V)
ShortLegend[raspi_PIUSV_-_U_batt]: V
kMG[raspi_PIUSV_-_U_batt]: ,
Factor[raspi_PIUSV_-_U_batt]: 0.001
YTicsFactor[raspi_PIUSV_-_U_batt]: 0.001
LegendI[raspi_PIUSV_-_U_batt]: U batt (V)
LegendO[raspi_PIUSV_-_U_batt]: U batt (V)
Legend1[raspi_PIUSV_-_U_batt]: U batt (V)
Legend2[raspi_PIUSV_-_U_batt]: U batt (V)
Legend3[raspi_PIUSV_-_U_batt]: Max. U batt (V)
Legend4[raspi_PIUSV_-_U_batt]: Max. U batt (V)
Alles anzeigen
Letzte Anweisung:
Und dann ein bißchen (ca. 10min.-15min.) warten...
Edit: Fiptehler und Links eingefügt