Prototyping Lab: Recipe 33.4

by kotobuki
以下のコードで用いているenvironment idとAPI keyはダミーですので
このままでは実際には動きません。
♥0 | Line 73 | Modified 2010-04-20 22:43:27 | MIT License
play

ActionScript3 source code

/**
 * Copyright kotobuki ( http://wonderfl.net/user/kotobuki )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/rWiL
 */

// 以下のコードで用いているenvironment idとAPI keyはダミーですので
// このままでは実際には動きません。
package {
  import flash.display.Sprite;
  import flash.events.*;
  import flash.net.Socket;
  import flash.utils.Timer;

  import funnel.*;
  import funnel.ui.*;

  public class DataOutToPachube extends Sprite {
    private var arduino:Arduino;

    // センサに接続したピン
    private var sensorPin:Pin;

    // Pachubeと接続するソケット
    private var socket:Socket;

    // Pachibeで使用するenvironment id(例:"1234")
    private static const ENVIRONMENT_ID:String = "1234";

    // Pachubeで使用するAPI key
    private static const API_KEY:String = "YOUR_API_KEY";

    // タイマー
    private var pulseGenerator:Timer;

    public function DataOutToPachube() {
      // Arduinoボードを準備
      var config:Configuration = Arduino.FIRMATA;
      config.setDigitalPinMode(9, PWM);
      arduino = new Arduino();

      // センサに接続したピンとしてA0をセット
      sensorPin = arduino.analogPin(0);

      // ソケットを生成してイベントリスナをセット
      socket = new Socket();
      socket.addEventListener(Event.CONNECT, onConnect);
      socket.addEventListener(ProgressEvent.SOCKET_DATA, 
                              onSocketData);

      // 間隔5000msのタイマーをセットしてスタート
      pulseGenerator = new Timer(5000);
      pulseGenerator.addEventListener(TimerEvent.TIMER, 
                                      onPulse);
      pulseGenerator.start();
    }

    // タイマーで一定間隔ごとにPachubeに接続
    private function onPulse(e:TimerEvent):void {
      socket.connect("www.pachube.com", 80);
    }

    // 接続が完了したらデータストリームを更新
    private function onConnect(e:Event):void {
      updateDataStream(0, sensorPin.value);
    }

    // データストリームを更新
    private function 
    updateDataStream(id:uint, value:Number):void {
      // データをXML形式で準備
      // 参考:http://www.eeml.org/xml/005/minimal.xml
      var data:XML = <eeml xmlns=
                     "http://www.eeml.org/xsd/005">
                     </eeml>
      data.environment.data.@id = id;
      data.environment.data.value = value;

      // ソケットで送信するデータを準備
      // 参考:http://community.pachube.com/api
      var request:String = "";
      request += "PUT /api/feeds/";
      request += ENVIRONMENT_ID + ".xml HTTP/1.1\r\n";
      request += "Host: www.pachube.com\r\n";
      request += "X-PachubeApiKey: " + API_KEY + "\r\n";
      request += "Content-Length: ";
      request += data.toXMLString().length + "\r\n";
      request += "Connection: close\r\n";
      request += "\r\n";
      request += "<?xml version=\"1.0\" ";
      request += "encoding=\"UTF-8\"?>\r\n";
      request += data;

      // ソケットに対してデータを書き込んで出力バッファをフラッシュ
      socket.writeUTFBytes(request);
      socket.flush();
    }

    // データストリーム更新後にPachubeから返ってくる
    // リプライをパースして結果を表示
    private function onSocketData(e:ProgressEvent):void {
      // ソケットから受信したデータを読み出して行単位に分割
      var receivedData:String 
        = socket.readUTFBytes(socket.bytesAvailable);
      var headerArray:Array = receivedData.split("\r\n");

      // 分割した行の中から"HTTP/1."で始まる行を取り出して
      // HTTPステータスを表示
      for each (var headerLine:String in headerArray) {
        if (headerLine.indexOf("HTTP/1.") != -1) {
          var httpStatusParts:Array = headerLine.split(" ");
          if (httpStatusParts.length >= 3) {
            var httpStatusCode:int 
              = parseInt(httpStatusParts[1]);
            trace("HTTP status code: " + httpStatusCode);
          }
        }
      }
    }
  }
}