Obnizと超音波距離センサーを使って、LINE Botで距離を測定できる仕組みを考えた。




#はじめに

遠隔で距離を測定したいと思ったことありませんか？

Obnizを接続した超音波距離センサーを距離を測りたい場所に設置して、遠隔からLINE botでの操作で測定する仕組みを考えました。

#参考にしたサイト
ObnizのDocument　「超音波を利用した距離センサー」
https://obniz.io/ja/sdk/parts/HC-SR04/README.md

1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest
@n0bisukeさん
https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d

花粉ボット　@n0bisukeさん
https://qiita.com/n0bisuke/private/2d474506e43ebdb2711e

#概念図

![1216.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269534/86a08c80-c63d-f338-a0c6-f3f683e97619.jpeg)


#作り方

以下を準備
```npm init -y```
```npm i --save @line/bot-sdk express```
```npm install axios --save```
```npm install obniz```
```npm i -g ngrok```


以下のindex.jsを作成。

```index.js

'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;
const axios = require('axios');

const config = {
    channelAccessToken: '<YOUR_Channel_Access_Token>',
    channelSecret: '<Your_Channel_Secret>'
};

const app = express();

var Obniz = require('obniz');
var obniz = new Obniz("<YOUR_OBNIZ_ID>");

// 距離の値を全体で使えるようにこの階層で宣言
var distance = 0;

// 距離センサーも全体で使えるようにする
var hcsr04;

obniz.onconnect = async function () {
  obniz.display.clear();
  obniz.display.print("Measure!!");

  hcsr04 = obniz.wired("HC-SR04", {gnd:0, echo:1, trigger:2, vcc:3});
  hcsr04.temp = 25;
  hcsr04.reset_alltime = true;
  distance = await hcsr04.measureWait();  //これをWEB APIとして見立てる
  console.log("distance " + Math.round(distance) + " mm");

// displayに反映
  obniz.display.clear();
  obniz.display.print("distance " + Math.round(distance) + " mm");
}

app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  let mes = ''
  if(event.message.text === '距離'){
    mes = '測定開始します！'; //先に表示
    getDistanceValue(event.source.userId); //スクレイピング処理が終わったらプッシュメッセージ
  }else{
    mes = event.message.text;
  }

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: mes
  });
}

const getDistanceValue = async (userId) => {
  const res = await hcsr04.measureWait();  //WEB APIと見立てる
  let res1 = Math.round(res)
  console.log(res1);

// displayに反映
    obniz.display.clear();
    obniz.display.print("distance " + Math.round(res1) + " mm");

  await client.pushMessage(userId, {
      type: 'text',
      text: `距離は ${res1} mm`,
  });
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);
```

トンネリングサーバーを起動。 今回はNode.jsアプリケーションを3000番ポートで利用する。
```ngrok http 3000```

LINE Developers内の webhook URLに　`https://<XXXXXXXXXXX>.io/webhook`　を入力

ngrokを起動したターミナルとは別に、新しいターミナルを起動して
`node index.js `

これで、準備完了。


###ngrokより便利なものが出た
[ngrokよりserveoがすごい。０秒で localhostを固定URLで公開]
(https://qiita.com/kaba/items/53b297e2bfb5b4f20a48)
[1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest]
(https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E4%BD%9C%E6%88%90%E3%81%A8%E3%83%8F%E3%83%AD%E3%83%BC%E3%83%AF%E3%83%BC%E3%83%AB%E3%83%89)
の2つを参照。

コンソール内で
```ssh -o ServerAliveInterval=60 -R <つけたい名前>:80:localhost:3000 serveo.net```
たとえば
```ssh -o ServerAliveInterval=60 -R yamadataro:80:localhost:3000 serveo.net```
など。

できた
https://yamadataro.serveo.net/webhook
を　LINE画面のwebhookに登録する。
 



#動作画面

「距離」と送信したら、「測定開始します！」とまず返して、センサーで測定した結果が次に「距離は 249　mm」と返してくれます。それ以外のテキストを送ったら、オウム返しで戻ってきます。

<img width="375" alt="IMG_3592.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269534/419993fe-08a2-1a5f-e8fb-d522629b3d32.png">

obnizのdisplayにも、distance 249 mm　と測定値が表示されます。

動作動画はこちら。https://youtu.be/SBiX9L3JtJU


#考察

今回は、ngrokを使いましたが、Heroku, AWS lambda, Firebaseなどを使って、自分のPC内でnodeを動かす準備が不要の環境を作ろうと考えています。

離れた場所に設置したセンサーの測定値を見る方法として、LINE Botは非常にやさしいUIだと思います。

今回の方法は、家庭内での適応に加え、ビジネスの生産現場においても適応でき、非常に適応範囲の広いものと考えます。