あなたの腰は死なないわ。Obniz が守るもの。　-  IoT × Bot で座りすぎを防止せよ！ - 

# はじめに
皆様、昨今の情勢でいかがお過ごしでしょうか？
私は5月の初旬に**腰椎椎間板ヘルニアになり、1週間入院してしまいした。**
新人研修、GW を経て3営業日のこれからというタイミングでした。

ヘルニアの経緯は別途 note などにまとめるとして一度置いておき、
とりあえずまずは今後の健康のことを考えようと思いました。

そこで、在宅により顕著に明らかになった健康の敵である**「座りすぎ」**、こいつを防止するためにITを活用してみようと思いました。まあ、**高級なめっちゃいい椅子を買うという**のも大いにありだとは思いますが、手軽にできる改善策として今回はObnizを使ってみました。

本文内の過去記事引用も含めると、恐らく ```Azure が初めての方でも真似できる```ようになっていると思うので、気になる方はぜひお試しください。(一カ所参考リンクがあり、そこで過去記事を2つほど引用してます。必要に応じて確認してください)

## 何を作った？
今回作ったのは**長時間座っていたら警告してくれる Teams Bot** です。

IoT を使った開発は未経験だったのと、普段業務でTeamsを使用していることから、
業務中に使用するツールをなるべくまとめようとした結果です。

具体的に使用したものは以下の通りです。

- Obniz
    - IoT device でなるべくコンパクトなものを探した結果
    - 初めてだったので[スターターキット](https://obniz.io/ja/products/starterkit)を購入した
    - 使用センサについては後ほど
- Teams
    - 上述の通り通知を受け取るツールとして使用
    - 普段業務で使用しているツールに色んな機能を集約したかったため
- Azure Bot Service
    - bot の作成に使用
    - なるべくコンパクトにささっと作りたかったので使い慣れたものを使用した
    - 今回はProActiveメッセージの機能に全振りした。

なお、センサ部分関しては改良の余地が多いと感じているので、
アドバイスなどあればぜひ教えていただきたいです！

図はたぶんこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248829/4d61bb31-926b-9446-31a3-10e146449898.png)

こんな感じで Teams に通知がきます。

# Azure Bot Service 側の準備
今回の実装で Teams 側で行う動作は基本的にはありません。TeamsはProActiveにメッセージを受け取るのがメインです。
ここら辺に関しては依然に[そこそこ詳しめにまとめた記事](https://qiita.com/MinoMinoMinoru/items/cf31dd020191c09f5c71)がありますので、ご参考いただけると嬉しいです。（Azure への Deploy などは引用記事からさらに引用があるので、必要に応じて適宜確認。）

# Obniz 側の準備
今回は node.js で実装しました。最初は Browser で html にしてたのですが、
そのために Browser のタブを使用するのが面倒だなと感じたのと、
CORSの壁を突破する必要があり、嫌気がさしてNode.js にしました（ある方の助言のお陰様です。）
それはそうとCORSは今度勉強しますね #CORS から逃げるな

## 使用したセンサ
今回使用したセンサは"HR-505"という人感センサーです。
スターターキットには別のセンサが入っていたのですが、付属のセンサでは`onSnensorChanged のメソッドにしか対応していなかった`、つまりは自分の望みのタイミングでの状態の取得が難しかったため、別のセンサを追加購入しました。

- [使用した人感センサ](https://obniz.io/ja/sdk/parts/HC-SR505/README.md)
- [付属品の人感センサ](https://obniz.io/ja/sdk/parts/Keyestudio_PIR/README.md)

なお、Obnizの対応パーツは [obniz Parts Library のページ](https://obniz.io/ja/sdk/parts/)から確認できます。対応したFunctionも確認できるので、パーツを買う際はぜひご確認の上で購入をば。

## プログラム
Obnizで実行されるプログラムです。

```humansensor.js
var Obniz = require("obniz");
var request = require('request');

var obniz = new Obniz("<YOUR OBNIZ ID>");
obniz.onconnect = async function () {
    var humansensor = obniz.wired("HC-SR505", {vcc:0, signal:1, gnd:2});

    // 連続して座っているカウント
    let count = 0;
    // 座ってないカウント
    let nocount=0;
    // どれだけ座ってたら通知するか周りの変数
    const min = 10;
    const time2stand = 60*min
    console.log(min+"min")
    while (true) {
        var human = await humansensor.getWait();
        // 座ってたらカウント
        if(human){
            count++;
            nocount=0;
        }
        // 3 min 座ってなかったらカウントリセット
        else{
            nocount++;
            if(nocount==3){
                count=0;
                nocount=0;
                console.log("Reset Count")
            }
        }
        console.log(human ? 'Moving Something!' : 'Nothing moving');
        if (count == min) {
            console.log("POST")
            count=0;
            const url = `https://standing-bot.azurewebsites.net/api/notify`;

            var body = {
                "ref": {
                    "conversation": {
                        "id": "<YOUR CONVERSTATION ID>"
                    },
                    "bot": {
                        "id": "<YOUR BOT ID>",
                        "name": "<YOUR BOT NAME>"
                    },
                    "serviceUrl": "<YOUR SERVICE URL>"
                }
            }

            var options = {
                url: url,
                method: 'POST',
                json: true,
                form:body
            }

            request(options, function (error, response, body) {
                console.log(body);
            })

        }
        console.log(`count:`+count,"nocount:"+nocount)
        // 1 min ごとにセンシング 
        await obniz.wait(1000*60);
        // 毎秒センシングする場合はこっち
        // await obniz.wait(1000);
    }

};
```

汚いですが、短かったので面倒なので1つのファイルにまとめて、特にFunctionとかも分けてません。
この`var human = await humansensor.getWait();` のFunctionが使用できたので今回はこのセンサを採用しました。これはその時の値を取得しております。

Node.js を使用したので、このプログラムを保存した後、
Obniz の電源が入り、ネットワークの繋がった状態で powershell などから以下のコマンドを入力するとプログラムが実行されます。（てっきりObnizに組み込めるのかと思ってました）

```
node .\humansensor.js
```


# 実際に動かしてみた所感
- センシングしてもらえない時がある
    - 近くにいても人感センサの値が False になる
    - センサの仕様の問題なのか個体差なのか
    - 私がまだまだ半人前としてみなされている可能性もある
- Node のプログラムが止まる時がある
    - PowerShell を確認したら少し前のリクエストが残っている時も
    - リクエストがちゃんと投げれてないのかな？
        - ネットワークの問題？
        - await せずに投げっぱなしにする？
       
リクエストさえ実行できていれば、Bot 側のプログラムは特に問題なく実行できていました。ので、これら上記の Obniz 側の改善が必要そうです。もしも良いアイデアがあれば教えてください(笑)

# 最後に
私は一週間ほど入院して、だいたい 10 万円くらい入院時のお金がかかりました。Obniz とセンサーは合計しても 1 万円も行きません。さあ、聡明な皆様でしたら、何をすべきかわかりますね？（これらを試すかはともかく、ぜひご自愛ください。）