2019. 12. 25
ESP32 で作るSlack通知ボタン
この記事は Fusic その 2 Advent Calendar 2019 25 日目の記事です。
はじめに
カレンダーの最終日ですが、気負わず普通の記事を書こうと思います。
今回は Wifi 搭載のマイコン ESP32
を使って、簡単な Slack 通知ができるボタンを作ってみたいと思います。
使用機器
- ESP32-DevKitC ESP-WROOM-32開発ボード
- ブレッドボード
- ジャンパ線
- データ通信可能な USB-micro ケーブル
環境構築手順
Arduino IDE のインストール
- ここ からOSにあったものを選んでダウンロード
- 解凍
- 起動
こんな画面が出たらOK
ESP32 開発ボード用のライブラリを追加
- Arduino IDE を起動
- メニューから Arduino - Preferences... を選択
- Additional Board Manager URLs に https://dl.espressif.com/dl/package_esp32_index.json を追加
- メニューから Tools - Board - Boards Manager... を選択
- Esp32 で検索
- esp32 by Espressif Systems をインストール
開発ボードと接続するためのシリアルポートの準備
- Arduino IDE のメニューから Tools - Port - /dev/cu.SLAB_USBtoUART を選択できるか確認(Macの場合)
- 多分普通は無いので https://jp.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers をインストール
- インストール後は、セキュリティとプライバシーで実行許可を与える必要があると思う(再起動も必要かも)
※ ボードを接続した状態じゃないと「ポート」のリストに表示されないので注意
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);
}
結果
こちらがボタンを押す前。
こちらが今回組み上げた回路です。今後のためにスイッチを増やしているので、ごちゃごちゃしています。
Wifiに接続している時は青色のLEDを点灯させて、接続状態がひと目で分かるようにしています。
この状態で青色のボタンを押すと、Slackにメッセージを投稿する処理が発火します。
写真だとわかりにくいですが、通信中は緑色のLEDを点灯させています。
数秒くらいで、Slackにメッセージが投稿されます。
無事にボタンを押すと Slack に通知が飛ぶ Slack 通知ボタンができました。
まとめ
今日は ESP32 を使って Slack 通知ボタンを作ってみました。 「ボタンを押すと」のところを別のセンサーにしてみたり、「Slackに通知」の部分を別のAPIにしてみたりすれば、可能性は無限大ですね。
それでは良いお年を!