2

赤外線学習リモコンKURO-RSのWebコントロールパネル作った

赤外線学習リモコンをWebブラウザから使えるようにした。SinatraとMongoDBで、RubyでBuffalo/玄人志向の赤外線学習リモコンを操作するで作ったkuro-rs-serverを操作する。


shokai/kuro-rs-control-panel – GitHub


これでアプリから様々な機器を操作できる。家に帰る前に暖房つけたりとかNFCでテレビ動かしたりとか。


機能はこれだけ。全部GUIとJSON APIがある。

  1. 赤外線を読む
  2. 赤外線データに名前をつけて保存する
  3. 名前を指定して赤外線を発射させる
  4. データ内容を指定して赤外線を発射させる


■画面
保存した赤外線データの一覧と、新規データの保存ボタンがある
KURO-RS Control Panel


赤外線データのpermalink。 /ir/(名前) にある。
学習ボタンを押してすぐKURO-RSに赤外線を当てると
KURO-RS Control Panel


読み取られる。保存したりその場で試し撃ちしたりできる。
KURO-RS Control Panel
画面下にAPIのヘルプがあって、
curl -d 'name=tv/ch2' http://localhost:8787/kuro-rs.json
のようにHTTP-POSTで名前を指定して赤外線発射、などの方法が書いてある。



■使ってみよう
Sinatraの他にMongoDBと、KURO-RSが必要。
このコントロールパネルはkuro-rs-serverと通信するので、サーバーとは別プロセスでkuro-rs-serverも起動して使う。

git clone git://github.com/shokai/kuro-rs-control-panel.git
cd kuro-rs-control-panel
bundle install
cp sample.config.yaml config.yaml
config.yamlを編集する。kuro-rs-serverのアドレスぐらいしか編集する必要ない。


kuro-rs-serverを起動する
kuro-rs-server /dev/tty.usbserial-00012a34b5 --port 8786


コントロールパネルも起動する
ruby development.rb
もしくはpassenger使うとよい。

2

IO-DATAのNFCタグリーダーをHTTP、WebSocket、Socketから使えるようにした

NFCタグリーダーをサーバーにした。
shokai/nfctag-server – GitHub


特殊なデバイスはみんなサーバーにしてHTMLとJSから使えるようにすればいい。
1つのハードウェアにいくつもアプリをぶら下げれるし、アプリはハードウェアと別のマシンで動かせるし、JavaScript書けるし、とにかく楽だ。


下は以前作ったWebSocket clientでnfc-tag-serverに接続してtagを読んでいるところ。
タグがある時はhex dumpされた文字列が、無い時はfalseが送信されてくる。同じ値がHTTPや普通のTCP Socketでも取れるようになっている。
NFC Tag Server



■NFCタグリーダー

これ使ってる。USB接続で、けっこうどこででも売ってる。これじゃなくてもlibnfcで動くデバイスならいけるはず。
ただしlibnfcでFeliCaが読めなかった。MIFAREタグなら読めた。

I-O DATA FeliCa&MIFAREカード対応 NFCリーダー・ライター「ぴタッチ」 USB2-NFC
アイ・オー・データ (2008-05-30)
売り上げランキング: 12161



■インストール
git clone git://github.com/shokai/nfctag-server.git
cd nfctag-server


Macの場合
brew install libnfc
gem install nfc eventmachine eventmachine_httpserver em-websocket args_parser
これで必要なライブラリがインストールされる。

Mac以外はlibnfcを自分でインストールすればたぶんok。Ubuntuは意外にもaptにlibnfc無かった。



■起動
./nfc-tag-server --http_port 8080 --websocket_port 8081 --socket_port 8082

これでHTTPとWebSocketと普通のTCP Socketのサーバーが同時に起動する。


それぞれ


HTTP-GET
curl 'http://localhost:8080'


WebSocket
## JavaScript
var ws = new WebSocket("ws://localhost:8081");
ws.onmessage = function(e){
Console.log(e.data);
};
websocket clientを使えばすぐ試せる



Socket
telnet localhost 8082

のような感じに接続して、tagのIDが読める。

2

RubyでBuffalo/玄人志向の赤外線学習リモコンを操作する

11月22-23日にSFC ORFというSFCの研究室の発表会があって、そこでデモするブツに使う部品としてBuffaloの赤外線学習リモコンのRubyラッパーを書きました。これで家に帰る前に暖房つけたりできてうれしいですね。

玄人志向のKURO-RSとBuffaloのPC-OP-RSを操作できます。

MacとLinuxと、試してないけどたぶんWindowsでも動く気がする。コードはgithubに置いてる

学習リモコン/KURO-RS/(1)使ってみる – 脳みそ沸騰中!のPerlのコードを参考にしました。

■PC-OP-RSを買う
気がついたらKURO-RSがどこにも売ってないんだけど、PC-OP-RSがKURO-RSと同じハードウェアで箱と付属ソフトが違うだけなのでどちらでも動かせます。

