メタラーまとんがハイソにやらかすようです

東大理系修士卒エンジニアのハイソサイエティ(上流階級)な日常

ソラコムのボタンでUbuntuとサーバーレス通信してみた!(AWS IoT 1-click / Lambda / AWS IoT / Windows Subsystem for Linux: WSL)

ども!まとんです。

ソラコムのボタンを使って、手元のパソコンと通信したい!という人のために、AWSの実装方法を紹介します。

使用するAWSのサービスは、AWS IoT 1-clickと、Lambdaと、AWS IoTです。

EC2インスタンスを使用しない、今話題のサーバーレスで実装します。

サーバーレスとは?

サーバーレスとは、所望のPythonスクリプトなどをLambda等に登録しておき、スクリプトだけを実行する、OSレスな実装方法です。

サーバーレスのメリットは、

(1)料金が安い:EC2インスタンスは起動するだけでお金がかかりますが、Lambdaは使用したCPUの時間単位で従量課金されます。Pythonの処理を軽くすれば、EC2を常時起動するよりも安く済むでしょう。

(2)OSのメンテナンスが不要:EC2インスタンスはOSやPythonなどの足回りを自分で管理するため、トラブル対応やバージョンアップ、負荷分散などに自分で対処する必要があります。一方、サーバーレスでは足回りをAWSがマネージドサポートするため、これらのわずらわしさから解放されます

作りたいもの

「ボタンを押したらソレノイドが動くおもちゃ」を作りたいです。

AWSの練習を兼ねているので、AWSを介した仕組みを実装します。

f:id:highso:20190310213744p:plain

想定しているアーキテクチャです。

SORACOMのボタン(SORACOM LTE-M Button powered by AWS)を押すと、AWS上でLambdaが走って、AWS IoTからMQTTをPublishします。

ソレノイドを駆動するArduinoは通信機能を持たないので、WiFiモジュールとセットになった評価基板が売られているESP32で代用し、iPhoneテザリングでインターネットに繋げます。

ESP32にAWS IoTの証明書を保存しておけば、これでセキュアに通信できるはず。

f:id:highso:20190224143744j:plain
f:id:highso:20190224215137j:plain
SORACOMボタンとソレノイド+Arduino

進捗

f:id:highso:20190421184300p:plain

この記事では、オレンジの枠内の実装をします。

青枠の箇所が気になる方は、過去の記事をご覧ください。

2019/2/24・・・ソラコムのボタンでAWS IoT 1-clickを起動する

【JAWS DAYS 2019参加レポ】「あのボタン」SORACOMの薄い本を買ってみた! - メタラーまとんがハイソにやらかすようです

2019/2/25・・・Arduinoでソレノイドを駆動する

ソレノイド(ZHO-0420S-05A4.5)をArduinoとMOSFETで動かしてみた! - メタラーまとんがハイソにやらかすようです

2019/3/11・・・Windows上でUbuntuを走らせて、AWS IoTと疎通確認する

AWS IoTをWSL(Windows Subsystem for Linux)のUbuntuで動かしてみた! - メタラーまとんがハイソにやらかすようです

参考にさせていただいた記事

AWS Lambda~AWS IoT間をSubscribeする - Qiita

【AWS Lambdaの基本コードその4】AWS IoTにメッセージをPublish|AWS, AWS IoT, AWS Lambda| | ナレコムAWSレシピ

動作環境

Ubuntu 18.04.2 LTS

 Ubuntuは手元のノートPCのWindows10上にWSLで走らせています。WSLの立ち上げ方については下記記事で詳細に解説しています。

AWS IoTをWSL(Windows Subsystem for Linux)のUbuntuで動かしてみた! - メタラーまとんがハイソにやらかすようです

Python 3.6.7

AWSアカウントを持っている

・ソラコムのボタンを持っている

Lambda用のIAMロールを作成

LambdaがAWS IoTにアクセスできるように、IAMロールを作ります。

AWSサービスから「IAM」を開く→「ロール」→「ロールの作成」

f:id:highso:20190421185320p:plain

AWSサービス」と「Lambda」を選んで、「次のステップ:アクセス権限」

「AWSIoTFullAccess」を検索して選択

タグで、キーに「Name」、値に「Highso_Lambda_IoT」を入力

ロール名に「role_Highso_Lambda_IoT」を入力して作成

これで、AWS IoTにフルアクセス権限を持つ、Lambda用のロール」ができました。

AWS IoTと通信するLambda関数の作成

まずリージョンを選びます。

1-clickはオレゴンでのみサポートされているので、オレゴンを選びます。

(後述しますが、Lambdaのリージョンはどこでも良さそうです)

AWSサービスから「Lambda」を開く→「関数の作成」

「一から作成」で、下記の通りに設定していきます。

・関数名:「PublishToAWSIoT」

・ランタイム:「Python 3.6」他にはJava、Go、Rubyなど選べます

・実行ロール:「既存のロールを使用する」

・既存のロール:先ほど作った「role_Highso_Lambda_IoT」を選択

f:id:highso:20190421190219p:plain

作成したLambda関数の設定画面。

フロー図から、AWS IoTに対してアクセス許可されていることが分かります。

f:id:highso:20190421190435p:plain

Lambda関数はブラウザ上でコーディングが可能です。

ここに、AWS IoTのトピック名「HighsoTopic」に対して「Hello from Lambda」とPublishするPythonスクリプトを書きます。

スクリプト部分は下記記事を参考にさせていただきました。

【AWS Lambdaの基本コードその4】AWS IoTにメッセージをPublish|AWS, AWS IoT, AWS Lambda| | ナレコムAWSレシピ

具体的には、下記の通りです。コピペして使えます。

# coding: utf-8


