Freetel の通信量と料金をスクレイピングで取得し,IFTTT で Google スプレッドシートに送り込んでグラフ化する。
先日は Freetel の通信量と料金を Zabbix でグラフ化した (nlog(n): Freetel の通信量を Zabbix 2.4 でグラフ化)。グラフ化できたことには満足だが,若干の不満があった。それは,通信量と料金のグラフをひとつのグラフに表示できていないということである。単純にひとつにするならできるのだが,単位が違うために見やすいグラフにならないのが問題なのである。ここは,縦軸に,左軸と右軸の2軸をとって,片方に通信量,もう片方に料金としたい。Excel や Numbers であれば2軸のグラフは作成できる。しかし,もとになるデータはオンラインで毎時間更新されているので,オフラインに移動するのは面倒。そこでオンラインで完結する Google スプレッドシートを使うことにした。Google スプレッドシートに直接データを送り込むのは難しいので,IFTTT を使う。
方針としては,Freetel のマイページの通信量と料金を,自宅の Linux サーバでスクレイプして取得し,これを IFTTT に送り,IFTTT が Google スプレッドシート送り込むようにする。起動は1時間に1度とする。Google スプレッドシートには 2000 行まで書けるので,1か月分を1シートに収める計算になる。
IFTTT は,あるオンラインイベントが起きた時に,別のオンラインサービスを動作させるという,複数のオンラインサービスを連携させるサービスである。その動作が示す IF This Then That がサービス名の由来となっている (IFTTT - Wikipedia)。IFTTT は,サイトに登録されているレシピを使う。ここで「レシピ」とは,オンラインサービス同士を連携させるための,条件と動作の1つの組のことである。IFTTT には数多いレシピが登録されており,その中から自分にあったものを選択していくのが基本的な使い方であるが,登録済みのサイトやサービスはよく知られたものに限られる。
IFTTT には,レシピそのものを自分で作る機能が用意されているので,今回はこれを使う。それは Maker Channel というもので,作り方は IFTTTにMaker Channelができました | スイッチサイエンス マガジン に詳しい解説がある。
ここでは,「If Freetel is updated, then add row to Google spreadsheet」と読めるようにしたいので,イベント名を freetel_updated とする (好みなので何でもよい)。レシピを作成すると,秘密鍵の文字列が発行される。もし忘れたら Maker - IFTTT で参照できる。
この2つの文字列を使って,次の URL にアクセスすればトリガーイベントが発生する (IFTTT Maker Channel)。
トリガーイベントには,{Value1}, {Value2}, {Value3} の3つの値を送ることができる。
トリガーイベントによって実行されるアクションとして,「Create Trigger」→「Google Drive」→「Add row to spreadsheet」を選択し,例えば次のように登録する。
{{OccurredAt}} にはイベントが発生した時刻が入る。「Add row to spreadsheet」の説明によれば,2000行に達した時に新しいシートが作られるとある。
IFTTT のトリガーイベントに送る値を次のように決める。
Perl スクリプトとしては,前に作ったものに IFTTT へのアクセスを加えたものを用意する。
アクセスには WWW::Mechanize を使っている。$event と $secret_key は自分で設定・取得したものに書き換える。起動方法は,前回の「freetel-scrape.pl」を置き換えるだけでよい (nlog(n): Freetel の通信量を Zabbix 2.4 でグラフ化)。
Perl スクリプトを1回起動して一連の動作が完了すると,Google Drive にスプレッドシートが作られる。上記のように指定したとおり,IFTTT/Maker/freetel_updated/ フォルダにIFTTT_Maker_Events_freetel という名前のスプレッドシートになる。
IFTTT で追記されるそれぞれの列に名前をつけておく。1行目に Date, Phone などと書く。
受け取った通信量はバイト (B) なので,見やすいようにこれをギガバイト (GB) に変換する。E列を新しく作り,1行目に Usage (GB) と書いて,数値が入っている行に,例えば2行目なら「=C2/1024/1024/1024」としておく。
グラフの種類は「折れ線グラフ」,データとしては「A列」を選択した後に「別の範囲を追加」して「D列:E列」を選択,「1行目を見出しとして使用する」にチェック。
これで「グラフを挿入」して一旦描画した後に,右軸の名前を入れたりして微調整を行えば完成である。
1か月分のグラフができた。
Google スプレッドシートの問題としては,通信量 (GB) の列が計算になっているところで,手動で更新しなければならない点である。セルの右下角にマウスカーソルを合わせてダブルクリックすれば,値がある行すべてに計算値が反映されるのは Excel と同様だが,これをグラフを更新する度に行う必要がある。もう一つの方法としては,予め「Charge (GB)」の列を先に数百行まで入力してしまうということも考えられるが,まずいことが起こる。IFTTT は空行に追記するため,数百行下への追記になってしまうからだ。
いっそのこと,GB への変換はしないという選択肢もある。そうすれば,常にリアルタイムで反映されるし,「グラフを公開」にしておけば,スプレッドシートを開く必要はなく,Web からグラフが見えるようになるからである。
複数回線を持っている場合,データが混ざるため激しく上下に変動するグラフになる。これはフィルタをかけて電話番号を選択してやればよいが,これも手動の操作が必要になる。
グラフの種類としては,当初は「複合グラフ」を選択して作っていた。しかし,これには問題があった。複合グラフで,通信量を「折れ線グラフ」,料金を「棒グラフ」で描くと見栄えがいいのだが,棒グラフには一定の幅が必要なようで,グラフ領域を非常に横に長くしなければ全体が描けないことが分かった。横に長過ぎて画面をはみ出してしまうのである。そこで,仕方なく,両方を「折れ線グラフ」で描いたのである。
月が変わったときのシート交換の問題もある。IFTTT では,Google スプレッドシートが2000行になると新しいシートが作成されるようになっている。したがって,月の変わり目と同期していないのである。月が変わった時は手動で別シートを用意してやる必要がある。試してみたところ,「シート1」の名前を変更しても同じシートでデータが追記された。したがって,月の初めには,別のシートにグラフをまとめてコピーして「201608」などの名前をつけ,「シート1」のデータはクリアするという作業が必要になる。つまり,「シート1」は常に IFTTT からのデータを受け取るためのシートで,当月用。月が変わったらコピーしてクリアという作業になる。
Freetel の通信量と料金を Google スプレッドシートでグラフ化した。スプレッドシートの更新に手間がかかるが,グラフとしては見栄えがいいものになる。格安 SIM で楽しい節約生活のために。
2016年11月11日追記:
freetel.jp のウェブサイトが変更され,上記スクリプトは動作しなくなりました。最新版を GitHub に置きました (nlogcode/freetel-usage-charge)。
2017年1月31日追記:
freetel.jp のウェブサイトが変更されたので更新を行いました (nlogcode/freetel-usage-charge)。
Master Archive Index
Total Entry Count: 1957