初めてのNefryでチャラくてハデなLチカ

※この記事は [Nefry Advent Calendar 2017](https://qiita.com/advent-calendar/2017/nefry) の12月22日の記事です｡昨日21日は[BlueTone](https://qiita.com/BlueTone)さんの[NefryでJenkinsのXFD作ったり、電子工作コンテストで賞もらった話](https://qiita.com/BlueTone/items/0485d46e9a2563c4005c)でした！JenkinsとNefryが繋がるとはすごい。仕事ではJenkins使うことも有るので是非試してみたい！

こんにちは、Nefry大好き チャラ電Mitzです。

なんでNefryが大好きなのか？
それはSIerで色々と初心者な私でも気軽に楽しくIoTなモノ作りやが出来るきっかけになったのがNefryだから。
そんなわけでNefryで初めて作ったモノをご紹介します。
※超初心者な内容なのでご容赦下さい。
##まず完成したモノの紹介
![20171221_022541740.jpg](https://qiita-image-store.s3.amazonaws.com/0/189482/8919e46a-c5f3-865a-11f3-4b468fb12ab1.jpeg)

正直、ナニコレ？ですよね。
初めてのモノ作りってことで暖かく見守って下さい。

で、これが光るわけです。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">少しだけハデにLチカ<a href="https://t.co/Q8FWFpoIOm">https://t.co/Q8FWFpoIOm</a></p>&mdash; Chara電Mitz (@TECHNOmatz) <a href="https://twitter.com/TECHNOmatz/status/943543288136572928?ref_src=twsrc%5Etfw">2017年12月20日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
##概要
仕組みはこんな感じです。
![概要.jpg](https://qiita-image-store.s3.amazonaws.com/0/189482/dc8f2e10-6b9d-1989-528c-9d167bfeb9ff.jpeg)

ちなみに「Nefryクラウド」に（仮）と付いているのは今時点では正式サービスではないからとの事。
##やった事
今回やった事はこの５つ
・ツイートから特定のハッシュタグを拾ってNefryクラウド（仮）にPOST
・Slackへの通知
・LEDを光らせるパターンを作成
・Nefryクラウド（仮）からの連携とSlack通知の実装
・LEDテープで工作

この５つを説明させていただきます。
##ツイートから特定のハッシュタグを拾ってNefryクラウド（仮）にPOST
これはIFTTTで行います。
と、その前にNefryクラウド（仮）の取得が必要なのですが、こちらは[wamisnet](https://qiita.com/wamisnet)さんの[こちらの記事](https://qiita.com/wamisnet/items/38d6a5ac8332b090d0c2)を御覧ください。
また、後ほどIFTTTのWebhooksのSecret Keyを使用するのですが、それも[こちらのdotstudio.さんの記事](https://dotstud.io/blog/nefry-ifttt-push-line/)の最初の部分を参考にして事前に行っております。

上記にてNefryクラウド（仮）の取得とIFTTTのWebhooks確認作業が完了したらIFTTTの設定から。
まずはIFTTTのthisの部分。これはTwitterのこちらを選択。
![①IFTTT_this.jpg](https://qiita-image-store.s3.amazonaws.com/0/189482/cfd54205-a58b-7626-ba5f-f865d99f0803.jpeg)
そして検索対象の文字を設定
![①IFTTT_this_2.jpg](https://qiita-image-store.s3.amazonaws.com/0/189482/35673999-a0a6-355b-dd16-70206ed28943.jpeg)
今回は「mitz」を検索ワードとしています。

次にIFTTTのthatの部分。これはWebhooksで以下のように設定
![②IFTTT_that.jpg](https://qiita-image-store.s3.amazonaws.com/0/189482/1a4dd550-fdb7-12f7-15e3-611c270ad86f.jpeg)

Bodyの部分にuser、key、dataを設定するのですが、この設定についても先程のwamisnetさんの記事に説明が記載されています。ちなみに"data":"～"には、Nefryに通知したい文字をセットします。今回は「mitz」をPostする設定にしています。
##Slackへの通知
これもIFTTTで行います。
まずはIFTTTのthisの部分。これはWebhooksで適当なイベント名称を設定。
![③IFTTT_this.jpg](https://qiita-image-store.s3.amazonaws.com/0/189482/91e48ebd-f972-b8a6-04ff-d55ce04d08c0.jpeg)
この例では「FromNefryToSlack」としています。
次にIFTTTのthatの部分ですが、これはSlack（Post to channel）を選択して、対象のTeamとPost先のチャンネルを選択して、メッセージ・タイトル等を設定します。
※各自異なる内容になりますのでサンプル写真は割愛
##LEDを光らせるパターンを作成
ここからはArduino言語での実装
※関連する箇所のみ載せます。

```C++
#include <Adafruit_NeoPixel.h>

～～中略～～

// LED関連 
#define PIN            D2              // 動かすPIN
#define NUMPIXELS      120             // LED数120個
#define MAX_VAL        100             // LEDの明るさ 0 ～ MAX_VAL
#define MIN_VAL        5               // LEDの明るさ 0 ～ MAX_VAL
#define OFF_VAL        0               // LEDの明るさOFF 0

～～中略～～

// NeoPixel設定
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int delayval_long = 20; // 点灯していく秒数(ミリ秒)
int delayval_short = 5;  // 点灯していく秒数(ミリ秒)

～～中略～～

// 点灯パターン設定
// パターン１
 String Line_a1 = "#   #          ";
 String Line_a2 = "## ## #  #     ";
 String Line_a3 = "## ## #  #     ";
 String Line_a4 = "# # #   ### ###";
 String Line_a5 = "# # # #  #    #";
 String Line_a6 = "#   # #  #   # ";
 String Line_a7 = "#   # #  #  #  ";
 String Line_a8 = "#   # #  ## ###";
 String LineAll_a[120];

void setup() {
  pixels.begin();

// LEDパターンLINEの集約
// パターン１
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_a[i] = Line_a8.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_a[i+15] = Line_a7.charAt(i);
  }
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_a[i+30] = Line_a6.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_a[i+45] = Line_a5.charAt(i);
  }
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_a[i+60] = Line_a4.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_a[i+75] = Line_a3.charAt(i);
  }
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_a[i+90] = Line_a2.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_a[i+105] = Line_a1.charAt(i);
  }

～～中略～～

// パターン１点灯
    for(int i=0;i<NUMPIXELS;i++){     
      if (LineAll_a[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(MAX_VAL,0,0));
        pixels.show();
        delay(delayval_long);
      }
    }
    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_a[i] == "#"){
        pixels.setPixelColor(i, pixels.Color(0,MAX_VAL,0));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_a[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(0,0,MAX_VAL));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_a[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(MAX_VAL,MAX_VAL,0));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_a[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(MAX_VAL,0,MAX_VAL));
        pixels.show();
        delay(delayval_long);
      }
    }
    
    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_a[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(0,MAX_VAL,MAX_VAL));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      pixels.setPixelColor(i, pixels.Color(OFF_VAL,OFF_VAL,OFF_VAL));
      pixels.show();
      delay(delayval_short);
    }
    delay(1000);
```

このコーディング、冗長で見づらくてわかりづらいですよね。。。
使用したのはこの「フルカラーシリアルLEDテープ（1m）」
![スイッチサイエンス LEDテープ.jpg](https://qiita-image-store.s3.amazonaws.com/0/189482/0d043861-cdcb-b67e-7988-96bc8567bcd3.jpeg)
これを2本繋いでいるのですが、パネル状にするために60個LED／1本を2本、つまり合計120個のLEDを15個毎に分割した8本を並べてます。
そしてその8本を1列毎にドコを光らせるかを「点灯パターン設定」の箇所で設定してます。
ここで悩みました。。。実際にLEDを点灯させるのはプログラムの「パターン１点灯」の箇所なのですが、単純に120個のLEDを頭から順に点灯させるようにしています。その為、8ラインあるLED点灯パターンを120個1ラインに集約して点灯させているのですが、これを物理的にも8本のLEDテープ全てを単純に繋いで頭から末尾に向けて光らせるようとすると、繋部分の配線が長ーくなってしまうんです。
そして悩んだ結果、上下で隣り合ったLEDテープで頭部分同士と末尾部分同士を繋ぐ事で配線を短くする。点灯パターン8ラインを1ラインに集約する際にも交互に「頭→末尾」「末尾→頭」となるようにしてみました。
分かりやすくするとこんなイメージです。
![点灯パターン.jpg](https://qiita-image-store.s3.amazonaws.com/0/189482/7b27f450-7439-7616-fc64-77a37d85b57d.jpeg)
この「頭→末尾」「末尾→頭」と交互に集約しているのがプログラム上の「LEDパターンLINEの集約」の箇所です。

そして実際に点灯させているのが「パターン１点灯」の箇所ですが、ココではLEDのRED、GREEN、BLUE毎に強弱を変えて6色のパターンを実現しています。（最後にすべて消灯させています）
##Nefryクラウド（仮）からの連携とSlack通知の実装

```C++
#include <NefryCloud.h>

～～中略～～

// NefryCloud通知設定 
NefryCloud nefryCloud;

～～中略～～

void onpush(String message);

～～中略～～

// NefryCloud連携 内容の設定
  nefryCloud.begin("user","apikey");//サイトで登録したuser,apikeyを入力してください
  nefryCloud.on(onpush);

～～中略～～

void loop() {
  nefryCloud.loop();                        //NefryCloudからの通知
}

void onpush(String message) {               //Nefryクラウド(仮)から通知が来ます
  Nefry.print("onpush : ");
  Nefry.println(message);
  if(message.equals("mitz")){               //mitzという文字列がきたときに処理をする

```

こちらの設定説明については、前述のwamisnetさんの記事をご確認ください。
##Slackへの通知

```C++
#include <NefryIFTTT.h>

～～中略～～

// IFTTTへのSlack通知設定 
String Event;
String SecretKey;

～～中略～～

// IFTTT／Slack通知の内容設定
  Nefry.setStoreTitle("Secret Key",0);           //WebhooksのSecret Keyを指定
  Nefry.setStoreTitle("FromNefryToSkack",1);     //Nefry DataStoreのタイトルを指定
  SecretKey = Nefry.getStoreStr(0);              //Nefry DataStoreからデータを取得
  Event = Nefry.getStoreStr(1);                  //Nefry DataStoreからデータを取得

～～中略～～

// IFTTT連携／Slack通知
    bool sendData = IFTTT.send(Event, SecretKey,"Nefry",(String)(micros()/10000)+"秒");
                                      //IFTTTにデータを送信
                                      //Value1:Nefry,Value2:Nefryが起動してからの秒数
    if (!sendData) {                  //IFTTTにデータを送信が成功したか失敗したかの判定
      Nefry.setLed(255, 0, 0);        //Errの時、赤色点灯
    } else {
      Nefry.setLed(0, 255, 0);        //OKの時、緑色点灯
    }
    Nefry.ndelay(1000);               //送信後1秒間待つ
    }

```

こちらでは前述のIFTTTのWebhooks箇所で設定したイベント名称「FromNefryToSkack」等を設定していますが、前述したWebhooksのSecret Key指定も必要です。繰り返しになりますが、[こちらのdotstudio.さんの記事](https://dotstud.io/blog/nefry-ifttt-push-line/)をご覧ください。

##LEDテープで工作
実際に行った工作は以下の通り。
・LEDテープ2本を15個のLED毎に切断
・切断したLEDテープをパネル状に並べて再接続（はんだ付け：15箇所×3配線＝45回）
・パネル状に並んだLEDテープをプラスチック板に貼り付け
以上です。

##最後に
以上が初めてのNefryそして初めてのIoT工作でした。
自分で新たな何かを試したわけではなく、全て諸先輩方の記事を参考にさせていただいたので、やれば誰でも出来る初心者的な内容になっています。
でもとにかく楽しかった！本当に楽しかった！
そんなわけでNefry大好きチャラ電Mitzが誕生したわけであります。

今後も引き続きNefry工作にチャレンジして、少しでも私と同じようなNefry初心者・IoT初心者の参考になるような記事を出していこうかなぁと思います。

そしてNefryアドベントカレンダー明日23日は[tikchiku](https://qiita.com/tikchiku)さんです。[部屋の電気が付いたらLINEメッセージを送ってくれる仕組み(の前編)](https://qiita.com/tikchiku/items/b3158508b5d9da148112)の後編との事！楽しみです！

##最後の最後に
今回のArduinoプログラムのコーディングは超ツッコミどころ満載だと思いますが、参考までに敢えて全てを晒しちゃいます。
わたし、そもそもArduinoプログラム自体超初心者でもありますので優しい目で見てやって下さい。

※以下プログラムはLED文字の点灯パターンは2種類で「Mitz」と「IoTLT」になっています。
　その2パターン分、Twitterから抽出のIFTTTイベント登録が必要です。
　（”mitz”を抽出してNefryクラウドに”mitz”をPost、”iotlt”を抽出してNefryクラウドに”iotlt”をPostの2イベント）

```C++
#include <Nefry.h>
#include <Adafruit_NeoPixel.h>
#include <NefryIFTTT.h>
#include <NefryCloud.h>

// LED設定 
#define PIN            D2              // 動かすPIN
#define NUMPIXELS      120             // LED数120個(60個×2)
#define MAX_VAL        100             // LEDの明るさ 0 ～ MAX_VAL
#define OFF_VAL        0               // LEDの明るさOFF 0

// NeoPixel設定
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int delayval_long = 20; // 点灯していく秒数(ミリ秒)
int delayval_short = 5;  // 点灯していく秒数(ミリ秒)

// IFTTTへのSlack通知設定 
String Event;
String SecretKey;

// NefryCloud通知設定 
NefryCloud nefryCloud;

// 点灯パターン設定
// パターン１
 String Line_a1 = "#   #          ";
 String Line_a2 = "## ## #  #     ";
 String Line_a3 = "## ## #  #     ";
 String Line_a4 = "# # #   ### ###";
 String Line_a5 = "# # # #  #    #";
 String Line_a6 = "#   # #  #   # ";
 String Line_a7 = "#   # #  #  #  ";
 String Line_a8 = "#   # #  ## ###";
 String LineAll_a[120];

// パターン２
 String Line_b1 = "#    ### #  ###";
 String Line_b2 = "#     #  #   # ";
 String Line_b3 = "#     #  #   # ";
 String Line_b4 = "#     #  #   # ";
 String Line_b5 = "# ### #  #   # ";
 String Line_b6 = "# # # #  #   # ";
 String Line_b7 = "# # # #  #   # ";
 String Line_b8 = "# ### #  ### # ";
 String LineAll_b[120];

void onpush(String message);

void setup() {
  pixels.begin();

// LEDパターンLINEの集約
// パターン１
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_a[i] = Line_a8.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_a[i+15] = Line_a7.charAt(i);
  }
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_a[i+30] = Line_a6.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_a[i+45] = Line_a5.charAt(i);
  }
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_a[i+60] = Line_a4.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_a[i+75] = Line_a3.charAt(i);
  }
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_a[i+90] = Line_a2.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_a[i+105] = Line_a1.charAt(i);
  }
// パターン２  
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_b[i] = Line_b8.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_b[i+15] = Line_b7.charAt(i);
  }
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_b[i+30] = Line_b6.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_b[i+45] = Line_b5.charAt(i);
  }
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_b[i+60] = Line_b4.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_b[i+75] = Line_b3.charAt(i);
  }
  for(int i=0,j=14;i<15;i++,j--){
    LineAll_b[i+90] = Line_b2.charAt(j);
  }
  for(int i=0;i<15;i++){
    LineAll_b[i+105] = Line_b1.charAt(i);
  }

// IFTTT／Slack通知の内容設定
  Nefry.setStoreTitle("Secret Key",0);           //WebhooksのSecret Keyを指定
  Nefry.setStoreTitle("FromNefryToSlack",1);     //Nefry DataStoreのタイトルを指定
  SecretKey = Nefry.getStoreStr(0);              //Nefry DataStoreからデータを取得
  Event = Nefry.getStoreStr(1);                  //Nefry DataStoreからデータを取得

// NefryCloud連携 内容の設定
  nefryCloud.begin("user","apikey");//サイトで登録したuser,apikeyを入力してください
  nefryCloud.on(onpush);
} 

void loop() {
  nefryCloud.loop();                        //NefryCloudからの通知
}

void onpush(String message) {               //Nefryクラウド(仮)から通知が来ます
  Nefry.print("onpush : ");
  Nefry.println(message);
  if(message.equals("mitz")){               //mitzという文字列がきたときに処理をする

// パターン１点灯
    for(int i=0;i<NUMPIXELS;i++){     
      if (LineAll_a[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(MAX_VAL,0,0));
        pixels.show();
        delay(delayval_long);
      }
    }
    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_a[i] == "#"){
        pixels.setPixelColor(i, pixels.Color(0,MAX_VAL,0));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_a[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(0,0,MAX_VAL));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_a[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(MAX_VAL,MAX_VAL,0));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_a[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(MAX_VAL,0,MAX_VAL));
        pixels.show();
        delay(delayval_long);
      }
    }
    
    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_a[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(0,MAX_VAL,MAX_VAL));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      pixels.setPixelColor(i, pixels.Color(OFF_VAL,OFF_VAL,OFF_VAL));
      pixels.show();
      delay(delayval_short);
    }
    delay(1000);

  } else {
    if(message.equals("iotlt")){       //iotltという文字列がきたときに処理をする
// パターン２点灯
    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_b[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(MAX_VAL,0,0));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_b[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(0,MAX_VAL,0));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_b[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(0,0,MAX_VAL));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_b[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(MAX_VAL,MAX_VAL,0));
        pixels.show();
        delay(delayval_long);
      }
    }
    
    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_b[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(MAX_VAL,0,MAX_VAL));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      if (LineAll_b[i] == "#") {
        pixels.setPixelColor(i, pixels.Color(0,MAX_VAL,MAX_VAL));
        pixels.show();
        delay(delayval_long);
      }
    }

    for(int i=0;i<NUMPIXELS;i++){
      pixels.setPixelColor(i, pixels.Color(OFF_VAL,OFF_VAL,OFF_VAL));
      pixels.show();
      delay(delayval_short);
    }
    delay(1000);

// IFTTT連携／Slack通知（パターン2点灯の時のみSlack通知してます。）
    bool sendData = IFTTT.send(Event, SecretKey,"Nefry",(String)(micros()/10000)+"秒");
                                      //IFTTTにデータを送信
                                      //Value1:Nefry,Value2:Nefryが起動してからの秒数
    if (!sendData) {                  //IFTTTにデータを送信が成功したか失敗したかの判定
      Nefry.setLed(255, 0, 0);        //Errの時、赤色点灯
    } else {
      Nefry.setLed(0, 255, 0);        //OKの時、緑色点灯
    }
    Nefry.ndelay(1000);               //送信後1秒間待つ
    }
  }
}

```