RaspberryPi 3 Model B+でIoT監視カメラをつくる(その2GoogleDriveとLINEの設定) | そう備忘録

RaspberryPi 3 Model B+でIoT監視カメラをつくる(その2GoogleDriveとLINEの設定)

RaspberryPi(ラズパイ)でIoT監視カメラ

RaspberryPi 3 Model B+とカメラ(Raspberry Pi Camera Module V2)とモーションセンサー(HC-SR501)で動きがあった時だけ録画する監視カメラを作成したときの備忘録の2回目。

1回目はRaspberryPiとカメラ、モーションセンサーとの接続に関するこちらの記事を参照

IoT監視カメラと言うからにはインターネットに接続して情報をアップロードしたりメッセージのやりとりをしないといけない。

今回はGoogleDriveにファイルをアップロードするためのGoogleプロジェクトから認証情報の作成までとLINEからメッセージを発信する為のアクセストークンの発行に関する記事とする。

全体構成図

尚、1回目の記事でも載せているが今回も全体構成図を念の為、掲載する。

監視カメラシステムの全体構成図は以下の通り。

監視カメラ全体構成図

GoogleDriveへのアクセス

RaspberryPiのPythonのプログラムからGoogleDriveへアクセスする方法の手順は以下の通り。

  1. RaspberryPiにGoogleDriveにアクセスする為のモジュールのインストールする
  2. GoogleDeveloperでプロジェクトを作成する
  3. 認証情報を作成する
  4. APIサービスを有効化する
  5. 動画ファイル保存用のフォルダーを作成する
  6. settings.yamlを設定する
  7. プログラムからアクセスする

必要なモジュールのインストール

RaspberryPiからGoogleDriveにアクセスする為に必要なモジュールをインストールする。

LXTerminalからgoogle-api-python-clientを以下のコマンドでインストールする。

sudo pip3 install google-api-python-client

次にpydriveをインストールする。

pydriveは先程インストールしたgoogle-api-python-clientのラッパー(使いやすようにしたライブラリー)

sudo pip3 install pydrive
以上でRaspberryPi側でのインストールは終了。

GoogleDeveloperでプロジェクトを作成する

Google Developers Consoleにアクセスする。

初めてアクセスした時には利用規約への同意を求められるので利用規約にチェックして”同意して続行”をクリックする。

利用規約に同意する

プロジェクトの作成を行う。

”作成”をクリックする。

プロジェクトの新規作成

プロジェクト名欄に”SecurityCameraProject”を指定して「作成」ボタンをクリックする。

個人IDだったので場所は”組織なし”のまま変更していない。

プロジェクト名を指定して作成

プロジェクトが作成されたのでダッシュボードをクリックする。

プロジェクトが作成されたのでダッシュボードをクリックする

ダッシュボードが表示される。

プルダウンで先ほど作成したプロジェクトが選択されている。

複数のプロジェクトを作成した場合はこちらのプルダウンでプロジェクトを切り替える。

ダッシュボードが表示される

認証情報を作成する

左上のメニューのAPIとサービスー>認証情報を選択する。

尚、OAuthの仕様はこちらを参考にした。

APIIとサービスから認証情報を選択する

認証情報を作成ー>OAuthクライアントIDを選択する。

以前にGoogleSheetにアクセスした時は”サービスアカウントキー”を選択した

サービスアカウントキーは公開鍵と秘密鍵のペアを作成して認証する方法。

その時の記事はこちらを参照

OAuthクライアントID

右側の「同意画面を設定」をクリックする。

「同意画面を設定」は初回のみ表示される

同意画面を設定

アプリケーション名に”sk-SecurityCamera”を設定して下にスクロールする。

アプリケーション名を設定する

「保存」ボタンをクリックする。

尚、「スコープを追加」ボタンでスコープを設定できる模様。

しかし後述のsettings.yamlにてスコープを指定するのでここでは指定していない。

保存する

先程の画面に戻るので

  • アプリケーションの種類:その他
  • 名前:監視カメラ

を入力して「作成」ボタンをクリックする。

アプリケーションの種類を選択して「作成」

OAuthクライアントが作成されてクライアント IDとクライアント シークレットが表示される。

後からJSON形式でダウンロードできるのでここではコピーを取らなくても大丈夫。

”OK”をクリックする。

クライアントIDとクライアントシークレットが表示される

右のダウンロードボタンからJSONファイルのダウンロードを行い

  • ファイル名:client_secret.json

でプログラムディレクトリの配下にcertディレクトリを作成して保存した。

このファイルは後述するsettings.yamlで使用する。

JSON形式のダウンロード

認証情報の作成は以上で終了。

APIサービスを有効化する

GoogleDriveに関するAPIサービスを有効化する。

ダッシュボードに戻って”APIとサービスを有効化”をクリックする。

APIとサービスを有効化

一覧からGoogleDriveAPIを選択する。

