RESTで行うmyThings×IDCFcloud

題名の通り、RESTでmyThingsのIDCFチャンネルを使う話をしたいと思います。

myThingsってなに？　IDCFチャンネルってなに？　という方はmac008008さんが書いた
<a href="http://qiita.com/mac008008/items/0f2cebc4b0728b89cd39">myThingsとIDCFチャンネルでできること</a>
をご覧ください

ちなみにmyThingsを使って、こんなのを作ることができます!
[myThingsから電気を操作](https://www.facebook.com/hajime.hata.33/videos/910027335701142/)

#なんでRESTなのか
IDCFサーバと自作デバイス間の通信にはMQTT、REST、WebSocketを保証しています。
そして、<a href="http://www.idcf.jp/cloud/iot/detail01.html">公式のスタートアップガイド</a>はMQTTを使用しています。
しかし、MQTTを使用するためにはライブラリを入れる必要があり手間がかかりますし、また自作デバイスの種類によってはMQTTのライブラリがそもそも存在しない場合が有ります。
例えば、自分がmyThingsを使って開発していた当初はmbedやarduinoといったデバイスはMQTTのライブラリがなく、RESTを使って開発しました。
また、ハッカソンなどで開発を急いでおり、学習コストをかけずにさっさと通信したいという人の参考になればと思います。

今回、自分が用意したプログラムは計６つです
言語はPHP、JavaScript、Pythonの３種類
種類はIDCFへのデータ送信用、データ受信用の２種類
です。

iPhoneから通信を行いたい方はcalmscapeさんが書いた<a href="http://qiita.com/calmscape/items/348bbaa392398539b140">iBeaconをmyThingsのトリガーに利用する</a>を参考にしてください
Androidからの通信を行いたい方は是非とも先駆者になってください！

それでは、まず送信側からソースコードを載せたいと思います
#送信用プログラム一覧
使っている組み合わせは下記のものになります
<img width="375" alt="IMG_0867.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/100189/8f1b257b-2643-c95b-3a04-68edb7c90a42.png">

<div class="myThings-recipe"><a class="myThings-recipe-inner" href="http://mythings.yahoo.co.jp/share/recipe?id=De2%5FNayJHXrgJQHbCnzahg%2D%2D" target="_blank"><img class="myThings-recipe-img" src="http://mythings.yahoo.co.jp/share/image/idcfrontier/wwwPush/1450781276"><div class="myThings-recipe-detail"><span class="myThings-recipe-title">IDCF受信確認</span>
<span class="myThings-recipe-url">http://mythings.yahoo.co.jp/share/recipe?id=De2%5FNayJHXrgJQHbCnzahg%2D%2D</span><div class="myThings-recipe-btnwrap"></div></div></a></div><link href="https://embed-things.mashroom.in/css/embed.css" rel="stylesheet">
上記のリンクをスマホからタップするとすぐにこの組み合わせが使えます。

送信プログラムを実行したのちに、この組み合わせが実行されるとプッシュ通知が手元にやってきます

##PHP
$php send.php
をターミナルから行うことで実行されます

```lang:send.php
<?php

$url ='http://{ip-address}.jp-east.compute.idcfcloud.com/data/{trigger_uuid}'
//sample $url ='http://xxx-xxx-xxx-xxx.jp-east.compute.idcfcloud.com/data/xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';


$headers = array(
	'meshblu_auth_uuid: {trigger_uuid}',
	'meshblu_auth_token: {trigger_token}',
);

$options = array('http' => array(
    'method' => 'POST',
    'header' => implode("\r\n", $headers),
));

$contents = file_get_contents($url, false, stream_context_create($options));

?>

```

##JavaScript
$node send.js
をターミナルから行うことで実行されます

事前に
$npm install w3c-xmlhttprequest
を行う必要が有ります

```lang:send.js
var XMLHttpRequest = require('w3c-xmlhttprequest').XMLHttpRequest;
var request = new XMLHttpRequest();
var url ='http://{ip-address}.jp-east.compute.idcfcloud.com/data/{trigger_uuid}'
//sample var url ='http://xxx-xxx-xxx-xxx.jp-east.compute.idcfcloud.com/data/xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';


request.open('POST', url);
request.setRequestHeader("meshblu_auth_uuid", "{trigger_uuid}");
request.setRequestHeader("meshblu_auth_token","{trigger_token}");
request.send();
```

##Python
$python send.py
をターミナルから行うことで実行されます

```lang:send.py
# -*- coding: utf-8 -*-

import uuid
import urllib
import urllib2

url ='http://{ip-address}.jp-east.compute.idcfcloud.com/data/{trigger_uuid}'
#sample url ='http://xxx-xxx-xxx-xxx.jp-east.compute.idcfcloud.com/data/xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

headers = {
	'meshblu_auth_uuid': '{trigger_uuid}',
	'meshblu_auth_token': '{trigger_token}'
}

values = {'data' : "test"}
data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
```

#受信用プログラム一覧
受信時は送信時と違いちょっと複雑になります。
なぜならば、タイムアウトの処理を行う必要があるからです。（といってもエラーを処理を追加しているだけなのですが）
IDCFCloudになにもデータがない場合、レスポンスを返さないため、自作デバイス側がレスポンス待機状態になってしまい、そのままタイムアウトという流れでエラーが発生します。

使っている組み合わせは下記のものになります
<img width="375" alt="IMG_0866.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/100189/27bd79d4-4826-92db-3def-9adf289a5717.png">

<div class="myThings-recipe"><a class="myThings-recipe-inner" href="http://mythings.yahoo.co.jp/share/recipe?id=79FjhO2GYV2Rd1iWraKgDw%2D%2D" target="_blank"><img class="myThings-recipe-img" src="http://mythings.yahoo.co.jp/share/image/yjweather/idcfrontier/1450781936"><div class="myThings-recipe-detail"><span class="myThings-recipe-title">IDCF送信確認</span>
<span class="myThings-recipe-url">http://mythings.yahoo.co.jp/share/recipe?id=79FjhO2GYV2Rd1iWraKgDw%2D%2D</span><div class="myThings-recipe-btnwrap"></div></div></a></div><link href="https://embed-things.mashroom.in/css/embed.css" rel="stylesheet">
上記のリンクをスマホからタップするとすぐに使えます。

受信プログラムを実行したのちに、この組み合わせが実行されると自作デバイスまで情報がやってきます
successと書かれている部分に通信成功時の処理を書いていただければと思います。

余談なのですが、天気チャンネルの「今日の天気予報」トリガーはいつでも発動するため、デバックにとても便利です

##PHP
$php receive.php
をターミナルから行うことで実行されます

```lang:receive.php
<?php

$url ='http://{ip-address}.jp-east.compute.idcfcloud.com/subscribe'
# sample url ='http://xxx-xxx-xxx-xxx.jp-east.compute.idcfcloud.com/subscribe'

$headers = array(
	'meshblu_auth_uuid: {action_uuid}',
	'meshblu_auth_token: {action_token}',
);

$timeout = 2.0;
$options = array(
	'http' => array(
		'method' => 'GET',
		'header'  => implode("\r\n", $headers), 
		'timeout' => $timeout,
	)
);

while(TRUE){
	try{
		$fp = fopen($url , 'r', false, stream_context_create($options));
		if($fp == false){	//失敗時
			continue;
		}
		print($fp);
		$str = fgets($fp);
		if(strlen($str) >0){
			echo 'success' ;
		}
	}
	catch (Exception $e)
	{	
		print('miss');
		print($e->getMessage());
	}

}
fclose($fp);
```

##JavaScript
$node receive.js
をターミナルから行うことで実行されます

事前に
$npm install w3c-xmlhttprequest
を行う必要が有ります

```lang:receive.js
var XMLHttpRequest = require('w3c-xmlhttprequest').XMLHttpRequest;
var request = new XMLHttpRequest();
var url ='http://{ip-address}.jp-east.compute.idcfcloud.com/subscribe'
// sample var url ='http://xxx-xxx-xxx-xxx.jp-east.compute.idcfcloud.com/subscribe'

request.open('GET', url);
request.setRequestHeader("meshblu_auth_uuid", "{action_uuid}");
request.setRequestHeader("meshblu_auth_token", "{action_token}");
request.send();

request.onreadystatechange = function (){
	switch(request.readyState){
		case 3:
			if(request.responseText.length > 0){
				console.log('sucess')
			}
			break;
	}
}
```
##Python
$python receive.py
をターミナルから行うことで実行されます

```lang:receive.py
# -*- coding: utf-8 -*-

import uuid
import urllib
import urllib2
import sys

print 'start'

url ='http://{ip-address}.jp-east.compute.idcfcloud.com/subscribe'
# sample url ='http://xxx-xxx-xxx-xxx.jp-east.compute.idcfcloud.com/subscribe'

headers = {
	'meshblu_auth_uuid': '{action_uuid}',
	'meshblu_auth_token': '{action_token}'
}



req = urllib2.Request(url, None, headers)
timeout = 1.0

while True:
	try:
		res = urllib2.urlopen(req, None, timeout)
		if len(res.msg)>0:
			print 'success'
	except:
		print 'timeout'

```

以上です。
いかがだったでしょうか？
とても単純なのですが、ところどころ知らないと苦労するところがあったと思います。
ぜひささっと解決したいときにお使いください。

#最後に：なぜ自作デバイス開発にmyThingsを使う必要があるのか
これについて、結構疑問に思う人が多いと思います
実際によく聞かれます
正直公開されているAPIならば、自分で実行した方がリアルタイムですし、内容も把握しているので正確です
自分がmyThingsを使うにあたって良いと思ったことを最後に書いて、この記事の締めにしたいと思います。
**1.APIを変更するときに便利**
　使ってみたけど微妙だったな、ってAPIはたくさんあると思います。しかし、開発コストを結構かけてしまったのもあって変更しずらいというのもあると思います。しかし、myThingsを使うとそこの変更がすべてUI上でできるので、変更も簡単ですし、開発コストも少なくて非常に楽でした

**2.スマホから実行できる**
　myThingsにはいますぐ組み合わせの実行を行う「手動実行」という機能があります。こちらを使うと、スマホのUIを作っていないのにスマホから自作デバイスを操作できるようになります。お手軽にスマホと連動できるので、自作デバイスをIDCFCloudに繋げただけなのにリッチなものをつくれます。

ぜひこの記事を読んで興味を持っていただけた方は、myThingsを使って自作デバイスを作ってみてください！

P.S.
組み合わせのOGP表示にはhimara2さんの作った[myThings シェアURL 変換ツール](http://embed-things.mashroom.in)を使いましたー
ありがとうございます！

send.jsはショッカソン2015に参加されたMC@チームカフェラテの茶圓さんからいただきました！
ありがとうございます！