今回は、Arduino使ってWebにデータ飛ばしてみます!
ArduinoでWebにデータ飛ばす、となるとだいたいfluentdに投げて
elastic searchとkibanaでビジュアライゼーションみたいな感じの構成を取ることが多いと思いますが
今回はSalesforceに直接投げます。
直接投げると言っても、Arduino自体はSSLサポートしていないので
Web経由でプロキシを介して通信をする
シリアル通信経由でArduinoと直接つないでいるPCから通信をする
Arduino yunを使ってyunのLinux側のcurlで通信をする(ことが出来るらしい)
といった手段を取る必要があります。
今回は1の方法で”ボタンを押すとArduinoからChatterに投稿する”というモノを作ります。
参考サイト:
Qoosky - 電子工作でインターネットに無線接続して通信を行う (Arduino)
0. 準備
必要な物は以下になります。・Arduino Uno R3
・タクトスイッチ
・ジャンプワイヤとか抵抗とかブレッドボード
Arduino単体ではWebに飛ばせないのでEthenet Shieldを装着してください。
ちびファイは無くてもOKですが、無いとLANケーブルをArduinoに繋げるハメになり
配線がもどかしいので無線LANコンバータがあると非常に便利です。
電子回路関連はArduinoのスターターキットを買うと一式まとめて買えるのでオススメ。
1. 回路等の組み立て
回路は以下のようになります。スイッチ押したら電気通るだけの超シンプル構造です。ちなみに、この図はfritzingを使ってます。回路図とか書くときは便利らしい。
実際はこんな感じになります。上のLANケーブルはちびファイに繋がってて、下はPCと繋がってます。
2. Arduinoにプログラムを書き込む
Arduinoのマイコンボードに以下のプログラムを書き込みます。スイッチ押すとWeb ProxyにGETリクエストが飛びます。
#include <SPI.h>
#include <Ethernet.h>
const int BUTTON = 7;
int val = 0;
int old_val = 0;
//ethernetシールドのmacアドレス
byte mac[] = {0x**, 0x**, 0x**, 0x0F, 0x8B, 0x8A};
//Web proxyのIPアドレス
IPAddress server(192,168, 1, 2);
EthernetClient client;
//http接続がclose状態であればtrue
boolean isClose = true;
void setup(){
pinMode(BUTTON, INPUT);
Serial.begin(9600); //シリアル通信はデバッグ用
Ethernet.begin(mac);
}
void loop(){
val = digitalRead(BUTTON);
if (val == HIGH && old_val != val && isClose) {
if (client.connect(server, 80)) {
Serial.println("connect");
sendHttpRequest();
}
delay(10);
}
old_val = val;
if (client.available()) {
char c = client.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!client.connected() && !isClose) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
isClose = true;
}
}
//Web Proxyにデータを送信
void sendHttpRequest() {
isClose = false;
client.println("GET /salesforce/arduino-proxy.php HTTP/1.1");
client.println("Host: 192.168.1.2");
client.println("Connection: close");
client.println();
}
3. ArduinoとSalesforceをつなぐWeb proxyサーバの設定
適当なローカルネットワーク上のPCにWebサーバをインストールして、phpが動くように設定。ファイアーウォールの80番を開けるのもお忘れなく。
参考URL:ja:zoo:window7firewall [McNeel Wiki]
phpは以下を設置。
接続アプリ作るの面倒だったのでSOAPでログインしてSessionIDを拝借するスタイルで書いてます。
<?php
require_once("./phptoolkit/soapclient/SforcePartnerClient.php");
define("SF_USERNAME", "input your username");
define("SF_PASSWORD", "input your password");
$arduino_ip = "192.168.1.7";
//arduinoからの通信のみを許可する。
if ($_SERVER["REMOTE_ADDR"] !== $arduino_ip) {
echo $_SERVER["REMOTE_ADDR"];
exit();
} else {
echo "success";
}
$connection = new SforcePartnerClient();
$soapclient = $connection->createConnection("./phptoolkit/soapclient/partner.wsdl.xml");
$login = $connection->login(SF_USERNAME, SF_PASSWORD);
preg_match("/(https:\/\/.+?)\/.+/", $connection->getLocation(), $match);
$base_url = $match[1];
$body = array(
"body" => array(
"messageSegments" => array(
array(
"type" => "Text",
"text" => "hello chatter with arduino!!"
)
)
)
);
$response = httpRequest($connection->getSessionId(), "POST", $base_url . "/services/data/v30.0/chatter/feeds/news/me/feed-items", json_encode($body));
$connection->logout();
function httpRequest($sessionId, $method, $url, $data) {
$ch = curl_init();
if($method == "POST"){
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
} else {
curl_setopt($ch, CURLOPT_URL, $url . "?" . $data);
}
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type:application/json", "Authorization: Bearer " . $sessionId));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
これで、スイッチを押すとWeb Proxyを介してChatterにフィードが投稿されます。
今回はスイッチでしたが、センサ等でも基本構造は同じです。
例えば、センサである閾値を越えたらSalesforceにデータを格納みたいなことも出来ます。