k-masatany.com

  • About
  • Blog
  • Contact
  • About
  • Blog
  • Contact

2019. 12. 25

ESP32 で作るSlack通知ボタン

この記事は Fusic その 2 Advent Calendar 2019 25 日目の記事です。

はじめに

カレンダーの最終日ですが、気負わず普通の記事を書こうと思います。

今回は Wifi 搭載のマイコン ESP32 を使って、簡単な Slack 通知ができるボタンを作ってみたいと思います。

使用機器

  • ESP32-DevKitC ESP-WROOM-32開発ボード
  • ブレッドボード
  • ジャンパ線
  • データ通信可能な USB-micro ケーブル

環境構築手順

Arduino IDE のインストール

  1. ここ からOSにあったものを選んでダウンロード
  2. 解凍
  3. 起動

img

こんな画面が出たらOK

ESP32 開発ボード用のライブラリを追加

  1. Arduino IDE を起動
  2. メニューから Arduino - Preferences... を選択
  3. Additional Board Manager URLs に https://dl.espressif.com/dl/package_esp32_index.json を追加
  4. メニューから Tools - Board - Boards Manager... を選択
  5. Esp32 で検索
  6. esp32 by Espressif Systems をインストール

img

開発ボードと接続するためのシリアルポートの準備

  1. Arduino IDE のメニューから Tools - Port - /dev/cu.SLAB_USBtoUART を選択できるか確認(Macの場合)
  2. 多分普通は無いので https://jp.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers をインストール
  3. インストール後は、セキュリティとプライバシーで実行許可を与える必要があると思う(再起動も必要かも)

※ ボードを接続した状態じゃないと「ポート」のリストに表示されないので注意

Slack 通知ボタンとして使用する

ひとまずインターネットに接続する

まずはESP32をインターネットの海に出航させます。 といっても、サンプルコードがあるので全くもって難しいことは有りません。

また、ESP32はWifiモジュールが搭載されているので、電源さえ投入すれば今回のサンプルコードは動作します。

#include <WiFiClientSecure.h>\t// HTTPS接続が可能なWifiクライアントを利用可能にするためのライブラリ

const char* ssid     = \"ssid\";\t// SSID
const char* password = \"password\";\t\t// Wifi パスワード
const char* host = \"fusic.co.jp\";\t\t// 試しに接続するホスト名

