# SC CrossLabハンズオン_演習ガイド
###### tags: `CrossLab`
# 目次
### [ハンズオン概要](#ハンズオン概要)
* [ハンズオンの全体構成](#ハンズオンの全体構成)
* [ハンズオンで作成するシナリオ](#ハンズオンで作成するシナリオ)
### [Day1](#Day1)
* [VANTIQの登録](#VANTIQの登録)
* **ラボ**
* [Step1:VANTIQアカウントの作成](#Step1:VANTIQアカウントの作成)
* [プロジェクトの作成](#プロジェクトの作成)
* **ラボ**
* [Step1:Projectsの作成](#Step1:Projectsの作成)
* [使用する水位計の確認](#使用する水位計の確認)
* **ラボ**
* [Step1:使用する水位計を決める](#Step1:使用する水位計を決める)
### [Day2](#Day2)
* [VANTIQのType](#VANTIQのType)
* **ラボ**
* [Step1:水位計のデータの型の確認](#Step1:水位計のデータの型の確認)
* [Step2:SchemaTypeの作成](#Step2:SchemaTypeの作成)
* [Step3:StandardTypeの作成①](#Step3:StandardTypeの作成①)
* [Step4:StandardTypeの作成②](#Step4:StandardTypeの作成②)
* [VANTIQのSourceとTopic](#VANTIQのSourceとTopic)
* ラボ
* [Step1:VANTIQが外部と通信する先の確認](#Step1:VANTIQが外部と通信する先の確認)
* [Step2:Slack用のSourceの作成](#Step2:Slack用のSourceの作成)
* [Step3:MessagePub+用のSource](#Step3:MessagePub+用のSource)
* [Step4:MessagePub+用のTopicの作成](#Step4:MessagePub+用のTopicの作成)
* [Step5:Appの動作確認のためのTopicの作成](#Step5:Appの動作確認のためのTopicの作成)
### [Day3](#Day3)
* [VAILの基礎](#VAILの基礎)
* **ラボ**
* [Step1:Serviceの作成](#Step1:Serviceの作成)
* [Step2:Serviceに紐づけられたProcedureの作成](#Step2:Serviceに紐づけられたProcedureの作成)
* [Step3:FOR文](#Step3:FOR文)
* [Step4:IF文 ](#Step4:IF文 )
* [Step5:リスト型](#Step5:リスト型)
* [Step6:Dict型(辞書型)](#Step6:Dict型(辞書型))
* [Step7:リスト型とDict型(辞書型)の融合](#Step7:リスト型とDict型(辞書型)の融合)
* [Step8:Type用意](#Step8:Type用意)
* [Step9:Typeの操作①](#Step9:Typeの操作①)
* [Step10:Typeの操作②](#Step10:Typeの操作②)
* [VANTIQのRuleとProcedure](#VANTIQのRuleとProcedure)
* **ラボ**
* [Step1:Slackに通知するProcedureの作成](#Step1:Slackに通知するProcedureの作成)
* [Step2:MsgPub+にSubScribeするRuleとProcedureのインポート](#Step2:MsgPub+にSubScribeするRuleとProcedureのインポート)
### [Day4](#Day4)
* [VANTIQのAppBuilderに関して](#VANTIQのAppBuilderに関して)
* **ラボ**
* [Step1:環境構築とイベントの受信Activity「GetEventFrom_MsgPub」の作成](#Step1:環境構築とイベントの受信Activity「GetEventFrom_MsgPub」の作成)
* [Step2:イベントの受信の確認](#Step2:イベントの受信の確認)
* [Step3:Tranformation Activity_1](#Step3:Tranformation-Activity_1)
* [Step4:Enrich Activity_1](#Step4:Enrich-Activity_1 )
* [Step5:Filter Activity_1](#Step5:Filter-Activity_1)
* [Step6:Procedure Activity_1](#Step6:Procedure-Activity_1)
* [Step7:Enrich Activity_2](#Step7:Enrich-Activity_2)
* [Step8:Tranformation Activity_2](#Step8:Tranformation-Activity_2)
* [Step9:SaveToType Activity](#Step9:SaveToType-Activity)
* [Step10:Filter Activity_2](#Step10:Filter-Activity_2)
* [Step11:Procedure Activity_2](#Step11:Procedure-Activity_2)
* [Step12:水位計を接続する](#Step12:水位計を接続する)
### [Day5](#Day5)
* [VANTIQのRESTAPI](#VANTIQのRESTAPI)
* **ラボ**
* [Step1:Postmanへの登録](#Step1:Postmanへの登録)
* [Step2:Postmanの基本](#Step2:Postmanの基本)
* [Step3:Postmanのダウンロード](#Step3:Postmanのダウンロード)
* [Step4:アクセストークンの作成](#Step4:アクセストークンの作成)
* [Step5:APIを用いて、VANTIQのTypeからデータを取得する](#Step5:APIを用いて、VANTIQのTypeからデータを取得する)
* [Step6:APIを用いて、VANTIQのTypeへデータを追加する](#Step6:APIを用いて、VANTIQのTypeへデータを追加する)
* [Step7:APIを用いて、Topicに直接イベントをPOSTする](#Step7:APIを用いて、Topicに直接イベントをPOSTする)
---
# ハンズオン概要
## ハンズオンの全体構成
CrossLabに設置されている簡易水位計のデータを、MQTT BrokerであるMessagePub+を介して、EDAであるVANTIQからSubscribeし、リアルタイムで処理を行う。

## ハンズオンのシナリオ
CrossLabに設置されている簡易水位計において、以下を実現する。
1. 30秒ごとに2台ある水位計の値を取得する。
2. データの処理を行いやすいように、データを整形する。
3. 2台ある水位計に対してそれぞれ担当者を紐づける。
4. 自身が操作する水位計のデータのみを抽出する。
5. 1つ前の水位計の値を、old_valueとしてTypeに格納する。
6. old_valueの値を現在のイベントに付加させる。
7. 必要なデータのみにイベントを整形する。
8. 水位計のデータをTypeに格納する。
9. 現在の水位計の値が1つ前の水位計の値(old_value)より大きいかつ、現在の水位計の値が8.5以上かを判定する。
10. 上記判定した結果Trueの場合、Slackに通知する。

---
# Day1
## VANTIQの登録
### 概要
このLabでは、VANTIQのアカウントを作成する。
### 注意事項
ユーザー管理のため、アカウント保持者は全員**nttcom_root**というNameSpaceにまず紐づけられ、その後ユーザ管理者によって、各プロジェクトのNameSpaceに紐づけられます。
**nttcom_root**はあくまでユーザ管理が目的なので、Projects等は作成しないでください。
このハンズオンは、**SWB_SmartCity**というNameSpaceで行います。
**SWB_SmartCity**は、自由にVANTIQを勉強することを目的といたNameSpaceのため、今後も自由にご活用ください。
### ラボ
* [Step1:VANTIQアカウントの作成](#Step1:VANTIQアカウントの作成)
#### Step1:VANTIQアカウントの作成
* 自分のVANTIQアカウントの作成を行う
1. 招待メールが新規アカウント登録者へ送信されるので、メール中段にある「here」のURLをクリックする。

2. 画面下部の「登録」をクリックする。

3. 以下の情報を入力し、アカウント登録する。
* First name:名(英語表記) 例 Taro
* Last name:姓(英語表記) 例 Yamada
* Email:認証をしたメールアドレス
* Username:認証をしたメールアドレス
* Password:任意のパスワード(12 文字以上)
* Confirm password:パスワードの再入力

4. 2要素認証の登録画面が表示されるので、Google AuthenticatorやAuthyというアプリを利用して、QRコードを読み込む。QRを読み込むとワンタイムコードが発行されるので、それを入力し、送信をクリックする。
* **デバイス名は空欄で可です**
* 私はAuthyというアプリを利用しています。AppleWatchで確認できるので。

5. 認証のメールが登録したメールアドレスに届くので、メール本文のリンクをブラウザで開くことで、アカウント登録が完了する。

6. ログイン後、ポリシーへの同意を求められるので、同意する。

7. 新規プロジェクト作成を求められるが、「キャンセル」をクリックする。

8. ユーザ管理者に、利用するNameSpace(今回は**SWB_SmartCity**) に紐づけるよう依頼をする。
**VANTIQのアカウント作成の手順は以上です。**
## プロジェクトの作成
### 概要
このLabでは、VANTIQの新規のプロジェクトを作成する。
### 注意事項
NameSpace **「SWB_SmartCity」** は色々な人が検証や、勉強のために使用するNameSpaceなので、今回作成するプロジェクト名には必ず自分の名前をつけること。
### ラボ
* [Step1:Projectsの作成](#Step1:Projectsの作成)
#### Step1:Projectsの作成

* 自分が作業するためのProjectの作成を行う
1. ナビゲーションバーのユーティリティにある **「nttcom_root」** と書いているところあるいは地球儀のマークをクリックする。

2. **「SWB_SmartCity」** を選択し、NameSpaceを **「nttcom_root」** から **「SWB_SmartCity」** に変更する。

3. ナビゲーションバーのプロジェクトから、**「Projects」** をクリックし、**「新規プロジェクト...」** をクリックする。

4. **「プロジェクトの追加」** を選択し、**「続行」** をクリックする。

5. **「空のプロジェクト」** を選択し、**「続行」** をクリックする。ff
※基本的に新規プロジェクトを作成する際は常に **「空のプロジェクト」** を選択すること。

6. プロジェクト名に **「LabHandsOn_\<YourName>」 ※\<YourName>は自分の名前** と入力し、**「終了」** をクリックする。

**新規プロジェクトの作成は以上です。**
## 使用する水位計の確認
### 概要
CrossLabには、水位計が2台ある。
* 水位計01(河川1)
* 水位計02(河川2)

このあとの演習で、自身がどちらの水位計を使用するかを決める。
### 注意事項
水位のデータとしては、両方の水位計のデータがVANTIQ上に流れてくるので、一人でこの演習を実施していたとしても、自身が担当しない水位計の担当者も決めること。
### ラボ
#### Step1:使用する水位計を決める
* [Step1:使用する水位計を決める](#Step1:使用する水位計を決める)
* 2台ある水位計のうちどちらを使用するかを決める。
* 一人で演習を行っている場合、基本的に水位計01(河川1)を使用すること。
1. この後の演習で、どちらの水位計を使用するかを決める。
以下の情報は都度演習ガイドに記載しているので、控える必要はない。
* 水位計01の情報
| 水位計01の情報 | VANTIQでSubscribeするデータ |
| ---------- | --------------------------- |
| DeviceName | Device-Shibaura3_TamachiGP_4_Lab_L-1 |
| point | 01-Distance |
* 水位計02の情報
| 水位計02の情報 | VANTIQでSubscribeするデータ |
| ---------- | --------------------------- |
| DeviceName | Device-Shibaura3_TamachiGP_4_Lab_L-2 |
| point | 02-Distance |
**使用する水位計の情報の確認は以上です。**
**Day1のハンズオンは以上となります。お疲れさまでした。**
---
# Day2
## VANTIQのType
### 概要
このLabでは、Typeを作成する。VANTIQのTypeには**Standard**と**Schema**の2種類存在する。
* **Schema Type**
受信するイベントの**構造と型を理解するため**に利用されます。この Labでは以下の1つの**SchemaType**を作成する。
* **WaterGauge_\<YourName> ※\<YourName>は自分の名前**
* Subscribeする水位計のイベントの構造と型の把握、理解のためのType。
* **Standard Type**
**データベースのテーブル**のような仕組みで情報の保存に使用する。この Labでは以下の2つの**StandardType**を作成する。
* **Users_\<YourName> ※\<YourName>は自分の名前**
* **「誰が」**、**「どの水位計」** を管理しているかという情報を格納するためのType。
* **Data_\<YourName> ※\<YourName>は自分の名前**
* 受信した水位計の**情報**を格納する。
* どの水位計か
* その水位計の管理者
* 水位計が示している値
* 1つ前のイベントにて水位計が示した値
この Lab では上記の計3つのTypeの定義を行い、必要なデータの追加を行う。

### 注意事項
作成するTypeの名前には必ず、**_\<YourName> ※\<YourName>は自分の名前** をつけること。
### ラボ
* [Step1:水位計のデータの型の確認](#Step1:水位計のデータの型の確認)
* [Step2:SchemaTypeの作成](#Step2:SchemaTypeの作成)
* [Step3:StandardTypeの作成①](#Step3:StandardTypeの作成①)
* [Step4:StandardTypeの作成②](#Step4:StandardTypeの作成②)
#### Step1:水位計のデータの型の確認
* 今回のハンズオンで、VANTIQがSubscribeする水位計のデータの型を確認する。
* 以下がVANTIQがSubscribeする水位計のデータである。
* 水位計01
```
{
"value": {
"type": "SensingHistory",
"dateProcessed": "2022-05-31T13:03:30+09:00",
"value": 3.5,
"unit": "m",
"site": "Site-Shibaura3",
"building": "Building-Shibaura3_TamachiGP",
"floor": "Floor-Shibaura3_TamachiGP_4",
"space": "Space-Shibaura3_TamachiGP_4_Lab",
"device": "Device-Shibaura3_TamachiGP_4_Lab_L-1",
"point": "01-Distance",
"collectProcessPattern": "1",
"dataAdministrator": "Organization-TGPLabo",
"id": "Device-Shibaura3_TamachiGP_4_Lab_L-1_01-Distance_2022-05-31T13:03:30+09:00"
},
"topicName": "/v1/bousai/ntt.com/shibaura/grandpark/labo/showcase/watergauge01/waterlevel"
}
```
* 水位計02
```
{
"value": {
"type": "SensingHistory",
"dateProcessed": "2022-05-31T13:03:00+09:00",
"value": 3.5,
"unit": "m",
"site": "Site-Shibaura3",
"building": "Building-Shibaura3_TamachiGP",
"floor": "Floor-Shibaura3_TamachiGP_4",
"space": "Space-Shibaura3_TamachiGP_4_Lab",
"device": "Device-Shibaura3_TamachiGP_4_Lab_L-2",
"point": "02-Distance",
"collectProcessPattern": "1",
"dataAdministrator": "Organization-TGPLabo",
"id": "Device-Shibaura3_TamachiGP_4_Lab_L-2_02-Distance_2022-05-31T13:03:00+09:00"
},
"topicName": "/v1/bousai/ntt.com/shibaura/grandpark/labo/showcase/watergauge02/waterlevel"
}
```
VANTIQで受ける水位計のデータは、VANTIQのObject型(Dict型)であることがわかり、このObject型のKeyは **「"value"」** と **「"topicName"」** の2つであることがわかる。
また、Key: **「"value"」** に対するValue(値)も、Dict型(辞書型)であることがわかる。
2台ある水位計は、Key: **「"value"」** のValue(値)のDict型(辞書型)の中のKey: **「"device"」** と、Key: **「"point"」** の各Value(値)で判別できることがわかる。
今回のハンズオンでは、水位計を判別するために、Key: **「"value"」** のValue(値)であるDict型(辞書型)の中のKey: **「"point"」** のValue(値)を用いることにする。
このようにVANTIQのtopicで受信するデータの型を分析、理解した記録を残しておくために、SchemaTypeをTopicに対して設定する。
**水位計のデータの型の確認は以上となります。**
#### Step2:SchemaTypeの作成

* VANTIQがSubscribeする水位計のデータの構造と型の把握と理解のため、Schema Typeを作成する。
1. 今回受信する水位計のデータの形式を確認する。(step1にて実施済み)
【再掲】
VANTIQがSubscribeする水位計のデータは、Dict型(辞書型)であることがわかり、このDict型(辞書型)のKeyは **「"value"」** と **「"topicName"」** の2つである。
2. データの形式を確認したので、Schema Typeを作成していく。
ナビゲーションバーのツールキットより、**「追加」** > **「Type...」** を選択する。

3. 右上の **「+新規 Type」** をクリックし、Typeの新規作成画面を開く。

4. **Name**に **WaterGauge_\<YourName> ※\<YourName>は自分の名前** と入力し、**Role**を **Schema**に設定して **「OK」** をクリックする。
* 画像の **YourName** の部分を自分の名前にする。

5. **WaterGauge_\<YourName> ※\<YourName>は自分の名前** Typeの **「Properties」** タブを開き、 **「+Property の追加」** から、下記の表の通りにプロパティの設定を行う。
**プロパティの設定:** カラム名(列名/データの項目名)と、データの型の設定。
また、valueの水位計のデータは、**「Dict型(辞書型)」** であり、リスト型ではないので、**Multiにチェックは入れない。**
| Name | Description | Type | Required | 備考 |
|:---------:|:--------------------------:|:------:|:--------:| -------------------------------------------------- |
| topicName | MesPubにSubScribeするtopic | String | ✔️ | Key「**topicName**」のvalueは**String (文字列)型** |
| value | 水位計のデータ | Object | ✔️ | Key「**value**」のvalueは **Dict型(辞書型)** |

6. **「General」** タブを開き **「Group by」** に、**「topicName」** を設定する。
* **GroupBy**:指定したカラムの値をキーとしてレコードをグループ化することができる機能。
* 今回受信するMQTTBroker(MsgPub+)からSubscribeするtopicは一意に定まっており、topicごとに受信するデータが定められている。今回は受信するtopic(データ)ごとにグルーピングしたいので、カラム名「topicName」でグルーピングを行う。

7. Saveボタンをクリックし、Typeを保存する。

**WaterGauge_\<YourName>の設定は以上です。**
#### Step3:StandardTypeの作成①

* 「誰が」「どの水位計」を管理しているかという情報を格納するために、**Users_\<YourName> ※\<YourName>は自分の名前** というStandard Typeを作成する。
1. **「追加」** > **「Type...」** > **「+新規 Type」** をクリックし、Typeの新規作成画面を開く。
2. **Name**に **Users_\<YourName> ※\<YourName>は自分の名前** と入力し、**Role**を **Standard**に設定して **「OK」** をクリックする。

3. **Users_\<YourName> ※\<YourName>は自分の名前** Type の **「Properties」** タブを開き **「+Property の追加」** から以下の3つのプロパティを作成する。

| Name | Description | Type | Required | 備考 |
| ----- | -------------------- | ------- | --- | ---------------------------- |
| id | 番号 | Integer | ✓ | レコード(行)を一意にするため |
| Name | 水位計の管理者 | String | | |
| point | どの水位計かを示す | String | | |
4. **「Index」** タブを開き **「+Indexの追加」** をクリックする。

5. **「Is Index unique?」** にチェックを入れ、Keyに **「id(Integer)」** を設定して **「OK」** をクリックする。
* レコード(行)を一意にするために「id」カラムを用意したので、ここでidカラムをUniqueKeyにとする。
* **「_id」 はVANTIQ側が自動的に設定しているカラムなので、選ばないでください!**

6. **Save** ボタンをクリックし、Typeを保存する。
7. 情報を格納するため、**「新しいレコードの追加」** をクリックする。

8. 以下の情報を入力し、**「新規レコード」のボタン** をクリックし、新規レコードの追加を行う。
* 水位計01の担当者
| レコード名 | 入力値 |
| ---------- | ----------- |
| id | 01 |
| Name | 自分の名前 |
| point | 01-Distance |
* 水位計02の担当者
| レコード名 | 入力値 |
| ---------- | ----------- |
| id | 02 |
| Name | 自分の名前 |
| point | 02-Distance |

9. 同様に以下の情報を入力し、新規レコードの追加を行う。
* 水位計01の担当者
| レコード名 | 入力値 |
| ---------- | ----------- |
| id | 02 |
| Name | 自分以外の人の名前 |
| point | 02-Distance |
* 水位計02の担当者
| レコード名 | 入力値 |
| ---------- | ----------- |
| id | 01 |
| Name | 自分以外の人の名前 |
| point | 01-Distance |
**Users_\<YourName>の設定は以上です。**
#### Step4:StandardTypeの作成②

* **Data_\<YourName> ※\<YourName>は自分の名前** Standard Typeを作成する。
* **Data_\<YourName> ※\<YourName>は自分の名前** Typeには、受信した水位計の情報と1つ前の水位計が示した値を格納する。
1. **「追加」** > **「Type...」** > **「+新規 Type」** をクリックし、Typeの新規作成画面を開く。
2. **Name**に **Data_\<YourName> ※\<YourName>は自分の名前** と入力し、**Role**を **Standard**に設定して **「OK」** をクリックする。
3. **Data_\<YourName> ※\<YourName>は自分の名前** Type の **「Properties」** タブを開き **「+Property の追加」** から以下の5つのプロパティを作成する。
| Name | Description | Type | Required | 備考 |
| ---------- | ----------------------------- | ------ | --- | ------------------------ |
| DeviceName | デバイス名 | String | ✓ | レコードを一意にするため |
| Name | 水位計の管理者。 | String | | |
| old_value | 1つ前のイベントの水位計の値。 | Real | | |
| point | どの水位計かを示す。 | String | | |
| value | 水位計が示す値。 | Real | | |
4. **「Index」** タブを開き **「+Indexの追加」** をクリックする。
5. **「Is Index unique?」** にチェックを入れ、Keyに **「DeviceName(String)」** を設定し、 **「OK」** をクリックする。
* レコードを一意にするために「DeviceName」カラムを用意したので、ここでDeviceNameカラムをUniqueKeyにとする。
6. **「Natural Keys」** タブを開き **「Keyの設定」** をクリックする。
7. Keyに **「DeviceName」** を設定して **「OK」** をクリックする。
「DeviceName」は人間が識別できる(意味がわかる)カラム名なので、NaturalKeyとする。

8. Save ボタンをクリックし、Typeを保存する。
9. 情報を格納するため、**「新しいレコードの追加」** をクリックする。
10. 以下の情報を入力し、新規レコードの追加を行う。
* 水位計01の担当者
| レコード名 | 入力値 |
| ---------- | ------------- |
| DeviceName | Device-Shibaura3_TamachiGP_4_Lab_L-1 |
| Name | 自分の名前 |
| old_value | 0.5 |
| point | 01-Distance |
| value | 1.5 |
* 水位計02の担当者
| レコード名 | 入力値 |
| ---------- | ------------- |
| DeviceName | Device-Shibaura3_TamachiGP_4_Lab_L-2 |
| Name | 自分の名前 |
| old_value | 0.5 |
| point | 02-Distance|
| value | 1.5 |
**Data_\<YourName>の設定は以上です。**
**Typeを作成するハンズオンは以上です。お疲れさまでした。**
## VANTIQのSourceとTopic
### 概要
このLab では、SourceとTopicを作成する。
**Source**は、外部システムとの接続ポイントであり、データの送受信の入り口(インターフェイス)です。MQTT、RESTだけでなく、KAFKAやEMAILなど、様々な種類が選択可能。
**Topic**は VANTIQシステムの内部でのデータの送信先となる仕組みである。主にDay4で扱うAppBuilederで使用する。

### 注意事項
今回、このハンズオン特有の手順が出てくるので、手順をしっかり守ること。
また基本的に、作成するSourceとtopic名には **_\<YourName> ※\<YourName>は自分の名前** をつけること。(既に作成済みのものを流用する場合は別)
### ラボ
* [Step1:VANTIQが外部と通信する先の確認](#Step1:VANTIQが外部と通信する先の確認)
* [Step2:Slack用のSourceの作成](#Step2:Slack用のSourceの作成)
* [Step3:MessagePub+用のSource](#Step3:MessagePub+用のSource)
* [Step4:MessagePub+用のTopicの作成](#Step4:MessagePub+用のTopicの作成)
* [Step5:Appの動作確認のためのTopicの作成](#Step5:Appの動作確認のためのTopicの作成)
#### Step1:VANTIQが外部と通信する先の確認
* 今回、VANTIQが外部と通信する先を確認する。

この図より、今回のハンズオンでVANTIQは、MQTT Brokerである **「MessagePub+」** と、**「slack」** と通信することがわかる。
また、VANTIQにて受信するイベントは **「MQTT BrokerであるMessagePub+」** なので、VANTIQにおいてtopicは、「MessagePub+」の分だけ用意をする。
#### Step2:Slack用のSourceの作成

* Slack用のSourceを作成する
1. ナビゲーションバーのツールキットの **「追加」** をクリックし、**「Source」** を選択する。

2. **「+新規Source」** をクリックする。

3. 以下の項目を入力する。
* Source Nameに **「SendToSlack_\<YourName>」 ※\<YourName>は自分の名前** と入力する。
* Source Typeは **「REMOTE」** を選択する。
* Slackのincomming WebhookはHTTPsの通信のため。

4. **Propertiesタブ** を開き、ServerURIの部分に、以下のURIを入力し、保存ボタンをクリックする。
* このURIはSlackのincomming WebhookのURLです。今回のハンズオンではincomming Webhookの作成は対象外なので、予めこちらで作成してあるものを使用する。
`https://hooks.slack.com/services/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`

**Slack用のSourceの作成は以上です。**
#### Step3:MessagePub+用のSource

* MessagePub+用のSourceを追加
* 水位計のデータに関しては既に他のNameSpace(防災案件)で利用しており、防災案件用のMessagePub+とVANTIQの間の接続ルールは決められているため、既に存在するSourceを利用する。
勉強のために、インポート後、Sourceの設定項目は確認すること。
1. ナビゲーションバーのツールキットの **「追加」** をクリックし、**「Source」** を選択する。
2. **「SensorEventSource」** を選択肢し、**「選択した項目の追加」** をクリックする。

**MessagePub+用のSourceのインストールは以上です。**
#### Step4:MessagePub+用のTopicの作成

* MessagePub用からデータを受信するためのtopicを追加
* Step3同様、水位計のデータに関しては既に他のNameSpace(防災案件)で利用しており、防災案件用のMessagePub+とVANTIQの接続のルールが決められているため、既に存在するTopicを利用する。
1. ナビゲーションバーのツールキットの **「追加」** をクリックし、**「Advanced」** より、**「topic」** を選択する。

2. **「/topic/watergauge」** を選択し、**「選択した項目の追加」** をクリックする。

3. IDE Docks(左側)のProject Contentsより、**「/topic/watergauge」** を選択する。

4. MessageType(Topicと紐づけるSchemaType)が「WaterGauge」になっているが、これは既にあるTopicを全員で共有しているからである。本来ならMessageTypeには、**ラボ:Typeの作成** で作成したSchemaType **「WaterGauge_\<YourName>」 ※\<YourName>は自分の名前** を紐づけるのだが、今回使用するTopicは全員で共有しているため、あらかじめ用意されているSchemaType **「WaterGauge」** を使用することにする。

**補足:** Topicを新規作成する時の画面
Nameに「/」で始まるtopic名を設定。(このTopic名がVANTIQ内で使用するTopicとなる)
MessageTypeに、このTopicに合わせて作成したSchemaTypeを選択する。

**MessagePub+用のtopicのインストールは以上です。**
#### Step5:Appの動作確認のためのTopicの作成
* Appを作成時に動作確認を行う用のTopicを作成する。
1. ナビゲーションバーのツールキットの **「追加」** をクリックし、**「Advanced」** より、**「topic」** を選択する。
2. 「+新規Topic」をクリックする。
3. Nameに **「/topic/watergauge_\<YourName>」※\<YourName>は自分の名前** と入力し、Message Typeに、前のラボの[Step2](Step2:WaterGauge_\<YourName>という-Schema-Typeの作成)で作成した **「WaterGauge_\<YourName」 ※\<YourName>は自分の名前** を選択し、「OK」をクリックする。

**:Appの動作確認のためのTopicの作成は以上です。**
**最後に、ナビゲーションバーのプロジェクトより、プロジェクトの保存を行ってください!** 
**Day2のハンズオンは以上となります。お疲れさまでした。**
---
# Day3
## VAILの基礎
### 概要
このLab では、VAILを用いてプログラミングの基本を学ぶ。
VAILはVANTIQ特有の言語だが、主に **RULE** や、**Procedure** といったVANTIQでは欠かせないリソースで使われている。
また、VAILは **JavaScript** と **SQL** を合わせた言語なため、VAILを通して、JavaScriptとSQLの基礎を学ぶことができる。
### 注意事項
作成するリソース名には **_\<YourName> ※\<YourName>は自分の名前** をつけること。
### ラボ
* [Step1:Serviceの作成](#Step1:Serviceの作成)
* [Step2:Serviceに紐づけられたProcedureの作成](#Step2:Serviceに紐づけられたProcedureの作成)
* [Step3:FOR文](#Step3:FOR文)
* [Step4:IF文 ](#Step4:IF文 )
* [Step5:リスト型](#Step5:リスト型)
* [Step6:Dict型(辞書型)](#Step6:Dict型(辞書型))
* [Step7:リスト型とDict型(辞書型)の融合](#Step7:リスト型とDict型(辞書型)の融合)
* [Step8:Type用意](#Step8:Type用意)
* [Step9:Typeの操作①](#Step9:Typeの操作①)
* [Step10:Typeの操作②](#Step10:Typeの操作②)
#### Step1:Serviceの作成
* VAILを書く練習をする際にProcedure用いるが、そのProcedureをまとめるためのリソース**Service** を作成する。
1. ナビゲーションバーのツールキットの **「追加」** から、**「Service」** を選択

2. 「新規サービス」を選択

3. 「Name」欄に **「VAIL_Practice_\<YourName>」 ※\<YourName>は自分の名前** を入力し、「OK」をクリックする

**Serviceの作成に関しては以上です。**
#### Step2:Serviceに紐づけられたProcedureの作成
* ProcedureをServiceに紐づける形で作成する。
* このStepに関しては、今回のラボで毎回行う。
1. IDE Docksの「Project Content」のServiceを展開し、Step1で作成した **「VAIL_Practice_ < YourName>」 ※\<YourName>は自分の名前** を選択する。

2. 上部の「Implement」Tabを選択する

3. Procedureの「+」をクリックし、「新規Procedure」を選択する

4. 「procedure_name_here」を該当の名前に変更する(Step3以降で都度指示)
今回は **「Test_\<YourName>」 ※\<YourName>は自分の名前** とする。


5. 保存する。

6. 「確認」のポップアップが出てくるので、「Repair Interface」を選択する。

**Serviceに紐づけられたProcedureの作成に関しては以上です。**
**この手順は、今回のラボにて毎回行ってください。**
#### Step3:FOR文
* VAILでFor文を書いてみる
* **ログに5回「Miffy」と出力するFor文を書いてみる**
1. [Step2](#Step2:Serviceに紐づけられたProcedureの作成)を全て行う
* 手順4の「procedure_name_here」を **「VAIL_For_Statement_\<YourName>」 ※\<YourName>は自分の名前** とする。
2. 右下のDebuggingをクリックし、ログやエラーメッセージが見えるようにする。

3. 「ログメッセージ」を選択し、ログが確認できるようにする。もし「エラー」にチェックが入っていたらチェックを外す。


4. 以下を参考に、5回「YourName_Miffy」とログに出力するFor文を書く。
* **\<YourName>は自分の名前を入力すること**
```
//5回「Miffy」とログに出力させる
// range(from, to, increment)
//increment:増加分
for i in range(0, 5, 1) {
log.info("YourName_Miffy")
}
```

5. 保存マークをクリックする。
6. **手動の実行ボタンをクリックし、手動でこのProcedureを実行する。**
* この後何度も出るので覚えてください

7. ポップアップが出現するので、実行をクリックする。
8. 先述の通り、5回「Miffy」とログに出力されているのが確認できる。

* **ログに5回「Minnie」と出力するが、3回目でループを抜けるようなFor文を書く**
9. さきほどのログをクリアする。
* VANTIQでクリアを行う際はこのマークをクリックする

10. 以下を参考に、手順4で書いたものを **「/\*」** と **「\*/」** で挟んでコメントアウトする。
```
/*
//5回「Miffy」とログに出力させる
// range(from, to, increment)
//increment:増加分
for i in range(0, 5, 1) {
log.info("YourName_Miffy")
}
*/
```
11. 以下を参考に、5回「YourName_Minnie」とログに出力するが、3回目のループで抜け出すような処理を施しているFor文を書く。
* プログラミングの世界では「0」から数え始める。
* **\<YourName>は自分の名前**
```
//3回目のループ処理で抜け出す
for i in range(0, 5, 1) UNTIL i == 2 {
log.info("YourName_Minnie")
}
```

12. 保存マークをクリックする。
13. 手動の実行ボタンをクリックする。
14. ポップアップが出現するので、実行をクリックする。
15. 先述の通り、3回「Minnie」とログに出力されているのが確認できる。

**For文に関しては以上です。**
#### Step4:IF文
* **aの値が11以上だったら「Pooh」と出力し、11未満だったら「Duffy」と出力するIF文を書いてみる**
* **定数の場合**
1. [Step2](#Step2:Serviceに紐づけられたProcedureの作成)を全て行う
* 手順4の「procedure_name_here」を **「VAIL_IF_Statement_\<YourName>」 ※\<YourName>は自分の名前** とする。
2. 以下を参考に、IF文を書く。
```
PROCEDURE VAIL_Practice.VAIL_IF_Statement()
//変数「num」を定義し、10という数字を格納する。
var num = 10
//変数「ans」を定義
var ans
//IF 変数「num」が11以上なら
if num >=11 {
//変数「ans」に"Pooh"を格納
ans = "Pooh"
// 変数「num」が11未満なら
} else if num < 11 {
//変数「ans」に"Duffy"を格納
ans = "Duffy"
}
//出力結果として変数「ans」を返す
return ans
```

3. 保存マークをクリックする。
4. 手動の実行ボタンをクリックする。
5. ポップアップが出現するので、実行をクリックする。
6. 今、**変数numの値が10** のため、**「"Duffy"」** と返ってくることを確認する。
* **変数の場合**
7. 以下を参考に、手順2で作成した`PROCEDURE VAIL_Practice.VAIL_IF_Statement()`の括弧内に、**整数の変数「num」:(num Integer)** を定義する。
```
PROCEDURE VAIL_Practice.VAIL_IF_Statement(num Integer)
```
8. 手順2で作成した`PROCEDURE VAIL_Practice.VAIL_IF_Statement()`の`var num = 10` と書かれた行をコメントアウトする。
```
//var num = 10
```

9. 保存マークをクリックする。
10. 手動の実行ボタンをクリックする。
11. 手順7において変数を定義したので、数字を入力する画面が出てくる。**11より大きい整数を入力**し、実行をクリックする。

12. **11以上の数字** を入力したので、IF文の判定より、**「"Pooh"」** 書かれていることを確認する。
**IF文に関しては以上です。**
#### Step5:リスト型
* **リスト型の取り扱いについて学ぶ。**
* **1つ目の要素を取り出す。**
1. [Step2](#Step2:Serviceに紐づけられたProcedureの作成)を全て行う
* 手順4の「procedure_name_here」を **「VAIL_Array_\<YourName>」 ※\<YourName>は自分の名前** とする。
2. 以下を参考にリスト **「Mix_Array」** を定義する。
* 1つのリストには、String型や、数値型などさまざまなデータ型の要素を入れることが可能。
```
//リストを定義する
var Mix_Array = [1,2,3,"One","two","three"]
```
3. 以下を参考に、1つ目の要素を取得する。
* **1つ目の要素は、リスト名[0]** で取得することができる。
* プログラミングにおいて、1個目を表す数字は **0** となる。
```
//1つ目の要素を取得する。
//1つ目の要素をFirstElementと定義する。
var FirstElement = Mix_Array[0]
return FirstElement
```

4. 保存マークをクリックする。
5. 手動の実行ボタンをクリックする。
6. ポップアップが出現するので、実行をクリックする。
7. リスト **「Mix_Array」** の1つ目の要素である、 **「1」** が返ってくることを確認する。
* **リストの一番最後の要素を取得する。**
8. 手順3で書いた部分を「/\*」と「\*/」で挟んでコメントアウトする。
```
/*
//1つ目の要素を取得する。
//1つ目の要素をFirstElementと定義する。
var FirstElement = Mix_Array[0]
return FirstElement
*/
```
9. 以下を参考に、最後の要素を取得する。
* 最後の要素は、**リスト名[-1]** で取得することができる。
```
//最後の要素を取得する。
//最後の要素をLastElementと定義する。
var LastElement = Mix_Array[-1]
return LastElement
```

10. 保存マークをクリックする。
11. 手動の実行ボタンをクリックする。
12. ポップアップが出現するので、実行をクリックする。
13. リスト **「Mix_Array」** の最後の要素である、**「"three"」** が返ってくることを確認する。
* **リスト「Mix_Array」の8個目の要素に「(updated)」を格納する。**
14. 手順8で書いた部分を「/\*」と「\*/」で挟んでコメントアウトする。
```
/*
//最後の要素を取得する。
//最後の要素をLastElementと定義する。
var LastElement = Mix_Array[-1]
return LastElement
*/
```
15. 以下を参考にリスト「Mix_Array」の8個目の要素に「"(Updated)"」を格納する。
```
//リストの8個目の要素に"(Updated)"を入れる
Mix_Array[7] = "(Updated)"
return Mix_Array
```

16. 保存マークをクリックする。
17. 手動の実行ボタンをクリックする。
18. ポップアップが出現するので、実行をクリックする。
19. 以下の画像のような、リスト **「Mix_Array」** が返ってくることを確認する。
* **return Mix_Array** としているので、リスト全体が返ってくる。
* リスト **「Mix_Array」** にはもともと6個しか要素が入っておらず、今回は8個目の要素に、「"(Updated)"」を入れたため、7個目の要素は **「null」** と表示される。

**List型に関しては以上です。**
#### Step6:Dict型(辞書型)
* **Dict型(辞書型)の取り扱いについて学ぶ。**
* **全ての要素を取り出す。**
1. [Step2](#Step2:Serviceに紐づけられたProcedureの作成)を全て行う
* 手順4の「procedure_name_here」を **「VAIL_Array_Dict_\<YourName>」 ※\<YourName>は自分の名前** とする。
2. 以下を参考にDict型(辞書型)**「Lab」** を定義する。
```
//Dict型を定義する
var Lab = {
"Name" : "CrossLab",
"Building" : "Tamachi_GP"
}
```
3. 以下を参考に、Dict型(辞書型)**「Lab」** の全ての要素を取得する。
```
//全ての要素を取得する
return Lab
```

4. 保存マークをクリックする。
5. 手動の実行ボタンをクリックする。
6. ポップアップが出現するので、実行をクリックする。
7. 先ほど定義したDict型(辞書型)**「Lab」** が返ってくることを確認する。

* **Key「Name」に対するValueを取得**
8. 手順3で書いた部分を「/\*」と「\*/」で挟んでコメントアウトする。
```
/*
//全ての要素を取得する
return Lab
*/
```
9. 以下を参考に、Dict型(辞書型) **「Lab」** のKey「Name」に対するValueを取得する。
```
//Key「Name」に対するValueを取得
return Lab["Name"]
```

10. 保存マークをクリックする。
11. 手動の実行ボタンをクリックする。
12. ポップアップが出現するので、実行をクリックする。
13. Dict型(辞書型) **「Lab」** のKey「Name」に対するValue「"CrossLab"」が返ってくることを確認する。

**Dict型(辞書型)に関しては以上です。**
#### Step7:リスト型とDict型(辞書型)の融合
* **リストの要素に、Dict型(辞書型)のデータを入れた際のデータの扱い方について学ぶ。**
* **全ての要素を取り出す。**
1. [Step2](#Step2:Serviceに紐づけられたProcedureの作成)を全て行う
* 手順4の「procedure_name_here」を **「VAIL_Array_List_Dict_\<YourName>」 ※\<YourName>は自分の名前** とする。
2. 以下を参考にリスト **「Lab」** を定義する。
```
//要素がDict型のリスト「Lab」を定義する
var Lab = [
{
"Name" : "CrossLab",
"Building" : "Tamachi_GP"
},
{
"Name" : "OpenHub",
"Building" : "Otemachi"
}
]
```
3. 以下を参考に、リスト **「Lab」** の全ての要素を取得する。
```
//全ての要素を取得する
return Lab
```

4. 保存マークをクリックする。
5. 手動の実行ボタンをクリックする。
6. ポップアップが出現するので、実行をクリックする。
7. 先ほど定義したリスト **「Lab」** が返ってくることを確認する。

* **リストの2つ目の要素のKey「Building」に対するValueを取得**
8. 手順3で書いた部分を「/\*」と「\*/」で挟んでコメントアウトする。
```
/*
//全ての要素を取得する
return Lab
*/
```
9. 以下を参考に、リスト **「Lab」** の2つ目の要素のKey「Building」に対するValueを取得する。
```
//リストの2つ目の要素のKey「Building」に対するValueを取得
return Lab[1]["Building"]
```

10. 保存マークをクリックする。
11. 手動の実行ボタンをクリックする。
12. ポップアップが出現するので、実行をクリックする。
13. リスト **「Lab」** の2つ目の要素のKey「Building」に対するValue **「"Otemachi"」** が返ってくることを確認する。

**リスト型とDict型(辞書型)の融合に関しては以上です。**
#### Step8:Type用意
* **Step9** と **Step10** で、VAILでTypeの操作を行うので、そのためのTypeを追加する。
1. ナビゲーションバーのツールキットの **「追加」** より、**「Type」** を選ぶ。
2. **「追加」** > **「Type...」** > **「+新規 Type」** をクリックし、Typeの新規作成画面を開く。
3. **Name**に **HelloProject_\<YourName> ※\<YourName>は自分の名前** と入力し、**Role**を **Standard**に設定して **「OK」** をクリックする。
4. **HelloProject_\<YourName> ※\<YourName>は自分の名前** Type の **「Properties」** タブを開き **「+Property の追加」** から以下の5つのプロパティを作成する。
| Name | Type | Required |
| --------- | ------- | -------- |
| age | Integer | |
| GroupName | String | |
| id | Integer | ✓ |
| name | String | ✓ |
| NickName | String | |

5. **「Index」** タブを開き **「+Indexの追加」** をクリックする。
6. **「Is Index unique?」** にチェックを入れ、Keyに **「id(Integer)」** を設定して **「OK」** をクリックする。
* レコード(行)を一意にするために「id」カラムを用意したので、ここでidカラムをUniqueKeyとする。
7. **「Natural Keys」** タブを開き **「Keyの設定」** をクリックする。
8. Keyに **「id」** を設定して **「OK」** をクリックする。
9. Save ボタンをクリックし、Typeを保存する。
10. 情報を格納するため、**「新しいレコードの追加」** をクリックする。
11. 以下の情報を入力し、新規レコードの追加を行う。
| レコード名 | 入力値 |
| --------- | ------- |
| age | 23 |
| GroupName | モーニング娘。 |
| id | 1 |
| name | 佐藤優樹 |
| NickName | まーちゃん |
12. **「新規レコードの追加」** をクリックし、以下の情報も追加する。
| レコード名 | 入力値 |
| --------- | ------- |
| age | 21 |
| GroupName | アンジュルム |
| id | 2 |
| name | 佐々木莉佳子 |
| NickName | りかこ |
| レコード名 | 入力値 |
| --------- | ------- |
| age | 20 |
| GroupName | Juice=Juice |
| id | 3 |
| name | 井上玲音 |
| NickName | れいれい |
13. Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** の中身を確認するために、**「すべてのレコードの表示」** をクリックする。

14. レコードの中身を確認する。3行のレコードが登録されていることがわかる。

**Typeの用意に関しては以上です。**
#### Step9:Typeの操作①
* **VAILでTypeの中身を取得する方法について学ぶ。**
* **全レコードを取得するSQL文を書く**
1. [Step2](#Step2:Serviceに紐づけられたProcedureの作成)を全て行う
* 手順4の「procedure_name_here」を **「Type_GetData_\<YourName>」 ※\<YourName>は自分の名前** とする。
2. 以下を参考に、全プロパティを取得するSQLを書く。
* FROM HelloProject **_YourName** となっているところには、自分がStep2でインポートしたType **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** に書かれているものに書き換える。
```
//全プロパティの取得
var members = SELECT * FROM HelloProject_YourName
```

3. 保存マークをクリックする。
4. 手動の実行ボタンをクリックする。
5. ポップアップが出現するので、実行をクリックする。
6. Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** に格納されている全データを取得する。
* 「\_id」、「ars\_*」はシステムが自動で付与する。
```
[
{
"_id": "62b31012243afb727e739090",
"id": 1,
"name": "佐藤 優樹",
"GroupName": "モーニング娘。",
"NickName": "まーちゃん",
"age": 23,
"ars_namespace": "SWB_SmartCity",
"ars_version": 1,
"ars_createdAt": "2022-06-22T12:50:26.174Z",
"ars_createdBy": "67d1e343-6f47-4dd5-8580-3133c83c459e"
},
{
"_id": "62b30054243afb727e738c03",
"id": 2,
"name": "佐々木 莉佳子",
"GroupName": "アンジュルム",
"NickName": "りかこ",
"age": 21,
"ars_namespace": "SWB_SmartCity",
"ars_version": 1,
"ars_createdAt": "2022-06-22T11:43:16.466Z",
"ars_createdBy": "67d1e343-6f47-4dd5-8580-3133c83c459e"
},
{
"_id": "62b30095243afb727e738c18",
"id": 3,
"name": "井上 玲音",
"GroupName": "Juice=Juice",
"NickName": "れいれい",
"age": 20,
"ars_namespace": "SWB_SmartCity",
"ars_version": 1,
"ars_createdAt": "2022-06-22T11:44:21.534Z",
"ars_createdBy": "67d1e343-6f47-4dd5-8580-3133c83c459e"
}
]
```
* **Type「HelloProject_\<YourName>」の全レコードのうち、特定のカラム名のデータを取得するSQL文を書く**
7. 手順3で書いた部分を「/\*」と「\*/」で挟んでコメントアウトする。
```
/*
//全プロパティの取得
var members = SELECT * FROM HelloProject_YourName
*/
```
8. 以下を参考に、Type「HelloProject」の全データから、「name」カラムに格納されているデータを取得する。
* FROM HelloProject **_YourName となっているところには、自分がStep2でインポートしたType **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** に書かれているものに書き換える。
```
//全件、特定のプロパティを取得
var members = SELECT name FROM HelloProject_YourName
```

9. 保存マークをクリックする。
10. 手動の実行ボタンをクリックする。
11. ポップアップが出現するので、実行をクリックする。
12. Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** の全レコードにおける、「name」カラムに格納されているデータが返ってくることを確認する。
* 「\_id」はシステムが自動で付与するデータ

* **Type「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** の全レコードの中から、WHERE句にて特定のカラム名のデータを取得するSQL文を書く**
13. 手順8で書いた部分を「/\*」と「\*/」で挟んでコメントアウトする。
```
/*
//全プロパティの取得
var members = SELECT name FROM HelloProject_YourName
*/
```
14. 以下を参考に、Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** の全レコードから、WHERE句で、「Group」アンジュルムに所属している人の「id」と「name」カラムに格納されているデータを取得する。
* FROM HelloProject **_YourName** となっているところには、自分がStep2でインポートしたType **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** の **\<YourName>** に書かれているものに書き換える。
```
//全件、特定のプロパティを取得
var members = SELECT id, name FROM HelloProject_YourName WHERE GroupName == "アンジュルム"
```

15. 保存マークをクリックする。
16. 手動の実行ボタンをクリックする。
17. ポップアップが出現するので、実行をクリックする。
18. Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** の全データから、WHERE句で、「Group」アンジュルムに所属している人の「id」と「name」カラムに格納されているデータが返ってくることを確認する。

**VAILでTypeの中身を取得する方法に関しては以上です。**
#### Step10:Typeの操作②
* **VAILでTypeを操作する方法について学ぶ。**
* **TypeへデータのINSERT(挿入)を行う。**
1. [Step2](#Step2:Serviceに紐づけられたProcedureの作成)を全て行う
* 手順4の「procedure_name_here」を **「Type_DataManipulation_\<YourName> ※\<YourName>は自分の名前** とする。
2. 以下を参考に、**Type「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** にデータを挿入するSQL文を書く。
* FROM HelloProject **_YourName**となっているところには、自分がStep2でインポートしたType **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前**の、 **\<YourName>** に書かれているものに書き換える。
* Dict型(辞書型)で挿入するデータを定義し、定義したDict型をINSERT文を用いて対象のTypeに挿入する。
```
//INSERT (追加)
var NewFavorites = {
id: 4,
name: "北川 莉央",
age: 18,
GroupName: "モーニング娘。",
NickName: "おんちゃん"
}
INSERT HelloProject_YourName(NewFavorites)
```

3. 保存マークをクリックする。
4. 手動の実行ボタンをクリックする。
5. ポップアップが出現するので、実行をクリックする。
6. Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** に、手順2で定義した「NewFavorites」のデータが返ってくることを確認する。
* 「\_id」、「ars\_*」はシステムが自動で付与する。

7. Procedureを実行したことで、データがType **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** に挿入されていることを確認する。IDE DocksのProject ContentsのTypeより、 **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** を選択する。
8. Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** において、**「全てのレコードを表示する」** をクリックする。
9. 手順2で定義した「New Favorites」のデータが新たに挿入されていることを確認する。
* もともとレコードが3行だったのが4行になっていることを確認する。

* **Typeに格納されているデータのUPSERT①**
* **UPSERTを用いてTypeに格納されているレコードのUPDATEを行う。**
10. 手順2で書いた部分を「/\*」と「\*/」で挟んでコメントアウトする。
```
/*
//INSERT (追加)
var NewFavorites = {
id: 4,
name: "北川 莉央",
age: 18,
GroupName: "モーニング娘。",
NickName: "おんちゃん"
}
INSERT HelloProject_YourName(NewFavorites)
*/
```
11. 以下を参考に、Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** に格納されているデータの「id」が「1」の「name」が「佐藤 優樹」が所属している「GroupName」を「モーニング娘。」から「M-Line」に変更するSQL文を書く。
* Dict型(辞書型)で挿入するデータを定義し、定義したDict型をUPSERT文を用いて対象のTypeの対象のデータのUPDATEを行う。
* 今回はUPDATEなので、最低限、UniqueKey(主キー)である「id」と、変更対象の「GroupName」のみ定義すればよい。
* FROM HelloProject **_YourName**となっているところには、自分がStep2でインポートしたType **「HelloProject_\<YourName>」** の **\<YourName> ※\<YourName>は自分の名前** に書かれているものに書き換える。
```
//UPSERT_1(UPDATE)
var NewFavorites2 = {
id: 1,
GroupName: "M-Line"
}
UPSERT HelloProject_YourName(NewFavorites2)
```

12. 保存マークをクリックする。
13. 手動の実行ボタンをクリックする。
14. ポップアップが出現するので、実行をクリックする。
15. 手順11で定義した「NewFavorites2」の「id」と「GroupName」が返ってくることを確認する。
* 「\_id」と「ars_\*」はシステムが自動で付与するデータ

16. Procedureを実行したことで、Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** の「id」が、1のレコードの「GroupName」が「モーニング娘。」から「M-Line」に変わっていることを確認する。IDE DocksのProject ContentsのTypeより、**「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** を選択する。
17. Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** において、**「全てのレコードを表示する」** をクリックする。
18. 手順11の「NewFavorites2」で定義した通り、「id」が1のレコードの「GroupName」が「モーニング娘。」から「M-Line」に変わっていることを確認する。

* **Typeに格納されているデータのUPSERT②**
* **UPSERTを用いてTypeにINSERTを行う。**
19. 手順11で書いた部分を「/\*」と「\*/」で挟んでコメントアウトする。
```
/*
//UPSERT_1(UPDATE)
var NewFavorites2 = {
id: 1,
GroupName: "M-Line"
}
UPSERT HelloProject_YourName(NewFavorites2)
*/
```
20. 以下を参考に、Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** に、データを挿入するSQL文を書く。
* Dict型(辞書型)で挿入するデータを定義し、定義したDict型を**UPSERT文**を用いて対象のTypeに挿入する。
* 今回は**INSERT**なので、全てのカラムに対するデータを指定する必要がある。
* FROM HelloProject **_YourName**となっているところには、自分がStep2でインポートしたType **「HelloProject_\<YourName>」** の **\<YourName> ※\<YourName>は自分の名前** に書かれているものに書き換える。
```
//UPSERT_2(INSERT)
var NewFavorites3 = {
id: 5,
name: "川村 文乃",
age: 22,
GroupName: "アンジュルム",
NickName: "かわむー"
}
UPSERT HelloProject_YourName(NewFavorites3)
```

21. 保存マークをクリックする。
22. 手動の実行ボタンをクリックする。
23. ポップアップが出現するので、実行をクリックする。
24. Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** に、手順20で定義した「NewFavorites3」のデータが返ってくることを確認する。
* 「\_id」、「ars\_*」はシステムが自動で付与する。

25. Procedureを実行したことで、レコードがType **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** に挿入されていることを確認する。IDE DocksのProject ContentsのTypeより、**「HelloProject_<\<YourName>」 ※\<YourName>は自分の名前** を選択する。
26. **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** において、**「全てのレコードを表示する」** をクリックする。
27. 手順20で定義した「NewFavorites3」のレコードが新たに挿入されていることを確認する。
* 4件あったレコードが5件に増えていることを確認する。

* **Typeに格納されているデータの削除**
28. 手順20で書いた部分を「/\*」と「\*/」で挟んでコメントアウトする。
```
/*
//UPSERT_2(INSERT)
var NewFavorites3 = {
id: 5,
name: "川村 文乃",
age: 22,
GroupName: "アンジュルム",
NickName: "かわむー"
}
UPSERT HelloProject_YourName(NewFavorites3)
*/
```
29. 以下を参考に、Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** に格納されているデータのうち、「id」が「1」のレコードを削除するSQL文を書く。
* 今回はDELETEなので、削除したい対象のカラム名をWHERE句で指定すれば良い。
* FROM HelloProject **_YourName**となっているところには、自分がStep2でインポートしたType **「HelloProject_\<YourName>」** の **\<YourName> ※\<YourName>は自分の名前** に書かれているものに書き換える。
```
//DELETE
DELETE HelloProject_YourName WHERE id == 1
```

30. 保存マークをクリックする。
31. 手動の実行ボタンをクリックする。
32. ポップアップが出現するので、実行をクリックする。
33. 削除したレコードの個数が返ってくることを確認する。
* 今回は対象が1つなので、1が返ってくる。

34. Procedureを実行したことで、手順29で指定したレコードがType **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** より削除されていることを確認する。IDE DocksのProject ContentsのTypeより、**「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** を選択する。
35. Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** において、**「全てのレコードを表示する」** をクリックする。
36. 手順29で指定したidのレコードが、Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** より削除されていることを確認する。
* 「id」1のレコードが削除されていることを確認する。
* 全レコードの件数が、5件あった状態から4件に減っていることを確認する。

**VAILでTypeを操作する方法に関しては以上です。**
**最後に、ナビゲーションバーのプロジェクトより、プロジェクトの保存を行ってください。**
**ラボ「VAILの基礎」に関しては以上です。お疲れ様でした。**
## VANTIQのRuleとProcedure
### 概要
このLabでは、Slackにて水位上昇の危険を知らせるためのProcedureの作成及び、MsgPub+から、データをSubscribeするためのRuleとProcedureのインポートを行う。
Day2同様、水位計のデータに関しては既に他のNameSpace(防災案件)で利用しており
、防災案件用のMessagePub+とVANTIQの間の接続ルールは決められているため、既にあるRuleとProcedureを利用する。
### 注意事項
基本的に、作成するRule、Procedure名には **_\<YourName> ※\<YourName>は自分の名前** をつけること。(既に作成済みのものを流用する場合は別)
### ラボ
* [Step1:Slackに通知するProcedureの作成](#Step1:Slackに通知するProcedureの作成)
* [Step2:MsgPub+にSubScribeするRuleとProcedureのインポート](#Step2:MsgPub+にSubScribeするRuleとProcedureのインポート)
#### Step1:Slackに通知するProcedureの作成

* **Slackに通知するProcedureを作成する。**
1. 新規のProcedureを作成する。ナビゲーションバーのツールキットの **「追加」** をクリックし、**「Advanced」** にカーソルを合わせ、**「Procedure」** をクリックする。

2. 右上の **「+新規Procedure」** をクリックする。

3. **「procedure_name_here」** の部分を消し、**「SendToSlack_\<YourName>」※\<YourName>は自分の名前** とし、保存する。


4. 以下を参考に、Slackにメッセージを送るProcedureを書く。
* **\<YourName>** は自分の名前にすること(自分で用意したものにすること)
```
//Slackに送るメッセージ「SlackMessage」を定義すると同時にデバイス定義する。
//"\n"で改行
var SlackMessage = "point : " + event.point + "\n"
//slackは投稿するときは文字列である必要がある。
//「SlackMessage」に、「point」と「水位」、「投稿者」、「"Msg : 水位上昇中!危険!"」という文字列を追加する。
SlackMessage += "水位 : " + event.value +"\n"
SlackMessage += "投稿者 : " + event.Name +"\n"
SlackMessage += "Msg : 水位上昇中!危険!\n"
//Slackに送るメッセージをDict型で定義する。
//bodyのValueは文字列である。
var msgbody = {
text : SlackMessage
}
//Slackにメッセージを送る
PUBLISH { body: msgbody } to SOURCE SendToSlack_YourName
```
5. Procedure名の()の中に、eventと入力する。

6. 保存をする。
**Slackに通知するProcedureの作成に関しては以上です。**
#### Step2:MsgPub+にSubScribeするRuleとProcedureのインポート

* **MQTTBrokerであるMsgPub+からデータをSubscribeし、VANTIQ内のTopicにイベントを投げるRuleとProcedureをインポートする。**
* Day2同様、水位計のデータに関しては既に他のNameSpace(防災案件)で利用しており、防災案件用のMessagePub+とVANTIQの間の接続ルールは決められているため、既にあるRuleとProcedureを利用する。
1. まずはRuleをインポートする。ナビゲーションバーのツールキットの **「追加」** をクリックし、**「Advanced」** にカーソルを合わせ、**「Rule」** をクリックする。

2. **「sensorEvent」** にチェックを入れ、**「選択した項目の追加」** をクリックする。

3. 次にProcedureをインポートする。ナビゲーションバーのツールキットの **「追加」** をクリックし、**「Advanced」** にカーソルを合わせ、**「Procedure」** をクリックする。

4. **「ReceiveFromMqttSource」** にチェックを入れ、**「選択した項目の追加」** をクリックする。

5. ナビゲーションバーのプロジェクトより、プロジェクトの保存を行う。
**MsgPub+にSubScribeするためのRuleとProcedureのインポートは以上となります。**
**最後に、ナビゲーションバーのプロジェクトより、プロジェクトの保存を行ってください!** 
**Day3のハンズオンは以上となります。お疲れさまでした。**
---
# Day4
## VANTIQのAppBuilderに関して
### 概要
このLabでは、今回のハンズオンで実現したいシナリオを、実際にAppBuilderを用いて実装していく。
* ハンズオンのシナリオ
1. 30秒ごとに2台ある水位計の値を取得する。
**「GetEventFrom_MsgPub」**
2. データの処理を行いやすいように、データを整形する。
**「Extract_RequiredData」**
3. 2台ある水位計に対してそれぞれ担当者を紐づける。
**「EnrichNameFrom_Type_Users」**
4. 自身が操作する水位計のデータのみを抽出する。
**「Filter_MyWaterGauge」**
5. 1つ前の水位計の値を、old_valueとしてTypeに格納する。
**「SaveValueToType_Data_asOldValue」**
6. old_valueの値を現在のイベントに付加させる。
**「EnrichOldValue_toThisData」**
7. 必要なデータのみにイベントを整形する。
**「Extract_RequiredData_Last」**
8. 水位計のデータをTypeに格納する。
**「SaveTo_Type_Data」**
9. 現在の水位計の値が1つ前の水位計の値(old_value)より大きいかつ、現在の水位計の値が8.5以上かを判定する。
**「FilterByValue」**
10. 上記判定した結果Trueの場合、Slackに通知する。
**「Send_AlertToSlack」**
### 注意事項
ポップアップ等が出ない時は、画面のリフレッシュ(リロード)を行うとよい。
### ラボ
* [Step1:環境構築とイベントの受信Activity「GetEventFrom_MsgPub」の作成](#Step1:環境構築とイベントの受信Activity「GetEventFrom_MsgPub」の作成)
* [Step2:イベントの受信の確認](#Step2:イベントの受信の確認)
* [Step3:Tranformation Activity_1](#Step3:Tranformation-Activity_1)
* [Step4:Enrich Activity_1](#Step4:Enrich-Activity_1 )
* [Step5:Filter Activity_1](#Step5:Filter-Activity_1)
* [Step6:Procedure Activity_1](#Step6:Procedure-Activity_1)
* [Step7:Enrich Activity_2](#Step7:Enrich-Activity_2)
* [Step8:Tranformation Activity_2](#Step8:Tranformation-Activity_2)
* [Step9:SaveToType Activity](#Step9:SaveToType-Activity)
* [Step10:Filter Activity_2](#Step10:Filter-Activity_2)
* [Step11:Procedure Activity_2](#Step11:Procedure-Activity_2)
* [Step12:水位計を接続する](#Step12:水位計を接続する)
#### Step1:環境構築とイベントの受信Activity「GetEventFrom_MsgPub」の作成
* イベントを受信し、制御ロジックを組む環境である「App」および、イベントの受信の設定を行う。
1. ナビゲーションバーのツールキットの「追加」より、「Advanced」>「App...」を選択する。

2. **「+新規App」** をクリックする。

3. **「Name」** に、**「WaterGauge_YourName」 ※\<YourName>は自分の名前** と入力する。

4. **「Initiate」** をクリックし、 **「Name」を「GetEventFrom_MsgPub」** にし、 **「クリックして編集」** をクリックする。
5. **「inboundResource (Enumerated)」** で **「topic」** を選び、**「inboundResourceId (String)」** で、Day2のラボ[Step5](Step5:Appの動作確認のためのTopicの作成)で作成した、**「/topic/watergauge_YourName」※\<YourName>は自分の名前** を選び、**「OK」** をクリックする。

6. Appを保存する。
7. Projectの保存を行う。
**環境構築とイベントの受信Activityの作成に関しては以上となります。**
#### Step2:イベントの受信の確認
* 作成したApp、イベントの受信Activity **「GetEventFrom_MsgPub」** にて、手動でイベントを発生させ、データの受信できるかを確認する。
1. IDE DocksのProject Contentsの **「Topic」** より、**「/topic/watergauge_YourName」※\<YourName>は自分の名前** を選択する。

2. VANTIQのメイン画面(ペイン)のレイアウトが1×2になっているので、左側に **「App」** の **「WaterGauge_\<YourName>」 ※\<YourName>は自分の名前** の画面を、右側に **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の画面を配置する。

3. 画面左側のAppの画面より、先ほど作成した **「GetEventFrom_MsgPub」** をクリックし、App画面内の左側の設定画面の下部の **「TaskEventsの表示」** をクリックする。
 **→** 
* **「TaskEventsの表示」** をクリックすることによって、そのActivityを通ったデータを確認することができる。
4. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」 ※\<YourName>は自分の名前** の「PublishMessage」の中身を一回すべて消し、以下をコピペし、右下の「Publish」をクリックする。
* 水位計01を使用している方
```
{
"value": {
"type": "SensingHistory",
"dateProcessed": "2022-05-31T13:03:30+09:00",
"value": 3.5,
"unit": "m",
"site": "Site-Shibaura3",
"building": "Building-Shibaura3_TamachiGP",
"floor": "Floor-Shibaura3_TamachiGP_4",
"space": "Space-Shibaura3_TamachiGP_4_Lab",
"device": "Device-Shibaura3_TamachiGP_4_Lab_L-1",
"point": "01-Distance",
"collectProcessPattern": "1",
"dataAdministrator": "Organization-TGPLabo",
"id": "Device-Shibaura3_TamachiGP_4_Lab_L-1_01-Distance_2022-05-31T13:03:30+09:00"
},
"topicName": "/v1/bousai/ntt.com/shibaura/grandpark/labo/showcase/watergauge01/waterlevel"
}
```
* 水位計02を使用している方
```
{
"value": {
"type": "SensingHistory",
"dateProcessed": "2022-05-31T13:03:30+09:00",
"value": 3.5,
"unit": "m",
"site": "Site-Shibaura3",
"building": "Building-Shibaura3_TamachiGP",
"floor": "Floor-Shibaura3_TamachiGP_4",
"space": "Space-Shibaura3_TamachiGP_4_Lab",
"device": "Device-Shibaura3_TamachiGP_4_Lab_L-2",
"point": "02-Distance",
"collectProcessPattern": "1",
"dataAdministrator": "Organization-TGPLabo",
"id": "Device-Shibaura3_TamachiGP_4_Lab_L-2_02-Distance_2022-05-31T13:03:30+09:00"
},
"topicName": "/v1/bousai/ntt.com/shibaura/grandpark/labo/showcase/watergauge01/waterlevel"
}
```

5. 画面左側のApp画面の左側の **「TaskEventsの表示」** にデータが表示されていることを確認し、データ(青くなっている部分)をクリックする。

6. そのActivityを通ったデータを確認する。今回作成のActivityでただデータを受信しただけなので、手順4でPublishしたものと同じデータとなっていることが確認できる。確認し、「OK」をクリックする。

7. 画面左側のAppにおいて、Step1で作成した、**「イベントの受信Activity」** である **「GetEventFrom_MsgPub」** にマウスのカーソルを合わせ、スクロールホイールで、**「GetEventFrom_MsgPub」** の周りに余白ができるくらいに、 **「GetEventFrom_MsgPub」** のサイズを小さくする。

8. **「GetEventFrom_MsgPub」** の右上にバッジがついていることを確認する。

9. App画面の上部において、ランタイムステータスのクリアを行うボタンをクリックする。ランタイムステータスのクリアを行うことで、バッジの数を0クリアすることが可能となる。

10. 発生しなかった場合、Projectを1度保存し、画面のリフレッシュを行い、再度、**手順3-9** を行う。
**イベントの受信に関しては以上となります。**
#### Step3:Tranformation Activity_1
* データの処理を行いやすいように、受信したデータを、扱いやすいように整形する。
1. [Step1](#Step1:環境構築とイベントの受信Activity「GetEventFrom_MsgPub」の作成)で作成したActivity **「GetEventFrom_MsgPub」** を右クリックし、**「新規Taskとリンク」** をクリックする。
* このように1つ前のActivityを右クリックし、**「新規Taskとリンク」** をクリックすると、新しいActivityを作成することができる。

2. Activity Pattern を **「Transformation」** にし、Task Nameを **「Extract_RequiredData」** とする。
3. 新規作成した **「Extract_RequiredData」** をクリックし、**「クリックして編集」** をクリックする。

4. データの整形を行うために、画面上部の **「Transformation(Union)」** の「<null\>」をクリックする。

5. **「transformation Type:」** を **「Visual Transformation」** にし、**「Transformationの追加」** 部分に既存で設定されているレコードをゴミ箱マークより削除する。
* 既存のレコードはDay2のSchemaTypeを作成した際、設定したカラムに基づいて自動で作成されている。

6. **「+Transformationの追加」** の **「+」** を押し、レコードを追加する。

7. 追加したレコードに対して、**「Outbound Property」** に「point」と入力し、**「Transformation Expression」** の部分に **「event.value.point」** と入力する。

* Appに設定したTopicを通過後のデータは、「event」というKEY名のValue値として格納される。そのため、元のデータの **Key名「value」** の中にある **Key名「point」** や、**「device」、「value」** のValue値は、App上では `[event][value][point]` で取得することができる。
* Appに設定したTopicを通過後のデータ
```
{
event:{
"value": {
"type": "SensingHistory",
"dateProcessed": "2022-05-31T13:03:30+09:00",
"value": 3.5,
"unit": "m",
"site": "Site-Shibaura3",
"building": "Building-Shibaura3_TamachiGP",
"floor": "Floor-Shibaura3_TamachiGP_4",
"space": "Space-Shibaura3_TamachiGP_4_Lab",
"device": "Device-Shibaura3_TamachiGP_4_Lab_L-2",
"point": "02-Distance",
"collectProcessPattern": "1",
"dataAdministrator": "Organization-TGPLabo",
"id": "Device-Shibaura3_TamachiGP_4_Lab_L-2_01-Distance_2022-05-31T13:03:30+09:00"
},
"topicName": "/v1/bousai/ntt.com/shibaura/grandpark/labo/showcase/watergauge02/waterlevel"
}
}
```
* Dict型のデータは、例えばpointだったら、`[event][value][point]` で取得できるが、VANTIQでは、**\[]** ではなく、**「.」** を用い、`event.value.point`という形式で取得する。
8. 手順6を2回行い、レコードを増やし、以下の値を入力し、OKを「クリック」する。
| Outbound Property | Transformation Expression |
| ----------------- | ------------------------- |
| value | event.value.value |
| device | event.value.device |

* 今回Slackに送信するデータや、Typeに保存するデータとして最低限欲しいデータが以下となるので、 Transformation Activityにてデータを必要最低限のみにしている。
* point(デバイスの設置箇所)
* value(水位計の値)
* device(デバイス名)
9. 「Transformation Activity」の画面に戻るので、画面右下の「OK」をクリックする。
10. 画面左のAppを保存する。
11. このStepで作成した **「Extract_RequiredData」** をクリックし、App画面内の左側の設定画面の下部の **「TaskEventsの表示」** をクリックする。
12. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の左下にある **「Publish」** をクリックし、イベントを手動で発生させる。
13. 画面左のAppの左側の **「TaskEventsの表示」** にてデータを受信していることが確認できるので、データをクリックする。
14. データをクリックし、**「Transformation(Union)」** の画面(手順5-8)で設定したデータのみになっていることを確認し、「OK」をクリックする。

15. Appにおいて、ランタイムステータスのクリアを行う。
**データの整形1に関しては以上となります。**
#### Step4:Enrich Activity_1
* 2台ある水位計に対してそれぞれ担当者のデータを紐づける。
1. [Step3](#Step3:Tranformation-Activity_1)で作成したActivity **「Extract_RequiredData」** を右クリックし、**「新規Taskとリンク」** をクリックする。
2. Activity Pattern を **「Enrich」** にし、Task Nameを **「EnrichNameFrom_Type_Users」** とする。
3. 新規作成した **「EnrichNameFrom_Type_Users」** をクリックし、**「クリックして編集」** をクリックする。

4. **「associatedType (Enumerated)」** に、**「User_YourName」 ※\<YourName>は自分の名前** を選ぶ。
* 担当者のデータを紐づけるので、Day2で作成した「誰が」「どの水位計」を管理しているType **「Users_\<YourName>」 ※\<YourName>は自分の名前** を 選択する。

5. **「foreignKeys(Array of Property)」** の **\<null>** 部分をクリックする。

6. アイテムの追加で **「point」** と入力し、**「OK」** をクリックする。

* 先ほど選んだType **「Users_\<YourName>」 ※\<YourName>は自分の名前** と [Step3](#Step3:Tranformation-Activity_1)で整形したデータで同じカラム名なのが「point」なので、「point」を選択する。
7. **「Enrich Activity」** の設定画面に戻るので、**「OK」** をクリックする。
8. 画面左のAppを保存する。

9. このStepで作成した **「EnrichNameFrom_Type_Users」** をクリックし、App画面内の左側の設定画面の下部の **「TaskEventsの表示」** をクリックする。
10. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の左下にある **「Publish」** をクリックし、イベントを手動で発生させる。
11. 画面左のAppの左側の **「TaskEventsの表示」** にてデータを受信していることが確認できるので、データをクリックする。
12. データをクリック。
13. **「EnrichNameFrom_Type_Users」** (手順3-7)で設定したデータが付加されたていることを確認し、「OK」をクリックする。

14. Appにおいて、ランタイムステータスのクリアを行う。
**イベントとTypeに格納されているデータの結合に関しては以上となります。**
#### Step5:Filter Activity_1
* 自身が操作する水位計のデータのみを抽出する。
1. [Step4](#Step4:Enrich-Activity_1) で作成したActivity **「EnrichNameFrom_Type_Users」** を右クリックし、**「新規Taskとリンク」** をクリックする。
2. Activity Pattern を **「Filter」** にし、Task Nameを **「Filter_MyWaterGauge」** とする。
3. 新規作成した **「Filter_MyWaterGauge」** をクリックし、**「クリックして編集」** をクリックする。
4. 自分が操作する水位計のデータのみを抽出する。自分が操作する水位計を判別するkey名は「point」か「device」のいずれかである。今回は「point」で判別することにする。Filterの設定画面の一番上の項目「condition (Union)」に対する\<null>となっている箇所をクリックする。

5. 「Condition Type:」が、**VAIL Conditional Expression** であることを確認し、「condition」に対して以下の通りに入力し、「OK」をクリックする。
* 水位計01の担当者
`event.point == "01-Distance"`
* 水位計02の担当者
`event.point == "02-Distance"`

* Step3でTransform Activity **「Extract_RequiredData」** を作成した際、カラム名を、**「point」、「device」、「value」** にしたため、**「Extract_RequiredData」** を通過した **「point」、「device」、「value」** のデータは、Key名「event」のvalueに格納されるため、今回の「point」のデータの取得は「event.point」となる。
* **「Extract_RequiredData」** を通過前のデータ
```
{
event:{
"value": {
"type": "SensingHistory",
"dateProcessed": "2022-05-31T13:03:30+09:00",
"value": 3.5,
"unit": "m",
"site": "Site-Shibaura3",
"building": "Building-Shibaura3_TamachiGP",
"floor": "Floor-Shibaura3_TamachiGP_4",
"space": "Space-Shibaura3_TamachiGP_4_Lab",
"device": "Device-Shibaura3_TamachiGP_4_Lab_L-2",
"point": "02-Distance",
"collectProcessPattern": "1",
"dataAdministrator": "Organization-TGPLabo",
"id": "Device-Shibaura3_TamachiGP_4_Lab_L-2_01-Distance_2022-05-31T13:03:30+09:00"
},
"topicName": "/v1/bousai/ntt.com/shibaura/grandpark/labo/showcase/watergauge02/waterlevel"
}
}
```
* **「Extract_RequiredData」** を通過後のデータ
```
{
event:{
point:"01-Distance",
device:"Device-Shibaura3_TamachiGP_4_Lab_L-1",
value:3.5
}
}
```
6. Filterの設定画面に戻るので、「OK」をクリックする。
7. Appを保存する。
8. このStepで作成した **「Filter_MyWaterGauge」** をクリックし、App画面内の左側の設定画面の下部の **「TaskEventsの表示」** をクリックする。
9. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の左下にある **「Publish」** をクリックし、イベントを手動で発生させる。
10. 画面左のAppの左側の **「TaskEventsの表示」** にてデータを受信していることが確認できるので、データをクリックする。

11. データをクリックし、データの型がStep4と同じことを確認する。
12. 続いて画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** において、PublishMessage内を以下のように変更する。
* 水位計01を使用している方(02の水位計のデータを入力する)
```
{
"value": {
"type": "SensingHistory",
"dateProcessed": "2022-05-31T13:03:30+09:00",
"value": 3.5,
"unit": "m",
"site": "Site-Shibaura3",
"building": "Building-Shibaura3_TamachiGP",
"floor": "Floor-Shibaura3_TamachiGP_4",
"space": "Space-Shibaura3_TamachiGP_4_Lab",
"device": "Device-Shibaura3_TamachiGP_4_Lab_L-2",
"point": "02-Distance",
"collectProcessPattern": "1",
"dataAdministrator": "Organization-TGPLabo",
"id": "Device-Shibaura3_TamachiGP_4_Lab_L-2_01-Distance_2022-05-31T13:03:30+09:00"
},
"topicName": "/v1/bousai/ntt.com/shibaura/grandpark/labo/showcase/watergauge02/waterlevel"
}
```
* 水位計02を使用している方(01の水位計のデータを入力する)
```
{
"value": {
"type": "SensingHistory",
"dateProcessed": "2022-05-31T13:03:30+09:00",
"value": 3.5,
"unit": "m",
"site": "Site-Shibaura3",
"building": "Building-Shibaura3_TamachiGP",
"floor": "Floor-Shibaura3_TamachiGP_4",
"space": "Space-Shibaura3_TamachiGP_4_Lab",
"device": "Device-Shibaura3_TamachiGP_4_Lab_L-1",
"point": "01-Distance",
"collectProcessPattern": "1",
"dataAdministrator": "Organization-TGPLabo",
"id": "Device-Shibaura3_TamachiGP_4_Lab_L-1_01-Distance_2022-05-31T13:03:30+09:00"
},
"topicName": "/v1/bousai/ntt.com/shibaura/grandpark/labo/showcase/watergauge01/waterlevel"
}
```
13. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の左下にある **「Publish」** をクリックし、イベントを手動で発生させる。
14. 画面左のApp側で、Activity **「Filter_MyWaterGauge」** のみ、バッジの数が異なることを確認する。
* これは今回作成した「Filter」 Activityによるもので、この **「Filter_MyWaterGauge」** では、自分が操作する水位計のデータのみをフィルタリングしているので、他の人が操作している水位計のデータはフィルタリングによって除外されている。

15. 確認できたところで、画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** において、PublishMessage内を以下のように変更する。
* 水位計01を使用している方(水位計01のデータに戻す)
```
{
"value": {
"type": "SensingHistory",
"dateProcessed": "2022-05-31T13:03:30+09:00",
"value": 3.5,
"unit": "m",
"site": "Site-Shibaura3",
"building": "Building-Shibaura3_TamachiGP",
"floor": "Floor-Shibaura3_TamachiGP_4",
"space": "Space-Shibaura3_TamachiGP_4_Lab",
"device": "Device-Shibaura3_TamachiGP_4_Lab_L-1",
"point": "01-Distance",
"collectProcessPattern": "1",
"dataAdministrator": "Organization-TGPLabo",
"id": "Device-Shibaura3_TamachiGP_4_Lab_L-1_01-Distance_2022-05-31T13:03:30+09:00"
},
"topicName": "/v1/bousai/ntt.com/shibaura/grandpark/labo/showcase/watergauge01/waterlevel"
}
```
* 水位計02を使用している方(水位計02のデータに戻す)
```
{
"value": {
"type": "SensingHistory",
"dateProcessed": "2022-05-31T13:03:30+09:00",
"value": 3.5,
"unit": "m",
"site": "Site-Shibaura3",
"building": "Building-Shibaura3_TamachiGP",
"floor": "Floor-Shibaura3_TamachiGP_4",
"space": "Space-Shibaura3_TamachiGP_4_Lab",
"device": "Device-Shibaura3_TamachiGP_4_Lab_L-2",
"point": "02-Distance",
"collectProcessPattern": "1",
"dataAdministrator": "Organization-TGPLabo",
"id": "Device-Shibaura3_TamachiGP_4_Lab_L-2_02-Distance_2022-05-31T13:03:30+09:00"
},
"topicName": "/v1/bousai/ntt.com/shibaura/grandpark/labo/showcase/watergauge01/waterlevel"
}
```
16. Appにおいて、ランタイムステータスのクリアを行う。
**自身が操作する水位計のデータのみを抽出に関しては以上です。**
#### Step6:Procedure Activity_1
* 1つ前の水位計の値を、old_valueとしてTypeに格納する。
1. 新規Procedureを作成するために、ナビゲーションバーのツールキットの「追加」より、「Advanced」> 「Procedure」を選択する。
2. 右上の「+新規Procedure」をクリックする。
3. 「procedure_name_here」と書かれている部分を削除し、**「SaveOldValue_\<YourName>」 ※\<YourName>は自分の名前** とする。
4. ()の中にeventと入力する。

5. 以下をコピペする。その際、**\<YourName>** の部分には **自分の名前** を入力すること。
* Data_\<YourName>:Type「Data_\<YourName>」のこと
* Name:"\<YourName>":Type「User_\<YourName>」に登録した自分の名前
* **水位計01の担当者**
```
//AppではeventというKey名でデータが流れているので、このProcedureの前でActivityを作成している際は、Procedureの変数をeventとする。
//Type:Data_YourNameのカラム名「value」の値を、変数「OldData」とし、select文で取得する。
var OldData = select value FROM Data_YourName
//変数OldDataとして取得した値が配列になっているので、変数「OldValue」としてvalueのみを取り出す。
var OldValue = OldData[0]["value"]
//Type:Data_YourNameのカラム名「old_value」に、先ほど定義した変数「OldValue」をUPSERTする。
//Type:Data_YourNameのIndexおよびNatural Keyは「DeviceName」なので、「DeviceName」は必ず指定する。
var object = {
old_value : OldValue,
DeviceName:"Device-Shibaura3_TamachiGP_4_Lab_L-1"
}
UPSERT Data_YourName(object)
//次のActivityに、今流れてきているeventを流すために、eventをreturnする。
return event
```
* **水位計02の担当者f**
```
//AppではeventというKey名でデータが流れているので、このProcedureの前でActivityを作成している際は、Procedureの変数をeventとする。
//Type:Data_YourNameのカラム名「value」の値を、変数「OldData」とし、select文で取得する。
var OldData = select value FROM Data_YourName
//変数OldDataとして取得した値が配列になっているので、変数「OldValue」としてvalueのみを取り出す。
var OldValue = OldData[0]["value"]
//Type:Data_YourNameのカラム名「old_value」に、先ほど定義した変数「OldValue」をUPSERTする。
//Type:Data_YourNameのIndexおよびNatural Keyは「DeviceName」なので、「DeviceName」は必ず指定する。
var object = {
old_value : OldValue,
DeviceName:"Device-Shibaura3_TamachiGP_4_Lab_L-2"
}
UPSERT Data_YourName(object)
//次のActivityに、今流れてきているeventを流すために、eventをreturnする。
return event
```

6. Procedureを保存する。
7. Procedureの画面を右上の **「×」** をクリックして閉じる。
8. 現時点での、Type **「Data_\<YourName>」** のレコードを確認する。IDE DocksのProject Contentsの **「Type」** より、**「Data_\<YourName>」 ※\<YourName>は自分の名前** を選択する。
9. 「すべてのレコードを表示する」をクリックし、Valueとold_valueに入っている値を確認する。
* 今回は全員valueに1.5、old_valueに0.5というデータが格納されている。(Day2のVANTIQのTypeのラボ[Step4](Step4:Data_\<YourName>-Standard-Typeの作成)より)


10. IDE DocksのProject Contentsの **「Topic」** より、**「/topic/watergauge_YourName」※\<YourName>は自分の名前** を選択する。
11. IDE DocksのProject Contentsの **「App」** より、**「WaterGauge_YourName」 ※\<YourName>は自分の名前** を選択し、画面の左にApp、画面の右にtopicが表示されていることを確認する。

12. [Step5](#Step5:Filter-Activity_1)で作成したActivity **「Filter_MyWaterGauge」** を右クリックし、**「新規Taskとリンク」** をクリックする。
13. Activity Patternを **「Procedure」** にし、Task Nameを **「SaveValueToType_Data_asOldValue」** とする。
14. 新規作成した **「SaveValueToType_Data_asOldValue」** をクリックし、**「クリックして編集」** をクリックする。
15. procedure (Enumerated)の右側のプルダウンより、手順1-6で作成したProcedureを選択し、OKをクリックする。

16. Appを保存する。
17. このStepで作成した **「SaveValueToType_Data_asOldValue」** をクリックし、App画面内の左側の設定画面の下部の **「TaskEventsの表示」** をクリックする。
18. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の左下にある **「Publish」** をクリックし、イベントを手動で発生させる。
19. 画面左のAppにて、バッジの有無にてデータを受信していることが確認する。
20. 画面左のAppの左側の **「TaskEventsの表示」** にて受信したデータを確認するため、データをクリックする。

21. Type「Data_\<YourName>」のレコードを確認する。IDE DocksのProject Contentsの **「Type」** より、**「Data_\<YourName>」 ※\<YourName>は自分の名前** を選択する。
22. 「すべてのレコードを表示する」をクリックし、old_valueに入っている値を確認する。先ほどold_valueに格納されていた値は「0.5」だったが、今は先ほどvalueに入っていた「1.5」という値がold_valueに格納されていることがわかる。

23. IDE DocksのProject Contentsの **「Topic」** より、**「/topic/watergauge_YourName」※\<YourName>は自分の名前** を選択する。
24. IDE DocksのProject Contentsの **「App」** より、**「WaterGauge_YourName」 ※\<YourName>は自分の名前** を選択し、画面の左にApp、画面の右にtopicが表示されていることを確認する。

25. Appにおいて、ランタイムステータスのクリアを行う。
**1つ前の水位計の値を、old_valueとしてTypeに格納するProcedureの作成および、Appへの組み込みに関しては以上です。**
#### Step7:Enrich Activity_2
* old_valueの値を現在のイベントに付加させる。
1. [Step6](#Step6:Procedure-Activity_1)で作成したActivity **「SaveValueToType_Data_asOldValue」** を右クリックし、**「新規Taskとリンク」** をクリックする。
2. Activity Pattern を **「Enrich」** にし、Task Nameを **「EnrichOldValue_toThisData」** とする。
3. 新規作成した **「EnrichOldValue_toThisData」** をクリックし、**「クリックして編集」** をクリックする。
4. **「associatedType (Enumerated)」** に、**「Data_\<YourName> ※\<YourName>は自分の名前** を選ぶ。
* [Step6](#Step6:Procedure-Activity_1)で作成したprocedureによって、「Data_\<YourName>」に格納されたold_valueを今、App内を流れているイベントに格納する。
5. **「foreignKeys(Array of Property)」** の **\<null>** 部分をクリックする。
6. アイテムの追加で **「point」** と入力し、**「OK」** をクリックする。

* 先ほど選んだType **「Data_\<YourName>」 ※\<YourName>は自分の名前** と [Step6](#Step6:Procedure-Activity_1)で整形したデータで同じカラム名なのが「point」なので、「point」を選択する。
7. **「Enrich Activity」** の設定画面に戻るので、**「OK」** をクリックする。
8. 画面左のAppを保存する。

9. このStepで作成した **「EnrichOldValue_toThisData」** をクリックし、App画面内の左側の設定画面の下部の **「TaskEventsの表示」** をクリックする。
10. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の左下にある **「Publish」** をクリックし、イベントを手動で発生させる。
11. 画面左のAppの左側の **「TaskEventsの表示」** にてデータを受信していることが確認できるので、データをクリックする。
13. **「EnrichOldValue_toThisData」**(手順3-7)で設定したデータが付加されたていることを確認し、「OK」をクリックする。

```
{
"point": "01-Distance",
"value": 3.5,
"device": "Device-Shibaura3_TamachiGP_4_Lab_L-1",
"Users_YourName": {
"_id": "62bde154243afb727e76809f",
"Name": "MyName",
"id": 1,
"point": "01-Distance",
"ars_namespace": "SWB_SmartCity",
"ars_version": 2,
"ars_createdAt": "2022-06-30T17:45:56.810Z",
"ars_createdBy": "67d1e343-6f47-4dd5-8580-3133c83c459e",
"ars_modifiedAt": "2022-07-02T11:23:36.095Z",
"ars_modifiedBy": "67d1e343-6f47-4dd5-8580-3133c83c459e"
},
"Data_YourName": {
"_id": "62c03de0243afb727e76f39f",
"DeviceName": "Device-Shibaura3_TamachiGP_4_Lab_L-1",
"Name": "MyName",
"old_value": 1.5,
"point": "01-Distance",
"value": 1.5,
"ars_namespace": "SWB_SmartCity",
"ars_version": 8,
"ars_createdAt": "2022-07-02T12:45:20.666Z",
"ars_createdBy": "67d1e343-6f47-4dd5-8580-3133c83c459e",
"ars_modifiedAt": "2022-07-02T13:44:08.954Z",
"ars_modifiedBy": "67d1e343-6f47-4dd5-8580-3133c83c459e"
}
}
```
14. Appにおいて、ランタイムステータスのクリアを行う。
#### Step8:Tranformation Activity_2
* 必要なデータのみにイベントを整形する。
1. [Step7](#Step7:Enrich-Activity_2)で作成したActivity **「EnrichOldValue_toThisData」** を右クリックし、**「新規Taskとリンク」** をクリックする。
2. Activity Pattern を **「Transformation」** にし、Task Nameを **「Extract_RequiredData_Last」** とする。
3. 新規作成した **「Extract_RequiredData_Last」** をクリックし、**「クリックして編集」** をクリックする。
4. データの整形を行うために、画面上部の **「Transformation(Union)」** の **「<null\>」** をクリックする。
5. **「transformation Type:」** を **「Visual Transformation」** にし、**「Transformationの追加」** 部分に既存で設定されているレコードをゴミ箱マークより削除する。
* 既存のレコードは、[Step7](#Step7:Enrich-Activity_2)の手順13で確認したデータに基づいて自動で作成されている。
6. **「+Transformationの追加」** の **「+」** を押し、レコードを5つ分追加する。
7. 以下の値を入力し、OKを「クリック」する。
* **\<YourName>** には、**自分の名前**を入力すること。
| Outbound Property | Transformation Expression |
| ----------------- | ------------------------- |
| point | event.point |
| value | event.value |
| Name | event.Users_\<YourName>.Name |
| old_value | event.Data_\<YourName>.old_value |
| DeviceName | event.device |
8. 「Transformation Activity」の画面に戻るので、画面右下の「OK」をクリックする。
9. 画面左のAppを保存する。
10. このStepで作成した **「Extract_RequiredData_Last」** をクリックし、App画面内の左側の設定画面の下部の **「TaskEventsの表示」** をクリックする。
11. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の左下にある **「Publish」** をクリックし、イベントを手動で発生させる。
12. 画面左のAppの左側の **「TaskEventsの表示」** にてデータを受信していることが確認できるので、データをクリックする。
13. データをクリックし、**「Transformation(Union)」** の画面(手順4-7)で設定したデータのみになっていることを確認し、「OK」をクリックする。

14. Appにおいて、ランタイムステータスのクリアを行う。
**データの整形2に関しては以上となります。**
#### Step9:SaveToType Activity
* 水位計のデータをTypeに格納する。
1. [Step8](#Step8:Tranformation-Activity_2)で作成したActivity **「Extract_RequiredData_Last」** を右クリックし、**「新規Taskとリンク」** をクリックする。
2. Activity Pattern を **「SaveToType」** にし、Task Nameを **「SaveTo_Type_Data」** とする。
3. 新規作成した **「SaveTo_Type_Data」** をクリックし、**「クリックして編集」** をクリックする。
4. 「type (Enumerated)」の横のプルダウンより、**「Data_\<YourName>」 ※\<YourName>は自分の名前** を選び、**「Optional Parameter」のupsert(Boolean)** に、**☑️** をつけ、「OK」ボタンをクリックする。
5. 画面左のAppを保存する。
6. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の左下にある **「Publish」** をクリックし、イベントを手動で発生させる。
7. 画面左のAppにて、バッジの有無にてデータを受信していることが確認する。

8. Type「Data_\<YourName>」のレコードを確認する。IDE DocksのProject Contentsの **「Type」** より、**「Data_\<YourName>」 ※\<YourName>は自分の名前** を選択する。
9. 「すべてのレコードを表示する」をクリックし、valueに入っている値を確認する。先ほどvalueに格納されていた値は **1.5** だったが、今は先ほどTopicからPOSTした **3.5** という値がvalueに格納されていることがわかる。

↓

10. IDE DocksのProject Contentsの **「Topic」** より、**「/topic/watergauge_YourName」※\<YourName>は自分の名前** を選択する。
11. IDE DocksのProject Contentsの **「App」** より、**「WaterGauge_YourName」 ※\<YourName>は自分の名前** を選択し、画面の左にApp、画面の右にtopicが表示されていることを確認する。

12. Appにおいて、ランタイムステータスのクリアを行う。
**水位計のデータをTypeに格納に関しては以上となります。**
#### Step10:Filter Activity_2
* 現在の水位計の値が1つ前の水位計の値(old_value)より大きいかつ、現在の水位計の値が8.5以上かを判定する。
1. [Step8](#Step8:Tranformation-Activity_2)で作成したActivity **「Extract_RequiredData_Last」** を再び右クリックし、**「新規Taskとリンク」** をクリックする。
2. Activity Pattern を **「Filter」** にし、Task Nameを **「FilterByValue」** とする。
3. 新規作成した **「FilterByValue」**をクリックし、**「クリックして編集」** をクリックする。
4. 「Condition Type:」が、**VAIL Conditional Expression** であることを確認し、「condition」に対して以下の通りに入力し、「OK」をクリックする。
* 現在の水位が1つ前の水位(old_value)より大きいかつ、現在の水位が8.5以上である
`event.value > event.old_value and event.value >= 8.5`

5. Filterの設定画面に戻るので、「OK」をクリックする。
6. Appを保存する。
7. このStepで作成した **「FilterByValue」** をクリックし、App画面内の左側の設定画面の下部の **「TaskEventsの表示」** をクリックする。
8. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の「Publish Message」において、Key名「Value」のvalueである、Key名「value」のvalueを **3.5** から、**8.7** に変更する。

9. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の左下にある **「Publish」** をクリックし、イベントを手動で発生させる。
10. 画面左のAppの左側の **「TaskEventsの表示」** にてデータを受信していることが確認できるので、データをクリックする。
11. データをクリックし、**value**が**8.7**、**old_value**が**3.5**であることを確認する。
12. 続いて画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の「Publish Message」において、Key名「Value」のvalueである、Key名「value」の**value**を**8.7**から**8.5**に変更する。

13. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の左下にある **「Publish」** をクリックし、イベントを手動で発生させる。
14. 画面左のApp側で、Activity **「FilterByValue」** のみ、バッジの数が異なることを確認する。
* これは今回作成した「Filter」 Activityによるもので、今回のイベントの水位は8.5であり、Filterの条件より。old_valueの値「8.7」未満であるため、フィルタリングにより除外される。

15. 確認できたところで、画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** において、PublishMessage内を以下のように変更する。
16. Appにおいて、ランタイムステータスのクリアを行う。
**現在の水位計の値が1つ前の水位計の値(old_value)より大きいかつ、現在の水位計の値が8.5以上かを判定するActivityに関しては以上です。**
#### Step11:Procedure Activity_2
* Slackに通知する。
1. [Step10](#Step10:Filter-Activity_2)で作成したActivity **「FilterByValue」** を右クリックし、**「新規Taskとリンク」** をクリックする。
2. Activity Pattern を **「Procedure」** にし、Task Nameを **「Send_AlertToSlack」** とする。
3. 新規作成した **「Send_AlertToSlack」** をクリックし、**「クリックして編集」** をクリックする。
4. procedure (Enumerated)の右側のプルダウンより、**「SendToSlack_YourName」 ※\<YourName>は自分の名前** を選択し、OKをクリックする。

5. Appを保存する。
6. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の「Publish Message」において、Key名「Value」のvalueである、Key名「value」のvalueを8.5から8.9に変更する。

7. 画面右側の **「Topic」** の **「/topic/watergauge_YourName」※\<YourName>は自分の名前** の左下にある **「Publish」** をクリックし、イベントを手動で発生させる。
8. 画面左のAppにて、バッジの有無にてデータを受信していることが確認する。

9. Slackにて通知が来ていることを確認する。

10. Appにおいて、ランタイムステータスのクリアを行う。
**Slackに通知するActivityの作成に関しては以上です**
#### Step12:水位計を接続する
* CrossLabにある水位計に電源を入れ、実際に水位計を動かしながら、Appの動きを確認してみましょう!
1. App **「WaterGauge_YourName」※\<YourName>は自分の名前** において、[Step1](Step1:環境構築とイベントの受信Activity「GetEventFrom_MsgPub」の作成)で作成したActivity **「GetEventFrom_MsgPub」** をクリックし、**「クリックして編集」** をクリックする。
2. RequiredParameterの、**「inboundResourceId (String)」** において、**「/topic/watergauge_YourName」※\<YourName>は自分の名前** の部分を、プルダウンより、**「/topic/watergauge」※\<YourName>は自分の名前** を選択し、「OK」をクリックする。

3. Appの保存を行う。
4. Group1の方から実施するので、Group2の方は、Appを非アクティブの状態にする。Appの画面上部にある、チェックボックス☑️をクリックし、チェックが入っていない状態にする。

5. 再びAppを保存する。
6. Group1の方の実施が終わったら、Group1の方が、手順4と5を実施し、Appを非アクティブにする。
7. Group2の方がAppをアクティブ化する。先ほどのチェックボックスをクリックし、チェックが入ったことを確認し、Appを保存する。
**最後に、ナビゲーションバーのプロジェクトより、プロジェクトの保存を行ってください!** 
**Day4のハンズオンは以上となります。お疲れさまでした。**
---
# Day5
## VANTIQのRESTAPI
### 概要
Postman とは、APIを開発・テストするためのプラットフォームである。
今回はこのPostmanを用いてVANTIQのAPIを叩いてみる。
### 注意事項
Postmanに登録する際のメールアドレスは、会社のメールアドレスで登録可能です。
### ラボ
* [Step1:Postmanへの登録](#Step1:Postmanへの登録)
* [Step2:Postmanの基本](#Step2:Postmanの基本)
* [Step3:Postmanのダウンロード](#Step3:Postmanのダウンロード)
* [Step4:アクセストークンの作成](#Step4:アクセストークンの作成)
* [Step5:APIを用いて、VANTIQのTypeからデータを取得する](#Step5:APIを用いて、VANTIQのTypeからデータを取得する)
* [Step6:APIを用いて、VANTIQのTypeへデータを追加する](#Step6:APIを用いて、VANTIQのTypeへデータを追加する)
* [Step7:APIを用いて、Topicに直接イベントをPOSTする](#Step7:APIを用いて、Topicに直接イベントをPOSTする)
#### Step1:Postmanへの登録
* WebAPI開発用のツールであるPostmanに登録する。
1. 「 https://www.postman.com 」にアクセスし、**会社のメールアドレス** を入力し、**「Sign Up foFree」** をクリックする。

2. 英語で好きな **「User名」** と **「Password」** を設定し、**「Create Free account」** をクリックする。

3. **「Your name」** の部分にローマ字で名前を入力し、**「What is your role?」** は自分が該当するものを選択し(なんでも大丈夫です。)、**「Continue」** をクリックする。

4. **「Continue without team」** をクリックする。

5. **「Let's go」** をクリックする。

6. ナビゲーション(使い方の説明)が始まる。**ナビゲーションが不要な場合** は、画面のどこでもいいのでクリックする。読む場合は、**「OK」** をクリックする。

**Postmanへの登録は以上となります。**
#### Step2:Postmanの基本
* Postmanの基本的な使い方を紹介する。
1. Postmanを起動し、左のペインにある **「Workspaces」** を選択する。

2. Workspaceを選択する **「Your Workspaces」** という画面に変わるので、**「My Workspace」** を選択する。

3. 選択したWorkspaceの画面に変わる。左側のペインより、**「New Collection」** を選択する。

4. Collectionに名前をつける。真ん中のペインの上部に表示されている **「NewCollection」** と書かれている部分をクリックすると、Collectionの名前を書き換えることができる。

5. Collectionの名前を **「SC_VANTIQハンズオン」** とする。

6. 左側のペインの自分が作成したCollection名の下に、`This collection is empty. Add a request to start working.`というメッセージが出てくるので、リンクの部分の **「Add a request」** を選択する。
* 表示されたリクエストでAPIをテストするための設定をすることが可能となる。

7. **「NewRequest」** と書かれている部分を **「GetFromType」** に変更する。


**Postmanの基本的な使い方は以上となります。**
#### Step3:Postmanのダウンロード
* 自分の端末にPostmanのアプリケーションをダウンロードする。
1. [Postman](https://www.postman.com/)にアクセスする。
2. Berryに繋いでいる場合、テザリングや、CrossLabの無線に接続し、PulseSecure経由でインターネットに出れるようにする。
3. 左下にある **「Download Desktop App」** をクリックし、ダウンロードする。
* ダウンロードに5分程度かかる。

4. Postmanのセットアップをダウンロードできたら、実行し、インストールを行う。
5. 右上の **「Sign In」** をクリックする。

6. ブラウザでPostmanの画面が開かれるので、自分のアカウントを選択する。

7. ポップアップが出現するので、**「Open Postman app」** を選択する。

8. アプリケーションでサインインが完了するので、左上の **「WorkSpaces」** より、[Step2](#Step2:Postmanの基本)の手順2で選択した **「My WorkSapce」** を選択する。

**Postmanのアプリのダウンロードは以上となります。**
#### Step4:アクセストークンの作成
* 外部からVANTIQにアクセスを許可するためのアクセストークンを作成する。
1. ナビゲーションバーのツールキットの **「管理」** より、 **「Advanced」** を選択し、 **「AccessTokens」** を選択する。

2. **「+新規」** と書かれた部分をクリックし、アクセストークンの新規作成画面を開く。

3. **Name**の部分を **「HandsOn_Postman_\<YourName>」 ※\<YourName>は自分の名前** とし、**Expires At** を **「2023年の3月31日23時59分59秒」** にする。

4. 右側の3点リーダにカーソルを合わせると **「トークンをクリップボードにコピー」** と出るので、アクセストークンをコピーする。(のちほど使うので、メモ帳か何かに貼り付けしておきましょう!)

**VANTIQのAccessTokenの作成は以上となります。**
#### Step5:APIを用いて、VANTIQのTypeからデータを取得する
* Postmanを使用してTypeのデータを取得する。
1. [Step4](#Step4:アクセストークンの作成)の手順4でコピーしたAccessTokenをPostmanに登録する。[Step2](#Step2:Postmanの基本)で作成した Request **「GetFromType」** において、**「Authorization」** タブを開き、 **「Inherit auth from parent」** から、**「Bearer Token」** を選択する。

2. **「Token」** の箇所に、Step3の手順4でコピーしたAccessTokenを貼り付ける。

3. **「Headers」** タブを開き、**「KEY」** に **「Content-Type」** 、 **「VALUE」** に **「application/json」** と入力する。

4. GETと書かれた部分の「Enter Request URL」となっている部分に、以下のURLを入力する。
`https://app.evt.dev.smartcity-pf.com/api/v1/resources/custom/HelloProject_YourName`
* **「HelloProject_YourName」** となっている **「YourName」** の部分には自分の名前を入力する。(自分のProjectにある、Day3で使用した、**「HelloProject_\<YourName>」** とすること。)
* `https://app.evt.dev.smartcity-pf.com` は現在使用しているVANTIQのURLである。
* `< VANTIQのURL >/api/v1/resources/custom/<Type名>` が該当のTypeへのAPIである。

5. **「Send」** ボタンをクリックする。

6. 以下のような結果が返ってくることを確認する。
```
[
{
"_id": "62ba915e243afb727e75cd89",
"id": 2,
"name": "佐々木 莉佳子",
"age": 21,
"GroupName": "アンジュルム",
"NickName": "りかこ",
"ars_namespace": "SWB_SmartCity",
"ars_version": 1,
"ars_createdAt": "2022-06-28T05:27:57.945Z",
"ars_createdBy": "67d1e343-6f47-4dd5-8580-3133c83c459e"
},
{
"_id": "62ba915e243afb727e75cd8a",
"id": 3,
"name": "井上 玲音",
"age": 20,
"GroupName": "Juice=Juice",
"NickName": "れいれい",
"ars_namespace": "SWB_SmartCity",
"ars_version": 1,
"ars_createdAt": "2022-06-28T05:27:57.945Z",
"ars_createdBy": "67d1e343-6f47-4dd5-8580-3133c83c459e"
},
{
"_id": "62ba915e243afb727e75cd88",
"id": 4,
"name": "北川 莉央",
"age": 18,
"GroupName": "モーニング娘。",
"NickName": "おんちゃん",
"ars_namespace": "SWB_SmartCity",
"ars_version": 1,
"ars_createdAt": "2022-06-28T05:27:57.945Z",
"ars_createdBy": "67d1e343-6f47-4dd5-8580-3133c83c459e"
},
{
"_id": "62ba915e243afb727e75cd87",
"id": 5,
"name": "川村 文乃",
"age": 22,
"GroupName": "アンジュルム",
"NickName": "かわむー",
"ars_namespace": "SWB_SmartCity",
"ars_version": 1,
"ars_createdAt": "2022-06-28T05:27:57.945Z",
"ars_createdBy": "67d1e343-6f47-4dd5-8580-3133c83c459e"
}
]
```

7. Sendの結果、**「SSL Error」** が出た場合、右側の **「Disable SSL Verification」** を選択する。

8. VANTIQにアクセスし、Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** の **「すべてのレコードの表示」** から、現在レコードが4件あることを確認し、先ほどGETした際に表示された件数と同じであることを確認する。

9. 右上の **「Save」** をクリックし、RequestのSaveを行う。

**APIを用いた、VANTIQのTypeのデータ取得は以上となります。**
#### Step6:APIを用いて、VANTIQのTypeへデータを追加する
* Postmanを使用してTypeへデータを追加する。
1. 上部にある **「+タブ」** より、リクエストを追加する。

2. 名前の箇所に **「PostToType」** と入力し、保存するCollectionを **「SC_VANTIQハンズオン」** を選択し、**「Save」** をクリックする。

3. [Step5](#Step5:APIを用いて、VANTIQのTypeからデータを取得する)と同様に、[Step4](#Step4:アクセストークンの作成)の手順4でコピーしたAccessTokenをPostmanに登録する。**「Authorization」** タブを開き、 **「Inherit auth from parent」** から、**「Bearer Token」** を選択し、**「Token」** の箇所に、[Step4](#Step4:アクセストークンの作成)の手順4でコピーしたAccessTokenを貼り付ける。
5. **「Headers」** タブを開き、**「KEY」** に **「Content-Type」** 、 **「VALUE」** に **「application/json」** と入力する。
6. **「GET」** と書かれたところをクリックし、**「POST」** を選択する。


7. POSTと書かれた部分の「Enter Request URL」となっている部分に、先ほどと同様の以下のURLを入力する。
`https://app.evt.dev.smartcity-pf.com/api/v1/resources/custom/HelloProject_YourName`
* **「HelloProject_YourName」** となっている **「YourName」** の部分には自分の名前を入力する。(自分のProjectにある、Day3で使用した、**「HelloProject_\<YourName>** とすること。)
8. VANTIQにアクセスし、Type **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** の **「すべてのレコードの表示」** から、現在レコードが4件あることを確認する。

9. Propertiesタブより、 **「HelloProject_YourName」 ※\<YourName>は自分の名前** のカラム名を確認する。
**「id」「age」「name」「GroupName」「NickName」** カラムがあることがわかる。

10. POSTするデータを入力するために、Bodyタブを開き、**「raw」** のラジオボタンを選択し、「Text」となっている部分をプルダウンから **「JSON」** に変更する。

11. 入力欄に下記のように入力する。
```
[
{
"id":6,
"age":22,
"GroupName":"モーニング娘。",
"name":"加賀 楓",
"NickName":"かえでぃ"
},
{
"id":7,
"age":16,
"GroupName":"Juice=Juice",
"name":"入江 里咲",
"NickName":"りさち"
}
]
```

12. **「Send」** ボタンをクリックする。

13. Postmanで以下の結果が返ってくることを確認する。

14. VANTIQのType **「HelloProject_\<YourName>」 ※\<YourName>は自分の名前** の **「すべてのレコードを表示」** をクリックし、先ほどPostmanでPOSTした、**「id:6」** と、**「id:7」** のデータが新たに追加されていることを確認する。

**APIを用いた、VANTIQのTypeへのデータの追加は以上となります。**
#### Step7:APIを用いて、Topicに直接イベントをPOSTする
* HTTP/HTTPSの通信であれば、Topicに対して直接データをPOSTすることができることをDay2で学んだ。今回はそれを実行してみる。
1. VANTIQにて、**「/postman/SCHandsOn/\<YourName>」** という名前で新規のTopicを作成する。(**「YourName」** の部分は**自分の名前**)

2. **「PostmanTest_< YourName >」** という名前で、新規Appを作成する。 (**「YourName」** の部分は**自分の名前**)
3. 「Initiate」ボタンをクリックし、**「InboundResource」** に **「topics」** を指定し、手順1で作成したTopicを選択し、**「OK」** をクリックする。

4. 再度「Initiate」ボタンをクリックし、右側のペインより、名前を **「PostmanData」** に変更する。

5. Appの保存を行う。
6. 再度「Initiate」ボタンをクリックし、**「Task Events の表示」** をクリックし、以下の画像のような状態にし、流れてくるイベントを確認できるようにする。

7. postmanに戻り、**[Step6](#Step6:APIを用いて、VANTIQのTypeへデータを追加する)の手順1から6** を全て実行する。
* 手順3の名前の箇所は、 **「PostToTopics」** と入力する。
8. POSTと書かれた部分の「Enter Request URL」となっている部分に、以下のURLを入力する。
`https://app.evt.dev.smartcity-pf.com/api/v1/resources/topics//postman/SCHandsOn_YourName`
* **「SCHandsOn_YourName」** となっている **「YourName」** の部分には自分の名前を入力すること。
* `<VANTIQのURL>/api/v1/resources/topics/<Topic名>`がtopicへPOSTするときのAPIである。
9. POSTするデータを入力するために、Bodyタブを開き、**「raw」** のラジオボタンを選択し、「Text」となっている部分をプルダウンから **「JSON」** に変更する。
10. 入力欄に下記のように入力する。
```
{
"message": "From Postman"
}
```

11. **「Send」** ボタンをクリックする。

12. VANTIQに戻り、**「PostmanData」** Task が Postman からのイベントを受け取っていることを確認する。

**APIを用いた、VANTIQのTopicへのイベント送信は以上となります。**
**Day5のハンズオンは以上となります。お疲れさまでした。**
---