ガイガカウンタ・簡易モニタリングポスト製作日記(4)

  • RRDtoolその1
  • さて、続いて受け取ったデータをどのようにLinuxPCに保管するかが問題になりました。ネットで検索すると、偉大なる先人の方々がPachube(パッチベイ)を使って放射線数値の公開をされています。データの保管とグラフ化、さらに多くの人と共有を行う素晴らしいサイトだと思います。

    その後、さらに検索して見つけたのがRRDtoolというソフトです。RRDtoolではデータの保管とグラフ化ができるみたいです。私のLinuxPCのdebian squeezeでは

    #aptitude install rrdtool

    でインストールすることができます。これを使わせてもらうことにします。

    いろいろな人のサイトを参考にさせていただきましたが、渡辺 勝弘さんが書かれた“じつはかんたん!! RRDTOOL”は、とても分かり易く記述されていて、RRDtoolに入門する人の必読書のようでした。また、RRDtool チュートリアルもすごく参考になりました。自動車のスピードを例にあげて解説されていますが、表記中のコマンドをコピーして実際に打ち込んでグラフが出来てしまいます。少し感動してしまいました。

    LinuxPCのターミナルからコピペで作成

    LinuxPCのターミナルからコピペで作成

    私の入手したRRDtoolは、このチュートリアルで解説されているバージョンから改訂があったみたいで、保存されているデータの表示に関して変更がありました。データの表示が、指数表示になっています。

    さて、次の順にスクリプトを組んでいけばよいことがわかりました。

    1 データベースを作成する rrdtool create(1回のみ)
    2 データを読み込ませる rrdtool update
    3 グラフを作成する rrdtool graph

    2と3はLinuxPCで一定時間ごとに行えば良いはずです。

    データベース radiation.rrdを作成します。よく分からないので上記のサイトの記述にある通りMRTGと同じだけサンプルをとるようにしましょう。5分間隔でデータを取得して約2年間分保持します。グラフはCPMデータの平均(AVERAGE)を表示させます。こんな感じでどうでしょうか。

    /usr/bin/rrdtool create radiation.rrd –step 300 \
    DS:mx_out:GAUGE:600:U:U \
    RRA:AVERAGE:0.5:1:600 \
    RRA:AVERAGE:0.5:12:700 \
    RRA:AVERAGE:0.5:24:770 \
    RRA:AVERAGE:0.5:288:797

    さて、続いてデータを読み込ませる段取りです。Windmeadow Labsさんのサイトや、satospoさんのサイトにperlで書かれた例がありましたので大変参考になりました。

    まず、CPANのDevice::SerialPortモジュールをインストールします。

    #perl -MCPAN -e shell
    cpan> install Device::SerialPort。

    続いて、librrds-prel もインストールです

    #aptitude sintall librrds-perl

    さて、いよいよupdate.plスクリプトです。USBから送られてくるデータを読み込み、データベースに読み込ませます。

    #!/usr/bin/perl

    use Device::SerialPort;
    use RRDs;

    ### Serial port set up ###
    my $port = Device::SerialPort->new(“/dev/ttyUSB0”);
    $port->databits(8);
    $port->baudrate(9600);
    $port->parity(“none”);
    $port->stopbits(1);

    ### Read CPM ###
    my $count = 0;
    while ($count == 0) {
    # Poll to see if any data is coming in
    my $char = $port->lookfor();

    if ($char) {
    @value = split(/,/, $char);
    $count = 1;

    # value[1] に入る1分間の移動平均CPM値(–>直前1分間のCPM値)を使用することにします
    }
    }
    $port->lookclear;

    ### Get current time ###
    my $time = time;

    #---->①

    ### update ###

    my $rrdfile = “/***path***/radiation.rrd”;
    my $values = “$time:” . $value[1];

    RRDs::update(“$rrdfile”,”$values”);
    my $ERR=RRDs::error;
    die “ERROR while updating $time $ERR\n” if $ERR;

    このようなスクリプトで”現在時刻とCPM値”を読み込ませようとしました。ちなみに、現在時刻はUNIX時間、CPM値は一分間の移動平均です。cronを使って5分間隔で実行すれば、きっとうまく行くはずです。やりました。

    でも、実際行ったところ問題が発生してしました。取り込んだデータは次のコマンドで確認できます。

    $ rrdtool fetch radiation.rrd AVERAGE --start スタート時間 --end 終了時間

    ・・・
    1324389000: 1.6000000000e+01
    1324389300: 1.4026666667e+01
    1324389600: 1.9920000000e+01
    1324389900: 2.0000000000e+01
    1324390200: 1.8026666667e+01
    ・・・

    データは取り込んでいるのですが、なんか値が変です。一番上は1.6000000000e+01で、これは1.6×10の意味でしょうから16CPMでOKなのですが、2行目は14.026666667CPMになっています。整数にならなくてはいけません。どうしたことでしょう?

    いろいろと検索した結果ようやくわかりました。cronで5分間隔でアップデートするのですが、その処理にかかる数秒間の遅延が原因のようです。基準の時間からずれている分をRRDtoolが勝手に補正してしまうのですね。#---->①の部分に次の行をいれて、LinuxPCで取得した時間を5分(300秒)単位に切り捨てました。

    $time = $time – ($time % 300);

    もう一度見てみると

    ・・・
    1324543200: 1.5000000000e+01
    1324543500: 2.0000000000e+01
    1324543800: 1.4000000000e+01
    1324544100: 2.0000000000e+01
    1324544400: 1.3000000000e+01
    ・・・

    今度は大丈夫でした。

    あらかじめ設定したCPM値を超えた時に警告メールを送るルーチンも付け加えます。

    ### alert ###

    #CPM値がlimitを超えたら警告メールを送ります。#
    #私の所では普段35を超えないので limit=50 CPMにしました。#

    my $limit = 50;

    #メールの送り先等#
    my $mail_sender =’送り主@ドメイン1′;
    my $mail_receiver =’受け手1@ドメイン2;受け手2@ドメイン3;・・・’;

    my $file_name =”***path***/alert.txt”;

    if ($value[1] > $limit ){

    ### 既にalert.txt が無ければ処理を行う (1回だけ送る) ###
    if (! -e $file_name){
    open (FH, “>$file_name”);
    print FH “radiation alert CPM:” . $value[1] .”\n”;
    close (FH);

    ### メールを送信 ###
    open FH, ‘|/usr/sbin/sendmail -t ‘ or die “Can’t Open\n”;
    print FH “From: “. $mail_sender . “\n”;
    print FH “To: “. $mail_receiver . “\n”;
    print FH “Subject: Radiation Alert.\n\n”;
    print FH “CPM: “. $value[1] . “\n”;
    close FH;
    }
    }

    このメールが送られて来ない事を心から祈ります。