【ラズパイDIY講座】ラズパイゼロで作る監視カメラ⑥〜Slackアプリから監視カメラ画像を取得してみる


2022/02/07
蛸壺の中の工作室|ラズパイゼロで作る監視カメラ⑥〜Slackアプリから監視カメラ画像を取得してみる

前回のMomoで作るリアルタイム監視カメラの話から少し間が飛んでしまいました。

前回までは
Momoによって自作監視カメラ作りを進めておりますが、今回は少し脇道に逸れて、Slackサーバー上で監視カメラシステムを動かす話題をちょっとだけ挟んでみます。


Slackサーバー(Slackアプリ)とは?

最近弊社の内部業務で色々とSlackアプリが活躍中で、ちょっとしたツールをSlackのワークスペース上で使うことが多くなったこともあり、折角ならお手軽な監視カメラからの画像取得もSlackからやってみたくなりました。

もちろんまだ主題のMomo(WebRTC)の話は中途半端にやりかけたままですので、今後きちんと完走させるつもりではあります。

Momoを利用して作るDIY監視カメラシステムのその後が気になっている方はもう暫くお待ちください...。

「Slackサーバー」とは、自宅や職場のサーバーマシーンで立てたオンプレのSlackアプリのことを指した言葉です。

弊社の運営している別のブログでSlackサーバーの構築方法を詳しく解説しておりますので、ご興味がありましたらそちらの内容をご確認ください。

本ブログでは、ラズパイゼロでSlackサーバーを起動させて、SlackからDM(ダイレクトメッセージ)で画像データの取得を投げかけることで、ラズパイゼロが監視カメラの画像をキャプチャして送り返してくれるSlackアプリを試してみることを以降で簡単に解説していきます。


ラズパイゼロにv12以降のNode.jsをインストールする

ラズパイゼロのアーキテクチャはarm32v6であり、今ではかなり古いものになってしました。

既にNode.jsの開発はサポート外になっていますので、オフィシャルにはv9のバージョンが最新です。

それでも有志の方がほそぼそと最新のNode.jsのビルド版を提供されています。

Node.js unofficial-builds project

これを利用させて頂くことで、比較的最新のNode.jsで動作しているようなSlackアプリもラズパイゼロで動かすことが可能となっています。

            $ curl -sL install-node.now.sh/lts -o node.sh
$ chmod +x node.sh
$ sudo BASE_URL=https://unofficial-builds.nodejs.org/download/release ./node.sh
[sudo] password for *****: 
  Configuration
> Version:  v16.13.2 (resolved from lts)
> Prefix:   /usr/local
> Platform: linux
> Arch:     armv6l

> Tarball URL: https://unofficial-builds.nodejs.org/download/release/v16.13.2/node-v16.13.2-linux-armv6l.tar.gz
? Install Node.js v16.13.2 to /usr/local? [yN] y    
> Installing Node.js, please wait
✓ Done

#👇後片付け
$ rm -rf node.sh

$ node --version
v16.13.2
        
現状ではNode v16までのビルド版が提供されていますのでこれをインストールしてみます。

ちなみにこの記事の執筆時現在で、世界的な半導体需要の影響で、ラズパイ製品が全て品切れ状態のまま入手困難な状況が続いています。

いつ頃までに安定的に市場に供給され通常の価格に戻るのか、先行き不透明な状態にあります。

そのような状況にありますので、ラズパイを使っているDIY愛好家には、困ったことに現在ラズパイゼロですらも、かなりの高値でメルカリ等で中古出品されているような始末です...。

早く通常の価格帯に戻り、また再びラズパイ製品が入手しやすくなることを祈るのみです。


Slackアプリの実装

ここからはSlackからDMを送ることでラズパイゼロからカメラ画像を送るまでの簡単なNode.jsのデモプログラムを作成します。

理想でいうとラズパイゼロ上でTypescriptのビルドしてゴリゴリとNodeアプリを開発していきたいところですが、ラズパイゼロのマシーンスペックがなさすぎで、ビルドの度にかなり時間が取られたり、アーキテクチャが古いために外部からSSH接続してリソースファイルをエディタで開く際にもエラーが発生して思うように行かないことが多いです。

よって、外部のそれないのスペックのPC上でビルドし完成したソースコードで、ラズパイゼロには本番環境だけで動作させる運用の方が良いでしょう。

今回は以下のように簡単なプロジェクト構造で走らせてみます。

            $ tree
.
├── package.json
└── index.js
        
でまずはpackage.jsonの中身です。

            {
  "name": "slack-home-monitor",
  "version": "0.0.1",
  "description": "Home monitor app with Bolt-js",
  "main": "index.js",
  "author": "tacoskingdom",
  "license": "UNLICENSED",
  "dependencies": {
    "@slack/bolt": "^3.9.0"
  }
}
        
