夜集中して、寝ないで頑張れる環境をつくり、疲れたらLINEで癒しの曲を！

## Obniz X LINE Botで勉強を頑張れる「環境づくり」にチャレンジ！
最近仕事が特に忙しく、**プログラミングスクールとの両立に苦労していました**。辛酸をなめる状況が続き、まとまった時間を捻出するのが難しい環境だからこそ、**よなよな勉強を頑張れる環境を整えたい。**



特に、**仕事後の夜の勉強時間を増やし、質も向上させたい**。そのために今回は、**IoTの力**を利用して、**３つの課題解決**に取り組んでみました。

##### ①　妻が部屋に入ってきて話し込んでしまう　→　集中モードの時は赤いLEDを点灯させる
##### ②　眠くなってくると、寝てしまう　→　ベッドに寝ようとするとき、警報を鳴らす
##### ③　休憩すると、長くなってしまう　→　疲れたよ！と送ると、自動的に癒しの音楽が流れ、その間だけ休憩する

**今回のイメージ動画をご覧ください。**

https://twitter.com/NORI30363592/status/1514439276674441219





## 課題①　妻が入ってきて、話し込んでじゃうので集中モードの時間を見える化したい
その日の出来事など妻と色々話すのはかけがえのない時間です。一方で勉強に集中するには、心を鬼にして**時間を決めて集中することも必要**です。時には、ついつい一緒になって、はいワイン一杯、二杯、、なんてこともあるから！妻にも協力いただき、集中モードをLEDライトの色で知らせ、赤が点灯している時は、入室を控えてもらうことにしました。

### 集中モード！の時は、部屋の入口の壁に赤いLED照明を点灯する
#### 集中する時間だから入室しないでね　→　LEDを赤く点灯

![red LED.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554652/b88ef938-d361-21df-5407-cd314a994cc6.jpeg)

#### 集中モード終わって、入室OK の時　→　LEDを青く点灯　
![Blue LED.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554652/06e89956-8afa-73df-d109-27e819973ea3.jpeg)

### 今日から使おう！と妻にも気に入ってもらえた
**集中したいとき時が一目瞭然**で、**話しかけるタイミングを見計らうことができて助かる**と意外にも好評。忙しい時には、話をしててもうわの空のことが多いみたいだし（反省）、お互い気持ちよく話せるようになり、夫婦円満につながるといいですね！


## 課題②　眠いけど、寝てしまうのを阻止する
ちょっと５分が致命的に！勉強の合間に、ちょっとだけ休憩とベッドに横になると、**気づいたら朝だった**という経験ありませんか？私はこれ結構やってしまうんです。朝起きて時計をみて、**しまった！うぅー**となるわけです。。。これを解決するために、今回作ったのが**アイマスクをとろうとした時に鳴る警報**です。
（アイマスクとる時じゃなくて、そのままベッドに設置したらよいのではと思われているいるかもしれません。。私も正直同じことを考え実装しようとしたところ、センサが過敏に反応して警報が鳴りやまなくなってしまい、軌道修正した経緯があります　涙）

