キノコやってみた Pepper ｘMESH = トントン相撲

# MESHボタンタグを使ってPepperでトントン相撲
Pepperのタブレットに写る力士を、MESHボタンタグを使ってトントン相撲させてみた！
http://meshprj.com/jp/tag/MESH-100BU-Button.html

## MESH側
こんな感じでMESHのカスタムタグの動作を記述。
ここではMESHボタンタグを押したら、ローカルサーバーにrequestを投げているだけで

```
var requestAjax = function(endpoint, callback) {
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function(){
		if (this.readyState==4 && this.status==200) {
			callback(this.response);
		}
	};
	xhr.responseType = 'json';
	xhr.open('GET',endpoint,true);
	xhr.send(null);
};

requestAjax("http://192.168.128.169:3000/foo", function(response){
	alert(response);
});
```

## ローカルサーバー側
node

```
var WebSocket = require('ws');
var express = require('express');
var app = express();

// MESHからの通知を受けるためにコネクションを張る
var server = app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

// Websocketのサーバー側の実装
var wss = new WebSocket.Server({server: server});

var connections = [];
wss.on('connection', function connection(ws) {
  console.log("[SERVER] connection");

  // PepperがWebsocketに接続したら、コネクション情報（connections）として保持
  connections.push(ws);
  ws.on('message', function(message) {
    console.log('SERVER received: %s', message);
    connections.forEach(function(c) {
      c.send(message);
    });
  });
  ws.on('close', function () {
    console.log('close');
    connections = connections.filter(function (conn, i) {
      return (conn === ws) ? false : true;
    });
  });
});

var client = new WebSocket('ws://192.168.128.169:3000/');
client.on('message', function(message) {
  console.log("CLIENT received: %s", message);
});

// MESHから叩かれるAPI
app.get('/hoge', function(req, res) {
  var data =  {mesh: '1'};

  // Pepper側に通知
  client.send(JSON.stringify(data));
  res.send(data);
});

app.get('/foo', function(req, res) {
  var data =  {mesh: '2'};

  // Pepper側に通知
  client.send(JSON.stringify(data));
  res.send(data);
});
```

## Pepper
websocketを使えるようにするために、githubからダウンロード。コレグラフプロジェクトのlib/websocketに配置。
https://github.com/websocket-client/websocket-client/tree/master/websocket

```
import thread, time, json, urllib, urllib2, sys, os, threading, base64

class MyClass(GeneratedClass):
    def __init__(self):
        GeneratedClass.__init__(self)

    def onLoad(self):
        self.memory = ALProxy("ALMemory")
        self.connectionToken = None
        self.framemanager = ALProxy("ALFrameManager")
        self.ws = None
        self.ws_connection_retry = 0
        pass

    def onUnload(self):
        self.connectionToken = None
        self.framemanager = None
        self.ws.close()
        self.ws = None
        self.ws_connection_retry = 0
        pass

    def onInput_onStart(self, pepper_id):
        self.init_read_library()
        self.init_websocket_connection()
        pass

    def onInput_onStop(self):
        self.onUnload() #it is recommended to reuse the clean-up as the box is stopped
        self.onStopped() #activate the output of the box

    def ws_on_message(self, ws, message):
        receive = json.loads(message)

        if str(receive["mesh"]) == "1":
            self.output_mesh1("1pushed");
        else:
            self.output_mesh2("2pushed");

    def ws_on_error(self, ws, error):
        self.output_connection_error()
        pass

    def ws_on_close(self, ws):
        self.logger.info('connection closed')
        pass

    def ws_on_open(self, ws):
        self.ws_connection_retry = 0
        self.logger.info('connection open')
        pass

    def init_websocket_connection(self):
        import websocket
        websocket.enableTrace(True)

        websocket.setdefaulttimeout(500)

        websocketUrl = "ws://192.168.128.169:3000"

        self.ws = websocket.WebSocketApp(websocketUrl,
            on_message = self.ws_on_message,
            on_error = self.ws_on_error,
            on_close = self.ws_on_close)

        self.ws.on_open = self.ws_on_open

        self.ws.run_forever()

        pass


    def init_read_library(self):
        self.folderName = os.path.join(self.framemanager.getBehaviorPath(self.behaviorId), "../lib/")

        if self.folderName not in sys.path:
            sys.path.append(self.folderName)
    ## ---- END INITIALIZE ---- ##
```