この記事はVOYAGE GROUP エンジニアブログ Advent Calendar 2014の13日目の記事です。 ちょっと前に、業務用のバスボタンを買ったので、バスボタンを押してiPhoneアプリのビルドができるシステムをつくってみました。 ビルドだけじゃなくて、バスボタンで起動、バスボタンでリリース、バスボタンでデプロイ……など、応用範囲が広いので、バスボタンをお持ちの方はぜひトライしてみてくださいね。
バスボタン
5月にやってた東急バス祭りでバスボタンを買いました。
https://twitter.com/TachibanaKaoru/status/462446028520570882
会社に持って行ったら、「やっぱりこれ押してデプロイできるといいよねー」と言われたので、とりあえずボタンを押してビルドできるシステムをつくってみることにしました。
Network処理が中心になるので、RaspberryPiを使って構成してみることに。
Raspberry Piの設定
まずは、Raspberry Piの設定から。 準備したのはこちらです。
- Raspberry pi(Model B)
- SD Card (500MB)
- HDMIケーブル
- プロジェクター
- USBキーボード
- USBマウス(結局使わなかった)
- USBケーブル(Micro USB-USBのタイプ)
- 無線LANアダプタ(USBにさすタイプ)
まずは、SD CardにRaspberry PiのOSをいれます。
まずはこちらからOSをダウンロード。 http://www.raspberrypi.org/downloads/ いろいろありますが、私はRASPBIANを選びました。
まず、最初にターミナルを起動して、df -hを実行します。 そのあと、SDカードをMacにマウントして、さらに df -hを実行します。 このときに増えている行がSDカードのディスク名になります。 私は disk4s1 という感じで表示されていました。
このディスク名(後半は省略してよいらしい)を指定して、アンマウントします。
sudo diskutil unmount disk4
そのあとに、そのディスク名と、ダウンロードしたファイルを指定してSDカードにイメージをかきこみます。
sudo dd if=2014-09-09-wheezy-raspbian.img of=/dev/rdisk4 bs=1m
(私はこの書き込みに2、3時間かかりました。)
さて、書き込みが完了したら、そのSDカードをRaspberryにさします。 さらに、USBマウスとキーボードを接続して、HDMIケーブルでプロジェクターと接続。 (別にプロジェクターではなくて適当なディスプレイでよいと思います。うちにはプロジェクターしかなかったので……) 最後にUSBケーブル(Micro USB-USBのタイプ)を電源(Macなどでも可)にさすと、RaspberryPiが起動します。
拡大するとこんな感じ。
起動すると、初期設定画面が表示されるので、そこで設定を変更します。 設定項目は多いですが、特に変更しなくても大丈夫です。 Advanced Optionsのなかにある、SSH経由のログインはonにしておいてください。
設定をおえると、OSが起動します。 (プロジェクターで設定すると、文字がよみにくいのでおすすめしません。)
無事に起動したところで、無線ネットワークの設定をします。
最初に/etc/network/interfacesファイルを変更。
sudo vi /etc/network/interfaces
下記の内容にしてください。
auto lo iface lo inet loopback iface eth0 inet dhcp allow-hotplug wlan0 iface wlan0 inet dhcp wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf iface default inet dhcp
次に無線LANのSSIDとパスワードを登録。 wpa_passphraseに自分の無線LANのSSIDとpasswordをいれてください。
wpa_passphrase mySSID myPassword
そうすると、このような出力が出ます。
network={ ssid="mySSID" #psk="myPassword" psk=12345678903b0c61064a34a76324eb5fa338c9a324f7a41b0c41424466fbac4c }
これに、無線LANの暗号化についての情報を加えます。
うちは、AirMac Extremeで「WPA/WPA2 パーソナル」の設定にしていたので、「WPA-PSK TKIP」ということなんだそうです。 その情報をあわせると、下記のようになるので、これを/etc/wpa_supplicant/wpa_supplicant.confに保存します。
network={ ssid="mySSID" proto=WPA pairwise=TKIP group=TKIP psk=12345678903b0c61064a34a76324eb5fa338c9a324f7a41b0c41424466fbac4c }
ここで再起動をすると、無線LANがつかえるようになっているはずです。
sudo reboot
ここまで設定すると、IPアドレスを指定してsshログインできるようになっていますが、さらに、avahi-daemonをいれると、Bonjour経由でホスト名でログインできるようになるので、おすすめです。
sudo apt-get update sudo apt-get install avahi-daemon
これで、無線LANでホスト名(デフォルトでは、raspberrypi.local)を指定してsshログインできるようになりました。
ピン入力を読み込む
次は、Raspberryで入力をハンドリングしてみます。
Raspberryには、26本のピンがついていますが、そのうちの一本(GPIO24)をつかって入力の値を見てみます。
GPIO24を使う宣言。
echo 24 > /sys/class/gpio/export
GPIO24のフォルダーに移動
cd /sys/class/gpio/gpio24
GPIO24を入力に使う宣言
echo in > direction
これでGPIO24に電流が流れると /sys/class/gpio/gpio24/value
ファイルの中身が1となり、とまると0になるようになります。
バスボタンの設定
さて、次はいよいよRaspberryPiとバスボタンの接続です。 バスボタンは業務用部品なので、回路図やガイドなどがありません。 なかを開けてみたり、バス降車ボタン買っちゃいましたのページを参考にして、とりあえず、こうつなげばスイッチのon/offの入力がとれることがわかりました。
ただし、ボタンを押したときに光る「とまります」ランプのつけ方はまだ不明です……。
ボタン入力検知スクリプト
さっきGPIO24で入力を検知するようにしたので、その値からイベントを起動するスクリプトが必要です。
Raspberry Piには、pi_piperやWiringPiなどの専用のライブラリがあるので、それをつかえばPINの検出などが楽にハンドリングできるようになっています。
ただ、今回はpi_perはインストールに失敗、WiringPiはインストールできたものの、PINの認識がうまくいきませんでした。
結局valueファイルに入ってる値をチェックするだけならシェルでもいいじゃん、ってことで、結局はライブラリをつかわず、地道にシェルをかきました。
1秒ごとにvalueファイルをチェックして、1になっていたら指定されたAPIをcurlします。 (curlで指定しているAPIはあとで作成します。)
#!/bin/sh valuefile=/sys/class/gpio/gpio24/value buttonstate=0 while true do while read line do # echo $line if [ $line = "1" ] && [ $buttonstate -eq 0 ] then echo "bus button is pressed!" curl http://maple.local:3000/users buttonstate=1 else echo "....wainting" fi done < $valuefile sleep 1 done busbutton.sh (END
ビルドサーバーのAPIの用意
さて、次にビルドサーバーのAPIを準備します。
ビルドサーバーには、自分のMacBook Airを使います。
私の MacBook AirにはOS X Serverがいれてあり、Xcode Botで自動ビルドできるようになっています。 このビルドをAPI経由で実行できればいいかなと思っていたんですが、現バージョンのOS X Serverではできなさそうです。(古いOS X Serverではできたようなのですが。)
仕方がないので、OS X Serverにデフォルトで入っているWeb Server(Apache)のPython wsgiを使おうとしたんですが、設定が複雑で、リタイア。
結局、自分のMacBook AirにRuby on Railsでサーバーをたてることにしました。
Ruby on Railsのチュートリアルに従って、Ruby On railsをインストール。 buildappというrailsのアプリを作成。
cd /buildapp/app/views/users/index.html.erb vi index.html.erb
自動生成されたファイルから、ビルド用のスクリプトが起動されるようにしました。
<!-- ここでビルド用のスクリプトを起動 --> <% value = %x( /Users/toyship/Desktop/buildapp/buildapp/app/views/users/build.sh ) %> <table> <tbody> <% @users.each do |user| %> <tr> <td><%= user.name %></td> <td><%= user.email %></td> <td><%= link_to 'Show', user %></td> <td><%= link_to 'Edit', edit_user_path(user) %></td> <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td> </tr> <% end %> </tbody> </table> <br>
ビルドスクリプト
さて。さらに、サーバーAPIから起動されるビルドスクリプトを作ります。
Xcodeのビルドをするだけなので、xcodebuildだけかいておけばいいんですが、せっかくなので、クリスマスらしくafplayで音楽再生機能も追加。ハレルヤコーラスです。 さらにそれっぽくなるように、 sayで文章を読ませるようにしてみました。
(本当は、ビルドが終わったらiTunes Connectにアップロードするとかちゃんとした機能をつけたかったんけど、なんだかどんどん変な方向にずれていきます……。)
say -v Kyoko "hello. バスボタンがおされました!プログラムを開始します。" say -v Alex "Bus button is pressed. we will start special program" say -v Cellos "Music Start!" afplay /Users/toyship/Desktop/Hallelujah.m4a & cd /Users/toyship/Desktop/christwork/Christmas /usr/bin/xcodebuild -configuration Debug say "任務が完了しました。" say -v Alex "Mission Completed." say -v Alex "Have a nice Christmas!" & say -v Otoya "よいクリスマスを!" & say -v Kyoko "よいクリスマスを!" &
say
sayは与えた文字列を音声出力してくれるコマンドだけど、再生時のvoiceの設定もできます。
たとえばこれだと、日本語の男性音声のおとやさんが「あけましておめでとうございます」といってくれます。
say -v Otoya "あけましておめでとうございます"
-vオプションに?をつけて起動すると、インストールされていれるvoiceをすべて表示してくれます。
say -v ?
なお、再生できる音声の種類が少ない場合、システム設定でダウンロードすると音声が増えます。
せっかくなので、Xcodeのビルド前、ビルドあとにも、sayで音声出力するスクリプトを追加。
これでビルドサーバー側の準備も完了です。
セットアップ
やっと準備がおわったので、いよいよセットアップ。 RaspberryPiの24ポートで先ほどのボタン検知用スクリプトを実行。
無事ビルドもできました。 かなり盛大な無駄ですが、せっかく買ったバスボタンを有効に使えたので、満足です。
さて、明日は、社内バーの存在確率が一番高い @a_macbee の出番です。