売上目標達成時にオフィスにファンファーレを盛大に轟かす方法を書くよ

image

IT系な企業だとオフィスがシーンと静まり返っていることもありますが、
あまりに静かだとメンバーの士気が上がっていきません。
Tokyo Otaku Modeのオフィスでは、Raspberry PiにNode.jsを入れてスピーカーを繋いだものがオフィスの片隅に置かれていて、デイリーの売上目標を達成時にファンファーレを流すようにシステム化しており、メンバーの士気を上げるのに一役かっています。
(誰もいない休みの日にも売上目標を達成するとファンファーレが鳴り響きます(๑´ڡ`๑))

さて今回は、そのシステムがどのように構築されているかを解説します。

Raspberry Pi

Raspberry Pi Type B 512MB を選びました。
スピーカーやモニタなどはオフィスに転がっているものを使いました。

セットアップ

NOOBS(New Out Of the Box Software) で入れることにします。
詳しくは http://www.raspberrypi.org/help/noobs-setup/ に書かれています。

ダウンロード からNOOBSイメージを、SD FormatterからSDカードのフォーマット用アプリケーションをダウンロードします。

HDMIモニタ、USBキーボードを繋いでおきます。
NOOBSが入ったSDカードを挿して起動すると、OS選択になるのでRaspbianを選びます。

RaspbianはDebianをRaspberry Piに最適化したOSで、公式の推奨OSでもあります。

OSのインストールが完了すると初期設定画面になります。

初期設定でSSHはEnableにしておきます。
また、デスクトップは不要なのでboot_behaviourはNOにしておきます。

初期設定が終わると、ユーザ名pi、パスワードraspberryでログインできるようになります。

ネットワークログイン設定

ホスト名で繋ぎたいので、Bonjour でマシンを見つけれるように Avahi を入れます。

1
2
$ sudo apt-get update
$ sudo apt-get install avahi-daemon

これでMacから

1
$ ssh pi@raspberrypi.local

で接続出来るようになります。

音を鳴らす

今回はスピーカーをステレオジャックにつないでHDMIを繋がないので、ステレオジャック優先にします。

1
$ amixer cset numid=3 1

この状態で、wavファイルならaplayコマンドで鳴らすことが出来ます。
録音したり、フリーWAV素材からファンファーレっぽいメロディを取得し、fanfare.wavという名前で配置しておきます。

1
$ aplay fanfare/fanfare.wav

ててててってってー♪

はい、鳴りましたね。

Node.jsを入れる

ここまででRaspberry Piで音は鳴るようになったので、Node.jsを入れてプログラムで色々APIを叩いて条件によって音を鳴らせるようにします。

Node.jsのインストールは時間がかかるので、screenを使えるようにしておくと便利です。

1
2
$ apt-get install screen
$ screen

Node.jsのインストールは nvm を使いました。

1
2
3
4
5
$ apt-get install wget
$ wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.15.0/install.sh | bash
$ nvm install 0.10
$ nvm use 0.10
$ nvm alias default 0.10

プログラムを書く

Web APIを叩くのであれば、 superagent を使ってサクッと書きます。

1
2
3
4
5
6
7
request = require('superagent')
request
.get('<url>')
.auth('id', 'pass')
.end(function(res){
// res.body
})

みたいにしてJSONのデータを取りに行けば、簡単にWebサービスの情報を元に処理を行うことが出来ます。

その後、データが条件を満たしていれば音を鳴らすようにします。

aplayで音が鳴らせることが確認できているので、単純に音を鳴らすコマンドをspawnしてやれば音が鳴ります。

1
2
3
4
5
6
7
8
9
10
Promise = require 'bluebird'
spawn = require('child_process').spawn
ringFanfare = ->
new Promise (resolve, reject)->
child = spawn 'aplay', ['fanfare.wav']
child.on 'exit', (c)->
if c is 0
do resolve
else
reject c

cronの設定

ひとまず、データを取りに行き、条件を満たしたかどうかで音がなるようになりました。
定期的にデータをチェックさせにいくのでcronに登録しておきます。

1
$ crontab -e

nano エディタが起動するので、1時間に1回チェックさせにいくには

1
2
PATH=/home/pi/.nvm/v0.10.26/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 0 * * * cd /home/pi/fanfare; coffee app.coffee >> /home/pi/fanfare/app.cooffee.log 2>&1

のように書いて保存します。

ファンファーレだけでは味気がない

ここまでで、定期的にデータをチェックし、条件を満たしたかどうかによって決められた音が鳴るようになりました。

ただ、それだけだと変化が少ないので、APIで取れた値を読み上げるように変更してみましょう。

HOYA Service CorporationのVoiceText Web APIというのがちょうどRaspberry Piを設定した頃に出てきていたので、これをラップするnpm moduleを公開し、利用しました。

node-voicetext

これを使って文章を喋らせることができます。

また、Node.jsから直接スピーカーに音を出すのには node-speaker を使うと便利です。

node-speakerのインストールには

1
$ sudo apt-get install libasound2-dev

が必要です。

1
2
3
$ npm install node-voicetext
$ npm install speaker
$ npm install coffee-script

この2つを組み合わせると、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
require 'coffee-script/register'
fs = require 'fs'
stream = require 'stream'
Speaker = require 'speaker'
VoiceText = require 'node-voicetext'
voice = new VoiceText('<your api key>')
text = process.argv[2] or 'きょうも いちにち がんばるぞい'
voice
.speaker(voice.SPEAKER.SHOW)
.emotion(voice.EMOTION.HAPPINESS)
.emotion_level(voice.EMOTION_LEVEL.HIGH)
.pitch(100)
.speed(100)
.volume(200)
.speak text, (e, buf)->
return console.error e if e
speaker = new Speaker
channels: 1
bitDepth: 16
sampleRate: 16000
bufferStream = new stream.Transform
bufferStream.pipe speaker
bufferStream.push buf
do bufferStream.end

というようなプログラムを書けば、いろいろ喋らせることができます。

aplayをspawnしている部分を書き換えればWeb APIで取れたデータをそのまま喋らせることもできます。

定時のラジオ体操アナウンスをさせたり、朝の挨拶させたり、今日の売上喋らせるなど色々応用が考えられますね。

まとめ

1台Raspberry Piがあると、色々使えて便利です。

Tokyo Otaku ModeではRaspberry PiにわざわざNode.jsを入れてまでNode.jsでやりたいんだというこだわりのある熱いエンジニアを募集しています。
興味のある方はこちらからご応募ください。