社内に例のボタンが先日届いたので使ってみました。
よく見る使い方ですが、ポチっと押すとラズパイに繋げたWebカメラが写真を撮り、 S3にアップロードしたりSlackに投稿したりするのを試してみましょう。
目次
撮影テスト AWS IoTの設定 実行スクリプトの編集 Lambda関数の変更 IoT 1-Clickの設定 slackへの投稿
撮影テスト
今回はfswebcamを使って写真を撮ります。
ラズパイへsshし、apt-get install fswebcamでfswebcamをインストールし、 fswebcam test.jpgでテスト撮影してみましょう。
無事写真が撮れたようです。
AWS IoTの設定
今回は以前のブログで作成したモノやスクリプトそのまま使い回しちゃいます。 ので、モノの状態を管理してくれるAWS IoTのThing Shadowを使います。 状態のRunningが1の場合、写真撮って0に戻します。
モノの設定等は以下の記事に記載してあります。
AWS IoT – インスタンスの起動状態をRaspberry Piに繋げたLEDで監視しよう
写真撮ってアップロードするだけなのでShadow stateを使用したこの方法はあまりスマートではないのですが…… ボタンでstateの切り替えを応用したら色々と面白い事が出来そうですね。
上記環境より変更するのは実行スクリプトとLambdaになります。
実行スクリプトの編集
まずは画像アップロード用のバケットをs3に作成しましょう。
今回はboto3を使うので、amユーザーを用意、boto3とawscliをインストールし、 aws configure行います。
runningが1の時写真撮ってs3上げる様にちょこっと編集加えます。
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient import json import time import datetime import logging import subprocess import boto3 s3 = boto3.resource('s3') bucketName = "xp-rpi-pic" def updateState(): report_json = '{"state":{"desired": {"running": 0}}}' deviceShadowHandler.shadowUpdate(report_json, None, 5) def take_pic(payload, response, token): payloadDict = json.loads(payload) if int(payloadDict["state"]["running"]) == 1 : today = datetime.datetime.today() filedate = today.strftime("%Y%m%d_%H%M%S") filename = "%srpipic.jpg" % filedate cmd = "fswebcam %s" % filename subprocess.call(cmd,shell=True) s3.Bucket(bucketName).upload_file(filename,filename) updateState() host = "xxxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com" port = 8883 clientId = "xxxxxxxx" thingName = "xxxxxxx" rootCAPath = "xxxxxxx" certificatePath = "xxxxxxx" privateKeyPath = "xxxxxxx" #logger = logging.getLogger("core") # Python 3 logger = logging.getLogger("AWSIoTPythonSDK.core") # Python 2 logger.setLevel(logging.DEBUG) streamHandler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') streamHandler.setFormatter(formatter) logger.addHandler(streamHandler) # Init AWSIoTMQTTShadowClient myAWSIoTMQTTShadowClient = None myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(clientId) myAWSIoTMQTTShadowClient.configureEndpoint(host, 8883) myAWSIoTMQTTShadowClient.configureCredentials(rootCAPath, privateKeyPath, certificatePath) # AWSIoTMQTTShadowClient configuration myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20) myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec # Connect to AWS IoT myAWSIoTMQTTShadowClient.connect() deviceShadowHandler= myAWSIoTMQTTShadowClient.createShadowHandlerWithName(thingName, True) deviceShadowHandler.shadowRegisterDeltaCallback(take_pic) while True: pass
Lambda関数の変更
前回はインスタンスの状態を反映させてましたが、今回はボタン押したらrunningを1にしたいだけです。
import boto3 import json def lambda_handler(event, context): state = "1" client = boto3.client('iot-data') response = client.update_thing_shadow( thingName='xxxxxxx', payload=json.dumps({"state":{"desired": {"running": state}}}) )
IoT 1-Clickの設定
後はボタンにLambda関数を紐づけます
デバイスの登録等は以下の記事にあります。
AWS IoT Enterprise Buttonを使ってみよう
AWSコンソールのIoT 1-Clickに移動し プロジェクトを作成し……
Lambda関数を紐づけ……
プレイスメントを作成し、デバイスに紐づければ設定完了です。
Slackへの投稿
折角なのでSlackへの投稿も試してみました。
Slack Appsよりbotを作成し、tokenをメモし、指定のチャンネルにbotを招待します。 channelsはチャンネルのurlを見ればすぐ分かります。
import requestsし、s3にアップロードする箇所を変更しましょう。
files = {'file': open(filename, 'rb')} param = { 'token': "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 'channels': "xxxxxx" } requests.post(url="https://slack.com/api/files.upload",params=param, files=files)
これでボタンをポチポチしますとSlackに写真が投稿されるはずです。