ﾀﾞｧ ｼｴﾘｲｪｽなライブラリをつかって、みんなでﾀﾞｧしたい。

TongChangさんからバトンを引き継ぎまして、[IoTLT Advent Calendar 2017](https://qiita.com/advent-calendar/2017/iotlt)の6日目を担当いたします、[ポキオ](https://pokiiio.github.io/)です。こんにちは。


人生初のアドベントカレンダー参加、そして人生初のQiitaへの書き込みということで、右も左もわかりませんが、生暖かい目で見守って頂けると幸いです。


<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">がじぇるね賞をいただきました！<br>ありがとうございました！<a href="https://twitter.com/hashtag/iotlt?src=hash&amp;ref_src=twsrc%5Etfw">#iotlt</a> <a href="https://t.co/8Xul5wcMpo">pic.twitter.com/8Xul5wcMpo</a></p>&mdash; ポキオ (@pokiiio) <a href="https://twitter.com/pokiiio/status/776072737127182336?ref_src=twsrc%5Etfw">September 14, 2016</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

初めてIoTLTで登壇したのが、1年以上前のvol.19（＠三菱総研）でした。その時から京急ネタで色々やらせていただいてきました。今回のアドベントカレンダーも京急ネタでやらせていただいてきます（笑）


## 京急なライブラリとは


前置きがかなり長くなりましたが、今回のネタはESP8266（Arduino）で使える「京急なライブラリ」です。


> [ESP8266Keikyu
> https://github.com/pokiiio/ESP8266Keikyu](https://github.com/pokiiio/ESP8266Keikyu)


このライブラリを使うと、**京急の運行状況が簡単に確認できる**という神がかったものに仕上がっています。「なかなかIoTはハードルが高い」「わたしも京急がすき」「ﾀﾞｧなガジェットが作りたい」というひとにぴったりなライブラリとなっています。（そんな人いるのか？）



## なにができるのか


上記ライブラリをインストールしたあとに、ESP8266向けのArdunoスケッチ上で、


```c
#include <ESP8266Keikyu.h>
```

こんな感じでincludeしてあげます。そして、Wi-Fiが使える状態（インターネット接続可能なアクセスポイントに接続済み）で、


```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からの振替輸送受託のため遅れています
```


こんな感じで、ちょっと細かめにステータスを分けています。特に、`KEIKYU_STATUS_DELAYED_DUE_TO_JR`のケースはなんとも切ない気分になるので、敢えて分けています（笑）


![keikyu.gif](https://qiita-image-store.s3.amazonaws.com/0/212109/4013e944-ddc3-8e8d-7c3f-485fba661a09.gif)


このステータスによって、LEDチカさせたりすれば、簡単に京急遅延監視ガジェットが作れます。ページの最後に、サンプルコードも用意しています、もしご興味があれば、作ってみて下さい。


## ごめんなさい案件


もちろん、いろいろと制約はあります。


 - ESP8266用です。 ~~ESP32などには使えません。~~ [**ESP32用も作りました！**](https://github.com/pokiiio/ESP32Keikyu)
 - 京急専用です。他社線には対応していません。
 - **どこで**遅延が発生しているのかはわかりません。
 - 京急の運行情報ページをパースしている関係上、ページ構成が変更になると正しく情報を取得できない可能性があります。
 - 京急の運行情報ページをパースしている関係上、あまり短いインターバルで関数をコールしないで下さい。サーバーに負担がかかってしまいます。


あまり目くじらを立てずに使って頂けると助かります。ご意見などはいつでも歓迎です。



## 本当はJRも好きなんですよ


![ポキオ](https://lh3.googleusercontent.com/-oeeMD1P4Sn1v1VJUieBfutDbZOiYsbfxe2AsmsLo298S2AjaUwILovArpmtGc8qetBWi2ianSMa=s600 "ポキオ")


今回も鉄分高めな内容でしたが、生活と切って切り離せない鉄道をIoTでより身近に感じられると、もしかしたらハッピーになれることもあるかも？遅延監視ガジェットだけでなく、色んなネタにも今後チャレンジしていきますので、乞うご期待下さい。


**あしたは、多方面で活躍されているtseigoさんです！**
どんなネタなのか気になります！

## Appendix


[ESPr Developer](https://www.switch-science.com/catalog/2500/)に[マイコン内蔵RGB LED](http://akizukidenshi.com/catalog/g/gI-08412/)を接続して、運行状況に応じてLEDを光らせるサンプルコードです。


[ESP8266 core for Arduino](https://github.com/esp8266/Arduino)がすでにインストールされている状態を想定しています。また、以下のライブラリも使用しています。

 - [Adafruit NeoPixel Library](https://github.com/adafruit/Adafruit_NeoPixel)：LEDの制御に必要
 - [EmotionalBlink](https://github.com/pokiiio/EmotionalBlink)：LEDをじんわり点滅させたり、パリピ点滅をするために使用



```c
#include <ESP8266WiFi.h>
#include <Adafruit_NeoPixel.h>
#include <EmotionalBlink.h>
#include <ESP8266Keikyu.h>

#define SSID "pokio" // アクセスポイントのSSID
#define PASSWORD "inkeikyuwetrust" // アクセスポイントのパスワード
#define INTERVAL_SEC 10 * 60 // 運行情報を確認する間隔：10分
#define PIN 4 // マイコン内蔵RGB LEDの信号線を繋いだピン番号：4番ピン
#define NUMLED 1 // マイコン内蔵RGB LEDの個数：今回は1個

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

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

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

  // NeoPixelの初期化
  pixels.begin();
}

void loop() {
  // Wi-Fi接続
  connectWifi();

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

  // Wi-Fi切断
  disconnectWifi();

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

void connectWifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(SSID, PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    // Wi-Fi接続試行中は白い点滅
    Blink.softly(&pixels, NUMLED, 255, 255, 255);
  }

  Serial.println("connected!");
}

void disconnectWifi() {
  WiFi.disconnect();
  Serial.println("disconnected!");
}

void blinkLed() {
  if (keikyuStatus == KEIKYU_STATUS_DELAYED_DUE_TO_JR) {
    // 振替輸送受託が理由で遅延している場合は、パリピ点滅
    Blink.likePartyPeople(&pixels, NUMLED, INTERVAL_SEC * 1000);
    return;
  }

  int r, g, b;

  switch (keikyuStatus) {
    case KEIKYU_STATUS_UNKNOWN:
    case KEIKYU_STATUS_NORMAL:
      // 情報取得エラー・平常運転時は光らせない
      r = 0;
      g = 0;
      b = 0;
      break;
    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);
  }
}
```


💩