JavaScriptもろくに書けない元アプリケーションエンジニアが、IoTをやりたくて、まずはMilkcocoaのお勉強から始めてみました。
きっかけ
そもそも、画像関連のエンジニアをしていたのですが、最近になってDeep Learningが流行りだしたので、それに伴いデータ送信側のIoTにも興味を持ち始めました。
そこでIoTLTを知り、参加(見るだけ ^^;)していたところ、「なんかみんな『Milkcocoa』ってのを使っているぞ?」てことで、試してみることにしました。
Milkcocoaって何よ?
しかし肝心の「Milkcocoa」が何者かよくわかりません。
そこで、本陣に切り込むことにしました。
...よくわからん。
チュートリアルを見ました。
ようやく理解できました。
タダで使えるキュー(非同期通信)ですね。
- タグつけて、データを送る
- タグで監視して、データを受け取る
で、送り側がIoT端末で、受け側がPCだと。(チュートリアルの例)
とりあえず仕組みはわかりましたので、実際に何かサンプルを作ってみることにします。
なお、ホスティングは「BitBalloon」がいいよと書いてあったので、それを使ってみます。
※「BitBalloon」に関してはこちらを参考にさせていただきました。
※実は「Heroku」も気になっている
サンプル:画像送信
★★★ まだ動いていません! ★★★
目指しているもの
- スマホを傾けると、傾きによって2種類の異なる画像が送られる
- 送られた画像をPC側で取得し、表示する
画像の送り方
Milkcocoa経由でバイナリデータを送る方法がわからなかったため、ここを参考にして、base64にエンコード/デコードしてみる。
送り側(スマホ)
- 最初に2種類の画像を読み込み、base64にエンコードしておく
- スマホを傾けたら、それぞれの画像をMilkcocoaに送る
- 下記ソース以外に「landscape.png」「portrait.png」のファイルを置いておく
<body>
<img crossOrigin="Anonymous" id="img_landscape" src="./landscape.png" /><br/>
<img crossOrigin="Anonymous" id="img_portrait" src="./portrait.png" /><br/>
<textarea id="log" rows="10" cols="40"></textarea>
<div id="output"></div>
<script src="https://cdn.mlkcca.com/v0.6.0/milkcocoa.js"></script>
<script src="main-sp.js"></script>
</body>
window.onload = function(){
var currentMode = 'portrait';
var output = document.getElementById('output');
var img_landscape = document.getElementById('img_landscape');
var img_portrait = document.getElementById('img_portrait');
var image_landscape = ImageToBase64(img_landscape, "image/png");
var image_portrait = ImageToBase64(img_portrait, "image/png");
document.getElementById('log').value = image_portrait;
// app_idは自分のものに書き換えてください
var milkcocoa = new MilkCocoa('app_id.mlkcca.com');
var ds = milkcocoa.dataStore('gravity');
window.addEventListener('devicemotion', function(e){
gravity = e.accelerationIncludingGravity;
output.innerHTML
= 'x方向: '+gravity.x
+ '<br>y方向: '+gravity.y;
sendModeFromGravityValue(gravity);
},true);
function sendModeFromGravityValue(g){
// 絶対値を取得
var x = Math.sqrt(g.x * g.x);
var y = Math.sqrt(g.y * g.y);
// portrait -> landscape
if(currentMode === 'portrait' && x > 8.5 && y < 1.5){
currentMode = 'landscape';
ds.send({mode: image_landscape});
document.getElementById('log').value = image_landscape;
}
// landscape -> portrait
if(currentMode === 'landscape' && x < 1.5 && y > 8.5){
currentMode = 'portrait';
ds.send({mode: image_portrait});
document.getElementById('log').value = image_portrait;
}
}
function ImageToBase64(image_src, mime_type) {
// New Canvas
var canvas = document.createElement('canvas');
canvas.width = image_src.width;
canvas.height = image_src.height;
// Draw
var ctx = canvas.getContext('2d');
ctx.drawImage(image_src, 0, 0);
// Image Base64
return canvas.toDataURL(mime_type);
}
};
受け側(PC)
- 送られてくるのを監視し、来たらコールバック関数に飛ばす
- コルバック関数内で「image.src」に直接base64のデータを代入する
- 下記ソース以外に「dummy.png」のファイルを置いておく
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<title>PC側</title>
</head>
<body>
<img crossOrigin="Anonymous" id="image" src="./dummy.png" />
<textarea id="log" rows="10" cols="40"></textarea>
<script src='https://cdn.mlkcca.com/v0.6.0/milkcocoa.js'></script>
<script src="main-pc.js"></script>
</body>
window.onload = function(){
var image = document.getElementById('image');
// app_idは自分のものに書き換えてください
var milkcocoa = new MilkCocoa('app_id.mlkcca.com');
var ds = milkcocoa.dataStore('gravity');
ds.on('send', changeViewFromSentMode);
function changeViewFromSentMode(sent){
image.src = sent.value.mode;
document.getElementById('log').value = sent.value.mode;
}
};
しかし動かない..._| ̄|○
「Milkcocoaへの送信」~「Milkcocoaからの受信」のどこかで失敗している模様。
(受信イベントが発火しない)
もしかしたら、送信できるデータのサイズの制限があるのだろうか...
(文字数が少ないと、ちゃんと送れることは確認済み)
後日談
見つけました。
※4KBより大きいメッセージの送信はできません。
とのこと。