Amazon MonitronのデータをKinesis Data Streamsにエクスポートしてみた

2023.08.21

こんにちは。CX事業本部Delivery部のAkkyです。

Amazon Monitronの日本国内での販売が開始され、弊社でもさっそく検証を行っています。

アカウントの準備、ゲートウェイの設定~データの取得までの流れは、以下の記事に詳しくまとまっていますので、ぜひご覧ください。

今回は、Amazon Monitronで取得したデータをKinesis Data Streamsにエクスポートしてみましたので、ご紹介します。

エクスポートの選択肢

Amazon Monitronでは、S3とKinesis Data Streamsの2つのサービスにデータをエクスポートできます。

ただし、S3に関してはエクスポートのたびにサポートケースを発行する必要があるなど、日常的に自動化することはできず、主にデバッグ用に使用することが想定されているようです。

そのため、日常的にデータをエクスポートするにはKinesis Data Streamsが唯一の選択肢となります。こちらを使うと取得されたデータのほか、ゲートウェイの接続・切断のイベントも取得できます。

公式ドキュメントはこちらになります

サービスの作成

Kinesis Data Streamsの作成

まずはKinesis Data Streamsを作ります。Monitronと同じリージョンに作れば問題ありません。 Monitronでは、基本的にはデータの取得間隔が1時間に1回のみなので、センサーが相当多くない場合は、容量モードをプロビジョンド、1シャードにするとコストが抑えられます。 この場合、書き込みは1MB/s、読み込みは2MB/sまでになります。

Monitronの設定(Live data export)

マネジメントコンソールでMonitronを開き、プロジェクトを選択すると、Live data exportという項目があります。 この中にあるStart live data exportをクリックすると、以下のような項目が開きます。

ここで先ほど作成したKinesis Data Streamsを選択してStart live data exportボタンをクリックすると、データの転送が設定できます。

送信されるデータ

測定データ

Monitronでは基本的に測定間隔が1時間に1回ですので、測定されるまで待つか、スマホをタッチしてデータを取得させることができますので、この操作を行います。

以下のようなJSONデータが取得できました。(扇風機に取り付けてテストしました)

{
    "timestamp": "2023-08-18 **:**:**.***",
    "eventId": "*",
    "version": "2.0",
    "accountId": "123456789012",
    "projectName": "<ProjectName>",
    "eventType": "measurement",
    "eventPayload": {
        "siteName": "Site 1",
        "assetName": "扇風機",
        "positionName": "モーター",
        "assetPositionURL": "https://app.monitron.aws/#/********/*******/@assets/*********/********/@details",
        "sensor": {
            "physicalId": "************",
            "rssi": -42
        },
        "gateway": {
            "physicalId": "************"
        },
        "sequenceNo": 6,
        "features": {
            "acceleration": {
                "band0To6000Hz": {
                    "xAxis": {
                        "rms": 1.5184
                    },
                    "yAxis": {
                        "rms": 3.7219
                    },
                    "zAxis": {
                        "rms": 9.4316
                    }
                },
                "band10To1000Hz": {
                    "totalVibration": {
                        "absMax": 1.0514,
                        "absMin": 0,
                        "crestFactor": 2.5115,
                        "rms": 0.4186
                    },
                    "xAxis": {
                        "rms": 0.2587
                    },
                    "yAxis": {
                        "rms": 0.2036
                    },
                    "zAxis": {
                        "rms": 0.2587
                    }
                }
            },
            "velocity": {
                "band10To1000Hz": {
                    "totalVibration": {
                        "absMax": 2.1331,
                        "absMin": 0,
                        "crestFactor": 1319.883,
                        "rms": 1.6161
                    },
                    "xAxis": {
                        "rms": 1.1227
                    },
                    "yAxis": {
                        "rms": 0.6362
                    },
                    "zAxis": {
                        "rms": 0.973
                    }
                }
            },
            "temperature": 25.3
        },
        "models": {
            "temperatureML": {
                "previousPersistentClassificationOutput": "HEALTHY",
                "persistentClassificationOutput": "HEALTHY",
                "pointwiseClassificationOutput": "INITIALIZING"
            },
            "vibrationISO": {
                "isoClass": "CLASS1",
                "mutedThreshold": null,
                "previousPersistentClassificationOutput": "HEALTHY",
                "persistentClassificationOutput": "HEALTHY",
                "pointwiseClassificationOutput": "HEALTHY"
            },
            "vibrationML": {
                "previousPersistentClassificationOutput": "HEALTHY",
                "persistentClassificationOutput": "HEALTHY",
                "pointwiseClassificationOutput": "INITIALIZING"
            }
        },
        "measurementTrigger": "measurementTrigger"
    }
}

大まかには加速度と温度の値、そして機械学習での判定結果が取れます。

加速度センサーの値は、スマホアプリではRMS(band10To1000Hz.totalVibration.rms)だけが見られますが、実際にはxyzが独立で取れ、10-1000Hzでフィルタする前の値も見ることができます。直流成分がカットされているから重力加速度が出てこなかったわけですね。 また、絶対値の最大値と最小値、クレストファクタ(波高率)も計算されています。

データのスキーマは公式ドキュメントにありますが、measurementTriggerなど追加されている項目が見受けられます。

measurementTriggerは定期取得ではmeasurementTriggerとなり、スマホから強制取得した場合にはnfcWakeupになっていました。

ゲートウェイの接続・切断イベント

{
    "timestamp": "2023-08-18 **:**:**.***",
    "eventId": "*********************************",
    "version": "2.0",
    "accountId": "123456789012",
    "projectName": "<ProjectName>",
    "eventType": "gatewayConnected",
    "eventPayload": {
        "siteName": "<ProjectName>",
        "gatewayName": "*******************",
        "gatewayListURL": "https://app.monitron.aws/#/********/@gateways",
        "gateway": {
            "physicalId": "**********"
        }
    }
}

接続時にeventTypeにgatewayConnected、切断時にはgatewayDisconnectedが入ってきました。

実験中、Wi-Fiの安定性のためか不明ですが、接続・切断イベントがごく短い間隔で送信されることがありました。

なお、ドキュメントによるとイベントにはsensorConnectedsensorDisconnectedassetStateTransitionもあるようです。

まとめ

Amazon MonitronのデータをKinesis Data Streamsにエクスポートしてみました。MonitronはWebアプリやスマホアプリだけでも完結して使うことができますが、LambdaやKinesis Client Libraryを使って他のシステムと連携することも可能になりますね。

引き続き、Monitronの活用方法を検証していきたいと思っています。