凹みTips

C++、JavaScript、Unity、ガジェット等の Tips について雑多に書いています。

on{x}が面白いので色々やってみた


はじめに

on{x} とは Microsoft が開発している Android 上で動く「日常のタスクを自動化してくれる」ツールです。Android の機能で何かイベントをキャッチ(ある場所についた、ある WiFi spot に接続した等)したらほげほげする、みたいなことができます。スマホは要はセンサの詰まった宝箱のようなものなので、わざわざこういったセンサを自作しなくともスマホを利用してあげれば、たいていのやりたいことは実現できます。似たようなコンセプトのものには Tasker が挙げられます。

両者の違いは、Tasker では XML でタスクを登録する一方、on{x} では JavaScript で色々できる点ですね。こちらのがグッときます。発表されてから大分立ちますが最近興味を持ってきたので始めてみました。

on{x} を使ってみる

登録の仕方は以下のサイトを参考にしてみて下さい。

基本的な使い方は facebook アカウントでログインしてレシピを作成、on{x} アプリをインストールした Android 端末で同じ facebook アカウントにログイン、すると自動で作成したレシピがダウンロードされてよしなに実行してくれる、といった感じです。

on{x} でレシピを作成する方法はおおまかに分類して3種類あります。

  • 1から書く
  • 公式レシピを利用する
  • 公式レシピのコードを利用して書く

ひとつひとつ紹介していきます。

1から書く


Create ボタンをポチッとすると上のような画面が開き、Hello world がサンプルコードとして予め入力された状態になります。

// This is a sample code for a basic rule you can create.
// When the script is saved, the code is pushed to the Android phone and pops a "Hello World" notification.

// Triggers the function when the screen unlocks
device.screen.on("unlock", function(){
	var notification = device.notifications.createNotification('Hello world!');
	notification.show();
	console.log('Hello World notification was sent to the phone');
});

on{x} というだけあって、device.screen.on というメソッドで unlock イベント(デバイスのロックを解除)を受け取り、Hello world を表示する通知を作成して実行しています。console.log の出力はブラウザ上で確認でき、log、info、warning、error と4段階のものを分類して使用することができます。その他詳細については以下の documentation のページを参照してみて下さい。

公式レシピを利用する


また、1から作らずとも、Microsoft が用意してくれているレシピを使用することもできます。イベントにはプレースホルダが用意されていてアプリケーションや時間を入力することができます。

公式レシピのコードを利用して書く

レシピのページから右上にある「<> code」ボタンをクリックすると、そのレシピのコードがあらかじめ入力されたページが表示され、そこから「create new code from source code」することができます。ちょっと公式レシピを改造したい時に便利です。

なんか作ってみる

屋根の下にいると GPS 役に立たないことが多いので特定の SSID を見つけたらほげほげして欲しいと思っていたら、よいサンプルコードを見つけました。

ほぼ写経ですが参考に書いてみました。

var networks = [
    {
		name    : "ACCESS POINT A",
		message : "Welcome @ A"
	},
	{
		name    : "ACCESS POINT B",
		message : "Welcome @ B"
	}
];

var detectedNetwork = null;

device.network.on('wifiOff', function() {
	if (detectedNetwork) {
		device.notifications.createNotification('Goodby from ' + detectedNetwork.name).show();
		detectedNetwork = null;
	}
});

device.network.on('wifiScan', function(signal) {
	if (!detectedNetwork) {
		var results = signal.scanResults;

		for (var i = 0; i < results.size(); ++i) {
			var wifi = results.get(i);

			for (var j = 0; j < networks.length; ++j){
				var network = networks[j];
				if(wifi.SSID == network.name) {
					device.notifications.createNotification(network.message).show();
					detectedNetwork = network;
				}
			}
		}
	}
});

特定の WiFi スポットに来たりログアウトするとブルッと震えて通知くるようになります。

on{x}の限界

on{x} は外部とのまだ連携に強くありません。例えば、とある場所についたら twitter で自動的に呟いて欲しい、といったことは oAuth 認証が出来なかったりするのでできません。ifttt(http://ifttt.com/)のようにサービスをつなげてくれたら良いのですが。。

on{x}の限界を超えて

twitter で呟かせる、といったことは Tweet on{x} というサービスを作ってくれている人が居るので実際にはこれを利用すればできると思います。

が、例えば家の電気をつけるなど twitter で呟かせること以外のことをしたい、となると詰みます。
そこで on{x} で出来ないことをするためには、自分でメッセージを受け取って処理するサーバを立てる必要があります。ちょっと面倒な感じもしますが、逆に考えればサーバを立てさえすればスマホのセンサを最大限に利用してなんでも出来てしまう、と捉えることもできます。
今回は twitter で呟かせるサーバを自分で立ててみます。といってもそんなに大事ではなく、node.js を利用すれば以下の様なコードを書くだけで簡単に呟かせるサーバを立てることができます。node.js を利用した twitter での呟かせ方については以下を参考にして下さい。

var twitter = require('twitter');
var http    = require('http');

// 10080 番ポートで HTTP サーバを立ち上げる
http.createServer(function(request, response) {

	// 引数を解析
	var argv = {};
	request.url.slice(1).split('&').forEach(function(arg) {
		var keyVal = arg.split('=');
		argv[keyVal[0]] =  keyVal[1];
	});

	// oAuth で twitter に接続
	var twit = new twitter({
		consumer_key        : argv['ck'],
		consumer_secret     : argv['cs'],
		access_token_key    : argv['atk'],
		access_token_secret : argv['ats']
	});

	// つぶやく
	var msg = argv['t'];
	twit.updateStatus(msg, function (data) {
		var statusCode = data.statusCode || 200;
		response.writeHead(statusCode, {"Content-Type": "text/plain"});
		response.write(statusCode.toString());
		response.end();
	});

}).listen(10080);

process.on('uncaughtException', function (err) {
	console.log('uncaughtException: ' + err);
});

URL の引数に oAuth 認証に必要なトークン等の情報を与えてあげれば中で node.js の twitter モジュールを利用して呟いてくれる感じです。まじめにやるのなら REST のような感じで xml でやり取りするのが良いと思いますが、今回は簡単のため適当に。

そして on{x} 側では次のようなコードを書きます。

device.screen.on("unlock", function() {
	device.ajax(
		{
			url     : 'http:///* ここにサーバの URL を入れる */:10080/ck=consumer_key&cs=consumer_secret&atk=access_token_key&ats=access_token_secret&t=unlocked',
			type    : 'GET',
			headers : {'Content-Type': 'plain/text'}
		},
		function onSuccess(body, textStatus, response){
			device.notifications.createNotification(body).show();
		},
		function onError(textStatus, response){
			device.notifications.createNotification(textStatus).show();
		}
	);
});

これで、デバイスをアンロックすると「unlocked」と oAuth 認証したアカウントでつぶやくことができます。
twitter で呟かせる部分を変えてあげれば、on{x} と連携していろんなことが出来るようになりますね!

おわりに

今作ってる音声認識家電コントロールとかと組み合わせて何か面白いことしたいなぁ。