Tesselにブラウザから命令してみる

ブラウザでTesselに命令をするテストです。といっても、よくあるWebSocketを使ったチャットアプリの仕組みと大体同じです。

![76931da233792736a72ad97577b42891.gif](https://qiita-image-store.s3.amazonaws.com/0/37412/b92e7c74-1727-bc11-fc5f-4cd69db79f81.gif)

##ソース
https://github.com/megurock/remote-tessel

##サーバ

httpサーバとWebソケットサーバを起動します。


```
$ node server.js
```

内容はこんな感じです。

```js:server.js
var http = require("http");
var ws = require("nodejs-websocket");
var fs = require("fs");

http.createServer(function (req, res) {
	fs.createReadStream("index.html").pipe(res)
}).listen(8080);

var server = ws.createServer(function (connection) {
	connection.nickname = null;
	
	connection.on("text", function (str) {
		if (connection.nickname === null) {
			connection.nickname = str;
			broadcast(str + " entered");
		} else
			broadcast("["+connection.nickname+"] "+str);
	});

	connection.on("close", function () {
		broadcast(connection.nickname+" left");
	})
})
server.listen(8081);

function broadcast(str) {
	server.connections.forEach(function (connection) {
		connection.sendText(str);
	})
}

```

##クライアント

###Tessel

Nodeモジュールをインストールします。今回は[気候センサー](http://start.tessel.io/ja/modules/climate)を使っています。

```
$ npm install nodejs-websocket climate-si7020
```

Tesselをwifiに接続します。

```
$ tessel wifi -n ネットワーク名 -p パスワード
```

Tesselをチャットに参加させます。

```
$ tessel run client.js
```

Tesselで実行するスクリプトです。「温度は？」か「湿度は？」というメッセージを受信したら、それぞれの値をセンサーから読み取り、チャットに流します。

```js.client.js
var ws = require("nodejs-websocket");
var tessel = require('tessel');
var climatelib = require('climate-si7020');
var climate;
var ipAddress = "192.168.0.5"; // サーバのIPアドレスです
var port = "8081";
var nickname = "tessel";

/**
 *
 */
function connectWebSocket() {

	// Set the binary fragmentation to 1 byte so it instantly sends anything we write to it
	ws.setBinaryFragmentation(1);

	var connection = ws.connect('ws://' + ipAddress + ':' + port, function() {
		console.log("Socket connected.");
		connection.sendText(nickname);

		connection.on("text", function(command) {
			if (command.indexOf('tessel') !== -1) {
				return;
			}

			switch(true) {
				case (command.indexOf('温度は？') !== -1):
					readTemperature(function(message) {
						connection.sendText(message);
					});
					break;
				case (command.indexOf('湿度は？') !== -1):
					readHumidity(function(message) {
						connection.sendText(message);
					});
					break;
				default:
						//
				}
			});
	});
}

function readTemperature(callback) {
	climate.readTemperature('c', function(err, temp) {
		var message;
		if (err) {
			message = err.message;
		} else {
			message = "現在のお部屋の温度は" + temp.toFixed(2) + "℃です。";
		}
		callback(message);
	});
}

function readHumidity(callback) {
	climate.readHumidity(function(err, humid) {
		var message;
		if (err) {
			message = err.message;
		} else {
			message = "現在のお部屋の湿度は" + humid.toFixed(2) + "%RHです。";
		}
		callback(message);
	});
}

function init() {
	climate = climatelib.use(tessel.port['A']);
	climate.on('ready', function () {
		console.log('Climate sensor is ready.');
		connectWebSocket();
	});
}


init();
```

###ブラウザ

ブラウザは普通のチャットアプリですね。

```html:index.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Tessel Remote Example</title>
<script>
var connection;
window.addEventListener("load", function () {
	var nickname = prompt("Choose a nickname")
	if (nickname) {

		connection = new WebSocket("ws://"+window.location.hostname+":8081");
		connection.onopen = function () {
			console.log("Connection opened");
			connection.send(nickname);
			document.getElementById("form").onsubmit = function (event) {
				var msg = document.getElementById("msg");
				if (msg.value) {
					connection.send(msg.value);
				}
				msg.value = "";
				event.preventDefault();
			}	
		};

		connection.onclose = function () {
			console.log("Connection closed");
		};

		connection.onerror = function () {
			console.error("Connection error");
		};

		connection.onmessage = function (event) {
			var div = document.createElement("div");
			div.textContent = event.data;
			document.body.appendChild(div);
		};
	}
})
</script>
</head>

<body>
<form id="form">
Message: <input size="50" id="msg"> <input type="submit" value="Submit">
</form>
</body>
</html>
```

## その他
ウチの部屋、メチャクチャ暑いです..。
Tesselを使えば、外出先から自宅の温度を確認しつつ、[リモコンでエアコンON](http://start.tessel.io/ja/modules/ir)とかできると思うので、引き続き遊んでみます。

## 参考
- [TesselでWebSocketをしゃべる](http://qiita.com/takayukii/items/5af9f55738f567422105)