題名の通り、RESTでmyThingsのIDCFチャンネルを使う話をしたいと思います。
myThingsってなに? IDCFチャンネルってなに? という方はmac008008さんが書いた
myThingsとIDCFチャンネルでできること
をご覧ください
ちなみにmyThingsを使って、こんなのを作ることができます!
myThingsから電気を操作
#なんでRESTなのか
IDCFサーバと自作デバイス間の通信にはMQTT、REST、WebSocketを保証しています。
そして、公式のスタートアップガイドはMQTTを使用しています。
しかし、MQTTを使用するためにはライブラリを入れる必要があり手間がかかりますし、また自作デバイスの種類によってはMQTTのライブラリがそもそも存在しない場合が有ります。
例えば、自分がmyThingsを使って開発していた当初はmbedやarduinoといったデバイスはMQTTのライブラリがなく、RESTを使って開発しました。
また、ハッカソンなどで開発を急いでおり、学習コストをかけずにさっさと通信したいという人の参考になればと思います。
今回、自分が用意したプログラムは計6つです
言語はPHP、JavaScript、Pythonの3種類
種類はIDCFへのデータ送信用、データ受信用の2種類
です。
iPhoneから通信を行いたい方はcalmscapeさんが書いたiBeaconをmyThingsのトリガーに利用するを参考にしてください
Androidからの通信を行いたい方は是非とも先駆者になってください!
それでは、まず送信側からソースコードを載せたいと思います
#送信用プログラム一覧
使っている組み合わせは下記のものになります
送信プログラムを実行したのちに、この組み合わせが実行されるとプッシュ通知が手元にやってきます
##PHP
$php 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
を行う必要が有ります
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
をターミナルから行うことで実行されます
# -*- 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になにもデータがない場合、レスポンスを返さないため、自作デバイス側がレスポンス待機状態になってしまい、そのままタイムアウトという流れでエラーが発生します。
受信プログラムを実行したのちに、この組み合わせが実行されると自作デバイスまで情報がやってきます
successと書かれている部分に通信成功時の処理を書いていただければと思います。
余談なのですが、天気チャンネルの「今日の天気予報」トリガーはいつでも発動するため、デバックにとても便利です
##PHP
$php 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
を行う必要が有ります
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
をターミナルから行うことで実行されます
# -*- 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 変換ツールを使いましたー
ありがとうございます!
send.jsはショッカソン2015に参加されたMC@チームカフェラテの茶圓さんからいただきました!
ありがとうございます!