SORACOM LTE-M Button Plus と kintone で高齢者を見守るシステムの試作

## 概要
これまで田舎で一人暮らしの親の見守りのためにIoTシステムを試作してきましたが、
・インターネット接続環境を契約していない
・スマホはおろか携帯も電話をかけるしか利用しない
・センサ設置に良い場所は配線しずらく、電池駆動での頻繁な交換は対応できない
・WiMAX、sigfoxなどの安価な通信サービスはエリア外
などの要因で実運用を断念してきました。

ちなみに、一人暮らしの親は普段の生活で電気ポットなどの通知機能がある家電は使いません。

そんな折にふと、SORACOM の @ma2shita さんの以下のレシピを参照、簡単に応用できるではないですか！
【IoT DIY レシピ】SORACOM LTE-M Button Plusでできる、ドアの開閉モニタリング
https://soracom.github.io/iot-recipes/door-monitoring-by-soracom-lte-m-button/

SORACOM LTE-M Button なら KDDI のエリアで通信可能、電池は長持ち。田舎の親でも毎日利用する冷蔵庫の開閉回数カウントは見守りに使えそうです。先ずは自宅の冷蔵庫で試してみることにしました。

今回は SORACOM LTE-M Button Plus に磁気センサーを付けた試験機を用意、SORACOM Func で AWS Lambda をキック、kintone にデータを保管し、分析するシステムを構築します。
![BT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/a597bf44-727b-be91-b064-63138db60e72.png)

## 用意するもの
![IMG_7459.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/a8fd1725-d0d2-3b54-0ea5-13c10323fd58.jpeg)
今回の試作は以下の機器を準備。
__・SORACOM LTE-M Button Plus（7,380円）__
　https://soracom.jp/products/gadgets/button_plus/
__・uxcell ドアマグネット 表面実装 有線NCドア センサーアラーム磁気リードスイッチ（671円）__
　https://www.amazon.co.jp/dp/B07FLWGS73/
磁気リードスイッチは、磁気センサー（A接点型）と同じです。

利用するサービスは以下。
__・SORACOM__
　https://soracom.jp/
__・Amazon AWS__
　https://aws.amazon.com/jp/
__・kintone__
　https://kintone.cybozu.co.jp/
いずれも無償枠や、試用が可能です。

## 事前準備
以下を参考に SORACOM LTE-M Button の登録から動作確認までを行います。
__SORACOM LTE-M Button の登録から動作確認まで__
https://soracom.github.io/iot-recipes/door-monitoring-by-soracom-lte-m-button/#2
環境がない場合は Amazon AWS のアカウント登録と、kintone は30日の試用の申込を行います。

## SORACOM LTE-M Button の動作確認
以下を参考に SORACOM LTE-M Button に磁気センサーを接続します。
__磁気センサーと SORACOM LTE-M Button の接続まで__
https://soracom.github.io/iot-recipes/door-monitoring-by-soracom-lte-m-button/#3

### 追加の説明
設置前なら、以下の写真のように配線をセロテープで仮止めでも十分でしょう。
![IMG_7462.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/1d363b6d-6e7a-a327-a8d8-f7df5fecf27f.jpeg)
SORACOM の__「コンソール画面」__から、SORACOM LTE-M Button のグループを設定します。
![BT01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/ec58b430-0fa0-4ea1-37eb-495a0598d698.png)
今回設定するのは __SORACOM Air for Celluar__ と __SORACOM Funk__ ですが、動作確認のため __SORACOM Harvest__ も利用します。
![BT02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/eadb4d79-e06f-b593-74e3-603e67c8bade.png)
なお、SORACOM Funk の設定は kintone や AWS Lambda の設定完了後に行います。
SORACOM Air for Celluar の__「バイナリーパーサ設定」__のフォーマットを以下に設定します。
![BT03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/83d4d7d5-e7ed-7dd0-89fa-6d9f315575fc.png)
__「SORACOM Harvest の設定」__を有効にします。
![BT04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/76b42a82-3a71-3cd9-7957-945d3302b9f7.png)
以上のグループの設定を終えてから、磁気センサの着け離しを行います。
正常に動作している場合は、ボタンのランプが橙色から緑に変化、消滅します。

__「コンソール画面」__でデータを確認します。
![BT04B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/c13b87b5-8b54-9559-e476-4528691c65da.png)
SORACOM Harvest が有効な場合は、以下のような結果を確認できます。
![BT05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/2cbe8a03-bfe7-89d3-6125-999514bed043.png)
磁気センサの着け離しの動作を短い時間で1回、長い時間で1回、短い時間で2回行うと、clickType が変化することがわかります。

受信するデータは以下です。

```
{
    "clickType":1,
    "clickTypeName":"SINGLE",
    "batteryLevel":1,
    "binaryParserEnabled":true
}
```

