この章の終わりには、サーバーレスアプリケーションで次のようなことができるようになります。
次のステップでは、AWS Lambda でサーバーレス関数を作成する方法を詳しく説明しています。関数は IoT Core からの Device Shadow メッセージを待ち、メッセージを機械学習エンドポイントで使われる形式に変換し、その後機械学習エンドポイントを呼び出して roomOccupancy の分類と推論の信頼スコアを返すコードの一部を定義します。
classifyRoomOccupancy
という名前を使用します。import json
import boto3
import os
# Receives a device shadow Accepted document from IoT Core rules engine.
# Event has signature like {"state": {"reported": {"sound": 5}}}.
# See expectedAttributes for full list of attributes expected in state.reported.
# Builds CSV input to send to SageMaker endpoint, name of which stored in
# environment variable SAGEMAKER_ENDPOINT.
#
# Returns the prediction and confidence score from the ML model endpoint.
def lambda_handler(event, context):
client = boto3.client('sagemaker-runtime')
print('event received: {}'.format(event))
# Order of attributes must match order expected by ML model endpoint. E.g.
# the same order of columns used to train the model.
expectedAttributes = ['sound', 'temperature', 'hvacStatus', 'roomOccupancy', 'timestamp']
reported = event['state']['reported']
reported['timestamp'] = event['timestamp']
reportedAttributes = reported.keys()
# Validates the input event has all the expected attributes.
if(len(set(expectedAttributes) & set(reportedAttributes)) < len(expectedAttributes)):
return {
'statusCode': 400,
'body': 'Error: missing attributes from event. Expected: {}. Received: {}.'.format(','.join(expectedAttributes), ','.join(reportedAttributes))
}
# Build the input CSV string to send to the ML model endpoint.
reportedValues = []
for attr in expectedAttributes:
reportedValues.append(str(reported[attr]))
input = ','.join(reportedValues)
print('sending this input for inference: {}'.format(input))
endpoint_name = os.environ['SAGEMAKER_ENDPOINT']
content_type = "text/csv"
accept = "application/json"
payload = input
response = client.invoke_endpoint(
EndpointName=endpoint_name,
ContentType=content_type,
Accept=accept,
Body=payload
)
body = response['Body'].read()
print('received this response from inference endpoint: {}'.format(body))
return {
'statusCode': 200,
'body': json.loads(body)['predictions'][0]
}
SAGEMAKER_ENDPOINT
と入力し、[値] には SageMaker エンドポイント名を入力します。前章の最後のステップでこのリソースに名前を付けました。このモジュールでは roomOccupancyEndpoint
という名前とします。thermostatRule
という名前を付けています。invokeSageMakerEndpoint
のような名前を付け、[ポリシーの作成] を選択します。ブラウザこのIAMコンソールのタブを閉じても構いません。これらのステップでもって、AWS Lambda 関数の設定が完了します。例えば、Lambda 関数が次の Device Shadow の更新を受信した場合、
{
"state": {
"reported": {
"sound": 20,
"temperature": 58.8,
"hvacStatus": "HEATING",
"roomOccupancy": true
}
},
"timestamp": 1234567890
}
SageMaker エンドポイントの呼び出し後、次のレスポンスを返します。
{
"statusCode": 200,
"body": {
"predicted_label": "false",
"probability": "0.9999991655349731"
}
}
次のステップでは、Lambda 関数統合を使用するため、IoT Core ルール (thermostatRule
という名前のルール) を更新します。
thermostatRule
をクリックします。SELECT CASE state.reported.sound > 10 WHEN true THEN true ELSE false END AS state.desired.roomOccupancy FROM '$aws/things/<<CLIENT_ID>>/shadow/update/accepted' WHERE state.reported.sound <> Null
を読み込んでいます。SELECT cast(get(get(aws_lambda("arn\:aws\:lambda\:REGION\:ACCOUNT_ID\:function\:FUNCTION_NAME", *), "body"), "predicted_label") AS Boolean) AS state.desired.roomOccupancy FROM '$aws/things/<<CLIENT_ID>>/shadow/update/accepted' WHERE state.reported.sound <> Null
REGION
(コンソールヘッダーで現在のリージョンを確認します。Oregon
ではなく us-west-2
のような形式になっています)、ACCOUNT_ID
(ユーザー名が表示されたコンソールヘッダーメニューに、ハイフンのない 12 桁の数字として記載されています)、FUNCTION_NAME
(作成した AWS Lambda 関数名で classifyRoomOccupancy
という名前になっています) を必ず置き換えてください。FROM トピックの «CLIENT_ID» プレースホルダーも忘れずに変更しますしてください。これで、IoT ワークフローはデプロイされたエンドポイントからトレーニング済み機械学習モデルを使用して、スマートサーモスタットが発行したメッセージを新しい roomOccupancy 値として分類するようになります。
次章に進む前に、サーバーレスアプリケーションが想定どおりに設定されているかを検証できます。
$aws/things/<<CLIENT_ID>>/shadow/update
(«CLIENT_ID» は置換) にサブスクライブすると、こちらに 2 種類のメッセージが表示されます。1 つ目はスマートサーモスタットが発行した state.reported
パスのペイロードです。もう 1 つは、サーモスタットルールにより発行されるようになった、機械学習モデルが決める state.desired.roomOccupancy
値のペイロードです。想定どおりに機能していれば、このモジュールは完了です。 まとめ に進んでください。
AWS IoT Kit now features direct access to
M5Stack Forum
, which is a community-driven, questions-and-answers service. Search re:Post using the
Core2 for AWS
tag to see if your question has been asked and answered. If not, ask a new question using the Core2 for AWS
tag.