冒頭の動画は切り抜きのみだったので、youtubeにアップした動画をご紹介します。
(私の変な声が入ってますが、、ご容赦ください）

https://www.youtube.com/watch?v=nFLMq-dY7Dg

### 警報がうるさいので、ベッドに横になるのをあきらめる
Obnizに取り付けたスピーカー結構大きい音がなるんですよ。
さすがに、警報うるさい！となり、効果てきめんですね。そうなると、癒しの音楽が聴きたーい！となるわけです。ということで課題➂の解決に進みたいと思います！


## 課題➂　休憩すると、長くなってしまうのを解決する

休憩する時は、好きな音楽をかけたい。そして休憩時間を管理して、おもいっきりリラックスしたい！そんな私の願いを叶えてくれるのが、**エリククラプトン**の「**Wonderful Tonight**」が流れる癒しの**LINE Bot**です。余談ですが、この曲は結婚式で妻と連弾した思い出の一曲で、当時始めたばかりのギターを、めちゃめちゃ緊張して演奏したのを思い出します。

### Step 1: ピアノで音にしたい曲を演奏して、ドレミでノートに記録する
↓　下手くそな演奏で恐縮ですが、、まずピアノを弾いて、ドレミをひろっていきました。


https://twitter.com/NORI30363592/status/1514450701602070528


### Step 2: 早見表を使い音階のヘルツに変換していき、LINE Botを制作する

https://twitter.com/NORI30363592/status/1514195524177457153

[音階の周波数の早見表](https://tomari.org/main/java/oto.html)










## 事前準備と実装方法
### Obnizの設定を行う
今回の3つの課題解決ものづくりには、全て**ObnizのIoT技術**を活用しました。設定方法はこちらをご参照ください。**初めてのIoT体験**ですが、このObniz１Yの設定がその第一歩となりました。

[Obnizの設定方法](https://zenn.dev/protoout/articles/49-obniz-wifi-setup)

### 実行環境
実行環境
VScode (v1.65.2)
node.js(v17.6.0)
npm(v8.5.1)


### コード

##### LED照明
点灯させたい色のLEDを設置し、どちらか1つを実行します。
（色を変えたいときは、もう一方のコードを実行します）

<details><summary>LEDライト(赤色）点灯用</summary><div>

```js
const Obniz = require('obniz');
const obniz = new Obniz('XXXXXXXX'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // 超音波測距センサを利用する
    const hcsr04 = obniz.wired('HC-SR04', { gnd: 0, echo: 1, trigger: 2, vcc: 3 });
    // RGB LEDを利用
    const rgbled = obniz.wired('WS2811', { gnd: 6, vcc: 7, din: 8 });

    // setIntervalで一定間隔で処理
    setInterval(async function () {
        // 距離を取得
        let distance = await hcsr04.measureWait();
        // そのままだと小数点以下の桁数がやたら多いので整数に丸めてもよい
        //distance = Math.floor(distance);

        // 距離が5cm以上かどうかの判定
        if (distance > 50) { // 50mm = 5cm 以上の場合
            ///光る
            rgbled.rgb(255, 0, 0);
            
            }else {
                rgbled.rgb(0, 0, 0);
              }


    }, 1000); // 1000ミリ秒 = 1秒おきに実行
}
```

</div></details>

<details><summary>LEDライト(青色）点灯用</summary><div>

```js
const Obniz = require('obniz');
const obniz = new Obniz('XXXXXXXX'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // 超音波測距センサを利用する
    const hcsr04 = obniz.wired('HC-SR04', { gnd: 0, echo: 1, trigger: 2, vcc: 3 });
    // RGB LEDを利用
    const rgbled = obniz.wired('WS2811', { gnd: 6, vcc: 7, din: 8 });

    // setIntervalで一定間隔で処理
    setInterval(async function () {
        // 距離を取得
        let distance = await hcsr04.measureWait();
        // そのままだと小数点以下の桁数がやたら多いので整数に丸めてもよい
        //distance = Math.floor(distance);

        // 距離が5cm以上かどうかの判定
        if (distance > 50) { // 50mm = 5cm 以上の場合
            ///光る
            rgbled.rgb(255, 0, 0);
            
            }else {
                rgbled.rgb(0, 0, 0);
              }


    }, 1000); // 1000ミリ秒 = 1秒おきに実行
}
```
</div></details>


##### 寝かせないブー（警報）

<details><summary>寝かせないブー</summary><div>

```js
const Obniz = require('obniz');
const obniz = new Obniz('XXXXXXXX'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
    // 超音波測距センサを利用する
    const hcsr04 = obniz.wired('HC-SR04', { gnd: 0, echo: 1, trigger: 2, vcc: 3 });
    // RGB LEDを利用
    const rgbled = obniz.wired('WS2811', { gnd: 6, vcc: 7, din: 8 });
    // スピーカーを利用
    const speaker = obniz.wired('Speaker', { signal: 10, gnd: 11 });

    // setIntervalで一定間隔で処理
    setInterval(async function () {
        // 距離を取得
        let distance = await hcsr04.measureWait();
        // そのままだと小数点以下の桁数がやたら多いので整数に丸めてもよい
        //distance = Math.floor(distance);

        // 距離が5cm以上かどうかの判定
        if (distance > 50) { // 50mm = 5cm 以上の場合
            ///光る
            rgbled.rgb(255, 0, 0);
            // 528Hz で音を鳴らす
            speaker.play(528);
            }else {
                rgbled.rgb(0, 0, 0);
                speaker.stop();
              }


    }, 1000); // 1000ミリ秒 = 1秒おきに実行
}
```
</div></details>

#### LINE Botで癒しの曲

<details><summary>LINE Botで癒しの曲を流す</summary><div>

```js
'use strict';

// obniz呼び出し
const Obniz = require('obniz');
const obniz = new Obniz('XXXXXXXX');  // Obniz_ID に自分のIDを入れます

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

const config = {
    channelAccessToken: 'XXXXXXXXX',
    channelSecret: 'XXXXXXXXXXXX'
};

const app = express();

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

// obniz接続
obniz.onconnect = async function () {
  obniz.display.clear();
  obniz.display.print("obniz meets LINE Bot!");
}

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

  let mes = ''
  if(event.message.text === '疲れたよ！'){
    mes = '癒しの音楽送るよ♪'; //待ってねってメッセージだけ先に処理
    getAskObnizSpeaker(event.source.userId); //スクレイピング処理が終わったらプッシュメッセージ
  }else{
    mes = event.message.text;
  }

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

const getAskObnizSpeaker = async (userId) => {
 // スピーカーを呼び出す
 const speaker = obniz.wired("Speaker", {signal:0, gnd:1});
 console.log("Speaker")
 await client.pushMessage(userId, {
  type: 'text',
  text: "頑張っているあなたが好き❤　だから寝ないで💜",
});

 // 音階とhzの参考サイト https://tomari.org/main/java/oto.html
 await speaker.play(1174.659); // D6 レ
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1479.978); // F#6 ファ#
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1760.000); // A6 ラ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1975.533); // B6 シ
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1760.000); // A6 ラ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1479.978); // F#6 ファ#
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1174.659); // D6 レ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1108.731); // C#6 ド#
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1318.510); // E6 ミ
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1760.000); // A6 ラ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1975.533); // B6 シ
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1760.000); // A6 ラ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1318.510); // E6 ミ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1108.731); // C#6 ド#
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(200);
 await speaker.play(987.767); // B5 シ
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1174.659); // D6 レ
 await obniz.wait(200);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1567.982); // G6 ソ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1975.533); // B6 シ
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1567.982); // G6 ソ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1174.659); // D6 レ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(987.767); // B5 シ
 await obniz.wait(250);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1760.000); // A6 ラ
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(1975.533); // B6 シ
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(2217.461); // C#7 ド#
 await obniz.wait(600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(2637.020); // E7 ミ
 await obniz.wait(700);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(2637.020); // E7 ミ
 await obniz.wait(50);
 await speaker.stop();
 await obniz.wait(20);
 await speaker.play(2349.318); // D8 レ
 await obniz.wait(800);
 
 speaker.stop();
}
```
</div></details>


### 参考記事
これらの**先輩方の記事があったから**こそ、今回実装することができました！**ありがとうございました!**。

https://qiita.com/naokiuc/items/7aecf478e8893d41f16f
https://qiita.com/dsvvpxgcseldie/items/c72c822946221849e790
https://qiita.com/Naru0607/items/b523cf9f67fa18bcf7d7


## 今後チャレンジしたいこと

### Alexaに話しかければ、LEDライトを遠隔で赤く点灯できるようにしたい
LEDを赤く点灯させる時に、Node.jsで毎回実行するのではなく、Amazonエコーを使いはなしかけることで全自動にしたい！

下のObnizの説明ブログも参考にさせていただき、IFTTTとの連携も行い、あと少しのところまできたと思うのですが、断念しました。結構頑張ったのに、今回は残念。これが出来ると更に便利になりそうなので、またチャレンジしたいです。

ご参考までに、設定方法のページ等お伝えします。

●Obniz公式（参考にしたサイト）
https://obniz.com/ja/products/obnizboard#areapdctSpec

●**Obnizの説明ブログ→設定の仕方が詳しくでています**
（Youtube動画でサービスの内容もご確認いただけます）
https://blog.obniz.com/make/obniz-alexa-ifttt

●Obnizサンプルコード（Alexaとの連携についても知った）
https://obniz.com/ja/doc/sample-codes

●IFTTTとの連携用
https://ifttt.com/onboarding


### 最後に

**最後までお読みいただき、ありがとうございました！**

今回は、IoTでobnizに触れることは、とても**楽しかったです**。ものづくりの幅が広がるなーと実感しました。**また何か作ってみたいです！**