Slack経由で遠隔のRaspberryPiに写真を撮らせアップさせる

# Slack経由で遠隔のHUBOT+RaspberryPiに写真を撮らせアップさせる
## 1. はじめに
どうもISAOXです。
今回もSlack経由でRaspberryPiに何かやらせるシリーズです。
以下の投稿記事でSlack上でBOTに命令を出せば遠隔のRaspberryPi(以下RPi)のスクリプトを実行できるようになりました。
この記事の環境もこれをベースにしてます。参考下さい。

* [GitHub + Slack + RaspberryPiを用いたHUBOT開発環境の構築](http://qiita.com/IsaoNakamura/items/c6be85cf99d93c8d50a2)

今回はこの遠隔のRPiに写真を撮らせてSlackに写真をアップロードさせてみようと思います。
これができれば、遠隔地をモニタリングしたりと用途は広がりそうです。

## 2. 前提条件
この記事の前提条件は以下です。

* インターネットに接続したRaspberryPi(Raspbian)がある。
* RPi上でHUBOTを起動できる環境にしている
* Slackを利用している + Slack上でHUBOT用のBOTを追加している。
* RaspberryPiにカメラモジュールを接続して使える状態にある。

## 3. RPiに写真を撮らせる道具の準備
カメラモジュールのセッティング等は[RaspberryPi本家サイト](https://www.raspberrypi.org/documentation/usage/camera/)を参考にしました。
今回は静止画を撮るのでコマンド[raspistill](https://www.raspberrypi.org/documentation/usage/camera/raspicam/raspistill.md)を使います。
RPi上で以下のように命令すれば静止画を撮ってくれます。

`raspistill -o test.jpg`

※[コマンドのオプション](https://www.raspberrypi.org/documentation/raspbian/applications/camera.md)等の詳細な使い方はRaspberryPi本家サイトにあります。


なので、raspistillを実行するShellスクリプトを用意してRPi上に配置します。
このShellスクリプトの第1引数を出力ファイル名に、以降はコマンドオプションとしてraspistillに渡す仕様です。

```stillpi.sh
#!/bin/sh

echo "raspistill -o $@"
raspistill -o $@
```

## 4. RPi上のHUBOTがShellスクリプトを呼ぶ準備
RPi上のHUBOTが読み込むcoffeeスクリプトに『raspistill』という文字列が来たら上記Shellスクリプトを呼び出す命令を追記します。
追記したらRPiを再起動するなどしてHUBOTが最新のcoffeeスクリプトを読み込んでおくようにしておきましょう。

```test.coffee
request = require "request";
fs = require "fs";

module.exports = (robot) ->
  robot.respond /raspistill (.*)|raspistill/i, (msg) ->
    # raspistillの後に文字があればコマンドオプションとして使う
    arg = msg.match[1]

    # 出力ファイル名はYYYY-MM-DD_HHmm_ss.jpgとする。(出力先は各自の環境にあわせること)
    dt = new Date()
    year = dt.getFullYear()
    month = ("0"+( dt.getMonth() + 1 )).slice(-2)
    date = ("0"+dt.getDate()).slice(-2)
    hour = ("0"+dt.getHours()).slice(-2)
    min = ("0"+dt.getMinutes()).slice(-2)
    sec = ("0"+dt.getSeconds()).slice(-2)
    file_path = "/home/pi/picam/"
    file_name = "#{year}-#{month}-#{date}_#{hour}#{min}_#{sec}.jpg"
    msg.send "file_name: #{file_name}"

    # RPi上の写真を撮るShellスクリプトを実行する。
    # execではなくexecSyncで同期的に実行しないと、写真を撮る前にアップロード命令が走る
    @execSync = require('child_process').execSync
    command = "sudo -u pi sh /home/pi/GitHub/StudyRPi/Hubot/iotbot/my_exec/stillpi.sh #{file_path}#{file_name} "
    command = "#{command} #{arg}" if arg?
    msg.send "Command: #{command}"
    @execSync command, (error, stdout, stderr) ->
        msg.send error if error?
        msg.send stdout if stdout?
        msg.send stderr if stderr?

    # 撮った写真をSlackへアップロードする
    api_url = "https://slack.com/api/"
    channel = msg.message.room
    options = {
        token: process.env.HUBOT_SLACK_TOKEN,
        filename: file_name,
        file: fs.createReadStream("#{file_path}#{file_name}"),
        channels: channel
    }

    request
    .post {url:api_url + 'files.upload', formData: options}, (error, response, body) ->
        if !error && response.statusCode == 200
        msg.send "OK"
        else
        msg.send "NG status code: #{response.statusCode}"
```
## 5. Slack上のBOTに写真を撮ってアップロードしてもらうように命令する
Slack上でBOTに以下のようにしてRPiに写真を撮ってアップロードしてもらうように命令します。
するとBOTが反応しRPiのShellスクリプトを実行してくれました！
![Picture](https://github.com/IsaoNakamura/StudyRPi/blob/master/Hubot/image/sc_raspistill.png?raw=true)
※上のスクリーンショットはSlack上の『DIRECT MESSAGES』上で入力しているので頭に指定するBOT名は省略してます。

## 6. 最後に
これでBOTは目を手に入れました。
以下の投稿記事では口を手に入れてます。

* [SlackのメッセージをHUBOT+AquestalkPiを用いてRaspberryPiにしゃべらせる](http://qiita.com/IsaoNakamura/items/186125b295fafd3fc1cf)

どんどんできることが増えてきましたね！
どんな用途・UXができるか皆さんも考えてみてください。