## kintone アプリの作成
SORACOM LTE-M Button Plus のデータを蓄積、解析する kintone アプリを作成します。
![BT06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/f99e7233-d3f9-96b8-7cc8-9eb2d2eb56b2.png)
アプリはいたってシンプル、以下の2つの項目とAPIトークンを設定するだけです。

| フィールド名 | タイプ | フィードコート・要素ID |
|--------------|--------|----------------|
| 開催日時 | 日時 | 開催日時 |
| 開閉状況 | 文字列（1行） | 開閉状況 |

APIトークンのアクセス権は、レコード追加のみ設定します。
## Amazon AWS Lambda の設定
SORACOM LTE-M Button Plus のデータを kintone に保管するために、__Amazon AWS Lambda__ を利用します。
__Amazon AWS のコンソール画面__から、__Lambda の関数__を開き__「関数の作成」__を行います。
![BT07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/b33210c5-8814-de64-eaea-812e827c350b.png)
__「一から作成」__を選択し、__関数名__を入力、__ランタイム__は __Node.js 12.x__ を選択して、関数を作成します。
以下は必須ではないですが、私の場合は以下のように設定しています。（説明は省略）
![BT08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/b93a451c-30e3-b503-b701-84ee4c1f78ca.png)
![BT09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/e2dc0b4a-4535-9746-c646-a14ce8fa82ee.png)
タイムアウト初期値だけは10秒以上にしておくと良いでしょう。

関数作成後、右上に表示される__「ARN」__は SORACOM Funk の設定に必要ですので、控えておきます。
![BT10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/67d3436e-2abc-649b-9e74-b185a6ed79ac.png)
今回は以下の node.js のプログラムを Lamda に設定しました。（説明は省略）
以下は過去の環境を流用したため sync-request で実装しています。

```index.js
'use strict';

const request = require('sync-request');
const Domain     = "cybozu.com";
const Subdomain  = "サブドメインを設定";
const Path       = "/k/v1/record.json";
const Protocol   = "https://";
const AppId      = "アプリIDを設定";
const Token      = "アプリのトークンを設定";

exports.handler = async (event, context) => {

    let clicktype = event.clickTypeName;
    let message = "";
    if(clicktype == "SINGLE"){
        message = "冷蔵庫で素早い開閉";
    } else if (clicktype == "DOUBLE"){
         message = "冷蔵庫でダブル開閉";
    } else if (clicktype == "LONG") {
        message = "冷蔵庫を開閉した";
    } else {
        message = "不明";
    }
    
    require('date-utils');
    let dt = new Date();
    let url = Protocol + Subdomain + '.' + Domain + Path;
    let json = { 
        "開閉日時": { "value" : dt.toFormat("YYYY-MM-DDTHH24:MI:SSZ") },
        "開閉状況" : { "value" : message }
    };
    let res = funcPostKintoneRecode(request, url, AppId, Token, json);

};

function funcPostKintoneRecode(request, url, appId, token, json)
{
	var response = request('POST',url,{
        headers: {
            'Content-type': 'application/json',
            'X-Cybozu-API-Token': token
        },
        json: { app : appId, record: json },
    });
    return JSON.parse(response.getBody('utf8'));
}

```
AWS Lamda の開発等についての詳細は、以下などの情報を参考に。
__【AWS入門】Lambdaの概要とサンプルコードで手を動かしながら実践入門__
https://fukatsu.tech/aws-lambda
__AWS Lambda 開始方法__
https://aws.amazon.com/jp/lambda/getting-started/
__Lambda の Node.js でもっといろんなパッケージを使いたいとき__
https://tech-lab.sios.jp/archives/9017
__AWS Lambda Layersでnode_modulesを使う__
https://xp-cloud.jp/blog/2019/01/12/4630/
## AWS アカウントの追加
SORACOM Funk が Amazon AWS Lambda をキック（起動）するための、AWS アカウントを追加します。
こちらについては、以前詳しく説明した以下を参考に。

__SORACOM GPS マルチユニット のデータを kintone に保存する（AWS アカウントの追加）__
https://qiita.com/yukataoka/items/c07b78f5151c29ac8858#aws-%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AE%E8%BF%BD%E5%8A%A0

ユーザの追加に成功したら、__アクセスキーID__と、__シークレットアクセスキー__を控えておきます。

## SORACOM Funk の設定
SORACOM LTE-M Button のアクションから Amazon AWS Lambda をキック（起動）する SORACOM Funk を設定します。
![BT13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/04dd0f8d-57c1-1a36-e31c-31fd76c137bb.png)
「サービス」は AWS Lambda、「送信データ形式」は JSON を設定します。
「関数のARN」は AWS Lambda の設定で控えた ARN を入力します。

「認証情報」の設定は、以前詳しく説明した以下を参考に。

__SORACOM GPS マルチユニット のデータを kintone に保存する（SIMグループの追加と設定）__
https://qiita.com/yukataoka/items/c07b78f5151c29ac8858#sim%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%81%AE%E8%BF%BD%E5%8A%A0%E3%81%A8%E8%A8%AD%E5%AE%9A

