GPSマルチユニットSORACOM Edition 使ってみて、だいたい1ヶ月経ちました。

ソラコムTシャツ欲しいけど、これじゃ貰えないなーって思っている人です。

---
[GPSマルチユニットSORACOM Edition 使ってみた(開封の儀)](https://qiita.com/keni_w/items/f8e78812298093aab9b4)の続きです。

GPSマルチユニット SORACOM Edition購入して、約1ヶ月経ちました。
とりあえず行ったことは、**SORACOM Laggon**による可視化、***SORACOM Funk***経由で、AWS LambdaでSlack通知の2つです。

### Lagoonによる可視化
とりあえず、オフィスの気温、湿度の可視化をしてます。
<img width="1297" alt="気温と湿度" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/dc00b9ce-0b3a-4545-7eee-70adf2e2aabc.png">

とりあえず、平日の10時から19時までの15分置きに加速度を除くデータを送信させてますが、12日間ぐらいは稼働するようです。
残量レベル3が一番長く、2、1は短いようです。
消費電力については、@1stshipさんの[GPSマルチユニットSORACOM Edition消費電力の研究](https://qiita.com/1stship/items/61e630c1a74121c569d8)をご覧いただくといいと思います！

<img width="1264" alt="電池残量" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/0bd89b21-102f-2fbd-2f29-0819f7bae9d7.png">

ちなみに、初めて、Lagoonを真面目wに触るので、こんなことをつぶやいてみたり。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">SORACOM LagoonでGPSマルチユニットの気温と湿度を可視化するために、初めてまともなグラフを作ってみた。最小最大を適切にセットしないと、変動幅が大きくなって、見辛いグラフになることがわかったのが学び。 <a href="https://twitter.com/hashtag/soracom?src=hash&amp;ref_src=twsrc%5Etfw">#soracom</a></p>&mdash; Kenichiro Wada (@Keni_W) <a href="https://twitter.com/Keni_W/status/1232230304800112640?ref_src=twsrc%5Etfw">February 25, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



### SORACOM Funk経由でSlack通知
GPSマルチユニットからは、Funk経由で、AWS Lambdaでデータを送信できるので、
そこから、Slackにも通知させています。

![Slack通知](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72752/b4fd666a-0120-52fc-935e-3c01a9cb6f40.jpeg)


base64デコードするもんだと思っていたので、とりあえず流してみたら、デコードされてeventに入ってきたので、ほんと
Funk神！って思いましたね。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">GPSマルチユニットのデータをSORACOM Funk経由でLambdaに流したらbase64デコードされて出てきた。検証が1個減った。Funk素敵！<a href="https://twitter.com/hashtag/soracom?src=hash&amp;ref_src=twsrc%5Etfw">#soracom</a></p>&mdash; Kenichiro Wada (@Keni_W) <a href="https://twitter.com/Keni_W/status/1230353705158864896?ref_src=twsrc%5Etfw">February 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

とりあえずソースはこんな感じ。
node.js v12のランタイムで動作確認してます。
大した内容じゃですが、どこかで、使い方含めて、githubで公開します。


```:handlr.js
'use strict'
const moment = require('moment-timezone');
const AWS = require('aws-sdk');
AWS.config.update({ region: 'ap-northeast-1' });
const kms = new AWS.KMS();
const request = require('request-promise');

const encryptedSlackWebHookUrl = process.env['SLACK_WEBHOOK_URL'];
let decryptedSlackWebHookUrl;

/**
 * 環境変数復号化
 * @param {*} decryptedEnvKey 
 */
async function decryptedEnv(decryptedEnvKey) {

  const data = await kms
    .decrypt({
      CiphertextBlob: new Buffer(process.env[decryptedEnvKey], 'base64'),
    })
    .promise();
  return String(data.Plaintext);
}

/**
 * データ整形
 * @param {*} event 
 */
async function formatData(event) {

  let typeStr; 
  if (event.type === 0) {
    typeStr = '自動'
  } else {
    typeStr = '手動'
  }
  return {
    locationLat : event.lat,
    locationLon : event.lon,
    batteryLevel: event.bat,
    signalLevel: event.rs,
    temperature: event.temp,
    humidity: event.humi,
    type: typeStr
  }
}
/**
 * Slack POST
 * @param  {[type]} data [description]
 * @return {[type]}       [description]
 */
async function postSlackMessage(data) {
 
  console.log('slack Call');

  let messageArray = [];
  messageArray.push(`${moment().tz("Asia/Tokyo").format('YYYY-MM-DD HH:mm:ss')}の測定値`);
  messageArray.push(`温度: ${data.temperature}`);
  messageArray.push(`湿度: ${data.humidity}`);
  messageArray.push(`バッテリーレベル: ${data.batteryLevel}`);
  messageArray.push(`電波レベル: ${data.signalLevel}`);
  messageArray.push(`${data.type}実行されました。`);
  // 位置情報付与
  if (data.locationLat !== null && data.locationLon !== null) {
    messageArray.push('GPSマルチユニット 現在位置: ');
    messageArray.push(`https://www.google.com/maps?q=${data.locationLat},${data.locationLon}`);

  }
  const message = messageArray.join('\n');
  // リクエスト設定
  const options = {
    url: decryptedSlackWebHookUrl,
    method: 'POST',
    headers: {
      'Content-type': 'application/json'
    },
    body: {
      "text": message
    },
    json: true
  };
  // メッセージ送信
  const res = await request(options)
  .then(function (body) {
    console.log('Slack Post Message Sucuessful! :', JSON.stringify(body, 2));
    if (body == 'ok') {
      return true;
    } else {
      return false;
    }
  })
  .catch(function (err) {
    console.log('Slack Post Error: ' + err);
    return false
  });
  console.log(res);
  return res;
};

