SORACOM GPS マルチユニット のデータを kintone に保存する

## 概要
発表と同時に注文していた「GPS マルチユニット SORACOM Edition スターターキット」が届いたので早速 kintone へのデータ保存を試してみました。
![GPS マルチユニット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/56b97c39-c806-853f-d1eb-d0cba7cf32a8.jpeg)
SORACOMエンジニアブログによると、GPSマルチユニットは Unified Endpoint を経由して、Harbest Data や、Beame、Funnel、Funk で利用できます。
![Qiita](https://blog.soracom.jp/images/2020-02-12-gps-multiunit-soracom-edition/architecture.png "Qiita")
SORACOMエンジニアブログ（[4 つのセンサーと省電力通信 LTE-M 内蔵「GPS マルチユニット SORACOM Edition」発売開始！](https://blog.soracom.jp/blog/2020/02/12/gps-multiunit-soracom-edition/)）より引用

そこで、今回は以下のようにGPSマルチユニットから、Unified Endpoint、SORACOM Funk を経由して、AWS Lambda をキックして kintone  にレコードを追加する方法を試してみました。
__GPS マルチユニット－＞Unified Endpoint－＞SORACOM Funk－＞AWS Lambda－＞kintone__
## GPS マルチユニットの準備
「GPS マルチユニット SORACOM Edition スターターキット」には、GPS マルチユニット SORACOM Edition、SORACOM 特定地域向け IoT SIMカード (plan-D サイズ：ナノ / データ通信のみ) 、充電/給電用マイクロUSBケーブル 1本が同梱されています。
![GPS マルチユニット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/faa372dd-719d-dc5e-fb00-76eeca835f0b.jpeg)
すでにSORACOMのサイトに一通りのドキュメントがあり、それを参考に本体にSIMを入れた後に前面にあるボタンを1秒以上押すか、同梱されているUSBケーブルで充電すると本体が起動します。

__GPS マルチユニット SORACOM Edition 製品仕様__
https://dev.soracom.io/jp/gps_multiunit/specification/
__GPS マルチユニット SORACOM Edition デバイスの使い方__
https://dev.soracom.io/jp/gps_multiunit/how-to-use/
## kintone の準備
今回はGPS マルチユニットのデータをkintoneに保存しますので、以下のドキュメントを参考にGPSマルチユニットのデータを全て保管するkintoneのアプリを用意します。

__GPS マルチユニット SORACOM Edition 機能の説明__
https://dev.soracom.io/jp/gps_multiunit/how-it-works/

kintoneに以下のようなフォームを持つアプリを追加します。
![q01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/afec39bf-6397-9599-b7e1-bd83ed7bd065.png)

| フィールド名 | タイプ | フィードコート・要素ID |
|--------------|--------|----------------|
| 日時 | 日時 | datetime |
| 緯度(Y) | 数値（少数9桁） | lat |
| 経度(X) | 数値（少数9桁） | lon |
| 電池残量 | 数値（少数0桁） | bat |
| アンテナ感度 | 数値（少数0桁） | rs |
| 温度 | 数値（少数1桁） | temp |
| 湿度 | 数値（少数1桁） | humi |
| 加速度X | 数値（少数1桁） | x |
| 加速度Y | 数値（少数1桁） | y |
| 加速度Z | 数値（少数1桁） | z |
| タイプ | 数値（少数0桁） | type |

あとアプリの設定画面で、レコード追加権限を持つ__APIトークン__を追加、控えておきます。
完成したアプリは以下です。
![q02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/fc4d48af-d5ed-ac49-952a-d576e15f03ca.png)
## AWS アカウントの追加
次に、GPS マルチユニットからのデータを受信処理する AWS Lambda をキック（起動）するための、AWS アカウントを追加します。AWS コンソール __IAM__ のユーザ画面で、ユーザを追加します。
![q09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/d9dc0918-d674-8acd-549f-14b5291853ad.png)
ユーザの詳細設定で「ユーザ名」を入力し、「アクセスの種類」に__プログラムによるアクセス__を選択し、次のステップに移ります。
![q10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/c450bae8-9bf2-275a-9e99-2688930822f9.png)
アクセス許可の設定で「既存ポリシーを直接アタッチ」を選択し、「ポリシーのフィルタ」に __AWSLambdaFullAcess__ を選択して、次のステップに進みます。
![q11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/ddb19a56-9f6d-bc03-54a6-7af83882cc88.png)
本来は先に AWS Lambda 側の設定を行った後に以下のような「ポリシーの作成」を行った方が良いのですが、今回は試験的に試すだけですのでAWSLambdaFullAcessにしています。
![q12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/58de2754-6772-9c08-fcbc-9aed231aa1f8.png)
ユーザの追加に成功したら、__アクセスキーID__と、__シークレットアクセスキー__を控えておきます。
![ユーザ追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/ccd68082-5d77-7538-91f9-3169707100dc.png)
以上でアカウントの追加は完了です。

## AWS Lambda の準備
続いて、GPS マルチユニットからのデータを受信処理する AWS Lambda の設定を行います。「関数の作成」で「関数名」を入力し、ランタイムが __Node.js 12.x__、その他の項目は変更せず関数を作成します。（写真はソースコード他の設定を終えた状態。）
画面右上の __ARN（写真はグレーで消している）は、GPS マルチユニットの通信設定に必要__なので控えておきます。
![q03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/3ee3977a-3e48-2159-7c17-f6ea42c0a177.png)
作成した関数の基本設定の「メモリ（MB）」を__256MB__に、「タイムアウト」を__30秒__に設定します。（メモリは初期値の128MBでも良いですが、タイムアウト初期値3秒は kintone API のレスポンスに遅延が発生する場合も想定して10秒以上に変更した方が良いでしょう。）
![q04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/fd8f02be-9539-10a7-000f-19991aa2ccd3.png)
作成した関数の非同期呼び出しの「イベントの最大有効時間」は__1分__程度に、「再試行」は__0__で行なわないようにします。（今回は、通信のタイムアウトなどで処理が中断した場合は再実行しない設定にしています。）
![q05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/53d1f84d-f102-5b11-fba8-195c9c72ac8a.png)
[GPS マルチユニット SORACOM Edition 機能の説明](https://dev.soracom.io/jp/gps_multiunit/how-it-works/)で紹介しているGPS マルチユニットから送信されるbase64をデコードしたフォーマットを参考に、関数のテストを追加します。
![q06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/55838e97-f32d-030f-9d89-567307ae81c9.png)

```
{
	"lat":35.000000,
	"lon":139.000000,
	"bat":3,
	"rs":4,
	"temp":16.0,
	"humi":32.4,
	"x":0.0,
	"y":-64.0,
	"z":-960.0,
	"type":0
}
```

最初うっかり[GPS マルチユニット SORACOM Edition 機能の説明](https://dev.soracom.io/jp/gps_multiunit/how-it-works/)で紹介している base64 ペイロードデータを処理するプログラムを作成し、base64 ペイロードデータテストを設定していましたが、実際は SORACOM Funkから Lambda にデータが渡される時にはbase64デコードしているため上記の設定になります。
![q07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/079bc15f-5c90-66f3-e74c-ac2670557eec.png)
テスト実行後、kintone にレコードが追加されているのが確認できます。
![q08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/48b4a04e-2fb5-1a05-6897-e1b11b86e062.png)
## AWS Lambda のプログラム
AWS Lambda のプログラムは、以下の node.js のパッケージ request-promise と moment を追加する必要があります。
https://www.npmjs.com/package/request-promise
https://www.npmjs.com/package/moment

Lambda で node.js のパッケージを使う説明は割愛しますが、以下などを参考に設定すると良いでしょう。
__Lambda の Node.js でもっといろんなパッケージを使いたいとき__
https://tech-lab.sios.jp/archives/9017
__AWS Lambda Layersでnode_modulesを使う__
https://xp-cloud.jp/blog/2019/01/12/4630/

Lambda ではGPS マルチユニットからのデータは Json 形式で簡単に受け取れるため、実装は kintone API の Json フォーマットに変換して POST するだけです。

```index.js
'use strict';

const request = require('request-promise');
const moment  = require("moment");

const Domain     = "cybozu.com";
const Subdomain  = "SUBDOMAIN";
const Path       = "/k/v1/record.json";
const Protocol   = "https://";
let   Url        = Protocol + Subdomain + '.' + Domain + Path;

const AppId  = "KINTONE_APP_ID";
const Token  = "KINTONE_TOKEN";

exports.handler = async function(event, context, callback) {
	console.log('Function Start.');
	
	var dateTime = moment().format("YYYY-MM-DDTHH:mm:ssZ");
	var json = {
		"dateTime" : { "value" : dateTime },
		"lat"      : { "value" : event.lat },
		"lon"      : { "value" : event.lon },
		"bat"      : { "value" : event.bat },
		"rs"       : { "value" : event.rs },
		"temp"     : { "value" : event.temp },
		"humi"     : { "value" : event.humi },
		"x"        : { "value" : event.x },
		"y"        : { "value" : event.y },
		"z"        : { "value" : event.z },
		"type"     : { "value" : event.type },
	};
	await PostKintoneRecode(request, Url, AppId, Token, json);
	
	console.log('Function Stop.');
};

// kintone のデータを追加する
async function PostKintoneRecode(request, url, appId, token, json)
{
    try {
        var options = {
            url: url,
            method: 'POST',
            headers: {
                'Content-type': 'application/json',
                'X-Cybozu-API-Token': token
            },
            json: { app : appId, record: json },
        };
        await request(options);
        return true;
    } catch (err) {
        console.error(JSON.stringify(err));
        return false;
    }
}
```

## GPS マルチユニットの設定
最後に、いよいよGPS マルチユニットの設定に入ります。（翌日気づいたのですが、すでにSORACOMさんの丁寧なドキュメントが公開されていましたので、以下を参考にすると良いでしょう。）
__GPS マルチユニット SORACOM Editionを使用して、定期的に位置情報を送信する__
https://dev.soracom.io/jp/start/gps_multiunit_location/
### SIMの有効化
SORACOM のコンソールにログインして、以下の画面に遷移してGPS マルチユニットに付属していた SIM（plan-D ナノサイズ）を有効化します。
__Menu－＞発注－＞注文履歴－＞「受け取り確認」ボタン__
![q14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/c42f7461-9fe8-0b8f-76a0-8749758b74e5.png)
### SIMグループの追加と設定
SIM 有効化後、SIM グループの画面でグループを追加します。
![q15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/b458413b-6166-9104-a011-179310e1008b.png)
追加したグループの Unified Endpoint を設定します。今回は SORACOM Funk を利用しますので「フォーマット」に __SORACOM Funk__ を選択します。
![q16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/046dad3c-db4b-cd0d-2623-0e603a5d1a2d.png)
追加したグループの SORACOM Funk を以下のように設定します。「サービス」は __AWS Lambda__ を選択、「送信データ作成」は __JSON__ を選択、「認証情報」を追加（追加方法は後述）、「関数のARN」は先に控えておいた Lambda の ARN を入力します。
![q17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/e1e1ac7c-a812-9c9a-f4c3-f149fb3c90e7.png)
「認証情報」の追加は、「認証情報」の項目にマウスを移動すると以下が表示されるので、クリックすると追加画面が表示されます。
![q18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/ec30ccfb-1fce-bdd7-b792-d11d2db41afb.png)
「認証情報」追加画面の「認証情報ID」と「概要」を入力し、「識別」は__AWS 認証情報__を選択、「AWS Access Key ID」と「AWS Secret Access Key」は__AWS アカウントの追加で保管したアクセスキーIDとシークレットアクセスキー__を入力し、登録します。
![q19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/68a52472-97e9-970d-e6a3-889405650c2b.png)
以上のグループの設定が完了したら SIM 管理画面に戻り、先に有効化した SIM にこのグループを紐づけます。
![q20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/a9a31d8d-05c0-6fb4-2708-7d9349ffd07f.png)
### GPS マルチユニット本体の設定
SIM と SIMグ ループの登録・紐づけ後、以下の画面に遷移して GPS マルチユニット本体を設定します。
__Menu－＞ガジェット管理－＞GPS マルチユニット__
GPS マルチユニットの画面から、新規デバイス設定を行います。
使用するSIMを選択する画面で先に登録したSIMを選択し「次へ」遷移、設定を保存するグループを選択する画面で既存のグループを利用を選択し先ほど作成したグループを選択して「設定を編集」画面に遷移します。

GPS マルチユニットの設定画面で、送信内容を全てチェックします。
![q21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/2f963274-5d61-ffbb-6cef-4a8fe5fc3f17.png)
送信先の「SORACOM Harvest（Lagoon）」をチェックします。（SORACOM Funk は最初からチェックされて、こちらでは変更できません。）
![q22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/02201afa-785a-484f-8e8c-79adc6d8a00f.png)
送信モードは「定期送信 - 手動モード」を選択します。
![q23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/411a0a17-9e75-c6e0-40bf-e7eacdf09a21.png)
定期送信 - 手動モード詳細設定は毎日10分毎に設定します。（最初のテスト時は最短の1分毎に設定していました。）
![q24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/dace18b2-211b-bb9c-176f-c517bac4a108.png)
加速度割り込みはお好みで良いでしょう。
![q25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/c196bf3d-6cd6-826d-7b94-ea7ab5d0bf2b.png)
以上の設定を完了したら「保存」します。
### GPS マルチユニットからデータ送信の確認
GPS マルチユニット本体の設定が完了した後、「データを確認」で GPS マルチユニット本体から送られてきたデータを確認できます。
![67b536157ac.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/5f76ab2d-81bc-75cf-807a-d087844ad1eb.png)
加速度Z の値が極端なため自動ではちょっと見ずらいですが、データが取得できていることが確認できます。
![q27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/b204e78e-89a7-3c43-a2bc-5e1b21118695.png)

## 結果
kintone アプリと AWS Lambda、GPS マルチユニットの全ての設定を終えると、フィールドにGPS マルチユニットの値がセットされたkintoneアプリのレコードが追加されます。（2020/02/21 自宅の地図は面白くないので外出時に差し替え。）
![q104.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/ae46c742-96a1-7797-ef46-82dc0167c1ec.png)

折角 GPS 情報が保管されていますので、住所/緯度経度変換プラグインで地図を表示させてみました。（2020/02/21 こちらの地図も差し替え。）
![q103.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/6069d5dd-0efe-a88c-51af-72ec379f02d0.png)
__住所/緯度経度変換プラグイン__
https://www.tis2010.jp/geocoding/

これで以前からやってみたいと思っていた kintone で移動環境計測のトレースができるので、2020/02/21朝に車の移動で早速試してみました。
![IMG_7197.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/8bed024b-4fde-0b3b-2a08-3bed06519ec1.jpeg)
その結果が以下です。
![q102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/16d7be2d-d694-6dec-e8b2-98f0fe47ca7c.png)
う～ん、車の移動ではデータが取得できない場合が多いようですね。週末はラーメン博があるので、食べ歩きで試してみるつもりです。
## 参考
__「GPS マルチユニット SORACOM Edition スターターキット」の出荷を開始いたしました！__
https://blog.soracom.jp/blog/2020/02/18/shipping-gps-multiunit-soracom-edition/
__GPSマルチユニットSORACOM Edition ユーザーガイド__
https://dev.soracom.io/jp/gps_multiunit/what-is-gps_multiunit/
__SORACOM Funk を利用して AWS Lambda を呼び出し Slack へ通知する__
https://dev.soracom.io/jp/start/funk_aws_lambda/
__SORACOM LTE-M Button を押したログを kintone に保管__
https://qiita.com/yukataoka/items/9f9daac2dc05194bbc63