AWS IoT TwinMaker Knowledge Graphを試してみた #reinvent

2022.12.11

こんにちは、CX事業本部 IoT事業部の若槻です。

AWS re:Invent 2022で、AWS IoT TwinMakerの新機能としてTwinMaker Knowledge Graphが発表されました。

画像はセッションAWS re:Invent 2022 - Unlocking business value and operational benefits with IoT solutions (IOT211-L)より。

TwinMaker Knowledge Graphを使用すると、ユーザーはTwinMaker上のデジタルツインに対してクエリを実行してコンテキスト化されたデータを取得し、リアルワールドのシステムについてより深いインサイトを得ることができるとのことです。

今回は、AWS IoT TwinMaker Knowledge Graphを学ぶのに丁度良さそうな公式Workshopコンテンツがあったのでやってみます。

やってみる

実施したのは次のWorkshopです。

TwinMakerワークスペースの作成

AWSにより予め用意されたCloudFormationテンプレートを使用して、TwinMakerワークスペースを作成します。(Workshopは学習環境が簡単に作成できる仕組みがあるのが嬉しいですね)

CloudFormationスタックの作成が開始されます。IoT TwinMakerのEntityが大量に作成されるので、しばらく待ちます。

SmartBuildingスタックの作成が完了しました。

AWS IoT TwinMakerコンソールにアクセスすると、SmartBuildingワークスペースが作成されているので選択します。

[Entities]では200以上のエンティティが作成されていることが確認できます。

エンティティのRelationshipを確認する

今回作成されたエンティティにはRelationshipプロパティが予め設定されています。Relationshipはエンティティコンポーネントの特別なタイプのプロパティです。

ここで次のAWS CLIコマンドを実行して、エンティティの情報を取得します。

aws iottwinmaker get-entity --entity-id room_9d575186-bf8b-5ceb-b12a-6a06d6b28e1d --region us-east-1 --workspace-id SmartBuilding

するとエンティティ名room_2の情報が取得できます。

{
    "arn": "arn:aws:iottwinmaker:us-east-1:XXXXXXXXXXXX:workspace/SmartBuilding/entity/room_9d575186-bf8b-5ceb-b12a-6a06d6b28e1d",
    "components": {
        "RoomComponent": {
            "componentName": "RoomComponent",
            "componentTypeId": "com.example.query.construction.room",
            "properties": {
                "isLocationOf": {
                    "definition": {
                        "dataType": {
                            "nestedType": {
                                "type": "RELATIONSHIP"
                            },
                            "type": "LIST"
                        },
                        "isExternalId": false,
                        "isFinal": false,
                        "isImported": false,
                        "isInherited": true,
                        "isRequiredInEntity": false,
                        "isStoredExternally": false,
                        "isTimeSeries": false
                    },
                    "value": {
                        "listValue": [
                            {
                                "relationshipValue": {
                                    "targetEntityId": "floor_83faea7a-ea3b-56b7-8e22-562f0cf90c5a"
                                }
                            }
                        ]
                    }
                },
                "roomFunction": {
                    "definition": {
                        "dataType": {
                            "allowedValues": [
                                {
                                    "stringValue": "meeting"
                                },
                                {
                                    "stringValue": "office"
                                },
                                {
                                    "stringValue": "restroom"
                                }
                            ],
                            "type": "STRING"
                        },
                        "isExternalId": false,
                        "isFinal": false,
                        "isImported": false,
                        "isInherited": false,
                        "isRequiredInEntity": false,
                        "isStoredExternally": false,
                        "isTimeSeries": false
                    },
                    "value": {
                        "stringValue": "office"
                    }
                },
                "roomNumber": {
                    "definition": {
                        "dataType": {
                            "type": "INTEGER"
                        },
                        "isExternalId": false,
                        "isFinal": false,
                        "isImported": false,
                        "isInherited": false,
                        "isRequiredInEntity": false,
                        "isStoredExternally": false,
                        "isTimeSeries": false
                    },
                    "value": {
                        "integerValue": 2
                    }
                }
            },
            "status": {
                "error": {},
                "state": "ACTIVE"
            }
        }
    },
    "creationDateTime": "2022-12-11T22:46:44.542000+09:00",
    "description": "",
    "entityId": "room_9d575186-bf8b-5ceb-b12a-6a06d6b28e1d",
    "entityName": "room_2",
    "hasChildEntities": false,
    "parentEntityId": "$ROOT",
    "status": {
        "error": {},
        "state": "ACTIVE"
    },
    "updateDateTime": "2022-12-11T22:46:45.331000+09:00",
    "workspaceId": "SmartBuilding"
}

