こんにちは!IoTLT Advent Calendar 2019 19日目担当のchinoppyです!
今回は、長野版IoT縛りの勉強会時に使用した、イベント風景自動Tweet/その写真を使って作ったパラパラ漫画と、構築したシステムについて紹介しますー
めざすもの
イベント風景自動Tweet
パラパラ漫画
撮影間隔が30分だったので、ちょっと物足りないですが・・・
システム構築
つかったもの
ハード
- Raspberry Pi 3 Model B
- OS:raspbian
- Raspberry Pi Camera Module V2 カメラモジュール
- SORACOM SIM、USBドングル AK-020
クラウド
- SORACOM
- SORACOM Beam
- AWS
- IoT Core
- Lambda
- STS
- S3
構成
処理内容
- Raspberry Piで写真撮影
- SORACOM経由でIoT Coreへトークンの取得リクエストをする
- STS経由でトークンを取得し、Raspberry Piへ送る
- 2で取得したトークンを使用して、S3へアップロード
- S3のTriggerでLambdaを実行し、Tweetする!
※ちなみに、今回、SORACOMを使用して、IoT Core経由でトークンを取得するようにしていますが、、、
※Raspberry Pi側にAWSのセキュリティ情報(シークレットキーなど)を保持させても問題ない環境でWifiが利用可能であれば、
※2、3は不要で、直接、S3へアップロードするのが楽かと思います!
環境構築
【Raspberry Pi】
ソースの詳細はこちら
※READMEなどちゃんと整備できていなくてすみません。。。
主になるソースはこちら
前提
- OSはインストールしてあり、SSHで接続できる
- カメラは接続済み
- USBドングルにSOARCOMのSIMがはいっていて、SORACOMへ接続済み
- 参考 : SORACOM Airの設定
Raspberry Piで写真撮影
この部分で、撮影タイミングの場合は撮影し、撮影タイミングではない場合は処理終了
・・・
# カメラ撮影
camera_obj = Camera(camera_shadow)
if not camera_obj.is_shooting():
return
camera_obj.shooting()
・・・
撮影時に使用するライブラリはpicameraし、撮影してます
from picamera import PiCamera
・・・
def _shooting(self):
・・・
camera = PiCamera()
・・・
# プレビュー開始
camera.start_preview()
# Camera warm-up time
time.sleep(5)
# 撮影
camera.capture(image_path, quality=self.shadow.quality)
# プレビュー終了しカメラクローズ
camera.stop_preview()
camera.close()
・・・
SORACOM経由でIoT Coreへトークンの取得リクエストをする
トークンの取得のリクエストと、取得はここで行っています
・・・
# tokenの取得要求
msg_token_req = MsgTokenReq(imsi=imsi)
# token取得するためsubscribe実行
result_sub = tasks_mqtt.run_subscribe_by_mqtt.delay(host, port, msg_token_req.get_sub_topic())
time.sleep(2)
try:
mqtt_client = CommMqtt(host, port)
mqtt_client.connect()
result = mqtt_client.publish(msg_token_req)
mqtt_client.disconnect()
except:
print("error")
while not result_sub.ready():
time.sleep(1)
value = redis_client.get('token')
・・・
SORACOM→IoT Core→Lambda→STS の戻りを待たないといけないので、celeryを使用して待ち、取得したトークンをredis経由で取得します。
S3へアップロード
アップロードはこの部分で行っています
・・・
# 撮影画像をS3へputする
send_images_data = SendImagesData(imsi, camera_obj)
# TODO S3 bucket名を可変にする
comm_aws_s3 = CommAwsS3('sample-iot-making-dev', [send_images_data])
ok_list, ng_list = comm_aws_s3.put_s3(payload_str)
・・・
取得したトークンを使用して、アップロードしてます
定期的に実行
今回は、cronを使用しています
※リポジトリをpiユーザのホームディレクトリにした場合です
$ cd /home/pi/iot_making_for_raspberry_pi
# ライブラリインストール
$ pip3 install -r requirements.txt
# cron
$ crontab -e
*/10 * * * * python3 ~/iot_making_for_raspberry_pi/main_camera.py
【AWS】
severless frameworkを使って構築しました
ソースの詳細はこちら
※こちらもREADMEなど整備できていなくすみません。。。
READMEのInstall部分、Usageの「deploy」を行い環境を構築
これで構成図のAWS部分は完成
その他:IoT Coreでモノの登録を行う
デバイス証明書(あとにでてくるSORACOMでも使用)とShadowの機能を使うため、モノの登録を行います
こちらを参照に、モノの名前は「SIMのIMSI」
IoT CoreのShadowを使う
設定値をShadowに持たせることにより、クラウドから設定を変更することができるようになります
IoT Coreのモノの中にある「シャドウ」に以下を登録
{
"desired": {
"sensor": {
"interval": 10
},
"camera": {
"quality": 10,
"shoot_timing": 1,
"resolution_width": 800,
"resolution_height": 600,
"tmp_dir": "/tmp",
"is_shooting": true,
"is_change_status": true
}
},
"reported": {
"sensor": {
"interval": 10
},
"camera": {
"resolution_width": 800,
"is_shooting": true,
"resolution_height": 600,
"tmp_dir": "/tmp",
"shoot_timing": 1,
"quality": 10,
"is_change_status": true
}
}
}
- desired
- デバイスへ要求する値
- reported
- デバイスの状態
「shoot_timing」を変更すると撮影タイミングを変えられます
ただし、Raspberry Pi側のcronでの実行間隔に依存します。。。
例)
- cronが10分毎
- ⇒shoot_timing=1 だと10分毎に撮影
- ⇒shoot_timing=3 だと30分毎に撮影
S3のTriggerでLambdaを実行し、Tweetする!
S3へ画像がputされたときに、Lambdaを起動するようにしています
・・・
#
# S3 TriggerでLambdaを起動
# https://serverless.com/framework/docs/providers/aws/events/s3/
#
notification_twitter:
handler: handler.notification_twitter
role: S3TriggerRoleForLambda
events:
- s3:
bucket: ${file(./serverless.env.yml):NAME_PREFIX}-iot-making-${opt:stage}
event: s3:ObjectCreated:*
rules:
- suffix: .jpg
existing: true
・・・
Lambdaはこちら
「event」内にbucket、objキーの情報があるので、S3から取得しTweetしてます
【SORACOM】
前提
- Webのコンソールは使用できる状態
- 使用するSIMは登録済み
SORACOM経由でIoT Coreへトークンの取得リクエストをする
この部分でBeamを使用するため、設定を行います
なのですが、まず、IoT Coreで取得したデバイス証明書の登録をします
「X.509証明書」を選択し必須項目を入力して登録
Beamの設定をします
- ホスト名は、IoT Coreのカスタムエンドポイントを入力
- 認証情報は、先ほど登録した二章情報を選択し設定
撮影に関しては、これで設定完了しTweetできるようになりました👏
パラパラ漫画について
こちらは、S3へ保存された写真をダウンロードして、iMovieで動画にしましたw
AWS CLIを使用すると簡単にダウンロードできます
$ aws s3 cp --recursive --exclude '*' --include 'camera_20190420*' s3://[bucket名]/[IMSI]/camera/ ./ --profile [pfofile名]
こんなかたちにすると、正規表現でダウンロードできるので楽です!
課題
- Raspberry Pi部分:S3へ画像送信時、bucket名が固定となっている
- ツイートの内容はコードを修正しないといけない。。。
- 送信間隔がcronでの間隔単位でしか設定できない。。。
別のイベントでも重宝してます👍