module.exports.soracom =  async(event, context)  => {
  console.log(JSON.stringify(event, 2));
  console.log(JSON.stringify(context, 2));

  decryptedSlackWebHookUrl = await decryptedEnv('SLACK_WEBHOOK_URL');
  const data = await formatData(event);

  const isPostSlack = await postSlackMessage(data);

  if (isPostSlack) {
    return {
      statusCode: 200,
      body: JSON.stringify(
        {
          message: 'Slack Post Message Successful!',
          input: data,
        },
        null,
        2
      ),
    };
  } else {
    return {
      statusCode: 500,
      body: JSON.stringify(
        {
          message: 'Slack Post Message Failed!',
          input: data,
        },
        null,
        2
      ),
    };
  }
};
```

最近、Serverless　Frameworkでデプロイするようにしているので、設定であるserverless.ymlはこんな感じにしてます。

```:serverless.yml

service: soracom-gps-multiUnit-receiver
provider:
  name: aws
  runtime: nodejs12.x

# you can overwrite defaults here
  stage: dev
  region: ap-northeast-1
  iamRoleStatements:
    - Effect: Allow
      Action:
        - KMS:Decrypt
      Resource: ${self:custom.kmsSecrets.keyArn}
plugins:
  - serverless-kms-secrets
custom:
  kmsSecrets:
    file: ${file(kms-secrets.${opt:stage, self:provider.stage}.${opt:region, self:provider.region}.yml)}
    keyArn: arn:aws:kms:ap-northeast-1:123456789012:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
functions:
  soracom:
    handler: handler.soracom
    memorySize: 256
    timeout: 25
    environment:
      SLACK_WEBHOOK_URL: ${self:custom.kmsSecrets.file.secrets.SLACK_WEBHOOK_URL}
```

Serverless.yml内で呼んでるKMSで暗号化したSlackのWebhook URLを格納してる設定ファイルは、このような構成です。流石にURLは抜いてます。

 ```:kms-secrets.dev.ap-northeast-1.yml
secrets:
    SLACK_WEBHOOK_URL: (暗号化された文字列)
keyArn: 'arn:aws:kms:ap-northeast-1:123456789012:key/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
```

### 次やること

本当は、2台同じのを用意するのがいいんでしょうけど、とりあえずはないので、[Grove IoT スターターキット for SORACOM(Wio LTE JP Version)](https://soracom.jp/products/kit/grovestarter_kit_lte/)付属（or別途購入）の温湿度センサーを使って、オフィスの２箇所の温度と湿度を可視化したいと思います。

あと、バッテリーを通知する何某かを作ろうかと（こちらはもっか実装中）