void setup() {
  Serial.begin(115200);
  pinMode(26,INPUT);
  pinMode(25,OUTPUT);

  Serial.print(\"Connecting to \");
  Serial.println(ssid);
  // Wifi 接続
  WiFi.begin(ssid, password);
  // ステータスが connected になるまで待機
  while (WiFi.status() != WL_CONNECTED) {
        delay(500);
    Serial.print(\".\");
  }
  // 接続情報をコンソールに表示
  Serial.println(\"\");
  Serial.println(\"WiFi connected\");
  Serial.println(\"IP address: \");
  Serial.println(WiFi.localIP());
  // サーバーへ接続するためのクライアントを作成
  WiFiClientSecure client;
  // ポート番号443を指定して接続
  const int httpPort = 443;
  if (!client.connect(host, httpPort)) {
          Serial.println(\"connection failed\");
      return;
  }
  // HP トップのコンテンツを取得
  String url = \"/\";
  Serial.print(\"Requesting URL: \");
  Serial.println(url);
  // HTTP のリクエストを作成
  client.print(String(\"GET \") + url + \" HTTP/1.1\\r\\n\" +
    \"Host: \" + host + \"\\r\\n\" +
    \"Connection: close\\r\\n\\r\\n\");
  unsigned long timeout = millis();
  // コンテンツの取得を待機
  while (client.available() == 0) {
        // 5s でタイムアウト
    if (millis() - timeout > 5000) {
          Serial.println(\">>> Client Timeout !\");
      client.stop();
      return;
    }
  }

  // 取得したコンテンツをバッファから取り出して表示
  while(client.available()) {
        String line = client.readStringUntil('\\r');
    Serial.print(line);
  }

  Serial.println();
  Serial.println(\"closing connection\");
}

void loop() {
      int old = LOW;
  int input = digitalRead(26);
  if (old != input) {
        old = input;
  }
  
  if (input == LOW) {
        digitalWrite(25,HIGH);
    
  } else {
        digitalWrite(25,LOW);
  }
}

このコードを書き込んでシリアルコンソールを見ると、FusicのコーポレートサイトのTOPのHTMLデータが表示されます。

<!DOCTYPE html>
<html>
  <head lang=\"ja\">
    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">

<meta name=\"keywords\" content=\"Fusic,システム開発,システム運用,アジャイル開発,採用情報,ITコンサルティング,福岡,九州,ベンチャー\">

・・・

スイッチが押されたらSlackにメッセージを投稿する

無事にWifiに接続できたので、今回はSlackにメッセージを投稿します。 もうここまできたら、ほぼ馴染み深いプログラムの世界です。

ソースコードは下記になります。
色々と書いていますが、大事なのは send_data() の部分です。
とは言え、ここはただHTTPのPOSTをしているだけなので、特に細かい説明はしません。
(相変わらずSlackのpayloadの仕様は面倒くさいですね)

#include <WiFiClientSecure.h>

const char* ssid     = \"ssid\";
const char* password = \"password\";
const char* host = \"hooks.slack.com\";
const char* hook_path = \"自分のIncomingWebHooksのPathを設定する\";
const int httpsPort = 443;

const int BLUE_LED = 13;
const int GREEN_LED = 12;
const int RED_LED = 14;

void setup() {
      Serial.begin(115200);
  pinMode(25,INPUT);
  pinMode(26,INPUT);
  pinMode(27,INPUT);
  pinMode(33,INPUT);
  pinMode(32,INPUT);
  pinMode(13,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(14,OUTPUT);

  // Wifi Setting
  Serial.print(\"Connecting to \");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  int wifi_status = 0;
  while (WiFi.status() != WL_CONNECTED) {
        delay(100);
    if (wifi_status == 0) {
          digitalWrite(BLUE_LED, HIGH);
      wifi_status = 1;
    } else {
          digitalWrite(BLUE_LED, LOW);
      wifi_status = 0;
    }
  }

  Serial.println(\"WiFi connected\");
  Serial.println(\"IP address: \");
  Serial.println(WiFi.localIP());
  digitalWrite(BLUE_LED, HIGH);
  wifi_status = 1;
}

void error_led(int num) {
        for(int i = 0; i < num; i++) {
        digitalWrite(RED_LED, HIGH);
    delay(300);
    digitalWrite(RED_LED, LOW);
    delay(300);
  }
}

void send_data(String message) {
      // Use WiFiClientSecure class to create TLS connection
  WiFiClientSecure client;
  Serial.print(\"connecting to \");
  Serial.println(host);
  if (!client.connect(host, httpsPort)) {
        Serial.println(\"connection failed\");
    error_led(3);
    return;
  }

  Serial.print(\"requesting URL: \");
  Serial.println(hook_path);

  client.print(String(\"POST \") + hook_path + \" HTTP/1.1\\r\\n\" +
      \"Host: \" + host + \"\\r\\n\" +
      \"User-Agent: ESP32Client\\r\\n\" +
      \"Content-Type: application/json\\r\\n\" +
      \"Content-Length: \"+ String(message.length()) +\"\\r\\n\\r\\n\" +
      message+\"\\r\\n\\r\\n\");

  Serial.println(\"request sent\");
  while (client.connected()) {
        String line = client.readStringUntil('\\n');
    if (line == \"\\r\") {
          Serial.println(\"headers received\");
      break;
    }
  }
  String line = client.readString();
  Serial.println(\"reply was:\");
  Serial.println(\"==========\");
  Serial.println(line);
  Serial.println(\"==========\");
  Serial.println(\"closing connection\");
}

void loop() {
      int white_button = digitalRead(25);
  int blue_button = digitalRead(26);
  int red_button = digitalRead(27);
  int gray_button = digitalRead(33);
  int black_button = digitalRead(32);

  if (blue_button == LOW) {
        digitalWrite(GREEN_LED, HIGH);
    send_data(\"{\\\"text\\\":\\\"Result: :apple:\\\",\\\"blocks\\\":[],\\\"attachments\\\":[{\\\"color\\\":\\\"#00FF00\\\",\\\"blocks\\\":[{\\\"type\\\":\\\"section\\\",\\\"text\\\":{\\\"type\\\":\\\"mrkdwn\\\",\\\"text\\\":\\\"A message *with some bold text* and _some italicized text_.\\\"}}]}]}\");
    digitalWrite(GREEN_LED, LOW);
  }
  
  delay(100);
}

結果

こちらがボタンを押す前。

img

こちらが今回組み上げた回路です。今後のためにスイッチを増やしているので、ごちゃごちゃしています。
Wifiに接続している時は青色のLEDを点灯させて、接続状態がひと目で分かるようにしています。
この状態で青色のボタンを押すと、Slackにメッセージを投稿する処理が発火します。

img

写真だとわかりにくいですが、通信中は緑色のLEDを点灯させています。

img

数秒くらいで、Slackにメッセージが投稿されます。

img

無事にボタンを押すと Slack に通知が飛ぶ Slack 通知ボタンができました。

まとめ

今日は ESP32 を使って Slack 通知ボタンを作ってみました。 「ボタンを押すと」のところを別のセンサーにしてみたり、「Slackに通知」の部分を別のAPIにしてみたりすれば、可能性は無限大ですね。

それでは良いお年を!

プロフィールアイコン
k-masatany k-masatany's memorandum
このエントリーをTwitterで共有 このエントリーをLINEで共有 このエントリーをはてなブックマークに追加

Table of Contents

  • はじめに
    • 使用機器
    • 環境構築手順
      • Arduino IDE のインストール
      • ESP32 開発ボード用のライブラリを追加
      • 開発ボードと接続するためのシリアルポートの準備
    • Slack 通知ボタンとして使用する
      • ひとまずインターネットに接続する
      • スイッチが押されたらSlackにメッセージを投稿する
      • 結果
  • まとめ

© 2021 k-masatany