yoppa.org


immediate bitwave

バイオメディア・アート

Pachubeで地球をセンシング、ネットワークでセンサー情報を共有する

今日の内容

  • Pachubeを使ってみる
    • 世界各地のpachubeの情報をモニターしてみる
    • Processingで、Pachubeの情報をリアルタイムに取得して、視覚化する
    • Arduinoで取得したセンサーの情報を、Pachubeに書き出し
    • センサーの情報をシェアしてみる

Pachubeとは?

  • http://www.pachube.com/
    • インターネットを介してリアルタイムにセンサーやからの情報を共有するプロジェクト
    • 世界中の環境、センサーからのリアルタイムの情報をモニター
    • 自作のデバイスを接続、世界に向けて情報を発信
    • ユーザ登録することで、APIを利用して様々なアプリケーションからPachubeの情報を送受信可能となる
      • Processing, openFrameworks, Java, Ruby, PHP, iPhone ..etc.a

ユーザ登録

  • PachubeのAPIを利用するために、まずはPachubeにユーザ登録する
  • もちろん無料
  • Sign upの登録フォームに必要情報を記入して送信 https://www.pachube.com/signup
  • 登録したemailアドレスに、メールが返送される
  • 登録完了メールの中の「API Key」というアルファベットと数値の文字列が開発の際に必要となるので、控えておく

