Temperaturmessung mit Linux

Wir planen eine (Raum) Temperaturmessung für einen Linux-Server.

Wir haben nun mit dem OpenCelsius-Projekt begonnen, die Komponenten dazu findet Ihr weiter unten auf dieser Seite. Der USB-Adapter wird beim Einstecken vom Kernel erkannt, es wird das Modul ds4960.ko geladen. Leider arbeitet es nicht mit dem Programm digitemp zusammen, wir mussten das Modul "Blacklisten", d.h. für Debian anlegen einer Datei digitemp.conf im Verzeichnis "/etc/modprobe.d/" mit folgendem Inhalt: "blacklist ds2490". Für Fedora braucht es einen Eintrag in /etc/modprobe.d/blacklist.conf "blacklist ds2490".

Danach kann man mit digitemp schon erste Versuchsmessungen starten. Das Programm legt mit "digitemp -i -a" im aktuellen Verzeichnis eine Konfigurationsdatei namens .digitemprc an, darin wird der Sensor "DS1820" registriert. Ihr findet ihn unter /dev/usb/001 -004, je nach Anschluss. Die Ausgabe der Temperatur kann in Celsius oder Fahrenheit erfolgen, die Standard-Einstellung zeigt beide Einheiten an. Erste Versuche mit Raumtemperatur und einem Schneeball konnten wir erfolgreich durchführen.  Bald gibt es hier eine ausführliche Beschreibung, Bilder und Screenshots. Als nächsten Schritt planen wir eine Anbindung mit RRDtool.

Die Hardware:

1 x COM to One-Wire USB Adapter, mit RJ11-Buchse als Schnittstelle zum One-Wire Bus, Kosten ca. 29.- Euro

1x Temperatursensor Dallas DS 1820 One-Wire, Kosten 1,40 Euro

Die Hardware wird vom aktuellen Linux-Kernel unterstützt, geplant ist ein Einsatz als Temperaturüberwachung in einem Serverraum.

Team: R.Peiler, J-C.Duberga, R.Vögtle, L.Matscholl. Bei Interresse bitte eine E-Mail an info(at)belug.de

Links:

Maxims White-Papers: White-Papers 1-Wire-Bus
Überblick 1-Wire to USB converter: Overview DS9490
Überblick 1-Wire to COM(seriell/RS232): Overview DS9097
Überblick Temp.Sens DS18S20: Overview DS18S20
Überblick Temp.Sens DS18B20: Overview DS18B20
Maxim Vergleich DS18S20/DS18B20: Vergleich S/B

Erweiterung 5.03.2010

Hallo BeLUGer Freunde, habe inzwischen ein wenig weitergemacht. Zuhause, und nicht unter den Augen des Vereins. Trotzdem möchte ich die hier entstandenen Dinge mitteilen, zur Kenntnis bringen und zum Weitermachen animieren. Es ist mir zu wenig und zu klein, um dies auf der offiziellen Homepage kundzutun. Ich habe nun hier auf meinem Rechner zuhause das Digitemp mal eine Weile rund um die Uhr laufen lassen und - auf die Schnelle davon Diagramme gezimmert. Die folgenden Scripts kurz Dokumentiert:

Initialisierung

Zuerst - und nach jedem hinzufügen (und abbauen) eines Messfühlers in den 1W-Bus - muss man das Programm Digitemp mit der Option "-i" aufrufen um die Kette zu initialisieren. Dabei fragt digitemp alle am 1W-Bus hängenden Devices ab und erzeugt eine versteckte Datei im aktuellen Verzeichnis:

Initialsierungs-Datei

TTY USB
READ_TIME 1000
LOG_TYPE 1
LOG_FORMAT "%b %d %H:%M:%S Sensor %s C: %.2C F: %.2F"
CNT_FORMAT "%b %d %H:%M:%S Sensor %s #%n %C"
HUM_FORMAT "%b %d %H:%M:%S Sensor %s C: %.2C F: %.2F H: %h%%"
SENSORS 4
ROM 0 0x10 0x80 0xF1 0x6F 0x01 0x08 0x00 0xAD
ROM 1 0x10 0xE4 0x4D 0x9C 0x01 0x08 0x00 0x25
ROM 2 0x10 0x2C 0x1D 0x70 0x01 0x08 0x00 0xD5
ROM 3 0x28 0xEA 0xC7 0xCE 0x01 0x00 0x00 0x0C

