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 ---- ##