ﾀﾞｧ ｼｴﾘｲｪｽなクリスマス

<img border="0" src="https://qiita-image-store.s3.amazonaws.com/0/212109/e8080903-9a48-bd9b-91a1-cdada120517b.jpeg" width="480">


こんにちは、[ポキオ](https://pokiiio.github.io/)です。
[Nefry Advent Calendar 2017](https://qiita.com/advent-calendar/2017/nefry)の10日目を担当します。



昨日のyamacho1111さんの記事、実益を兼ねた非常に興味深いIoTでした。GASを使って簡単にクローリングするのもスマートでした！[私のブログでもGASを扱ってきましたが、](http://relativelayout.hatenablog.com/search?q=gas)IoTとの親和性が非常に高いのおすすめです。



## 今年のAdvent Calendarネタの総まとめ


今思えば、随分前から京急ガジェットに情熱を注いできました。

 - [ESP8266を使って京急の運行状況を監視するガジェットを作った](http://relativelayout.hatenablog.com/entry/2016/08/26/125650)
 - [ESP8266を使った京急の運行状況を監視するガジェットを進化させた](http://relativelayout.hatenablog.com/entry/2017/03/25/003251)

そして、今年のAdvent Calendarでは今まで書いてきたコードをライブラリ化した話をメインにやってきました。


 - [ﾀﾞｧ ｼｴﾘｲｪｽなライブラリをつかって、みんなでﾀﾞｧしたい。](https://qiita.com/pokiiio/items/2b1ac1de32efe7a444a3)
 - [Nefry BTでエモいLチカをする
](https://qiita.com/pokiiio/items/f78f19bb6ced85cc2fe5)


これらの集大成として、**Nefry BT + EmotionalBlink + ESP32Keikyuで、京急の運行状況をさり気なく教えてくれるクリスマスツリーを作ります！**


## 用意するもの

### Nefry BT

<img border="0" src="https://qiita-image-store.s3.amazonaws.com/0/212109/ed6bc33e-b4d0-39d3-68de-76b2fb0f6295.jpeg" width="480">

秋葉原のツクモさんで売ってたラスイチのNefry BT。今回は、Nefry BTのディスプレイやBT機能を一切使わないので、Nefry BTのバージョンを`1.0.0`にロールバックして使っています。

### LEDテープ

<img border="0" src="https://qiita-image-store.s3.amazonaws.com/0/212109/863733ae-dfeb-dc5a-d2ff-3a3cc0f6c917.jpeg" width="480">

Amazonで売ってた899円のLEDテープ（1mで30個のLEDがついてるやつ）。Amazon Prime対応で、気づいたら注文ボタン押してた。

### 輝きが足りないクリスマスツリー

3COINS（300円均一のショップ）で買った安いやつ。娘（2才）はサンタさんとクリスマスツリーの区別がつかないため、非常に厄介。クリスマスツリーを買っただけなのに「サンタさんが来た！」とはしゃいでいた。

### EmotionalBlink

> [EmotinalBlink<br>https://github.com/pokiiio/EmotionalBlink](https://github.com/pokiiio/EmotionalBlink)

Adafruit NeoPixelなLEDやLEDテープをいい感じに光らせてくれるライブラリ。[以前ブログでこのライブラリを紹介したところ](http://relativelayout.hatenablog.com/entry/2017/11/29/005749)、**「誰得だよ」**っていう至極真っ当な意見を頂きましたが、イルミネーションを光らせてナンボな師走に於いては、このライブラリが火を噴きます。

### ESP32Keikyu

> [ESP32Keikyu<br>https://github.com/pokiiio/ESP32Keikyu](https://github.com/pokiiio/ESP32Keikyu)

**GitHubで京急の運行状況を扱ったライブラリを作っているのは僕だけです！（2017/12/08時点、自分調べ）**皆さんにも、気軽に京急の運行状況を知ってほしい、そう思って作ったライブラリです。[ESP32用](https://github.com/pokiiio/ESP32Keikyu)と[ESP8266用](https://github.com/pokiiio/ESP8266Keikyu)を用意していますので、皆さんも是非使って下さい。



## 作る


### ハードウェアな部分


まず、LEDテープの配線。


<img border="0" src="https://qiita-image-store.s3.amazonaws.com/0/212109/192004e5-e7ec-8656-300c-89d7673dbc50.jpeg" width="480">


と言っても、LEDテープには`5V`、`GND`、`DI(信号端子)`だけしか無く、LEDはすべて数珠つなぎにつながってます。それらの端子を、Nefry BTの`3.3V`、`GND`、`D2`につなぎます。~~5Vに繋いでないけど、動いてるから良いや（遠い目）~~

配線はこれだけ。


### ソフトウェアな部分


Nefry BTでやるのは、


> ①Wi-Fi接続 ⇒ ②LED初期化 ⇒ ③京急運行状況確認 ⇒ ④それに応じて光らせる ⇒ ③ ⇒ ④ ⇒ ・・・


こんな感じ。①はNefry BTに予め設定済みのアクセスポイントに接続されるので、コード上の処理は不要。


②は[Adafruit NeoPixelのリファレンス](https://github.com/adafruit/Adafruit_NeoPixel)通りに宣言。先程、信号端子を`D2`に挿したので、コード上で以下のように宣言しておく。

```c
#define PIN D2 // マイコン内蔵RGB LEDの信号線を繋いだピン番号：D2ピン
#define NUMLED 30 // マイコン内蔵RGB LEDの個数：今回は30個

// NeoPixel（LED）の宣言
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMLED, PIN, NEO_GRB + NEO_KHZ800);
```



③は[ESP32Keikyu](https://github.com/pokiiio/ESP32Keikyu)を使って取得します。

```c
int keikyuStatus = Keikyu.getStatus();
```


この関数を呼ぶだけ。ステータスの詳細は以下のようになってます。



```c
#define KEIKYU_STATUS_UNKNOWN 0           // 京急の運行情報が取得できません
#define KEIKYU_STATUS_NORMAL 1            // 京急は平常通り運転してます
#define KEIKYU_STATUS_DELAYED 2           // 遅れています
#define KEIKYU_STATUS_TERRIBLE 3          // ダイヤが乱れています
#define KEIKYU_STATUS_STOPPED 4           // 運転を見合わせています
#define KEIKYU_STATUS_DELAYED_DUE_TO_JR 5 // JRからの振替輸送受託のため遅れています
```


④は[EmotinalBlink](https://github.com/pokiiio/EmotionalBlink)で光らせます。通常はクリスマスっぽい光らせ方をしたいので、


```c
Blink.likeHolidaySeason(&pixels, NUMLED, INTERVAL_SEC * 1000);
```


`Blink.likeHolidaySeason()`で聖なる夜を演出します。が、京急が遅れているときは、じんわり点滅させます。


```c
Blink.softly(&pixels, NUMLED, r, g, b);
```

この`r, g, b`を運行状況によって変化させることで、京急の運行状況を知らせます。こんな感じでコーディングしていきます！（サンプルコードを最後に載せておきますので御覧ください）


## Let's blink!!


先程のLEDテープをクリスマスツリーに巻きつけます。


<img border="0" src="https://qiita-image-store.s3.amazonaws.com/0/212109/3e2d948d-98b2-9780-3abe-16cd2153da99.jpeg" width="480">


さぁ、Nefry BTを電源に繋いで光らせます。


### 京急が平常運転のとき

ふつーのクリスマスツリーっぽい光り方。綺麗ですね。

![1.gif](https://qiita-image-store.s3.amazonaws.com/0/212109/4334340d-3b31-187c-1ec1-618bdda67222.gif)


### 京急が遅れてるとき


黄色い優しい光で、遅延を知らせます。まぁ、ちょっとくらいの遅れなら、京急は頑張ってくれます。

![2.gif](https://qiita-image-store.s3.amazonaws.com/0/212109/e2a9a5d2-60d2-bc8a-0fa6-709064a84a13.gif)


### 京急のダイヤが大幅に乱れているとき

オレンジ色の光で、ヤバさを伝えます。さすがに京急も逝っとけダイヤになり始めますが、きっと京急は動いているので問題ないです。

![3.gif](https://qiita-image-store.s3.amazonaws.com/0/212109/63845c05-18ae-6314-8b3d-8eb8e809603c.gif)


### 京急が運転見合わせをしているとき

赤い怪しげな光り方をします。運転見合わせと言いつつも、行けるところまで行っちゃうのが京急です。多分問題ないです。

![4.gif](https://qiita-image-store.s3.amazonaws.com/0/212109/fa2ad229-3eed-f652-5916-10cfc041e3e1.gif)


### JRからの振替輸送を受託して遅れているとき

パリピのようにチカチカ光ります。京急に乗り慣れてない人がたくさん乗ってくるので、普段とは異なる混み方をします。それでも京急は頑張って走ってくれるので、大丈夫です。

![5.gif](https://qiita-image-store.s3.amazonaws.com/0/212109/e0c38527-7e60-8f85-e48b-cf243e17f11d.gif)

こんな感じです。


### Tipsとか

 - 都度都度消灯(`Blink.dismiss(&pixels, NUMLED);`)をすると、綺麗に光ります。
 - わりと大電流が流れてそうなので、強力なモバイルバッテリーが必要。
 - オレンジ色は黄色と見分けがつかないので、ちょっと微妙なんですよね・・・。実際の光り方を見ながらRGBをチューニングする必要がありそう・・・。



## そんなこんなで


<img border="0" src="https://qiita-image-store.s3.amazonaws.com/0/212109/d514dee3-415e-3e87-0751-d62eab8163c1.jpeg" width="480">


京急の運行状況とクリスマスツリーのイルミネーションをリンクさせてみました。

いまやGoogle HomeやAmazon Echoなどに話しかければ情報を取得できる現代。逆に話しかけなくても、ボタン操作をしなくても、なんとなく情報を教えてくれるようなガジェットに無性に興味があります。あまりでしゃばりすぎず、でも確実に大切な情報をさり気なく伝えてくれるガジェットを今後も作っていきたいです。



明日はminwinminさんです！NefryBTはIoTを始めるにはもってこいのボード、どんなIoTの記事なのか楽しみです！



## Appendix

サンプルコードを貼っておきます。


```c
#include <Adafruit_NeoPixel.h>
#include <EmotionalBlink.h>
#include <ESP32Keikyu.h>

#define INTERVAL_SEC 1 * 60 // 運行情報を確認する間隔：1分
#define PIN D2 // マイコン内蔵RGB LEDの信号線を繋いだピン番号：D2ピン
#define NUMLED 30 // マイコン内蔵RGB LEDの個数：今回は30個

// NeoPixel（LED）の宣言
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMLED, PIN, NEO_GRB + NEO_KHZ800);

// 京急の運行情報を保持しておく変数
int keikyuStatus = KEIKYU_STATUS_UNKNOWN;

void setup() {
  // Serialの初期化
  Serial.begin(115200);
  Serial.println("");

  pixels.begin();
}

void loop() {
  // 一旦消灯
  Blink.dismiss(&pixels, NUMLED);

  // 情報取得
  keikyuStatus = Keikyu.getStatus();

  // ステータス表示
  Serial.println(String(keikyuStatus));

  // 運行情報に基いてLEDを光らせる
  blinkLed();
}

void blinkLed() {
  int r, g, b;

  // 一旦消灯
  Blink.dismiss(&pixels, NUMLED);

  switch (keikyuStatus) {
    case KEIKYU_STATUS_UNKNOWN:
      // 情報取得エラー時は１回だけ白く点灯
      Blink.softly(&pixels, NUMLED, 255, 255, 255);
      return;
    case KEIKYU_STATUS_NORMAL:
      // 通常時はホリデーシーズン点灯
      Blink.likeHolidaySeason(&pixels, NUMLED, INTERVAL_SEC * 1000);
      return;
    case KEIKYU_STATUS_DELAYED_DUE_TO_JR:
      // 振替輸送受託が理由で遅延している場合は、パリピ点滅
      Blink.likePartyPeople(&pixels, NUMLED, INTERVAL_SEC * 1000);
      return;
    case KEIKYU_STATUS_DELAYED:
      // 多少の遅れは黄色く光らせる
      r = 255;
      g = 255;
      b = 0;
      break;
    case KEIKYU_STATUS_TERRIBLE:
      // 大幅なダイヤ乱れはオレンジ色に光らせる
      r = 255;
      g = 128;
      b = 0;
      break;
    case KEIKYU_STATUS_STOPPED:
      // 運転見合わせ時は赤い点滅
      r = 255;
      g = 0;
      b = 0;
      break;
  }

  for (int i = 0; i < INTERVAL_SEC; i++) {
    Blink.softly(&pixels, NUMLED, r, g, b);
  }
}
```