Raspberry PIとUSBマイクとMackerelを組み合わせて、室内の騒音レベルを可視化する

手近なものでできそうだったので、連休の合間にやってみました。

Raspberry Piの準備

Raspberry PIはすでに持っていたRaspberry Pi 2 Model Bを使います。

Raspberry Pi 2 Model B (1)

Raspberry Pi 2 Model B (1)

USBマイクはこれを使います。Raspberry Piでマイクを使うときはよく使われるものみたいですね。

SANWA SUPPLY MM-MCUSB16 USBマイクロホン

SANWA SUPPLY MM-MCUSB16 USBマイクロホン

Raspberry PiでUSBマイクを使う例は、それなりに検索するとでてきますが、以下の記事を参考にしました。

qiita.com

soundmeter

音声信号処理についての知見もないので、あまりそこで時間をかけたくないのでsoundmeterというのをつかってみました。

github.com

インストールはREADMEに従えばよいでしょう。インストールするとsoundmeterコマンドが使用できるようになります。

いくつかオプションがあり、RMSを取得するサンプリング時間や、結果の出力方法などを指定できます。

ちなみにRMSはRoot Mean Squareの略のようです。ざっくりイメージを掴むなら以下の記事を参考にしてみてください。

sleepfreaks-dtm.com

USBマイクのGAIN調整

soundmeterが使えるようになったら、USBマイクのGAINを調整します。

計測したい場所にRaspberry PIをおいて、soundmeterを実行しておきます。

オプション無しで実行すると、0.5秒ごとのRMSが表示されます。

もう一つターミナルを開いて、alsamixerコマンドを実行し、マイクのGAINを調整します。

f:id:ariarijp:20160717230306p:plain

Mackerelで可視化

ここまででRaspberry PiとUSBマイクを使って騒音レベルが取得できるようになったので、あとはMackerelにメトリックを送信するだけです。

Raspberry PiへのMackerel導入については割愛しますが、以前Qiitaに記事を書いたので、多少は参考になるかもしれません。

qiita.com

カスタムメトリックを使う

Mackerelにメトリックを送信するには、カスタムメトリックの仕様にあわせてスクリプトを書く必要があります。

mackerel.io

グラフ定義とメトリックを出力するスクリプトであれば、監視対象のホストで動けばどんな言語で書いてもいいと思いますが、

今回はRaspberry Piをつかっていることもあるので、素直にPythonで書いてみました。

gist.github.com

これを適当なディレクトリーに置きます。今回は/opt/mackerel-check-scripts/soundmeter.pyに置くものとしておきましょう。

mackerel-agent.confに設定を追加する

[plugin.metrics.soundmeter]
command = "/opt/mackerel-check-scripts/soundmeter.py"

上記の設定を追加し、mackerel-agentを再起動すると、数分後には以下のようなグラフが描画できていると思います。

f:id:ariarijp:20160717231903p:plain

実際のグラフを見ると途切れている箇所がありますが、時折soundmeterが以下の様なエラーを出してしまうので、おそらくこれが原因だと思いますが、厳密に計測したいわけでもないので、これは無視しています。

pi@raspberrypi:~ $ soundmeter
         8  Traceback (most recent call last):
  File "/usr/local/bin/soundmeter", line 9, in <module>
    load_entry_point('soundmeter==0.1.3', 'console_scripts', 'soundmeter')()
  File "/usr/local/lib/python2.7/dist-packages/soundmeter/meter.py", line 311, in main
    m.start()
  File "/usr/local/lib/python2.7/dist-packages/soundmeter/meter.py", line 116, in start
    self.record()  # Record stream in `AUDIO_SEGMENT_LENGTH' long
  File "/usr/local/lib/python2.7/dist-packages/soundmeter/meter.py", line 90, in record
    data = self.stream.read(FRAMES_PER_BUFFER)
  File "/usr/local/lib/python2.7/dist-packages/pyaudio.py", line 608, in read
    return pa.read_stream(self._stream, num_frames, exception_on_overflow)
IOError: [Errno -9981] Input overflowed

まとめ

すでにRaspberry PiやUSBマイクなどの機器が手元にあり参考にできる記事も多く、Mackerelの扱いにもある程度慣れているので、連休の合間に2時間ほど作業しただけでできました。

最近はre:dashやAnsible、AWS Lambdaなど、Pythonで書かれたもの/書くもののお世話になる機会が増えてきたので、もうすこしPythonを書けるようになりたいなと思ったりもします。