BUFFALO PCastTV2対応 PC用学習リモコンキット PC-OP-RS1
バッファロー (2006-09-10)
売り上げランキング: 4538



■インストール
gem install kuro-rs


そしてKURO-RSをMacやLinuxに刺す。
Windowsの人はドライバを入れてBuffaloアプリが動くことを確かめてからUSBポートに刺す。
KURO-RSはUSBポートに接続するとシリアルデバイスとして認識されます。MacやLinuxなら/dev/tty.usb****という名前になる。WindowsならドライバをインストールしていればCOM1とかCOM2とか名前がつく。


■赤外線リモコンを学習する
kuro-rsというコマンドがgemと一緒にインストールされています。

terminalで実行する
% kuro-rs /dev/tty.usbserial-0012a3b4
そして15秒以内に赤外線をKURO-RSの本体に当てると、termialに16進数で赤外線データが出力されます。


学習した赤外線を発射しましょう
% kuro-rs /dev/tty.usbserial-0012a3b4 ffffffff0300f0e0018083...
のように第二引数に16進数でデータを与えます。

これでテレビのチャンネルが切り替わるはず。


■自分のプログラムから使う
こんな感じでIOっぽく使えます。くわしくはexamplesディレクトリを見るといい。
require 'rubygems'
require 'kuro-rs'

# open KURO-RS
kr = KuroRs.open('/dev/tty.usbserial-0012a3b4')

# read
puts kr.read
## => hex dump (ffffffff0300f0e0018083...)

# write
kr.write 'ffffffff0300f0e0018083'

# close
kr.close

# block
KuroRs.open('/dev/tty.usbserial-0012a3b4'){|k|
k.verbose = true
puts k.read
## => hex dump (ffffffff0300f0e0018083...)
}


■Webアプリから使う
シリアルポートは複数プロセスで共有できないし、また複数スレッドから同時に書き込んだりもできないのでRailsやSinatraアプリにkuro-rs gemをそのまま組み込むのはオススメできません。

そういう時はkuro-rs-serverを使いましょう。


こうすると8080番portでhttpサーバーが起動します
% kuro-rs-server /dev/tty.usbserial-0012a3b4 --port 8080


curlから赤外線読み書きしてみる
# read
% curl 'http://localhost:8080'
# => hex dump (ffffffff0300f0e0018083...)


# write
% curl -d 'ffffffff0300f0e0018083...' 'http://localhost:8080'
readもwriteも正常に行われるとstatus 200が返ります。失敗すると200以外。

kuro-rs-serverを内部APIとしてRailsやSinatraから、あるいはAjaxから使うのが良いと思います。

0

canvasとwebsocketでお絵かき共有

http://canvas.shokai.org

HTML5のcanvasを使ってみたかったので作った。
websocketも使っているので、chromeかsafariで動く。ブラウザ2つ開いてみると、同期しているのがわかりやすい。

画像のURLを末尾につけるとその画像が読み込めて、マウスで線を引くとみんなでリアルタイムに描ける。Gyazoと合わせて使うと便利。
http://canvas.shokai.org/http://gyazo.com/365d02afdf4953d40ec904df5019aa13.png


ソースはgithubに置いた https://github.com/shokai/shared-canvas


こんな風に、オンラインゲームのマップを置いて、友達と「ここ攻めろ」みたいな指示を共有したいなと思って作ってみた。
http://canvas.shokai.org/http://gyazo.com/1b2f1f6b0df60aa2d0dfe3da79106a4e.png



canvasのプラグインは色々あるけど、canvasのAPIの操作感が変わりすぎる物ばかりだったので、とりあえず何も使わないで操作してみた → draw.js

Imageオブジェクトで画像を読み込んで、onloadイベント発生時にcanvasのサイズを変更するとぴったりのサイズになる。かならずdrawImage前にサイズ変更をすること。
92行目あたり

var draw_img = function(img_url, onload){
var img_tag = $('canvas#img');
ctx = img_tag[0].getContext('2d');
var img = new Image();
img.onload = function(){
img_tag.attr('width', img.width).attr('height', img.height);
ctx.drawImage(img, 0, 0, img.width, img.height);
if(onload && typeof onload == 'function') onload();
};
img.src = img_url; // 読み込み開始
};


rubyとem-websocketで作ったwebsocketサーバーは、daemontoolsで自動起動・復活するようにしてある。DBは無くて、最近10万本のlineの色と太さと座標データを保存している。
また線にはどの画像URLの線か、というデータも付いているので、これで画像URL毎に部屋分けを行っている。

5

Sinatra+Haml+jQuery入門

研究室の後輩にSinatraとhamlとjQueryを教えるために作ったテンプレートについて、ここにも書いておく

ソースコード https://github.com/shokai/sinatra-template
実際動いているもの http://masui.sfc.keio.ac.jp/sinatra-template/


