放射線量可視化(3):JSONによるデータ転送
注: この作業によって作成した可視化グラフはhttp://FromTo.Cc/rad/で、結果の定期ツイートは@xckbradで公開されています。
自宅サーバから公開サーバへのデータ転送法検討
さて、現在自宅サーバのPostgreSQL上に所得した放射線のデータが置かれており、 公開サーバにはApacheのサーバが動いているわけですが、 この間のデータ転送法を考えます。大きく分けて、
- 公開サーバ側から自宅サーバのPostgreSQLにアクセスしてデータを取得する
- 自宅サーバ側から公開サーバ上に何らかの方法でデータをコピーする
の2つが考えられると思います。しかし前者は、 どちらかといえば不安定な自宅サーバの状態に依存してしまい、 自宅サーバが落ちている場合や、 (動的IPしか今は持っていないので)DDNSのタイムラグなどでアクセスが途絶えた場合などに公開サーバ上でもデータが参照できなくなります。
そのため、今回は後者を採用しました。 前回採用を決定したHighcharts JSは、 JSON形式でのデータ取得が可能であるため、自宅サーバ上でJSONデータを生成し、 それをssh(ssh-agentを利用した都度パスワードなしscp)で転送することにしました。
JSON化のためのデータを準備
cronで毎分起動されるスクリプトexportjsonが、 JSONデータを生成し、公開サーバに転送しています。
JSONデータはPerlのJSONクラスで生成します。
とりあえず初期化はこんな感じ。
cronで起動された時に、他のcronジョブとタイミングをずらすために、20秒冒頭でsleep
してます。
#!/usr/bin/perl use strict; use DateTime; use DateTime::Format::Pg; use DBI qw(:sql_types); use DBD::Pg qw(:pg_types); use JSON; sleep 20; my $json_file = "/パス/doserae2-1day.json"; my $dest_json_file = "公開サーバホスト名:/パス/doserae2-1day.json"; my $db = DBI->connect ("dbi:Pg:dbname=doserae2", 'getrae', '****パスワード****', { RaiseError => 1, PrintError => 0, AutoCommit => 1, }); if (not $db) { die "connecting database failed"; }
データベースから最新1日分のデータを取り出し、
時刻をJavaScript形式(Unix Epoch Timeの1000倍)に直し、
その時点のμSv/hの値を組にして配列のリファレンスにします。
そしてこのリファレンスを@result
という配列に突っ込みます。
念のためμSv/hの値に0.0を足したりして、
数値データであることをしつこく強制しています
(時刻は既に1000を掛け算しているので問題ない)。
my @result = (); eval { my $sth = $db->prepare(<<EOT); SELECT tstamp, usv FROM radiation WHERE tstamp > CURRENT_TIMESTAMP - INTERVAL '1 day' ORDER BY id EOT $sth->execute(); while (my @data = $sth->fetchrow_array()) { my $tstamp = $data[0]; my $usv = $data[1] + 0.0; my $dt = DateTime::Format::Pg->parse_datetime($tstamp); $dt->set(nanosecond => 0); $dt->set(second => 0); $dt->set(minute => ($dt->minute - $dt->minute % 5)); my $jstime = $dt->epoch() * 1000; push @result, [$jstime, $usv]; } }; if ($@) { die "DB Error: $@\n"; }
データのJSON化と転送
そしてJSONオブジェクトを作って@result
をJSONエンコードします。
こいつを一時ファイルにセーブして、
scpを起動してファイルをコピーします
(ssh-agentを用いてscpでパスワードなしコピーが出来る準備は別途やっておく)。
my $json = JSON->new->allow_nonref; my $json_text = $json->encode(\@result); open my $jsonf, ">:utf8", $json_file or die "cannot open $json_file"; print $jsonf $json_text; close $jsonf; system "/usr/bin/scp $json_file $dest_json_file";
これは5分平均を24時間分、288ポイント分のデータを転送しているわけですが、 同様に2時間平均を12日分、1日平均を144日分、同様にJSONファイルを作成します。
あとは、この転送されたJSONのデータを、Highcharts JSでグラフ化するわけです。
続く。