一覧からGoogleDriveを選択する

Google Drive APIの「有効にする」ボタンをクリックする。

GoogleDrive APIを有効にする

有効化された。

有効化された

Google Drive APIの有効化は以上で終了。

動画ファイル保存用のフォルダーを作成する

録画ファイルを保存するフォルダーをマイドライブ内に作成する。

Google Driveのマイドライブにて新規ー>ドライブにてドライブ名:SecurityCameraDriveで作成する。

URLの最後の部分がフォルダーIDなので保存しておく。(プログラム内でアクセスする際に使用する)

フォルダーIDの取得

settings.yamlを設定する

settings.yamlファイルを作成してプログラムと同一フォルダーに文字コードUTF-8で保存する。

尚、settings.yamlの仕様はこちらのページを参考にした。

client_config_backend: file
client_config_file: cert/client_secret.json

save_credentials: True
save_credentials_backend: file
save_credentials_file: cert/credentials.json

get_refresh_token: True

oauth_scope:
  - https://www.googleapis.com/auth/drive.file

1行目のclient_config_backend: fileはクライアントの設定を”ファイルから読み込む”の指定。

2行目の”cert/client_secret.json”で読み込むファイル名を指定している。

前述のOAuthクライアントIDの作成でダウンロードしたJSON形式のファイルを指定している。

尚、fileを指定せずにclient_config_backend: settingsとしてsettings.yaml内にクライアントID、クライアントシークレットを直接指定する事も可能だがセキュリティ上、IDやキー関係は./cert/配下のファイルに集めてアクセス権限をしぼる事にした。

settings.yamlに直接指定する例
client_config_backend: settings
client_config:
 client_id: xxxxxxx.apps.googleusercontent.com
 client_secret: xxxxxxxx

4~6行目で認証情報の保存について指定している。

初回に認証した時の情報を保存しておき2回目から許可画面を表示をさせない。

  • save_credentials: True:認証情報を保存する
  • save_credentials_backend: file:ファイルに保存する
  • save_credentials_file: cert/credentials.json:保存先のファイル名の指定

11行目でスコープ(アクセス可能な範囲)を指定している。

”https://www.googleapis.com/auth/drive.file”

はアプリケーションで作成したファイルに対してのみアクセス可能の指定。

スコープはセキュリティ上は最小限にしておくのが望ましい。

例えば、

”https://www.googleapis.com/auth/drive”

の指定をしてもプログラムは正常に動作する。

しかし対象ドライブに対してフルパーミッション指定になってしまうのでセキュリティ上はあまりよろしくない。

スコープについてはこちらのページを参考にした。

プログラムからアクセスする

監視カメラのプログラムの前に下記の簡易プログラムを作成してGoogleDriveにアクセスをしてみた。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import json

from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

INITIAL_FILE= "./cert/initial.json" # 初期設定ファイル

try:
    if __name__ == '__main__':
        os.chdir(os.path.dirname(os.path.abspath(__file__))) # カレントディレクトリをプログラムのあるディレクトリに移動する
        with open(INITIAL_FILE) as f: # 初期設定ファイルの読み込み
            jsn = json.load(f)
            folder_id = jsn["folder_id"] # folder_idの読み込み

        gauth = GoogleAuth() # GoogleDrive認証
        gauth.LocalWebserverAuth()
        drive = GoogleDrive(gauth)

        f = drive.CreateFile({'title': 'video/video.h264',
                      'mimeType': 'video/H264',
                      'parents': [{'kind': 'drive#fileLink', 'id':folder_id}]})
        f.SetContentFile('video/video.h264')
        f.Upload() # up-load
except KeyboardInterrupt:
    pass

初期設定ファイルはJSON形式で”./cert/initial.json”に作成した。

{
	"folder_id": "xxxxxxxxxxxxxxxxxx",
	"line_token":"yyyyyyyyyyyyyyyyy",
	"location":"MyHome-West"
}

folder_idには前述の動画ファイル保存用のフォルダーIDを指定する。

line_tokenは後述のLINE Notifyから取得したトークンを指定する。

locationはカメラの設置場所を表しているが今回は未使用、次回以降の記事で説明する。

なお、settings.yamlは前述のファイルをプログラムと同一ディレクトリに保存している。

初回の認証

上記のプログラムを実行すると初回のみ認証画面が表示される。

※認証情報はsettings.yamlの設定に基づき”./cert/credentials.json”に保存される。

ログイン画面が表示されるのでログインする。

Googleのログイン

”許可”クリックする。

権限を許可

”許可”をクリックする。

許可をクリックする

上記の認証情報が”./cert/credentials.json”に保存されて2回目からはこのファイルが読み込まれるので上記の画面が表示されない。

ファイルのアクセス権

尚、”initial.json”と”client_secret.json”はセキュリティ上重要な項目が幾つか設定されているのでアクセス権を最小限にしておきたい。

