老眼と加齢性難聴のチェックができるLINE Bot×Iotの作成

##概要
プログラムの勉強を始めて3か月程の開業医です。最近ディスプレイを見る時間が長くなったせいか、年齢のせいか、近くの文字が見えにくくなってきました。

リーディンググラス（老眼鏡）について調べていると、**人差し指の指紋が一番鮮明に見える距離（近点）が30cm以上離れると老眼鏡が必要**で、近点の長さによってピント調節力が年齢相応かどうかや老眼度数もある程度わかるようです。

[参考サイト1](https://www.paperglass.jp/info/rougan-check/)　　[参考サイト２](https://www.jins.com/jp/st/reading_guide/)

今回、近点距離（人差し指の指紋が見える距離）を入力すると、ピント調節力がどの年齢相当か？老眼かどうか？老眼度数はどの程度か？がわかるLINE botを作成してみようと思いました。

同時にobnizでIotを作る勉強を始めたので、老眼判定LINE botと連携させて、判断された年齢でぎりぎり聴きとることができる高音（モスキート音）をスピーカーから出し、自分の可聴周波数がわかる加齢性難聴判定Iotを作成しました。

※老眼や加齢性難聴の診断を行う為には医療機関での検査が必要です。今回の記事の医療情報に関しては参考程度にして頂きたいと思います。

##実装内容
・LINE上に近点距離を入力すると老眼かどうか返答されるFAQBOT。
・返答と同時にその年齢でぎりぎり聞きとることができる高音（モスキート音）を出すIot。

##概念図
node.js expressでLINE bot APIとobnizを連携しました。
![rougann.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453374/c6992a6f-b0c9-466c-9301-ca0b66cd5bb1.jpeg)




##作成方法
前回はGoogle Spread Sheet × Google Apps Script × LINE の組み合わせでLINE botを作成しました。
[保育園・小中学校での感染症流行状況がわかる　Line Botの作成](https://qiita.com/doikatsuyuki/items/5939ba28326422c2b9bc)


今回はこちらの記事を参考にnode.js express × LINE bot API × obnizの組み合わせでLINE botとIotを作成しました。
[1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 ](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)

**1. Botアカウントを作成する**

**2. Node.jsでBot開発**

**3. ngrokでトンネリング**

上記の1～3を参考記事の通りに行います。初めての方でも1～2時間ほどで質問をオウム返しされるLINE botを作ることができます。

**4.obnizとの連携**

ここから先は、参考記事に掲載されている以下のコードに変更を加えていきます。

```js

'use strict';

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

const config = {
    channelSecret: '作成したBOTのチャンネルシークレット',
    channelAccessToken: '作成したBOTのチャンネルアクセストークン'
};
////////////////////////////////////////////////////////////////
ここにコードAをコピペしてください
////////////////////////////////////////////////////////////////

const app = express();

app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);

    //ここのif分はdeveloper consoleの"接続確認"用なので削除して問題ないです。
    if(req.body.events[0].replyToken === '00000000000000000000000000000000' && req.body.events[1].replyToken === 'ffffffffffffffffffffffffffffffff'){
        res.send('Hello LINE BOT!(POST)');
        console.log('疎通確認用');
        return; 
    }

    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);
  }

/////////////////////////////////////////////////////////////////
ここにコードBをコピペしてください。
/////////////////////////////////////////////////////////////////

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: event.message.text //実際に返信の言葉を入れる箇所
  });
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);
```
コードA
このコードをコピペすることでobnizが準備され、接続したスピーカーが使えるようになります。

```js

//　コードA
// Obnizの準備
var Obniz = require("obniz");
var obniz = new Obniz("Obniz ID");  // Obniz ID を入力
var speaker; // 全体で使えるようにするスコープ
obniz.onconnect = async function () {
    speaker = obniz.wired("Speaker", {signal:0, gnd:1});
}

```
コードB
このコードをコピペすることで近点距離によってLINE botからの回答を変え、スピーカーから出る音の周波数も変えます。

```js
  //コードB
  // LINE botのプログラム
  let ans = "";
  let question = event.message.text;
  let distance = parseInt(question);
  
  let hz;//モスキート音のhz

  if (distance>=80) {
    ans = "ピント調整力は61歳以上相当です。老眼の可能性が高いです。老眼度数は3以上と思われます。今流れているモスキート音は8000Hzです。";
    hz = 8000;
  }else if (distance >= 60){
    ans = "ピント調整力は56～60歳相当です。老眼の可能性が高いです。老眼度数は2.5程度と思われます。今流れているモスキート音は8000Hzです。";
    hz = 8000;
  }else if (distance >= 50){
    ans = "ピント調整力は51～55歳相当です。老眼の可能性が高いです。老眼度数は2程度と思われます。今流れているモスキート音は10000Hzです。";
    hz = 10000;
  }else if(distance >= 40){
    ans = "ピント調整力は46～50歳相当です。老眼の可能性が高いです。老眼度数は1.5程度と思われます。今流れているモスキート音は12000Hzです。";
    hz = 12000;
  }else if(distance >= 30){
    ans = "ピント調整力は41～45歳相当です。老眼の可能性が高いです。老眼度数は1程度と思われます。今流れているモスキート音は15000Hzです。";
    hz = 15000;
  } else if(distance<30) {
    ans = "ピント調整力は40歳未満相当です。老眼の可能性は低いです。今流れているモスキート音は16000Hzです。";
    hz = 16000;
  }else {
    ans = "指先にピントが合い、人差し指の指紋がはっきりと見えた距離を数字で入力してください。";
  }

  speaker.play(hz);


```

最後に textの部分をansに変更して完了です。

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

```



##動作確認
ちゃんと返信されています。
<img width="375" alt="IMG-0708.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453374/d7834d64-edd3-b8f0-c4a0-8eabb13695a8.png">
<img width="375" alt="IMG-0709.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453374/7f8c1909-f171-2fc0-c816-1d381202fda0.png">
音もちゃんと出ていました。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/m3biL5neSu">pic.twitter.com/m3biL5neSu</a></p>&mdash; 病気のセルフチェック (@Selfcheckhealt1) <a href="https://twitter.com/Selfcheckhealt1/status/1185772286244032512?ref_src=twsrc%5Etfw">2019年10月20日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


##考察
今回node.jsでLINE botを作成しました。前回のGoogle Spread Sheet × Google Apps Script × LINE の組み合わせに比べるとやや面倒なところはありますが、他のAPIと連携しやすいので応用が利きやすいと感じました。
また、初めてのobnizでしたが、スピーカーはピンを入れるだけで使えるので作成は驚くほど簡単でした。今度は超音波センサーを使って近点距離を自動で取得できるようにしたいと思いました。
ちなみに私は老眼は大丈夫そうでしたが、15000Hz以上の音は耳をスピーカーに近づかないと聞こえませんでした。