Dieses Wiki ist ein Archiv bis 2023. Das aktuelle Wiki findet sich unter https://wiki.hamburg.ccc.de/

Projekt:Temperaturmonitoring

From CCCHHWiki
Revision as of 16:47, 16 November 2012 by Thw (talk | contribs) (Aufbau)
Jump to: navigation, search

Temperaturmonitoring im Mex21

Da unsere Nebenkostenabrechung für 2010 sehr hoch bezüglich der Heizkosten ist, und für 2011 mehr zu erwarten ist, wurde ein Temperaturmonitoring auf die schnelle zusammen gehackt...

Zu sehen, hier: http://orga.hamburg.ccc.de/collectd/host.php?h=thw-Temperatursensor


Hardware

Kosten liegen bei ca. 250€ (privat bezahlt).


Software

  • Als Software kommt OpenWRT zum laufen (http://wiki.openwrt.org/toh/tp-link/tl-mr3020)
  • Da der Flash nur 4MB groß ist, ist am USB ein 8GB Stick dran, wo die restliche Software drauf ist
  • Installiert sind USB Treiber, perl, collectd und paar andere Sachen.


Aufbau

Wie schon erwähnt, läuft auf dem TP-Link eine OpenWRT mit Kernel 3.2.X. Das Temperaturmodul wird einfach per USB/Serial angesprochen. jeder Temperaturfühler aht eine Seriennummer, mit der er sich meldet sowie den aktuellen Wert. Ich habe da aus alten Zeiten ein Perlscript von mb(Ameise) verwendet, was bei uns im RZ seit ewigkeiten läuft. Dort sind die jeweiligen Seriennummern der genutzen Sensoren eingetragen, die alle Minuten abgefragt werden. Die Werte werden dann in dem collectd per exec-plugin und Script eingelesen. Selbiger schickt dann diese dann auf den als Serverkonfigurierten collectd Daemon zur orga.hamburg.ccc.de. Dort können mit der URL http://orga.hamburg.ccc.de/collectd/host.php?h=thw-Temperatursensor die aktuellen Werte betrachtet werden.


Orte der Sensoren

  • 1. Sensor: Fußboden, links unten vor dem Serverraum
  • 2. Sensor: Unterhalb der Zwischendecke vor dem Serveraum
  • 3. Sensor: im Serverraum, oberhalb der Decke
  • 4. Sensor: Zwischen Küche und Stützpfeiler, weit oben zu Betondecke
  • 5. Sensor: Ausserhalb der Fensterfront Eingang, beim Klappfenster
  • Die Sensoren sind am blauen Kabel zu erkennen. Bitte nicht entfernen oder beschädigen!


Messprotokoll

Die Messung soll über einen längeren Zeitraum erfolgen, um den Tag/Nacht- sowie Wochenrhythmus feststellen zu können. Zu sehen sollte das Verhältniss zwischen Aussen- und Innentemperatur sein. Relevant aber ist auch das Temeraturgefälle zwischen Fußboden, Zwischen- und Betondecke.

Dort können wir jetzt schon feststellen, das wir jeweils bis zu einen Grad Unterschied pro Höhe haben.

Beispiel: Fußboden 16°, Zwischendecke 17° und Betondecke 18°.

Darstellung

Die Daten werden per rrdtools generiert. Leider passen die Werte (2.1 K = 21°) noch nicht ganz so sauber, habe bisher noch nicht herausgefunden, wo ich das fixe. Kommt aber noch. Wichtig ist erstmal Daten sammeln (da haben wir das wieder...sammeln...)...

Fix: Ok, kleiner Schnipsel im Perl prg. eingebaut, das aus "1234" eine "12.34" wird.

Weiterhin, sollte es "1.23" mal sein, das er mir kein "12.30" sondern ein "01.23" macht. Jetzt sind die Werte für den collectd korrekt.

Die kleinen Spitzen rühren vom sprung 9.99 - 10.00 daher, weil er aus den 9.99 leider 99.90 machte. habe ich heute noch gefixt, bekomme aber nicht alle Peeks aus dem rrd file raus, bis auf das Grobe, das war schon heftig.



Erweiterungen

Vorstellbar ist die Verknüpfung mit dem Projekt:Heizungssteuerung und Dooris

Weiteres

Das Teil rebootet alle 24h, da im OpenWRT mit USB Stick und extX Filesystem es nach einer gewissen zeit Filesystemfehler gibt. Anfangs kamen nicht alle Prozesse hoch, was ich Stück für Stück gefixt habe. So langsam läuft es stabiler...


Scripte

/etc/init.d/rc.local

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.

LD_LIBRARY_PATH=/lib:/usr/lib:/opt/lib:/opt/usr/lib
HOME=/root
PS1=\u@\h:\w\$
LOGNAME=root
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/usr/sbin:/opt/usr/bin
SHELL=/bin/ash

sync

cd /root

set >/tmp/rc.local-set.log
env >/tmp/rc.local-env.log

ls -l /dev/ttyUSB0        >>/tmp/rc.local.log 2>&1
sleep 42
echo "Breakpoint 1"        >>/tmp/rc.local.log 2>&1
/etc/init.d/thermod start     >>/tmp/rc.local.log 2>&1

sleep 2
echo "Breakpoint 2"        >>/tmp/rc.local.log 2>&1
/etc/init.d/collectd start    >>/tmp/rc.local.log 2>&1

killall scp

sleep 23
echo "Breakpoint 3"        >>/tmp/rc.local.log 2>&1
/etc/init.d/openvpn start    >>/tmp/rc.local.log 2>&1

killall scp

exit 0

/etc/init.d/thermod

#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2011 OpenWrt.org

START=92

# SERVICE_USE_PID=1

start () {
    /opt/usr/bin/thermod >/dev/null 2>&1 &
}

stop() {
    killall -9 thermod
}

/opt/usr/bin/thermod

#!/usr/bin/perl -w
#############################################################################
#
# thermod... fuer die Humboldtstrasse
#
# wertet die daten von dem conrad- one-wire thermometersensoren
# aus und stellt sie auf port 4224 zur verfuegung.
#
#                              mb@irz42.net // Wed Apr  2 15:51:38 CEST 2003
#
#
# thermod-humhack:
#
# der thermod in der hum (popeye) glitscht staendig weg, wenn er per
# netz abgefragt wird...
#
# thermod-humhack schreibt einfach nur die werte alle minute in ein file.
# in der xinetd.conf ist ein service auf port 4224 (thermo) definiert,
# der macht einfach nur einen 'cat' auf diese datei.
#
#



use Fcntl;
use IO::Socket;
use Getopt::Long;

use vars qw/ $opt_debug /;

GetOptions ( "-debug" );

use strict;

####################################
# Port vom Conrad - Thermometerteil

my $tty = "/dev/ttyUSB0";

my $today = "";
my $copy = "";
my $syncDisk = "";
my $temp = "";
my $str = "";
my $len = 0;

####################################
# TCP - Port zum Abfragen der Werte

my $port=4224;

# my $thermofile = "/opt/www/mrtg/thermo.stat";
my $thermofile = "/tmp/thermo.stat";

####################################
# Seriennummern der Sensoren


my %sensorser =    ("7A7FE1010800", 421,
         "9EA4E1010800", 422,
         "3EAEE1010800", 423,
         "75A4E1010800", 424,
         "A37BE1010800", 425,
         "000000000000", 426,
         "000000000000", 427,
         "000000000000", 428,
         "000000000000", 429,
         "000000000000", 430,
         "000000000000", 431,
         "000000000000", 432,
         "000000000000", 433,
         "000000000000", 434,
         "000000000000", 435,
         "000000000000", 436,
         "000000000000", 437,
         "000000000000", 438,
         "000000000000", 439,
         "000000000000", 440
);


my @sensorlog;
my @temperatur;

my $inputline = "";
my $inchr = "";

my $client;
my $flags;

my $i = 0;

my $timer = 7;
my $saveintervall=60;

# my $timer = 10;
# my $saveintervall=23;


#############################################################################
# Verarbeite die Infoline
#
# "I070110DDD043000800E0"
#
#  I = Info, naechste Byte = logische sensornummer, 4.-9. byte: serialnum
#

sub do_info {

    my ($line) = @_;

    my $sensor = "";
    my $serial = "";

    if ( $line =~ /^I(\w\w)\w\w\w\w(\w{12})/ && ($sensor=$1, $serial=$2)) {

        $sensor = hex($sensor);

        $sensorlog[$sensor] = $sensorser{$serial};
        warn "Found sensor $sensor -> $serial" if $opt_debug;
    } else {
        warn "Possibly unknown sensor $line" if $opt_debug;
    }
}


#############################################################################
# Verarbeite die Valueline
#
# "V08078529"
#
#  V = Value, naechste Byte = logische sensornummer, 2.+3. byte: value
#

sub do_value {

    my ($line) = @_;

    my $sensor = "";
    my $value = "";

    if ( $line =~ /^V(\w\w)(\w\w\w\w)/ && ($sensor=$1, $value=$2)) {

        $sensor = hex($sensor);
        $value = hex($value);

        $temperatur[$sensorlog[$sensor]] = $value;
#        if ($value < 5000) {
#             print "$sensorlog[$sensor]] = $value\n";
#         } else {
#             print "$sensorlog[$sensor]] = $value - Fehler\n";
#         }
        }
}

#############################################################################
#
# checke die pruefsumme...
#
sub chk_crc {
    return (1);          # kommt spaeter...
}


#############################################################################
# main...

######################
# serielle aufmachen

open(THERMO, "$tty");
system("stty 4800 raw ignbrk clocal -echo -crtscts < $tty");

   $flags = fcntl(THERMO, F_GETFL, 0)
           or die "Can't get flags for the socket: $!\n";

   $flags = fcntl(THERMO, F_SETFL, $flags | O_NONBLOCK)
           or die "Can't set flags for the socket: $!\n";

##############################
# und die endlose schleife...

print "Start\n";
print "Debugmodus ist aktiv!\n" if $opt_debug;

while ( 42 ) {

    # XXX Temp sleep for checking 2010-11-05/fa
    # sleep 1;

    ##############################
    # zeichen an der seriellen ??

    if ( read (THERMO, $inchr, 1)) {

        if ( ord($inchr) == 13 ) {

            ####################
            # zeile komplett !!

            if ($inputline =~ /^I/ ) {
                do_info ($inputline);

            } else {

                if ($inputline =~ /^V/ ) {
                    do_value ($inputline);
                }
            }
            $inputline ="";

        } else {
            $inputline = $inputline.$inchr;
        }

    } else {

        ################################
        # werte ausgeben

        $timer--;

        if ($timer le 0) {
            $today=`date +\%Y\%m\%d-%H%M`;
             print "Write $thermofile ($today)\n\n" if $opt_debug;
            $timer = $saveintervall;

            $i = 421;
            while ( $i <= 425) {
               # $str = $temperatur[$i];
               $str = sprintf("%4.4d", $temperatur[$i]);
               # $len = length($str); # 4= 2.2 / 3 = 1.2
               # $len = $len -2;
               # $temp = substr($str, 0, 2).".".substr($str, 2, 2);
               $temp = substr($str, 0, 2).".".substr($str, 2, 2);
               open (OUTF, ">$thermofile-$i");
                printf ("%02d\t%d\t%s", $i, $temperatur[$i], $today) if $opt_debug;
               printf OUTF ("0\n%d\n%d Einheiten\n%s\n", $temperatur[$i], $i, $temp);
               $i++;
               close (OUTF);
            }
           
             # open (OUTF, ">$thermofile-alle");
             # printf OUTF ("%d:%d:%d:%d:%d\n",
             #      $temperatur[421],
             #      $temperatur[422],
             #      $temperatur[423],
             #      $temperatur[424],
             #      $temperatur[425]);
            close (OUTF);

            # $syncDisk=`sync`;
            # print $syncDisk;
           
            # $copy=`scp -i /root/.ssh/id_rsa -P 4222 /opt/www/mrtg/thermo.stat-* marvin\@mon01.irz42.net:~ >/dev/null 2>&1`;
            $copy=`scp -i /root/.ssh/id_rsa -P 4222 /tmp/thermo.stat-* marvin\@mon01.irz42.net:~ >/dev/null 2>&1`;
            print $copy;

        } else {

            # print "Timer: $timer\r";
            sleep (1);
        }
    }
}

close (THERMO);