この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
GPSマルチユニットSORACOM Editionをバッテリー駆動で使っているのですが、バッテリー残量が気になるのです。
SORACOM Lagoonを使えばバッテリー残量のアラート通知ができますが、せっかくなのでAWS IoT Coreに接続して、バッテリーの低残量を通知する仕組みを作ってみました。
おすすめの方
- GPSマルチユニットSORACOM Editionのバッテリー低残量を通知したい方
- SORACOM FunnelでAWS IoT Coreにデータを送信したい方
- AWS IoT Eventsについて知りたい方
- AWS IoT EventsをCloudFormationで作成したい方
SORACOM Funnel用のIAMユーザを発行する
CloudFormationテンプレート(IAMユーザ)
特定のトピックに対して、iot:Publish
できる権限のみを付与しています。
iam_user.yml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM User for SORACOM Funnel
Resources:
# SORACOM Funnel用のIAMユーザ
SoracomFunnelUser:
Type: AWS::IAM::User
Properties:
UserName: "soracom-funnel-user"
# IAMユーザに付与するIAMポリシー
SoracomFunnelUserPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: "soracom-funnel-user-policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action: "iot:Publish"
Resource: !Sub "arn:aws:iot:${AWS::Region}:${AWS::AccountId}:topic/soracom/gps-multiunit/*"
Users:
- !Ref SoracomFunnelUser
デプロイ
aws cloudformation deploy \
--template-file iam_user.yml \
--stack-name SORACOM-Funnel-IAM-User-Stack \
--capabilities CAPABILITY_NAMED_IAM \
--no-fail-on-empty-changeset
アクセスキーを取得
aws iam create-access-key \
--user-name soracom-funnel-user
SORACOM Funnelを設定してAWS IoT Coreにデータ送信する
SORACOMにAWS認証情報を登録
SORACOM Webコンソールにアクセスし、右上のメニューにある「セキュリティ」を選択します。
続いて、「認証情報ストア」にある「認証情報を登録」を選択します。
種別は「AWS認証情報」を選択し、さきほど取得したアクセスキーを貼り付けて登録します。
AWS IoT Coreエンドポイント取得
下記コマンドで取得できます。
aws iot describe-endpoint \
--endpoint-type iot:Data-ATS
SORACOM Funnelの設定入力
メニューの「SIMグループ」からGPSマルチユニットのSIMグループを選択します。
SORACOM Funnelの設定を行います。
項目 | 内容 |
---|---|
転送先サービス | AWS IoT |
転送先URL | xxxxx.iot.ap-northeast-1.amazonaws.com/soracom/gps-multiunit/#{imsi} |
認証情報 | さきほど登録した認証情報 |
送信データ形式 | JSON |
AWSs IoT Coreでテスト
IoT Coreの「テスト」にアクセスして、下記トピックをサブスクライブします。
- soracom/gps-multiunit/+
しばらく待つとデータが送信されてきました!!!
JSON内容は下記です(一部マスクしています)
{
"operatorId": "xxx",
"timestamp": 1612846193590,
"destination": {
"resourceUrl": "xxx.iot.ap-northeast-1.amazonaws.com/soracom/gps-multiunit/#{imsi}",
"service": "aws-iot",
"provider": "aws"
},
"credentialsId": "funnel-aws-iot-core",
"payloads": {
"bat": 3,
"temp": 25.3,
"rs": 0,
"lon": 135,
"y": null,
"humi": 25.2,
"lat": 45,
"x": null,
"z": null,
"type": 1
},
"sourceProtocol": "udp",
"imsi": "111111111111111"
}
ここのbat
を監視し、必要に応じて通知すればOKですね。
なお、ペイロードの詳細はこちらに記載があります。
GPSマルチユニットの低残量を通知する
バッテリー残量による状態遷移
bat
の範囲は「-1,1〜3(-1は充電中)」です。今回は、bat=1
がバッテリー低残量とみなして通知する仕組みを作成します。
状態 | 遷移条件 |
---|---|
BatteryHigh | bat==3 |
BatteryLow | bat==1 |
状態管理はAWS IoT Eventsで行います。
CloudFormationテンプレート
- メール通知用のSNSトピック
- IoTルール
- IoTルール用のIAMロール
- IoT Eventsの入力情報
- IoT Eventsの探知器モデル
- IoT Eventsの探知器モデル用のIAMロール
- IoT Eventsの探知器モデル用のCloudWatchロググループ
notify_soracom_gps_multiunit_battery_low.yml
AWSTemplateFormatVersion: 2010-09-09
Description: IoT Events for SORACOM GPS Multiunit Notify Battery Low
Resources:
SoracomGpsMultiunitTopicRule:
Type: AWS::IoT::TopicRule
Properties:
RuleName: soracom_gps_multiunit_topic_rule
TopicRulePayload:
AwsIotSqlVersion: "2016-03-23"
RuleDisabled: false
Sql: >-
SELECT
topic(3) as imsi, payloads.bat
FROM
'soracom/gps-multiunit/+'
WHERE
payloads.type <> -1
Actions:
- IotEvents:
InputName: !Ref SoracomGpsMultiunitEventsInput
RoleArn: !GetAtt SoracomGpsMultiunitTopicRuleRole.Arn
SoracomGpsMultiunitNotifyBatteryTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: sample@example.com
Protocol: email
SoracomGpsMultiunitTopicRuleRole:
Type: AWS::IAM::Role
Properties:
RoleName: soracom-gps-multiunit-topic-rule-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: iot.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSIoTEventsFullAccess
SoracomGpsMultiunitEventsInput:
Type: AWS::IoTEvents::Input
Properties:
InputName: SoracomGpsMultiunitInputData
InputDefinition:
Attributes:
- JsonPath: imsi
- JsonPath: bat
SoracomGpsMultiunitBatteryDetectorModel:
Type: AWS::IoTEvents::DetectorModel
Properties:
DetectorModelName: soracom-gps-multiunit-battery-detector-model
Key: imsi
EvaluationMethod: BATCH
RoleArn: !GetAtt SoracomGpsMultiunitBatteryDetectorModelRole.Arn
DetectorModelDefinition:
InitialStateName: BatteryHigh
States:
- StateName: BatteryHigh
OnInput:
TransitionEvents:
- EventName: to_battery_low
NextState: BatteryLow
Condition: $input.SoracomGpsMultiunitInputData.bat == 1
- StateName: BatteryLow
OnEnter:
Events:
- EventName: send-mail-to-battery-low
Actions:
- Sns:
TargetArn: !Ref SoracomGpsMultiunitNotifyBatteryTopic
Payload:
Type: STRING
ContentExpression: "'バッテリーが低残量になりました。対象デバイス: ${$input.SoracomGpsMultiunitInputData.imsi}'"
OnInput:
TransitionEvents:
- EventName: to_battery_high
NextState: BatteryHigh
Condition: $input.SoracomGpsMultiunitInputData.bat == 3
OnExit:
Events:
- EventName: send-mail-to-battery-high
Actions:
- Sns:
TargetArn: !Ref SoracomGpsMultiunitNotifyBatteryTopic
Payload:
Type: STRING
ContentExpression: "'バッテリー残量が復旧しました。。対象デバイス: ${$input.SoracomGpsMultiunitInputData.imsi}'"
SoracomGpsMultiunitBatteryDetectorModelRole:
Type: AWS::IAM::Role
Properties:
RoleName: soracom-gps-multiunit-battery-detector-model-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: iotevents.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSNSFullAccess
デプロイ
aws cloudformation deploy \
--template-file notify_soracom_gps_multiunit_battery_low.yml \
--stack-name Notify-SORACOM-GPS-Multiunit-Battery-Low-Stack \
--capabilities CAPABILITY_NAMED_IAM \
--no-fail-on-empty-changeset
デプロイされた探知器モデルを確認する
無事にできました!
動作確認
BatteryHighになっている
さっそくディテクターの様子を見てみると、BatteryHigh状態になっていました。
バッテリー低残量が通知された
しばらく放置していると、バッテリー低残量が通知されました。
ディテクターの状態もBatteryLowになっています。
充電すると、バッテリー残量の復旧通知がきた
充電してしばらく待つと、バッテリー残量の復旧通知がきました。
ディテクターの状態もBatteryHighに戻りました。
おまけ
SORACOM Harvestでbat
を確認すると、下記のような状態でした。(送信間隔は5分)
bat | 時間 |
---|---|
2 | 約1時間半 |
1 | 約4時間半 |
今回はbat==1
で低残量を通知しましたが、あまり差がないので、bat==2
で通知しても良さそうですね。