出来るだけ軽くさせるために、最低限bolt-jsフレームワークだけはインストールします。これでパッケージインストールします。

            $ npm install
        
次にSlack Boltのドキュメントなどを参考に、とりあえずファイルをアップロードするイベントハンドラを作成します。

            const { App } = require('@slack/bolt');
const child_process = require('child_process');
const fs = require("fs");

const app = new App({
    token: process.env.SLACK_BOT_TOKEN,
    appToken: process.env.SLACK_APP_TOKEN,
    socketMode: true,
});

const fileName = "./snap_tmp.jpg";

app.message('watch', async ({ message, client, logger }) => {
    try {
        //👇撮影日時を取得
        const timestamp = child_process.execSync(`TZ=JST-9 date "+%Y年%m月%d日%H:%M"`);
        //👇カメラから画像をキャプチャ
        child_process.execSync(`raspistill -w 480 -h 360 -vf -hf -q 10 -o snap_tmp.jpg`);
        //👇画像をチャンネルへ送信
        await client.files.upload({
            channels: message.channel,
            initial_comment: `${timestamp.toString()}`,
            file: fs.createReadStream(fileName)
        });
        //画像の後片付け
        child_process.execSync(`rm -rf snap_tmp.jpg`);
  } catch (error) {
    logger.error(error);
  }
});

(async () => {
    await app.start(process.env.PORT || 3000);
    console.log('⚡️ Bolt app is running!');
})();
        

なお、Boltフレームワークで利用できるSlack Web APIの関数は多岐に渡りますので、こちらの
公式Documentationから用法・用途を確認してください。

また、カメラはラズパイ標準の
raspistillコマンドをそのまま利用しています。

raspistillコマンドでの画像保存に関しては
こちらの記事で色々と紹介されているので、各自撮影オプションを色々と調整してみてください。


「ラズパイ監視カメラ on Slackアプリ」の動作確認する

では、最後にちゃんと写真が撮影されているか、Slackの指定したチャンネルに転送できているかを確認します。

Botにスコープ権限を設定する

まず、Slackボットが写真を転送するためには、files:writeの権限スコープの付与を与えなければなりません。

Slack Appのダッシュボードから
[OAuth & Permisstions] > [Scopes]からBotにこのスコープを割り当てます。

合同会社タコスキングダム|蛸壺の中の工作室

これでボットがファイルをアップロードしてくれるようになります。

Slackサーバーを起動する

とりあえずSlackアプリ用のクレデンシャルを環境変数に通します。

            $ export SLACK_BOT_TOKEN=<ボットトークン>
$ export SLACK_APP_TOKEN=<アプリトークン>
        
で、Slackサーバーをラズパイゼロで立ち上げてみましょう。

            $ node index.js
⚡️ Bolt app is running!
        
これでSlackアプリ製監視カメラが常時オンラインで呼びかける形でモニタリングが開始されます。

ではとりあえずこのSlackアプリを仕込んだプライベートチャンネルで、ソースコードで指定していたメッセージイベントの
「watch」をチャンネルに投げかけてみましょう。

合同会社タコスキングダム|蛸壺の中の工作室

すると、とりあえず作業場の机に置いたラズパイカメラから飲みかけの焼酎古酒のボトルがハッキリと...試作機なのでまだデスクの上で置いている状態なのでお見苦しい点はさておき、リアルタイムに拘らなければなんとも簡単に監視カメラシステムが構築できました!

まだ改善の余地は多く残りますが、ひとまずは自宅監視カメラの出来上がりです。


まとめ

以上、Slackアプリとラズパイカメラとの開発の相性はとても良いので、簡単に格安のお宅監視カメラシステムが出来てしまいました。

パソコンにしろスマホにしろ、Slackさえインストールしてしまえば、いつでも何処でも好きなときにご自宅の様子を見守ることができます。

後は人感センサーと連動させて、赤外線に引っかかるとそれに反応して画像を通知してくれるようにすればいざという時のホームセキュリティにも使えるのではないかと思います。

さて今回は脇道には逸れましたが、元々WebRTCの自身の勉強も兼ねてこの課題に取り組んでおりましたので、次回からMomoの監視カメラシステムの話を再開していく予定です。

あともう少しお付き合い願えれば幸いです。

記事を書いた人

記事の担当:taconocat

ナンデモ系エンジニア

電子工作を身近に知っていただけるように、材料調達からDIYのハウツーまで気になったところをできるだけ細かく記事にしてブログ配信してます。