#ライブラリのimport
import json
import boto3

#Functionの開始を出力
print('Loading function')

#AWS IoT Data Planeオブジェクトを取得
iot = boto3.client('iot-data')

#Lambdaのメイン関数
def lambda_handler(event, context):

## TODO implement
#return {
# 'statusCode': 200,
# 'body': json.dumps('Hello from Lambda!')
#}

#トピックを指定
topic = 'HighsoTopic'
#メッセージの内容
payload = {
"message": "Hello from Lambda"
}

try:
#メッセージをPublish
iot.publish(
topic=topic,
qos=0,
payload=json.dumps(payload, ensure_ascii=False)
)

return "Succeeeded."

except Exception as e:
print(e)
return "Failed."

jsonやbotoなどをインポートしていますが、Lambdaはサーバーレスなので、これらライブラリのバージョンなどを自分で意識する必要はありません。マネージドサービスの良いところですね。

LambdaとAWS IoTの間の通信テスト

Lambda関数の画面で、「テスト」→keyやvalueを何も変えずに「作成」で、Pythonスクリプトがテスト起動されます。

AWS IoT側で、受信を確認してみましょう。

AWSサービスで「IoT Core」を開く→「テスト」

トピックのサブスクリプションに「HighsoTopic」と入力して「トピックへのサブスクライブ」を押すと、通信の待ち受け状態になります。

f:id:highso:20190421191934p:plain

この状態でLambdaをテスト実行して、「Hello from Lambda」が表示されれば、LambdaからAWS IoTの疎通はOKです!

 

ソラコムボタンを押してLambdaを起動する設定

次に、ソラコムボタンを押して、先ほど作ったLambdaを起動するように設定します。

僕はJAWS DAYS 2019のイベントでソラコムのボタン(+同人誌)を購入して、初期設定を行いました。その際の内容は下記記事にまとめました。

【JAWS DAYS 2019参加レポ】「あのボタン」SORACOMの薄い本を買ってみた! - メタラーまとんがハイソにやらかすようです

初期設定では、ボタンを押したときに「電話番号「090-XXXX-XXXX」にSMSを送る」という機能を紐づけていました。

今回、この紐づけを、先ほど作ったLambda関数に変更します。

ボタンを初期登録

AWSのサービスから「IoT 1-click」を開く→「管理」→「デバイス

f:id:highso:20190421192520p:plain

ボタンで初期設定をしたままになっている場合は、まず「デバイスの登録解除」をします。このとき、削除前に「デバイスID」をコピーしておきます。

次に、改めて登録します。「デバイスの登録解除」→先ほどコピーしたデバイスIDをペースト→「登録」

(デバイスIDをコピーし忘れた人は、ソラコムのボタンの裏のカバーを空けて、中のシールの「DSN」がデバイスIDです。)

これで、ボタンの登録が完了し、まだ機能が紐づいていない状態となりました。

ボタンとLambda関数を紐づける

Lambda関数を起動するプロジェクトを作成し、先ほど登録したボタンに紐づけていきます。

AWSサービスから「IoT 1-click」を開いて、「管理」→「プロジェクト」→「作成」

下記の通り設定していきます。

・プロジェクト名:「HighsoPublish」

・説明:「ハイソボタンを押すとAW IoTにPublish」

・デバイステンプレート→すべてのボタンタイプ

・デバイステンプレート名:「TestPublish」

・アクション:「Lambda関数の選択」

AWSリージョン:「オレゴン」(ここで、東京など他のリージョンも選べたので、Lambda関数を置くリージョンはオレゴンでなくともよさそうです。)

・Lambda関数:先ほど作成した「PublishToAWSIoT」

・プレイスメントの属性:(空欄)

「プレイスメントの作成」

・デバイスのプレイスメント名:「TestPublishPlacement」

・デバイスの選択→先ほど初期登録したボタンのIDを選択

「プレイスメントの作成」

これで、ボタンとLambda関数を紐づけることができました。

ためしにボタンを押してみて、Lambdaのテストをしたときと同様に、AWS IoT上で「Hello from Lambda」が表示されれば、紐づけOKです!

Ubuntuとの疎通を確認

あらかじめ、UbuntuにはAWS IoTでデバイス登録してあるとします。

バイス登録や、PythonのサンプルスクリプトAWS IoT Device SDK for Pythonが含む)の詳細な手順については、下記記事にまとめました。

AWS IoTをWSL(Windows Subsystem for Linux)のUbuntuで動かしてみた! - メタラーまとんがハイソにやらかすようです

UbuntuSDKをインストールしたディレクトリに移動

・「start.sh」の最後の行に「-t HighsoTopic」を追加してトピック名を設定

・「sh start.sh」で起動

f:id:highso:20190421195520p:plain

ボタンを押して、「Hello from Lambda」が表示されれば、ボタン→1-click→Lambda→AWS IoT→Ubuntuの疎通はOKです!

いかがでしたか?

今回やったことは下記です。

  • IAMでAWS IoTにアクセスできるLambda用のロールを作成
  • AWS IoTにPublishするLambda関数を作成
  • ボタンの1-click設定で作成したLambda関数を紐づけ
  • ボタン→1-click→Lambda→AWS IoT→Ubuntuの疎通を確認

AWS上の操作では躓くポイントは無く、サーバーレス実装ができました!AWSってすごいですね。

みなさんも是非、楽しいAWSライフを!!

そして僕は、ソリューションアーキテクトを目指します。

以上、メタラーまとんでした。

ではでは。

ソラコムのボタンはAmazonで買えます

SORACOM LTE-M Button powered by AWS

SORACOM LTE-M Button powered by AWS

 

関連記事

highso.hatenablog.com

highso.hatenablog.com

highso.hatenablog.com