## 計測の確認
以上の作業を完了し、事前に計測ができるか試験します。
磁気センサの着け離しを行い、kintone のアプリに以下のようなデータが保管できていれば成功です。
![BT14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/4a65ef31-131c-f838-a981-d687c210d99b.png)

他にどんな情報を入手可能か AWS Lamda の context を確認しました。

```
{
  callbackWaitsForEmptyEventLoop: [Getter/Setter],
  succeed: [Function],
  fail: [Function],
  done: [Function],
  functionVersion: '$LATEST',
  functionName: 'SORACOM_LTE-M_Button_Plus',
  memoryLimitInMB: '256',
  logGroupName: '/aws/lambda/SORACOM_LTE-M_Button_Plus',
  logStreamName: '2020/04/29/[$LATEST]fXXXXXXXXXXXXXXXXXXXXXXXXXX6',
  clientContext: {
    operatorId: 'OPXXXXXXXX8',
    coverage: 'jp',
    resourceType: 'Subscriber',
    resourceId: '4XXXXXXXXXXXXX9',
    sourceProtocol: 'udp',
    srn: 'srn:soracom:OP0032113518:jp:Subscriber:440525060031429',
    imsi: '4XXXXXXXXXXXXX9',
    imei: '3XXXXXXXXXXXXX8',
    locationQueryResult: 'success',
    location: { lat: 33.999999999999, lon: 133.999999999999 },
    custom: {
      operatorId: 'OPXXXXXXXXXXXX8',
      coverage: 'jp',
      resourceType: 'Subscriber',
      resourceId: '4XXXXXXXXXXXXX9',
      sourceProtocol: 'udp',
      srn: 'srn:soracom:OPXXXXXXXXXXX8:jp:Subscriber:4XXXXXXXXXXXXX9',
      imsi: '4XXXXXXXXXXXXX9',
      imei: '3XXXXXXXXXXXXX8',
      locationQueryResult: 'success',
      location: [Object]
    }
  },
  identity: undefined,
  invokedFunctionArn: 'arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
  awsRequestId: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX',
  getRemainingTimeInMillis: [Function: getRemainingTimeInMillis]
}
```

SORACOM LTE-M Button を識別可能にする IMSI も取得できそうです。さらに、SORACOM のコンソールで追加の設定は必要ですが、緯度、経度も取得できるので、これらのデータも活用可能ですね。

計測できることが確認ができたので SORACOM LTE-M Button を冷蔵庫に取り付けました。
以下は両面テープで冷蔵庫のドアに磁気センサを取り付けて、ドアを開閉したところです。（配線ははんだ付け後、熱収縮チューブで配線を保護しています。）
![IMG_7482.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/0006e35e-896e-91ff-de91-1eaa0bea8fa3.jpeg)
緑の点灯で、正常にデータの送信が完了したことが確認できます。

## 計測結果と分析
kintone のアプリを拡張して、以下の計測の結果を確認しました。
![BT18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/fa30e607-5a7e-b339-0a32-3e9a880fc58b.png)
kintone のアプリにはIMSI、GPS位置情報を追加しています。（GPS位置情報は一覧で見えないようにしています。）

### 日毎の冷蔵庫開閉回数
日毎の冷蔵庫の開閉回数をグラフにしてみました。
![BT16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/b86ac29e-6c0f-beb5-010d-3645bfe20dd6.png)
早くも平日と休日での冷蔵庫の開け閉めの相関関係が現れていますね。（笑）

### 時間毎の冷蔵庫開閉数
時間毎の冷蔵庫の開閉回数をグラフにしてみました。
![BT17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/87cd97ee-1e41-6c65-b677-8fb6c014b655.png)
キッチンの利用時間が推測できそうですね。（汗）
今後は時間帯毎に集計できるようにアプリを改造してみると、生活パターンなども分析できそうです。

### 各家庭毎の開閉状況把握
kintone のアプリに IMSI 情報を追加することで、人と紐づけして状況を把握しやすくなります。
![BT19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75892/7e8cc62b-64ae-463c-b218-a95d3aee0a42.png)

## 感謝
今回のきっかけとなった SORACOM の @ma2shita さん、Nao さんのわかりやすく、アイディアが広がるレシピに感謝です！
__【IoT DIY レシピ】SORACOM LTE-M Button Plusでできる、ドアの開閉モニタリング__
https://soracom.github.io/iot-recipes/door-monitoring-by-soracom-lte-m-button/

今回利用した SORACOM Funk もそうなんですが、__SORACOM__ が出すサービスは「やりたい！」ことのど真ん中ストライクで助かります。そして、データ解析を簡単にチームで簡単にできる __kintone__ や、利用したいデータ処理を安価なコストで粛々と実行してくれる __AWS__、__この組み合わせ最高__ですね！