NefryBTでDataStoreを使ったIoTデモ成功率を高めるネットワーク設定施策のメモ

この記事は[Nefry Advent Calendar 2017](https://qiita.com/advent-calendar/2017/nefry)の8日目の記事です。

7日目の記事は、@tokutoku393 さんの「[Nefry BTでほぼノンプログラムな湿度管理したい](https://qiita.com/tokutoku393/items/d4c91a28485bf568828c)」でした。センサーの試行錯誤お疲れ様です！（温湿度はわりとはまる）

ということで、NefryBTでDataStoreを使ったIoTデモ成功率を高めるネットワーク設定施策のメモです。

## IoTデモは諸刃の剣感がある

わたしはよくLTの中でIoTデモをします。

LTの中でIoTのデモをするといろいろと良いことがあり、登壇を聞いてくれている人と体験を共有できます。

効果としては絶大で、限られた時間の中で情報が圧縮して伝えられ、LTの内容により厚みが出せたり、雰囲気も盛り上がることで、LTの完成度が高まるというもの。

たとえば、こんな感じ。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">リアルタイムにも成功してホッしました！さきほど事前に撮影しておいた動画で赤いCubeでIoT機器がON、青いCubeでOFFするデモです。 <a href="https://twitter.com/hashtag/HoloLens?src=hash&amp;ref_src=twsrc%5Etfw">#HoloLens</a> <a href="https://twitter.com/hashtag/WinMR?src=hash&amp;ref_src=twsrc%5Etfw">#WinMR</a> <a href="https://twitter.com/hashtag/xRLT?src=hash&amp;ref_src=twsrc%5Etfw">#xRLT</a> <a href="https://twitter.com/hashtag/NefryBT?src=hash&amp;ref_src=twsrc%5Etfw">#NefryBT</a> <a href="https://twitter.com/hashtag/nodered?src=hash&amp;ref_src=twsrc%5Etfw">#nodered</a> <a href="https://twitter.com/hashtag/noderedjp?src=hash&amp;ref_src=twsrc%5Etfw">#noderedjp</a> <a href="https://twitter.com/hashtag/%E6%B8%8B%E8%B0%B7?src=hash&amp;ref_src=twsrc%5Etfw">#渋谷</a> <a href="https://twitter.com/hashtag/TechPlayjp?src=hash&amp;ref_src=twsrc%5Etfw">#TechPlayjp</a> <a href="https://t.co/Uu4HhuF3uQ">pic.twitter.com/Uu4HhuF3uQ</a></p>&mdash; 1ft_seabass (@1ft_seabass) <a href="https://twitter.com/1ft_seabass/status/918805272415502336?ref_src=twsrc%5Etfw">2017年10月13日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ただ、IoTデモですが結構いろいろな要因で失敗しやすいんですよね。盛り上がる効果は高いが、失敗するとキツい、下手をするとLTの流れが壊れてしまう諸刃の剣。それが、IoTデモ。

自分の登壇は自分で何とかするしかないですが、登壇イベントで他の方のトラブルを遭遇すると、胃がキューッとなりますし、もう、頑張れー！つながれー！うごけー！と心のなかで応援してます。

私がIoTデモでヒヤッとした経験からざっと上げてみても、会場のWi-Fiがネットワークセパレーターで切られており現場での機器の設定が最終的に出来なく困ったり、電源タップをうっかり抜いてしまい起動から再開（LT開始30秒前）だったり、会場のWi-Fiが開催前は安定していたのに、参加者が増えると不安定になってデモがうまくいかない、とかとか要因は様々あります。

## 結構効果が高い対策：自前ネットワークを持つ

ともあれ、経験から対策もしておりまして、対応した施策の中で結構効果が高いのは「**自前のテザリング or モバイルルーターを使うことでネットワーク周りの成功率を高める**」というものがあります。環境に影響が少なくトラブルに対応しやすい自前ネットワークを持つということですね。

![nefrybt-datastore-qiita_01.png](https://qiita-image-store.s3.amazonaws.com/0/56170/b043a9c2-c9a4-ae63-0905-4039c31c2b5c.png)


NefryBTでは複数のWi-Fi設定できるので、このように通常は家のW-Fiで対応を行い、現場ではテザリングのWi-Fiにつながるという風にすればネットワーク周りの不安はかなり減った形で対応ができます！

## しかし、これでも失敗する泣き所がある・・・ネットワーク違い

![nefrybt-datastore-qiita_02.png](https://qiita-image-store.s3.amazonaws.com/0/56170/6a5e0650-8180-b515-80db-ea573af1e878.png)

しかし、これでも失敗する泣き所があるんです。

テザリングを使うときに家でテストするときとネットワークが変わるので、データの送り先とかを再設定しないといけないんですね。

私の場合は、最近のトレンドは、ノートPCやRaspberry PiにMQTTブローカーを入れて、それを軸に連携するわけですが、その軸となるMQTTブローカーが、家で接続した場合だと192.168.8.XXXだったり、テザリングで接続した場合だと192.168.50.XXXだったりと変わってしまうんです。せっかく繋がってもDHCPでカジュアルにズレるケースもあるので油断なりません。このあたり。

たとえば、最近の制作で言うと、ATL SHOWCASEの<a href="https://atl-hiroo.recruit-tech.co.jp/showcase/archives/742" target="_blank">HoloTakibi</a>なのでこの手法を使っています。
もし詳しい実装が気になる方は、<a href="https://www.1ft-seabass.jp/memo/2017/10/10/nefrybt-mqtt-tape-led/" target="_blank">Node-RED MQTTブローカー経由でNefryBT＋フルカラーテープLEDを動かすメモ</a>もよろしければご覧ください。

遭遇したケースとしてはこんな感じです。

![nefrybt-datastore-qiita_03.png](https://qiita-image-store.s3.amazonaws.com/0/56170/219cb7a2-7010-bdf0-89b2-ecd57cd76e0a.png)

家のネットワークでテストしていたときに「よっしゃできたぞ！」ということで、現場に持っていってバタバタして、テザリング起動してLT臨んだら動かなかったという悲しい事象が待っている。こわいですね。

もちろん、時間に余裕がある時は、Arduino IDEからNefry BTに書き出し直せばいいんですが、バタバタしているときが危ない。**そして、LTのときはだいたいバタバタしている。**

## 成功率を高めるネットワーク設定施策とは

ということで、お待たせしました。このデータの送り先といった設定をなんとか手軽に変更したい。そうすれば、より成功率が高まる！

そこで使うのがNefryBTのDataStoreです。

![nefrybt-datastore-qiita_04.png](https://qiita-image-store.s3.amazonaws.com/0/56170/5daf0ade-be99-27e7-4fb6-2242dad86627.png)

Nefryの設定画面にアクセスすると出てくる機能で、ソースコード上で設定した項目が、こちらの管理画面で設定できるものです。使い方は<a href="https://nefry.studio/NefryLibrary/Module%E9%96%A2%E9%80%A3%E9%96%A2%E6%95%B0/" target="_blank">Module関連関数 - Nefry</a>に詳しく書いてありました。

## というわけで書いてみる

今回はテストということで、MQTT接続をしたNefryBTのボタンを押すとメッセージが飛ぶ仕組みです。

MQTTとNefryBTの連携周りはこちらを参考下さい。

<a href="https://www.1ft-seabass.jp/memo/2017/10/10/nefrybt-mqtt-tape-led/" target="_blank">Node-RED MQTTブローカー経由でNefryBT＋フルカラーテープLEDを動かすメモ – 1ft-seabass.jp.MEMO</a>

まず、MQTT接続をDataStoreから設定できるソース例は以下のとおりです。

```c
#include <Nefry.h>
#include <WiFiClient.h>
#include <PubSubClient.h>

IPAddress endpoint;
const int port = 1883;

String deviceNameStr,pubTopicStr,subTopicStr,ip1_str,ip2_str,ip3_str,ip4_str;
const char *pubTopic;
const char *subTopic;
const char *deviceName;
int ip1,ip2,ip3,ip4;

WiFiClient httpsClient;
PubSubClient mqttClient(httpsClient);
 
void setup() {

  //// NefryBT設定画面まわり ////////////////////////////////////////
  
  // NefryBTから値入力の場所を取得する
  Nefry.setStoreTitle("IP1",0);  // IP 右から1桁目
  Nefry.setStoreTitle("IP2",1);  // IP 右から2桁目
  Nefry.setStoreTitle("IP3",2);  // IP 右から3桁目
  Nefry.setStoreTitle("IP4",3);  // IP 右から4桁目
  Nefry.setStoreTitle("pubTopic",4);
  Nefry.setStoreTitle("subTopic",5);
  Nefry.setStoreTitle("deviceName",6);
  // IPアドレス：変換前に変数に入れておく
  ip1_str = Nefry.getStoreStr(0);
  ip2_str = Nefry.getStoreStr(1);
  ip3_str = Nefry.getStoreStr(2);
  ip4_str = Nefry.getStoreStr(3);
  // IPアドレス：IPを数字に変換
  ip1 = ip1_str.toInt();
  ip2 = ip2_str.toInt();
  ip3 = ip3_str.toInt();
  ip4 = ip4_str.toInt();
  // NefryBT入力画面
  pubTopicStr = Nefry.getStoreStr(4);
  subTopicStr = Nefry.getStoreStr(5);
  deviceNameStr = Nefry.getStoreStr(6);
  pubTopic = pubTopicStr.c_str();
  subTopic = subTopicStr.c_str();
  deviceName = deviceNameStr.c_str();
  // IPAddress型に収納。配列っぽく入れる。
  endpoint[0] = ip1;
  endpoint[1] = ip2;
  endpoint[2] = ip3;
  endpoint[3] = ip4;

  //// 以下通常処理 ////////////////////////////////////////
  
  Serial.begin(115200);
  
  mqttClient.setServer(endpoint, port);
  mqttClient.setCallback(mqttCallback);

  Nefry.enableSW(); // SW有効化
  
  connectMQTT();
}
 
void connectMQTT() {
    Serial.println("connectMQTT");
    Serial.println(deviceName);
    while (!mqttClient.connected()) {
      Serial.print(".");
        if (mqttClient.connect(deviceName)) {
            Serial.println("Connected.");
            int qos = 0;
            mqttClient.subscribe(subTopic, qos);
            Serial.println("Subscribed.");
        } else {
            Serial.print("Failed. Error state=");
            Serial.print(mqttClient.state());
            // Wait 5 seconds before retrying
            delay(5000);
        }
    }
}
 
void mqttCallback (char* topic, byte* payload, unsigned int length) {
    String str = "";
    Serial.print("Received. topic=");
    Serial.println(topic);
    for (int i = 0; i < length; i++) {
        Serial.print((char)payload[i]);
        str += (char)payload[i];
    }
    Serial.print("\n");
    
    Nefry.ndelay(1000);
}
 
void mqttLoop() {
    if (!mqttClient.connected()) {
        connectMQTT();
    }
    mqttClient.loop();
}

int sensorValueCurrent;
 
void loop() {
  mqttLoop();
  
  if (Nefry.readSW()) {
    // ボタンを押したときにメッセージを飛ばす
    Serial.println("sensor ON");
    mqttClient.publish(pubTopic, "{\"flag\":1}");
  }
  
  Nefry.ndelay(50);
}
```

### MQTT接続部分を担う部分

MQTT接続部分を担うのは、

```c
  // IPAddress型に収納。配列っぽく入れる。
  endpoint[0] = ip1;
  endpoint[1] = ip2;
  endpoint[2] = ip3;
  endpoint[3] = ip4;
```

と、

```c
  mqttClient.setServer(endpoint, port);
```

ここで、ハードコードしてしまうと、前述した「時間に余裕がある時は、Arduino IDEからNefry BTに書き出し直せばいいけど、よく忘れるよね」状態になりますね。

そちらを、NefryBTのDataStoreから入力された値を反映することで

```
  // NefryBTから値入力の場所を取得する
  Nefry.setStoreTitle("IP1",0);  // IP 右から1桁目
  Nefry.setStoreTitle("IP2",1);  // IP 右から2桁目
  Nefry.setStoreTitle("IP3",2);  // IP 右から3桁目
  Nefry.setStoreTitle("IP4",3);  // IP 右から4桁目
  Nefry.setStoreTitle("pubTopic",4);
  Nefry.setStoreTitle("subTopic",5);
  Nefry.setStoreTitle("deviceName",6);
```

MQTT接続の接続先が設定画面から変えられるようになっています。

こちらを書き込んでみます。

![nefrybt-datastore-qiita_05.jpg](https://qiita-image-store.s3.amazonaws.com/0/56170/782b296f-f62a-ab46-2c74-dc2673fec650.jpeg)


## これで表示してみる

試してみましょう！管理画面に入ってDataStoreをクリックして表示します。

![nefrybt-datastore-qiita_06.png](https://qiita-image-store.s3.amazonaws.com/0/56170/3b1cbde7-86d7-d070-92eb-6d1c5fb9e01a.png)

DataStoreを表示するとこうなります！

![nefrybt-datastore-qiita_07.png](https://qiita-image-store.s3.amazonaws.com/0/56170/4ae91bd5-2580-9bad-8c20-a68b762a63a3.png)

IP1～4でIPを設定できて、その他にも、MQTTに関するトピック名や、名前がかぶると、MQTTブローカー自体が混乱し大惨事になりやすいdeviceName（MQTTのClientID）についても設定できるようになります。

## まとめ

ということで、NefryBTでDataStoreを使ったIoTデモ成功率を高めるネットワーク設定施策のメモをお伝えしました。

実際、こちらの仕組みをかれこれ3ヶ月くらい使っています。

![nefrybt-datastore-qiita_08.png](https://qiita-image-store.s3.amazonaws.com/0/56170/37f7f88d-e1f8-a293-1f9f-96ce46df02d7.png)

まず、設定が手軽になることによってLT前の準備の煩雑さから開放され、スムーズに現場用の挙動を作り出すことが出来ました。

そうすることによって、登壇自体にも心の余裕が出来ます。さらに、LT直前にDataStoreページを見れば「うん、ちゃんと設定してるね、やるぞ！」と確認することもできていいことづくし。

そして、その積み上がった安心感が、タイトルにある「成功率を高める」ことにつながっています。

（とはいえ、これで油断していると、ほんとすごい「動かない！」に遭遇するので日々がんばりますw）

みなさんも、ご自分の作られた仕組みで、設定を気軽に変えたいものがあれば、DataStore検討してみて下さい。便利ですよー。

## 明日は

明日は、<a href="http://tech.innovator.jp.net/entry/commit2016" target="_blank">結果にコミットするベルト</a>など、数々の面白いIoTを作られる @yamacho1111 さんの「ニンテンドースイッチが買えた話」です！楽しみです！