room_2isLocationOfというRELATIONSHIPタイプのプロパティを持っています。現在はrelationshipValueとして1つのエンティティ(floor_83faea7a-ea3b-56b7-8e22-562f0cf90c5a)のみがtargetEntityIdとして指定されており、階層関係にあることが分かります。

また、次のようにコマンドを実行してエンティティfloor_83faea7a-ea3b-56b7-8e22-562f0cf90c5aの情報を取得することにより、さらに階層関係を追跡することが可能です。

aws iottwinmaker get-entity --entity-id floor_83faea7a-ea3b-56b7-8e22-562f0cf90c5a --region us-east-1 --workspace-id SmartBuilding

Knowledge Graphを確認する

コンソールのクエリエディターで次のクエリを実行します。名前がroom_%に合致するエンティティをすべて取得するというPartiQL仕様のクエリです。

SELECT e.entityName FROM EntityGraph MATCH (e) WHERE e.entityName LIKE 'room_%'

あれっエラーになりました。

クエリエディターを使うためにはビリングモードをSTANDARDまたはTIERED_BUNDLEに変更する必要があるようです。

AccessDeniedException
You cannot use ExecuteQuery with the current pricing mode: BASIC. Please change pricing mode to STANDARD or TIERED_BUNDLE through AWS IoT TwinMaker console setting page or UpdatePricingPlan api.

TwinMakerコンソール上方に[Opt in to use Knowledge Graph]というインフォバーが表示されていたのでクリックしてみたのですが何も起こりません。

[Settings]の[Pricing]タブから設定する必要があるようです。

今回はStandartに変更します。

変更できました。

インフォバーの記載も変わりました。(消えはしないんですね)

改めてクエリエディターからクエリを実行すると、実行が成功し条件に合致するエンティティの一覧を取得できました。

続いて次のクエリを実行します。これによりKnowledge Graphを確認します。

SELECT floor.entityName AS floor, room.entityName AS room FROM EntityGraph MATCH (floor)<-[:isLocationOf]-(room) WHERE room.entityName = 'room_2'

これによりルームroom_2isLocationOfの関係にあるフロアfloor_0が取得できました。

続いて次のクエリを実行します。先ほどと異なるのはMATCH式でr:isLocationOfrが付与されている点です。

SELECT floor, r, room FROM EntityGraph MATCH (floor)<-[r:isLocationOf]-(room) WHERE room.entityName = 'room_2'

実行するとroom_2floor_0に属しているというKnowledge Graphを可視化できました。

CLIで確認する

AWS CLIを使ってKnowledge Graphを確認することも可能です。

使うのはiottwinmaker execute-queryコマンドですが、最近追加されたものなのでAWS CLIのバージョンが古い場合は事前にアップデートしてください。

次のコマンドを実行します。

queryStatement="SELECT floor.entityName AS floor, room.entityName AS room FROM EntityGraph MATCH (floor)<-[:isLocationOf]-(room) WHERE room.entityName = 'room_2'"
workspaceId=SmartBuilding
aws iottwinmaker execute-query --workspace-id $workspaceId --query-statement "$queryStatement" --region us-east-1

room_2floor_0isLocationOfの関係をKnowledge Graphとして取得できました。

{
    "columnDescriptions": [
        {
            "name": "floor",
            "type": "VALUE"
        },
        {
            "name": "room",
            "type": "VALUE"
        }
    ],
    "rows": [
        {
            "rowData": [
                "floor_0",
                "room_2"
            ]
        }
    ]
}

Relationshipを変更する

エンティティのRelationshipは簡単に更新することもできます。

コンソールのエンティティ一覧でroom_2RoomComponentを選択して[Edit]をクリック。

プロパティをJSONで編集します。targetEntityIdfloor_895679ed-362a-5ef2-80fd-772d3fe56f79を指定します。

クエリエディターで前述と同じクエリを実行すると、room_2が所属するフロアがfloor_1に変更されていることが確認できました。

おわりに

AWS IoT TwinMaker Knowledge Graphを学ぶのに丁度良さそうな公式Workshopコンテンツがあったのでやってみました。

これにより新機能のKnowledge Graphがどういうものであるかについて学ぶことができました。エンティティがもっと多くなった場合にエンティティ同士の関係性を確認したい場合に役に立ちそうです。

参考

以上