Hierin sind nun die ID's der Messfühler gespeichert. Die Datei wird bei jedem weiterem Aufruf (Start) von digitemp eingelesen und muss im Working-Directory stehen.

Aufruf des Programms

Der Ansatz der folgenden Scripte ist der, Die Temperaturen kontinuierlich zu messen und in Dateien zu speichern um sie möglichst einfach weiterverwerten (Ansehen, Suchen, Editieren, Diagramme Zeichnen, ...) und verwalten zu können. Dazu wird das Programm Digitemp täglich um 0 Uhr mit einer neuen Ergebnisdatei gestartet. Datum ist im Dateiamen kodiert. Das Programm digitemp muss -LEIDER(!)- immer unter dem User "root" laufen. Um es mit seinen Parametern aufzurufen un in der Datei einen Kopf zu schreiben folgendes Scriptchen. Soll die Datei direkt in OpenOffice-Calc eingelesen werden, MUSS sie die Endung ".csv" haben, sonst wird sie als (fortlaufender) Text interpretiert! Dies war der erste Ansatz. Um einige Handgriffe zu sparen habe ich sie später in ".dat" (wie Daten-File) umbenannt, und verwende ein Script um sie handlicher umzurechnen.

Da digitemp nur die Zeitdifferenz und die Meßwerte in die Datei schreibt, ist es nötig und sinnvoll sich die Start-Zeit und vor allen Dingen die Zuordnung der Meßfühler in der Ergebnisdatei zu merken. (Die Überschriften müssen natürlich nach jedem Umbau der Meßstrecke angepaßt werden..). Und den Datei-Namen generieren wir aus dem Datum und der Uhrzeit, damit wir später unsere Meßwerte auch wiederfinden.

Start-Script templog im root-Directry

cd /home/lpmat/DIVERSE/BeLUG/OpnCels/
./templog
exit

Klein und windschnittig wird nur in das entsprechende Arbeitsverzeichnis gewechselt. Dort wird dann die eigentliche Arbeit verrichtet: Der Digitemp-Prozeß abgebrochen -falls läuft- und die Daten-Datei mit einem entsprechenden Header versehen.

Start-Script templog (working-Dir)

#!/bin/bash
#   Digitemp-Log
#   LpMat 20100204, 20100227,
#
DIGIPID=`ps -e | grep digitemp_DS2490`
DIGIPID=${DIGIPID::6}
echo "digitemp is running on --- $DIGIPID ---"
if (( $DIGIPID )) ; then
  echo "digitemp is running on --- $DIGIPID ---"
  echo "Kill It :  kill -HUP $DIGIPID"
  kill -HUP $DIGIPID
else
  echo "digitemp is currently NOT  running"
fi
DNAME=`date +%y%m%d%H%M`
#d  echo Name istgleich \[$DNAME\] aus Date
FNAME="Data/logtmp$DNAME.dat"
echo Digitemp-LOG  vom  `date` >$FNAME
echo $'Zeit \tVorlauf \tRaum \tAussen \tServer' >>$FNAME
echo $'[s]  \t[GradC] \t[GradC] \t[GradC] \t [GradC]'  >>$FNAME
cat $FNAME
chgrp -v users $FNAME
chown -v lpmat $FNAME
chmod -v a+rw  $FNAME
digitemp-3.6.0/digitemp_DS2490 -a -o2 -n0 -r750 -d10 -l$FNAME &
echo DigiTemp is running in Background...
echo "DigiTemp  writes File --->   $FNAME  !"
exit

Da templog unter Root-Rechten ausgeführt wird, ist es sinnvoll, gleich dafür zu sorgen, dass die entstehende Meßwertedatei gleich die "richtigen" Rechte hat, damit der Anwender + Auswerter nicht Admin sein muß.(chown,chgrp,chmod) Die entstehende Datei Data/logtmp1003040000.dat sieht dann so aus:

Daten-File von Digitemp

Digitemp-LOG vom Thu Mar 4 00:00:01 CET 2010
Zeit 	Vorlauf 	Raum 	Aussen 	Server
[s]  	[GradC] 	[GradC] 	[GradC] 	 [GradC]
0	19.75	20.44	0.81	23.75
10	19.75	20.50	0.81	23.75
20	19.75	20.56	0.81	23.75
30	19.75	20.50	0.81	23.75
...	...	...	...

