障害発生を光で知らせる！アラートランプを作成した話

## はじめに
こんにちは、menu事業部サーバーサイドエンジニアの新田です。

皆さんはシステムを運用していますでしょうか？  
システム運用をしていると、障害はつきもの。しかも、よりによって深夜に発生することってありませんか？😫

障害発生時にいち早く気が付けるかどうかが、被害を最小限に抑えるために非常に重要です。  
特に深夜に障害が発生した場合、なかなか気が付きづらいという問題があります。

弊社では、障害発生時にSlackにもメッセージが飛ぶようになっています。  
しかし、私個人は寝起きすぐにスマホを見ると、その後の集中力が落ちてしまう傾向があるので、どうにかスマホを見ずに気が付きたいものです。  
どうにか素早く、スマホを見ずに気がつくことができる方法はないでしょうか...？

…そうだ、光で知らせてもらいましょう！💡✨

## 🚨アラートを回す🚨
ということで、今回は障害発生を光で知らせるアラートランプを作ります。

仕組みはシンプル。Slackに障害通知が来たら、パトランプをピカピカ光らせるだけです🚨

使用する機材は、部屋に転がっていた以下のアイテムたち。

* ESP32 (マイコンボード)
* リレーモジュール (スイッチ役)
* パトランプ (主役)

![使用する機材の画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4013494/f84d021b-8975-4330-89ae-09084ec2b055.jpeg)

## 実装
まずは、ESP32をインターネットにつなげるところから始めます。

[サンプルコード](https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/WiFiClient/WiFiClient.ino)を利用してインターネットに接続できることを確認します。

サンプルはとある IoT プラットフォームへリクエストを送っているのですが、今回は Wifi に接続しインターネットへ接続できたことが確認できればいいので下記のように書き換えます。

```cpp
// RFC2606 で定められたテスト用ドメインへリクエストするように変更します
const char *host = "example.com";
const int httpPort = 80;  

// =====変更なし=====

void loop() {
  // パラメータ等を消してルートパス(/)へリクエストを送るように変更します
  NetworkClient client;
  String request = String("GET / HTTP/1.1\r\n") + "Host: " + String(host) + "\r\n" + "Connection: close\r\n\r\n";

  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  client.print(request);
  readResponse(&client);

  delay(10000); 
}
```

シリアルモニタにレスポンスが表示されていれば成功です。

次に、SlackAPIを使って、ESP32がSlackのメッセージを読めるようにします。

[Slack API の conversations.history メソッド](https://api.slack.com/methods/conversations.history)を利用することで、Slack からメッセージを取得することができます。  

```cpp
#include <WiFiClientSecure.h>

// =====変更なし=====

const char *host = "slack.com";
const int httpsPort = 443;
const char *CHANNEL_ID = "CHANNEL_ID"; // 監視したい対象のチャンネルID
const char *SLACK_TOKEN = "SLACK_TOKEN"; // 発行した API TOKEN

// =====変更なし=====

void loop() {

  WiFiClientSecure client;
  String url = String("/api/conversations.history?channel=") + String(CHANNEL_ID) + "&limit=1";
  String request = String("GET ") + url + " HTTP/1.1\r\n" +
                  "Host: " + String(host) + "\r\n" +
                  "Authorization: Bearer " + String(SLACK_TOKEN) + "\r\n" +
                  "Connection: close\r\n\r\n";

  if (!client.connect(host, httpsPort)) {
    Serial.println("connection failed");
    return;
  }

  client.print(request);
  readResponse(&client);

  delay(120000); 
}
```

メッセージを取得できることを確認できれば、コーディング部分はほぼ完了です!

続いてアラートのオンオフを制御できるように配線をしていきます。  
電池ボックスに絶縁体を挟んだ導線を接続し、動作を確認します。

![導線を合わせたらパトランプが回るgif画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4013494/412d2ebb-351b-493d-be23-75f518b0fc38.gif)

いい感じですね。

## 組み立て

では上記のコードや機材を下の配線図のように配線し、ESP32 からパトランプを制御できるようにします。

![手書き雑回路図.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4013494/8ec7ad75-fc4b-4179-af50-2c1a9d09c3f1.jpeg)

定期的に Slack のメッセージを読み取りに行き、障害が発生したのを確認したらリレーモジュールのスイッチをオン、障害が閉じたというメッセージを確認したらスイッチをオフにします。  

これで、Slack に障害報告が投稿されると、ESP32 がそれを検知し、リレーモジュールを介してパトランプを点灯させることができるようになりました。

![ランプが光らない画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4013494/802a836f-b4ca-4ccf-a0ba-b6092ab0c589.jpeg)

いざ、テストチャンネルへメッセージを送信して確認しようとすると…あれ、光らない？🤔

よく調べたら 使用している機材の GPIO 出力が上手くできておりませんでした...  
家の隅に転がっている機材はダメですね

仕方ないので、新しいESP32を購入しました。

交換して、再度テスト

Slackにテストメッセージを送信…

![slack_test_message.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4013494/30b9e8fc-8db4-4c4e-b7c4-778eef7ac3c2.png)

成功🚨


![パトランプが回り出す](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4013494/e28c5b48-24be-4031-a370-557f6bffdff8.gif)


これで、スマホを見なくても障害にいち早く気づくことができます！ 🙌

## 😎まとめ😎

今回は、ESP32とリレーモジュールで、障害発生時に光で知らせるアラートランプを作りました！

今は光だけでの通知なので今後は音や振動等も使用してわかりやすくしていきたいですね。

これで、夜中の安眠も守られる...はず...きっと...多分...

<!-- フッター -->

<hr>

### **▼採用情報**<br>
レアゾン・ホールディングスは、「世界一の企業へ」というビジョンを掲げ、「新しい"当たり前"を作り続ける」というミッションを推進しています。

現在、エンジニア採用を積極的に行っておりますので、ご興味をお持ちいただけましたら、ぜひ下記リンクからご応募ください。

https://recruit.reazon.jp/