一通り設定が終わったら以下のコマンドで所有者のRead(読み込み)権限のみに設定変更する。

デフォルトは644の権限が設定されていた
sudo chmod 400 client_secret.json
sudo chmod 400 initial.json
また”credentials.json”も所有者以外の権限は不要なので以下のコマンドで権限を必要最低限に設定する。
こちらは書き込み権限が必要
sudo chmod 600 credentials.json
ファイルのアクセス権限

Google Driveへのファイルの書き込みに関する設定は以上で終了。

LINEとの連携

次にLINEにメッセージを送るためにLINE Notifyでアクセストークンを取得する。

LINE Notifyに接続して”ログイン”をクリックする。

LINE Notifyにログイン

メールアドレスとパスワードでログインする。

ログイン

右上のアカウント名のプルダウンから”マイページ”を選択する。

アカウント名からマイページに移動

下にスクロールして「トークンを発行する」ボタンをクリックする。

トークンを発行する

  • トークン名:自宅監視カメラ
  • 1:1でLINE Notifyから通知を受け取るを選択

「発行する」ボタンをクリックする。

トークンを発行する

トークンが発行されるのでコピーしておく。

トークンが発行されるのでコピーしておく

発行されたトークンは前述の“./cert/initial.json”のline_tokenセクションに貼り付ける。

連携中サービスとして表示される。

連携中サービス

以上でGoogleDriveとLINEへの事前設定は終了。

次回以降の記事でPythonのプログラムの説明をしていく。

次回の記事はこちら

動画

この記事の内容を動画で説明しているので参考にして欲しい。

souichirou

やった事を忘れない為の備忘録 同じような事をやりたい人の参考になればと思ってブログにしてます。 主にレゴ、AWS(Amazon Web Services)、WordPress、Deep Learning、RaspberryPiに関するブログを書いています。 仕事では工場に協働ロボットの導入や中小企業へのAI/IoT導入のアドバイザーをやっています。 2019年7月にJDLA(一般社団法人 日本デイープラーニング協会)Deep Learning for GENERALに合格しました。 質問は記事一番下にあるコメントかメニュー上部の問い合わせからお願いします。

おすすめ

3件のフィードバック

  1. san より:

    貴殿のサイトを参考に、RaspberryPi4にて自宅監視カメラを
    構築しようとしております。

    カメラの撮影試験等は完了して、GoogleConsoleでの諸設定も
    済んでおります。
    次に貴殿のサンプルPythonプログラムを自分用にアレンジして
    起動させますが、以下のエラーでつまずいていまして、また、
    Python自体も詳しくなくて、これからという感じです。

    何かヒント等があれば助かります。
    よろしくお願いいたします。

    エラー内容)
    ~/bin $ python googledrive.py
    Traceback (most recent call last):
    File “/usr/local/lib/python3.7/dist-packages/pydrive/auth.py”, line 386, in LoadClientConfigFile
    client_type, client_info = clientsecrets.loadfile(client_config_file)
    File “/usr/local/lib/python3.7/dist-packages/oauth2client/clientsecrets.py”, line 165, in loadfile
    return _loadfile(filename)
    File “/usr/local/lib/python3.7/dist-packages/oauth2client/clientsecrets.py”, line 126, in _loadfile
    return _validate_clientsecrets(obj)
    File “/usr/local/lib/python3.7/dist-packages/oauth2client/clientsecrets.py”, line 101, in _validate_clientsecrets
    prop_name, client_type))
    oauth2client.clientsecrets.InvalidClientSecretsError: Missing property “redirect_uris” in a client type of “web”.

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
    File “googledrive.py”, line 19, in
    gauth.LocalWebserverAuth()
    File “/usr/local/lib/python3.7/dist-packages/pydrive/auth.py”, line 113, in _decorated
    self.GetFlow()
    File “/usr/local/lib/python3.7/dist-packages/pydrive/auth.py”, line 443, in GetFlow
    self.LoadClientConfig()
    File “/usr/local/lib/python3.7/dist-packages/pydrive/auth.py”, line 366, in LoadClientConfig
    self.LoadClientConfigFile()
    File “/usr/local/lib/python3.7/dist-packages/pydrive/auth.py”, line 388, in LoadClientConfigFile
    raise InvalidConfigError(‘Invalid client secrets file %s’ % error)
    pydrive.settings.InvalidConfigError: Invalid client secrets file Missing property “redirect_uris” in a client type of “web”.

    • san より:

      すみません、時間掛けて調査しまして自己解決できました。

      • souichirou より:

        sanさん

        コメントありがとうございます。
        Google Driveの認証でエラーになっているようですね。
        無事に解決できて何よりです。

        エラーの解決でどうしても分からない時はプログラムを最小単位にして少しずつ正しく動くかどうかを検証していくと早道だったりしますよ?

質問やコメントや励ましの言葉などを残す

名前、メール、サイト欄は任意です。
またメールアドレスは公開されません。