Tabulator bzw. Blank+Tab getrennt. Ungünstig: der Dezimalpunkt (engl. schreibweise) und die relative Zeit in Sekunden als erste Spalte (X-Achse). Sucht man etwa einen bestimmten Peak muss man viel rechnen. Daher hab ich die Ergebnis-Datei beim Einbau in die Chron-Tab umbenannt in ".dat" , welche ich dann später mit einem AWK-Skript in eine etwas handlichere ".csv"-Datei umbaue. Digitemp schreibt die Werte 'einzeln' in die Datei und nicht als Record/Zeile. (Zeitversatz, und bei zwischenzeitlichem weg-kopieren kann die Zeile unvollständig sein.)

Eintrag in cron / crontab

Der Eintrag bewirkt, dass die (kleine Start-Datei im "/root"-Verzeichnis) sowohl beim Rechner(-neu)Start ausgeführt wird, als auch täglich um o:oo:oo Uhr.

Crontab-Eintrag

singapore:/home/lpmat # crontab -l
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab.XXXXvnlsQQ installed on Wed Mar  3 01:00:51 2010)
# (Cron version V5.0 -- $Id: crontab.c,v 1.12 2004/01/23 18:56:42 vixie Exp $)
#  Temp-Logging   Start
#
#  LpMat  V1.0  20100303
#
@reboot     /root/templog > templog.log 2>&1
#
#  danach jeweils um 0:00 Uhr neu
0 0 * * *   /root/templog > templog.log 2>&1

Damit wird dann täglich ein Meßwerte-File erzeugt.. In der kleinen Datei (in /root/) "templog.log" ist jeweils nachzulesen ob der (letzte) Start geklappt hat, oder ggf. die Fehlermeldungen.

Script, um aus den ".dat" Dateien die ".csv"-Dateien zu erzeugen

Zur Zeit werden einfach alle "Data/*.dat" über den awk umgewandelt. Dabei wird vor allen Dingen die relative Zeit (in Sekunden) in eine menschlich leichter lesbare From von DD.MM.JJ HH:MM:SS umgewandelt. und natürlich bei der Gelegenheit auch gleich der Dezimalpunkt in das Komma getauscht (das alleine hätte natürlich der sed auch gekonnt).

Script cnvt.sh für alle Dateien

#!/bin/bash
#   Proj.  BeLUG   OpenCelsius / DigiTemp   V1.01  LpMat 20100228
#   Konvertiert alle xxx.dat - Dateien in  .../Data/ zu  xxx.csv
echo "START :  `date` " 
DATVZ="Data/"
DATFILE="logtmp1002121335.dat"
for DATEI in  Data/logtmp*.dat
  do
#    echo "$DATEI  -  ${DATEI/.dat/.csv}  "
#    awk -f cnvt.awk ${DATVZ}${DATFILE} >datax.csv
     awk -f cnvt.awk ${DATEI} >${DATEI/.dat/.csv}
  done
echo "Ende  :  `date` "

awk-Script cnvt.awk für die Umsetzung

