Raspberry Pi を遠隔操作して写真撮影・投稿。（Hubot＋Slack)

Raspberry Piを遠隔操作してカメラモジュールで撮影する覚え書きです。HubotとSlackを利用する事で外出先から自宅の撮影をすることも可能です。

## 環境

- Raspberry Pi2 ModelB （raspbian-Jessie・Node.js v4.2.4）
- PLANEX 無線LAN子機 (USBアダプター型) GW-USNANO2A (FFP)
- Raspberry Pi カメラモジュール Raspberry Pi Camera Board
- Raspberry Pi カメラモジュール専用　Blackケース

## 基本操作

Hubotスクリプト内に `child_process` を利用することでLinuxコマンドを実行する事が出来ます。

```coffeescript:scripts/sample.coffee
child_process = require('child_process')
module.exports = (robot) ->
  robot.respond /sample/i, (msg) ->
    child_process.exec 'ここにコマンド', (error, stdout, stderr) ->
    msg.send(stdout)
    msg.send(stderr)
    msg.send(error)
    return

```

これを利用すれば簡単に出来ると思ったのですが、アップロード操作に少々戸惑いましたのでまとめてみます。

## カメラモジュールの撮影

これはraspbianにカメラモジュール用のコマンドが用意されているのでドキュメントに沿って記述すれば大丈夫です。

```bash:ssh
$ raspistill -w 480 -h 360 -o ./images/raspi.jpg
```
hubotフォルダ直下に`images`フォルダを作り、そこに`raspi.jpg` という名前で写真を保存します。

ここでは幅480px、高さ360pxと指定しました。写真撮影の場合は同じファイル名であれば上書き保存されます。

## 画像ファイルのアップロード

ここで少し戸惑いました、結果からするとこんな感じの記述で上手く行きました。

```bash:ssh
$ curl -F file=@/home/pi/work/ヒューボットフォルダ名/images/raspi.jpg  -F channels=チャンネルのID -F token=スラックのウェブAPIのトークン https://slack.com/api/files.upload
```

Slackにコマンドラインからファイルアップロードをするには、[Slack Web API](https://api.slack.com/web) にてアクセストークンを取得する必要があります。

このアクセストークンを利用して外部から様々な操作をすることが可能になります。ファイルをアップロードする際は`https://slack.com/api/files.upload` というエンドポイントに`curl` コマンドを利用してファイルを送信する形になります。

[Slack Web API - files.upload](https://api.slack.com/methods/files.upload) にサンプルが乗っているのでこれを参考にしました。

```bash:example
$ curl -F file=@dramacat.gif -F channels=C024BE91L,#general -F token=xxxx-xxxxxxxxx-xxxx https://slack.com/api/files.upload
```

ファイル名の前に`@`を付けたり、チャンネルは`channels` だったり、チャンネルのIDを確認しなければならなかったり、サンプルに沿って記述すると２重で投稿されたりと…意外と面倒だったのですがRaspberry Piから投稿する際は上記の様なコマンドで写真をアップロード出来ました。

## ~~Hubot Scriptsのサンプル~~

```coffeescript:scripts/camera.coffee
child_process = require('child_process')
module.exports = (robot) ->
  robot.respond /camera/i, (msg) ->
    msg.send "OK. I'll take cool pic."
    child_process.exec 'raspistill -w 480 -h 360 -o ./images/raspi.jpg | curl -F file=@/home/pi/xxxxx/xxxxxx/images/raspi.jpg -F channels=xxxxxxxxx -F token=xxxx-xxxxxxxxxx-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx https://slack.com/api/files.upload', (error, stdout, stderr) ->
    msg.send(stdout)
    msg.send(stderr)
    msg.send(error)
    return
```
~~写真撮影→アップロードコマンドはパイプで繋げてみたところ上手くいきました。~~

## Hubot Scriptsのサンプル

パイプを利用してアップロードは可能ですが、写真の書き込みが終わる前にアップロードしてしまいます。（１回前の撮影分がアップロードされてしまう）

タイマーを利用して書き換えてみました。


```coffeescript:scripts/camera.coffee
child_process = require('child_process')
module.exports = (robot) ->
  robot.respond /camera/i, (msg) ->
    msg.send "OK. I'll take cool pic."
    child_process.exec 'raspistill -w 480 -h 360 -o ./images/raspi.jpg', (error, stdout, stderr) ->
      setTimeout ->
        child_process.exec 'curl -F file=@/home/pi/xxxxx/xxxxxx/images/raspi.jpg -F channels=xxxxxxxxx -F token=xxxx-xxxxxxxxxx-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxx https://slack.com/api/files.upload'', (error, stdout, stderr) ->
        msg.send(stdout)
        msg.send(stderr)
        msg.send(error)
        return
     ,3000
```

これで上手くいきました。

![Screenshot from 2016-04-17 17:36:19.png](https://qiita-image-store.s3.amazonaws.com/0/47128/b7cf9512-94f7-db11-55ed-a328b555d11c.png)

これは居間のChromebookから自室のRaspberry Piを操作して写真投稿してみたサンプルです。

Slackを利用することで外出先からスマホを利用して自宅の写真を確認することも可能ですね。

## 参考にさせていただきました

[Slackで現実世界も記録する - Qiita](http://qiita.com/KeitaMoromizato/items/1ecbfcd0f9343ce53975)