Webブラウザで情報を取得

  • まずは簡単な方法で情報を取得してみる
    • Pachubeトップページ(http://www.pachube.com/)のマップから、ひとつ場所(ふきだし)を選び、ふきだしのタイトルをクリック – 例えば、iddに設置されたiBioartを選択 – http://www.pachube.com/feeds/2263
    • センサーの設置位置と、現在の状況がリアルタイムに更新されている

  • タイトルの下にあるXMLファイルのURLをクリック (iBioartの場合は、http://www.pachube.com/api/feeds/2263.xml)
  • 文字と数字の羅列が表示される
  • ブラウザから「ソースを見る」を選択する – XML形式のファイルが表示される、これがPachubeからフィードのフォーマット(EEML形式)
<eeml xmlns="http://www.eeml.org/xsd/005" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5" xsi:schemaLocation="http://www.eeml.org/xsd/005 http://www.eeml.org/xsd/005/005.xsd"> 
  <environment updated="2010-07-11T03:28:16Z" id="2263" creator="http://www.haque.co.uk"> 
    <title>iBioart</title> 
    <feed>http://www.pachube.com/api/feeds/2263.xml</feed> 
    <status>live</status> 
    <description>A Plant connected with Pachube.</description> 
    <website>http://dp.idd.tamabi.ac.jp/bioart/</website> 
    <email>kubotaa@tamabi.ac.jp</email> 
    <location domain="physical" exposure="indoor" disposition="fixed"> 
      <name>Tama Art University, Tokyo</name> 
      <lat>35.6105400074836</lat> 
      <lon>139.351229667664</lon> 
    </location> 
    <data id="0"> 
      <tag>temperature</tag> 
      <value minValue="1.0" maxValue="168.0">83</value> 
    </data> 
    <data id="1"> 
      <tag>humidity</tag> 
      <value minValue="63.0" maxValue="306.0">145</value> 
    </data> 
    <data id="2"> 
      <tag>brightness</tag> 
      <value minValue="0.0" maxValue="942.0">846</value> 
    </data> 
    <data id="3"> 
      <tag>water</tag> 
      <value minValue="0.0" maxValue="842.0">209</value> 
    </data> 
    <data id="4"> 
      <tag>plant1</tag> 
      <value minValue="0.0" maxValue="928.0">353</value> 
    </data> 
    <data id="5"> 
      <tag>plant2</tag> 
      <value minValue="0.0" maxValue="1023.0">401</value> 
    </data> 
    <data id="6"> 
      <tag>plantdiff</tag> 
      <value minValue="-142.0" maxValue="220.0">141</value> 
    </data> 
    <data id="7"> 
      <tag>human</tag> 
      <value minValue="0.0" maxValue="1.0">0</value> 
    </data> 
  </environment> 
</eeml> 
  • このEEML形式のXMLファイルを様々なアプリケーションで解析することで、オリジナルのPachubeモニタを作成できる

Extended Environments Markup Language (EEML)

  • Pachubeでは、センサーや環境の情報を記述XML形式のフォーマットとして、Extended Environments Markup Language (EEML)というものを策定している
  • EEMLに関する詳細な情報は、http://www.eeml.org/ を参照

ProcessingでPachubeの情報を視覚化

  • Processingを仕様して、pachubeのEEMLを解析する
  • EEMLの解析のためのライブラリが公開されているので、これを利用すると便利
  • EEML for Processing (http://www.eeml.org/library/)

EEML for Processingをインストール

  • EEML for Processingのページから、Processing用のライブラリをダウンロード(http://www.eeml.org/library/eeml.zip)
  • Zipファイルを展開した「eeml」フォルダを、「ProcessingのSketchbookの場所/libaries/」以下にコピーする
    • ProcessingのSketchbookの場所は、ProcessingのPreferenceの、「Sketchbook location」で確認

まずは、シンプルに情報を表示

  • 最初のステップとして、遠隔地のセンサーの値を取得してテキストで出力してみる
import eeml.*; //eemlライブラリのインストール

//場所のIDを指定、iBioartは2263
int locationId = 2263;
//配信されているデータの数を指定
int dataNum = 8;
//EEMLからのデータ入力
DataIn dIn;
//データのタグを記録する配列
String[] tag = new String[dataNum];
//データの値を記録する配列
float[] value = new float[dataNum];

void setup() {
  size(400,400);
  //指定した場所から、EEML形式のデータを15秒ごとに受信する
  dIn = new DataIn(this,"http://www.pachube.com/api/feeds/" + locationId + ".xml", "※PachubeのAPI Keyを入力", 15000);
}

void draw() {
  background(0);
  fill(255);
  noStroke();
  //データの数だけ繰り返し
  for(int i=0; i < dataNum; i++){
    //データのタグと値の組み合わせを、テキスト表示
    text(tag[i] + " : " + value[i], 10, i * 20 + 20);
  }
}

//EEMLのデータを受信したら呼び出されるイベント
void onReceiveEEML(DataIn d) {
  //データの数だけ繰り返し
  for(int i=0; i < dataNum; i++) {
    //タグの文字列を取得
    tag[i] = d.getTag(i);
    //センサーの値を取得
    value[i] = d.getValue(i);
  }
}

センサーの変化をグラフ化する

  • センサーの値の変化をグラフで表示してみる
  • このコードを応用すれば、Pachubeの時系列のデータを様々な方法でビジュアライズできるはず
import eeml.*; //eemlライブラリのインストール

//場所のIDを指定、iBioartは2263
int locationId = 2263;
//配信されているデータの数を指定
int dataNum = 8;
//表示するグラフの高さ
int graphHeight = 65;
//隣接するグラフ同士の余白
int graphMargin = 5;
//EEMLからのデータ入力
DataIn dIn;
//データのタグを記録する配列
String[] tag = new String[dataNum];
//データの値を記録する配列
float[] value = new float[dataNum];
//ひとつ前のグラフの座標を記録する配列
float[] lastX = new float[dataNum];
float[] lastY = new float[dataNum];
//データを取得した回数を記録
int count = 0;

void setup() {
  size(800,570);
  smooth();
  //指定した場所から、EEML形式のデータを5秒ごとに受信する
  dIn = new DataIn(this,"http://www.pachube.com/api/feeds/" + locationId + ".xml", "※ PachubeのAPI Keyを入力", 5000);
  background(0);
}

void draw() {
}

//グラフの表示を初期化する
void initGraph() {
  background(0);
  noFill();
  stroke(63);
  //グラフの枠線を描いて、それぞれの値のタグを表示
  for(int i=0; i < dataNum; i++){
    //枠線の表示
    rect(10, i * (graphHeight + graphMargin) + graphMargin, width - 20, graphHeight);
    //データのタグと、最大値、最小値を取得
    String title = dIn.getTag(i) + " (" + dIn.getMinimum(i) + " - " + dIn.getMaximum(i) + ")";
    //取得したタグ、最大値最小値をテキストで表示
    text(title , 12, i * (graphHeight + graphMargin) + 22);
  }
}

//グラフの表示を更新
void showUpdate() {
  stroke(0, 255, 255);
  //データの数だけ繰り返し
  for(int i=0; i < dataNum; i++){
    //表示する座標を計算
    int top = i * (graphHeight + graphMargin) + graphMargin;
    int left = 10;
    int h = graphHeight;
    int w = width - 20;
    //データX座標が表示領域の幅に納まるようにマッピング
    float x = map(count, 0, 100, 10, w);
    //データのY座標が、データの最大値と最小値の範囲に納まるようにマッピング
    float y = map(value[i], dIn.getMinimum(i), dIn.getMaximum(i), top + h, top);
    //ひとつ前の座標から現在の座標まで直線をひく
    if(count > 0){
      line(lastX[i], lastY[i], x, y);
    }
    //現在の値を記録
    lastX[i] = x;
    lastY[i] = y;
  }
}

//EEMLのデータを受信したら呼び出されるイベント
void onReceiveEEML(DataIn d) {
  //データの数だけ繰り返し
  for(int i=0; i < dataNum; i++) {
    //タグの文字列を取得
    tag[i] = d.getTag(i);
    //センサーの値を取得
    value[i] = d.getValue(i);
    println(tag[i] + " : " + value[i]); 
  }
  //もし最初のデータだったら、グラフを初期化する
  if(count == 0) {
    initGraph();
  }
  //グラフの更新
  showUpdate();
  //カウンターを加算
  count++;
  //もし指定したカウントを越えたら、リセット
  if(count > 100) {
    count = 0;
  }
}

Pachubeにデータを配信する

  • Pachubeにユーザ登録をすると、データの受信だけでなく、データの配信をすることも可能
  • 配信したデータは、Pachubeの地図上に表示され、世界中から閲覧可能となる
  • しかし、配信するにはグローバルIPが設定された、外部から閲覧可能なサーバが必要となる
  • 今回は、ローカルなネットワーク(LAN)の中で、擬似的にPachubeのデータ共有を試してみる

Arduino + ブレットボード側の配線

  • 光センサー、温度センサー、湿度センサーなど、変化する値を出力可能なセンサーをブレッドボードに配線
  • ArduinoのAnalog inに接続する
  • 例:照度センサーをとりつけた場合

Funnelライブラリのインストール

  • 今回はArduinoとProcessingの通信にFunnelライブラリを使用
  • Google CodeよりFunnelの最新版をダウンロードする http://code.google.com/p/funnel/
    • 右側にある「Featured downloads: 」より、Funnelの最新版のパッケージ「Funnel-….zip」を選択
  • 「ProcessingのSketchbookの場所/libaries/」以下に「funnel」フォルダを作成
  • Zipファイルを展開、フォルダ「libraries」の中にある「processing」フォルダの中身を、作成した「funnel」フォルダ以下にコピー

Arduino側の準備

  • Arduinoには、StandardFirmataを読み込んでアップロードしておく
    • File > Example > Firmata > StandardFirmarta からロード

Processing側のプログラム

  • Arduinoからの入力を、Funnelを経由して取得し、それをeeml形式で送信するプログラム
import processing.funnel.*; //Funnelライブラリの読み込み
import eeml.*; //EEMLライブラリの読み込み

//Arduinoクラスを定義
Arduino arduino;
//Arduinoから取得した値
float myValue
//Pachubeへ送出する値
DataOut dOut; 

void setup() {
  size(400, 200);
  frameRate(15);
  //Arduinoを初期化
  arduino = new Arduino(this, Arduino.FIRMATA);
  //5210番ポートから、Pachubeへデータを送信
  dOut = new DataOut(this, 5210);
  //データにタグを付ける
  dOut.addData(0,"Brightness");
}

void draw() {
  background(0);
  fill(255);
  noStroke();
  //Arduinoのアナログ入力0番の値を取得
  myValue = arduino.analogPin(0).value;
  //画面上にテキストで表示
  text("Brightness : " + myValue, 10, 20);
}

//データ送出のリクエストで呼びだされるイベント
void onReceiveRequest(DataOut d){
   //Arduinoのアナログ入力0番の値を取得
   myValue = arduino.analogPin(0).value;
   //Pachubeに値を送出
   d.update(0, myValue); 
}
  • プログラムを起動したら、以下のURLにWebブラウザでアクセスしてみる
  • 送出したEEML形式のデータが見えているはず

Pachubeのデータをシェアする

  • 教室内の他の人のEEMLデータを見てみる
  • システム環境設定 > ネットワーク を開く
  • その中に表示されているIPアドレスを控えておき、周囲の人同士で、IPアドレスを教えあう
  • それぞれのURLにアクセス
  • 他の人のアドレスが参照できるはず

[参考] Pachubeデータを世界に公開する

  • ユーザ登録をすると、Pachubeのデータを公開することも可能
  • 公開するには、ArduinoとProcessingの稼動しているPCが、外部から参照可能なIPアドレス(グローバルIP)に接続されていることが必要
  • Pachubeにサインアップした状態で、新規にフィードを生成するページへ http://www.pachube.com/feeds/new
    • Feed Typeを「automatic」に
    • Feed URLを、Arduinoが接続されたPCの「グローバルIP:5210」にする
      • 例:設定されたグローバルIPが、169.254.0.201だったとしたら、Feed URLは http://169.254.0.201:5210 となる
    • 地図をダブルクリックして、データを配信している場所を指定
    • その他配信できる情報は全て記入
    • 「Save Feed」をクリックして配信開始!!

サンプルファイルのダウンロード

授業内でとりあげたコードは下記からダウンロードしてください。