#   AWK   Proj.  OpenCelsius   Konvertieren Daten in (OpenOffice) csv
#
#    Input-Format  (von Script+DigiTemp geschrieben
#Zeile
#  01! Digitemp-LOG vom Fri Feb 12 14:00:33 CET 2010
#  02!Zeit 	Vorlauf 	Raum 	Aussen
#  03![s]  	[GradC] 	[GradC] 	[GradC]
#  04!0 	50.81	22.06	0.81
#  05!10	51.25	22.06	0.81
#  06!20	51.56	22.06	0.88
#  ..! ...  usw.
#
#Zeile         ==>  Output   (Zeile 1-3 wie oben )
#  04!12.02.10 14:00:33 	50,81 	22,06 	0,81
#  05!12.02.10 14:00:43 	51,25 	22,06 	0,81
#
#  BeLUG,  Lutz Matscholl    Feb/2010   V1.01 20100228
#
#     Start-Block / Initial
BEGIN {
split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov dec", smon," ")
}
#
#  Für alle Zeilen in InDatei...  Zeile(FNR)
{
#
# 1.Zeile  (Start-Datum,+Zeit)    Merken + zu Unix-Time umrechnen
if( FNR == 1 ) {
  datumStr = $0
#  Monat  Text => Num;   Feb => 2
  Imon=0
  for( i=1; i<=12 ;i++ ){   if( $4 == smon[i] )imon=i;  }
# UmFormatieren Blänks werden 'gefressen'. Daher "X" und später austauschen
  initdate =  $8 "X" imon "X" $5 "X" substr($6,1,2) "X" substr($6,4,2) "X" substr($6,7,2) "X-1"
  gsub( "X", " ", initdate)
# Unix-Time  davon machen
  timstmp=mktime( initdate )
# echo to output
  print datumStr
  next
}
#
#  2.Zeile Meßstellen-Name
if ( FNR == 2  ) {
# merken für später
  namen = $0
# echo to output
  print
  next
}
#
#  3.Zeile  die Einheiten    (... wie 2.Zeile )
if ( FNR == 3  ) {
  einht = $0
  print
  next
} else {
#
#   Alle anderen (Messwerte-Zeilen....)
#
#       relative Zeit (Sekunden seit Start) in absolute umrechnen
        time = timstmp + int($1)
        zeit = strftime( "%d.%m.%y %H:%M:%S", time )
#       to Output,
        printf( "%s ",zeit)
#       In den Meßwerten, den amerianischen Dezimal-Punkt gegen Europ. Komma tauschen
        for ( i=2;  i<=NF; i++ ) {
           gsub( "\\.", ",",$i);  printf("\t%s ",$i);
        }
        printf(" \n")
# EndIf
}
#End-Block
}
#-----EoF-------

Das Ergebnis ist dann logtmp1003040000.csv , mundgerecht für OpenOffice-Calc

Digitemp-LOG vom Thu Mar 4 00:00:01 CET 2010
Zeit 	Vorlauf 	Raum 	Aussen 	Server
[s]  	[GradC] 	[GradC] 	[GradC] 	 [GradC]
04.03.10 00:00:01 	19,75 	20,44 	0,81 	23,75
04.03.10 00:00:11 	19,75 	20,50 	0,81 	23,75
04.03.10 00:00:21 	19,75 	20,56 	0,81 	23,75
04.03.10 00:00:31 	19,75 	20,50 	0,81 	23,75
...			... 	...	(...)

Wieder: Tabulator-getrennt (bzw. Blank+Tab). Start-Zeit? na klar Do.4.3.2010 um 0Uhr00 (20)10_03_04__00_00

Ergebnis

Darin läßt sich nun sehr leicht jeder Zeitpunkt finden und mit wenigen Handgriffen aka Mouseklicks ein hübsches Tagesdiagramm erstellen. Klick: OpenOffice-Calc Klick: Icon / Menü: Open File -Datei auswählen -Endung ".csv" .... ==> "OK" Fenster: Textimport:Import ==< Trenn-Optionen=Tab; ==> "OK" Mit Scrollbalken an das Ende der Tabelle. Letzten (rechten) Wert anklicken, markieren/selektieren. Mit Scrollbalken wieder ganz nach oben. Mit gedrückter Shift-Taste Feld A2 ("Zeit") anklicken. (Die ganze Tabelle ist nun ausgewählt.) Diagramm-Icon anklicken (oder Menü Einfügen ==>Diagramm) Diagramm-Typ XY auswählen, "Nur Linien" auswählen , und "Fertig stellen" und nun voi-la ist ein schickes Diagramm auf dem Schirm. (wenn man vor dem Diagramm der ersten Spalte das Zeit-Format "dd:mm:jj hh:mm:ss" zuweist, stehen sogar Tag und Tageszeit auf der x-Achse. *grinz* )

Schön zu sehen: wenn die Heizung anspringt wirds erstmal kalt. Regelzyklen der Heizung nach erreichen der Temperatur, herunter-regeln der Vorlauftemperatur. Sonnenschein auf dem Außenfühler. 'Kalt-Zacken' und Temperaturabfall durch Lüften.

Datenbank(MySql) + RRDtool in Digitemp

