はじめに
こちらはSORACOM Advent Calendar 2023 3日目の記事です。
昨日(12/2)は @kizawa2020 さんの(まさかの英語の!)会議脱出ボタングローバルバージョン!
あの大きいボタンを持っていないので、試すことはできませんが、Amazon Connectの箇所は参考になりそうなので、後日熟読したいと思います。
経緯
先日、SORACOM Harvestに保存されたデータをAPI経由で取得し、CSVにする方法を紹介しましたが、有識者の方から「そのままCSVで保存すれば?」とアドバイスをいただき、それはそうだということでやってみました。
お詫び
資料中のAWS等の設定でfunkとすべきところを凡ミスでfuncとしてしまってっていました。
お恥ずかしい限りですが、ご容赦ください。
事前知識
SORACOMにはSORACOM Funkというサービスがあり、クラウドファンクションアダプタと呼ばれるもので、SORACOMでデータを受信したタイミングでAWSのLambdaを直接呼ぶことができます。
以下のドキュメントではFunkを使い、Lambdaを呼ぶ手順が説明されているので、こちらをベースにやり方を説明したいと思います。
GPSマルチユニットSORACOM Editionの位置情報(緯度経度)をSORACOM Funk、AWS Lambdaを経由して、Amazon S3にCSVファイルとして保存します。
保存したCSVはPCのブラウザなどでダウンロードできるようにします。
なお、GPSマルチユニットについては、あらかじめバイナリパーサーの設定をしておく必要があります。
手順
ざっくり説明すると、以下となります。
AWSの作業
先にAWS側の作業です。
S3バケットの作成
今回、お試しのためセキュリティ的には問題がありますが、S3にCSVを置いて、ダウンロードできるようにします。
-
AWSコンソールのS3管理画面で「バケットを作成」をクリックします。
-
バケット名を入力し、リージョンを選択します。 この記事でバケット名は「soracom-func-s3-csv」としていますが、同じ名前は設定できないので、別の名前で作成してください。
-
ポリシーのJSONを記入し、「関数の保存」をクリックします。
JSONは以下となります。{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::(バケット名)/*" } ] }
実際の運用には以下のようなIPアドレス制限などでアクセス制限を行ってください。
https://www.jpcyber.com/support/allow-s3-access-from-specific-ip
緯度経度情報から自宅の場所がバレるといったリスクがあるので、ご注意ください!
Lambdaの作成
続いてLambdaの作成を行います。
コードの作成
-
AWSコンソールのLambda管理画面で「関数の作成」をクリックします。
コードの内容は以下の通りです。
import boto3
import datetime
def lambda_handler(event, context):
print("Event:", event)
print("Context:", context)
# S3バケット名とファイル名を指定
bucket_name = '(バケット名)'
file_name = 'test.csv'
# S3クライアントを作成
s3 = boto3.client('s3')
# 現在の日時を取得
current_time = datetime.datetime.now() + datetime.timedelta(hours=9)
formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
# 緯度経度のデータ(イベントから取得または固定値で設定)
latitude = event.get('lat', 35.6895) # 例: 東京の緯度
longitude = event.get('lon', 139.6917) # 例: 東京の経度
# CSV形式の文字列を作成
new_data = f"{formatted_time},{latitude},{longitude}\n"
# 既存のファイルをS3からダウンロード
try:
response = s3.get_object(Bucket=bucket_name, Key=file_name)
current_data = response['Body'].read().decode('utf-8')
except s3.exceptions.NoSuchKey:
# ファイルが存在しない場合は空の文字列をセット
current_data = ""
# 新しいデータを追加
updated_data = current_data + new_data
# 更新されたデータをS3にアップロード
s3.put_object(Body=updated_data, Bucket=bucket_name, Key=file_name)
return {
'statusCode': 200,
'body': 'Data added successfully!'
}
このコードはほぼChatGPTに作ってもらいました。
(いやー・・すごい時代になりました)
権限設定
続いてS3にアクセスするための権限設定です。
Lambdaのテスト
作成したLambda関数のテストをしてみます。
- 「テスト」タブを選択し、イベントJSONに適当な緯度経度情報を入力して「テスト」をクリックします。
テストデータのサンプル(JSON)は以下となります。{ "lat": 36.689, "lon": 139.691 }
- 前段階で作成したS3バケットに「test.csv」ができていればそちらを開いてみてください。JSONに記入した緯度経度が入っていればOKです。
IAMポリシー、ロールの作成
SORACOM FunkからLambdaを呼ぶためのIAMロールを作成します。
ポリシーの作成
-
AWSコンソールのIAM管理画面で「ポリシー」を選択し、「ポリシーの作成」をクリックします。
-
アクション許可「invokefunction」と入力すると書き込みで候補が出るので、チェックし、「ARNを追加」をクリックします。
ロールの作成
続いて作成したポリシーを割り当てたロールを作成します。
-
AWSアカウントを選択し、「別のAWSアカウント」を選択してアカウントID「762707677580(日本カバレッジの場合)」または「950858143650(グローバルカバレッジの場合)」を入力し、オプションの「外部IDを要求する…」を選択して(セキュリティ上リスクありそうですが、前述のドキュメントと同じ)「External-ID-Mej73gfhrFhimGKb」を入力して「次へ」をクリックします。
SORACOMの作業
つづいてSORACOM側の設定です。
認証情報の登録
FunkからLambdaを呼び出すための認証グループを作成します。
-
認証情報IDで任意の文字列を指定し、種別を「AWS IAMロール認証情報」を入力、ロールARNに前段でメモしたロールのARNを指定、外部IDに「External-ID-Mej73gfhrFhimGKb」を入力して登録をクリックします。
SIMグループの設定
最後にSIMグループの設定です。
該当SIMのSIMグループの編集画面を開き、SORACOM Funk設定をONにした後、サービスを「AWS Lambda」関数のARNをLambdaのARN、認証情報を先ほど作成した認証情報ID、送信データ形式を「JSON」にして保存します。
以上で設定完了です。
S3で作成したバケットのCSVのプロパティに「オブジェクトURL」がダウンロードする際に必要なURLです。
ダウンロードしたいパソコンのブラウザからこのURLにアクセスすると、CSVファイルがダウンロードできます。
まとめ
今回の手法ですが、尊敬する先輩、@tatsuya1970 さんにお誘いいただいて参加したweb3 Global Hackathonというハッカソンで、自動車の走行経路を保存、取得する方法として使いました。
※この実装ではGPSマルチユニットではなく、スマホを使っています。
残念ながら1次審査通過ならずでしたが、今回の記事を書くきっかけとなりましたし、まだまだ勉強不足ですがWeb3という新しい技術に触れることができました。
このアドベントカレンダーもですが、イベント参加はスキルアップやアウトプットの良い機会となります。ありがたい限りです。
ということで全くアドベントカレンダー感が無い記事となってしまいましたが、どなたかの参考になれば幸いです。
明日は @anysonica さん、今年も多方面に大活躍でしたので、楽しみにしてます!
引き続きSORACOM Advent Calendar 2023をお楽しみください。