git clone git://github.com/shokai/sinatra-template.git


■Sinatraを何に使うか
Sinatra+haml+jQueryが便利。
Railsと似てるけど、ちょっと違う。

個人的には
Rails → HTMLのページをいっぱい作るのに便利
Sinatra → 画面遷移あまりしなくて、同じURLのままjsonのAPIをjQueryのajaxで取得して動的に表示を変えるwebページを作るのには便利

に感じる。
でもSinatra自由すぎるので、ある程度実装パターンを知らないとメチャクチャになるのでこのテンプレートを参考にすると良いよ

個人的にはserial-http-gatewayと一緒に使ってデバイスと連動したwebページを作る、とかが手軽にできてよく使う。



■動かし方
gemでsinatra入れて、ruby development.ru
詳しくはREADME嫁


■テンプレートの解説
最低限の動作するおみくじアプリです
おみくじ結果をJSONで返すAPIがある
jQueryでajaxでJSON読んで表示する
hamlでhtmlを作る
開発用とデプロイ用の2種類のRackUp(*.ru)ファイル付き


■ファイルの説明
・README.md
 まず読め
・development.ru
 開発サーバーを起動し、main.rbとhelper.rbを読み込んでSinatraアプリを実行するスクリプト
・config.ru
 本番サーバーのapacheやnginxでsinatraアプリを実行するためのPassenger用スクリプト
・config.yaml
 ”やむる”形式の設定ファイルです。アプリのタイトルしか書いてない。
 ここに設定値を書くようにするとアプリを配布するのに便利
 (必要になったら)DBの接続設定などを書くと良い。
・Gemfile
 アプリで使うgemを書いておく
 bundlerでgemを管理する時に使う
・helper.rb
 起動時に一回だけ読み込まれる
 必要なライブラリをロードするコードはここに書く
 (必要になったら)データベースへの接続などをここで行うと良い。
 app_rootという関数が定義されている(重要)
 これにより、開発サーバー・サブドメインでの運用・サブディレクトリでの運用でも内部のURLがズレない
 jsからサーバーのAPIにアクセスする時、hamlでcssを読み込む時などに便利
・main.rb
 Sinatraアプリ本体
 HTTPでアクセスしてきた時のresponseを書く
 app_root/omikuji.json でアクセスしてきた時に、ランダムなおみくじを返す
・views/
 hamlを置くディレクトリ
・views/index.haml
 http://(app_root)/ にアクセスした時に表示されるhamlファイル
 index.hamlをどのURLの時に表示するかは、main.rbで指定している
 main.js, main.cssを読み込んでいる
 rubyの変数のapp_rootをjsの変数app_rootに渡している(重要)
・public/
 画像やjavascriptなどの静的ファイルを置くディレクトリ
・public/js/jquery.js
 最新版のjquery
・public/js/main.js
 index.hamlから読み込まれるJavaScript
・public/css/main.css
 index.hamlから読み込まれるcss

SinatraやjQueryの基本的な使い方についてはググる。ライブラリの入門サイトとかを頭から読むよりも既に動いているアプリのソースを読んでわからない所を調べるのが一番速い。


■工夫しているところ
そんなに多いわけでもないけど、
・config.ruとdevelopment.ruを分ける。developmentから起動した時だけsinatra/reloaderを使ってアプリを毎回リロードさせている
・helper.rbの中身は1プロセス毎に1回しか呼ばれないので、DBとの接続や設定ファイルの読み込みはmain.rbと分けてここに書いておくといい
・app_rootという関数を定義してあって、開発環境や本番環境でAPIのURLがずれないようにしている
haml内に書かれたRubyコードの動作についてはここにまとめた


■アプリの動作
ruby development.ruする→helper.rb読む→helperがyamlの設定ファイルを読む、app_rootという関数を作る→port8080でサーバーがthinに設定される→Sinatraアプリ(main.rb)を起動→main.rbは”/”へのアクセスにindex.hamlを返す、”/omikuji.json”にはランダムなおみくじと時刻を返す

ブラウザで”/”にアクセスする→cssとjsを読む、ajaxでおみくじを取得する関数がボタンに関連付けられる→ボタン押す毎におみくじ表示される



こんな感じで、ajaxでデータ取ってきてhtmlを書き換えるアプリの最低限のテンプレートを用意しました。
意外とDB無くてもglitchtweetTweetButton増井研オーディオAPIのようなものは作れるので、まずはDBなしでSinatra+Haml+jQueryで何か作ってみるのが良い。


DB使うときは、SQL系ならActiveRecordsかSequelかDataMapperあたりがメジャーなのかな?多分。そのへんをまず単体で使ってみて、適当にtwitterのクローラーとか作ってみると良い。
それからSinatraの中に混ぜて使ってみる。いきなりjsで画面が書き換えて、Sinatraもいじって、DBも使うとかやると確実に破滅するので一つずつやるのオススメします