Zwar wird irgendwo beschrieben, dass DigiTemp die Meßwerte in die Datenbank schreiben kann, doch sehe ich das nicht. Die Option "-e" wird (Vers.3.0.6) mit Fehlermeldung "ungültige Option" abgewiesen. In den mitgelieferten Scripts, wird jeweils das Programm DigiTemp als One-Shot aufgerufen und das Script sortiert die Meßwerte aus der Datei in die DB ein. Das ist sicher auch eine 'quick-&-dirty'-Methode, aber letztendlich nicht das, was ich mir unter programmatischer Einstellung in die DB vorstelle.

Fahrplan für die Zukunft

wie es weitergeht:

  • RRDtool in Betrieb nehmen und mit digitemp vernüpfen. Siehe hierzu:

Wikipedia: Wiki==>RRD-tool Grundlagen. + Linux-Magazin 03/10 Seite 78 ff.

  • Die anderen im Linux-Magazin genannten Soft-Tools ausprobieren.
  • Wie komme ich an die Rechner- und CPU-Temperaturen programmatisch heran ???
  • Logging der Temperaturen (Rechner/Serverraum) zusammen mit /proc/loadavg und /proc/status.
  • Herausbekommen WAS man mit dem 'normalen Linuxtreiber' lesen kann.

(warum muss der für Digitemp abgeschaltet (ge-blacklistet) werden???) Es ist doch sehr fragwürdig und mysteriös, dass wir einerseits auf der offiziellen BeLUG-Seite vollmundig von Kernel-Unterstützung schreiben, aber die erste Aktion ist, eben gerade diese Kernelunterstützung, in Form des Modules, herauszuschmeißen (blacklisten)? Net War?

  • Einbinden der in die NAGIOS Server-Überwachung.
  • Betrieb der Meßfühler an kleinen (Stromsparenden!!!) Embedded Systemen,

die die laufenden Temperaturen aufzeichnen und auf Flash zu speichern, um sie dann, wenn ein Server läuft, sie diesem mitzuteilen. (Lutz Meister).

  • Ein 'vernünftiges' Erfassungsprogramm sollte auch eine gewisse Überwachungs-Funktion ausführen. Etwa ein Script starten bei Über- unter-Temperatur, Kabelbruch etc. Eine konfigurierbare Hysterese. Diese Dinge sollten in einem anständigen Konfig-File messtellenbezogen stehen.

Temperatur aufs Display im Desktop im Fenster

Schön dass der Rechner unterm Tisch weiss, wie warm es ist. Die aktuellen Temperaturen müssen irgendwie auf den Bildschirm.  Dazu wurde erst mal ein kleines Test-Scriptchen verfaßt, zur Kontrolle.

Mit dem Unix-Befehl tail -f und einem XTerm ist das relativ schnell erledigt. Das Mini-Script muß nur herausfinden, wie die letzte, die aktuelle Datei heisst.

Bekannter weise hält ein gutes Provisorium ewig...

Scripte: Aktuelle Temperaturen auf den Desktop

# Script:   tempC.sh     ist in ein Icon eingebunden und ruft XTerm mit dem tempR1 auf.

#!/bin/bash
xterm  -geometry 40x3+1030+920 -T TempC_Vl_Az_Au_Wz -e
/home/lpmat/tempR1.sh &
exit


# Script:   tempR1.sh     Sucht die letzte (aktuelle) Datei und zeigt das Ende an.

#!/bin/bash
# ? FILE=`ls -t /home/lpmat/DIVERSE/BeLUG/OpnCels/Data/`
#
for  EINZ in /home/lpmat/Temperatur/Data/logtmp*.dat
  do
    LAST=$EINZ
  done
echo $LAST
tail -f -n2 $LAST

Update März 2015, Raspberry Pi unter Pidora

Nachem das ganze jahrelang lief, habe ich das -wie oben vorgeschlagen- auf den RaspberryPI migriert, ein kleines embedded Rechnerchen unter Linux. Das ging recht problemos. Unter Pidora ist das digitemp mit im Repository und kann direkt heruntergeladen und installiert werden.

Das Blacklisting des Teibers, wie oben beschrieben, ist immernoch, auch hier erforderlich. Danach läuft es auf der "Seifenschachtel" genau so, wie auf dem "Großen".

Berlin 5.März. 2010, Überarbeitet/Ergänzt März 2015   Lutz Matscholl