編集履歴一覧に戻る
Kojiのアイコン画像

Koji が 2021年02月28日13時46分25秒 に編集

初版

タイトルの変更

+

子供の外出帰宅時にSlackにメッセージを送信する

タグの変更

+

slack

+

ESP32

+

秋葉原2021

メイン画像の変更

メイン画像が設定されました

記事種類の変更

+

製作品

本文の変更

+

開発背景 共働き夫婦にとっては子供が学校から帰ってきているのか、塾や習い事に忘れず行っているか心配。でも本人に携帯を持たせて「ただいや、いってきますのメールをして」と言っても忘れることが多く心配は尽きない。 だったらメッセージ送信を楽にできればいいんじゃない?というわけで作ってみた。 構成部品 ESP32 マイコン内蔵RGBLED 通信ステータス表示用 100円ショップで購入したケース LED付きタクトスイッチ これを使って押している本人も変化を見てついていたら在宅、消えていれば外出中の判断ができるのと単純に押して楽しい。 ![キャプションを入力できます](https://camo.elchika.com/bd20b6f3ab9f7c339bd4afc6d5872bcb8dce80ca/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f66356339323432392d396536332d343063662d613132332d3965366434333930626238662f65366236316566652d306334342d343638392d393134352d383539313565333438663439/) うちは子供3人なのでそれぞれ別の色のボタンを用意して自分の色のボタンを押すと押した人の名前、時間と出発帰宅のメッセージをSlackに送信する。 ![配線概要](https://camo.elchika.com/f257d676973ebe0737fca08955c709bfb42362e3/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f66356339323432392d396536332d343063662d613132332d3965366434333930626238662f39653463636237382d613734372d343635372d396331622d303830613865316161393432/) プログラムは少し回りくどい。 最初の作成時にはIFTTTのMaker機能を使ってLINE Notifyに送信していたためプログラム構造がボタンを押されると特定のURLを踏む構造になっている。 いろいろ試したがIFTTTのMakerでは子供の名前や帰宅、出発のステータスを日本語で私でも文字化けが発生していたため3人分x帰宅、出発の2ステータスで6つのURLを呼び出す設計にしていた。 IFTTTの有料化に伴いGASに乗り換えLINEからSLACKに送信先を変えたため現時点ではこのような回りくどい方法をとらなくてもよいのだが全体の設計を作り替ええられておらずそのまま使用している。 ```プログラム:AdruinoIDEにて書き込み #include <WiFi.h> #include <WiFiClient.h> #include <HTTPClient.h> #include <Ticker.h> #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> #endif // Include Unopuino32 pin definition #include "Unopuino32.h" #define PIN 23 #define NUMPIXELS 1 const char* ssid = "xxxxxxxxxxxx";//自宅WifiのSSID const char* password = "XXXXXXXXXXXXX"; //自宅Wifiのパスワード #define Name2GOOUTURL "/macros/s/XXXXXXXXX/exec" #define Name2BACKURL "/macros/s/XXXXXXXXX/exec" #define Name3GOOUTURL "/macros/s/XXXXXXXXX/exec" #define Name3BACKURL "/macros/s/XXXXXXXXX/exec" #define Name1GOOUTURL "/macros/s/XXXXXXXXX/exec" #define Name1BACKURL "/macros/s/XXXXXXXXX/exec" const int modeButton = 27; const int Name1Button = 14; const int Name2Button = 12; const int Name3Button = 13; const int Name1LED = 5; const int Name2LED = 18; const int Name3LED = 19; bool Name1Home = true; bool Name2Home = true; bool Name3Home = true; bool modeHome = true; const int inputButton = 26 ; //GP8; // IO12 const int outputLed = 25;//GP4; // IO18 const int pinTemp = 34;//AD0; // pin of temperature sensor bool outputState = true; unsigned long t = 0; // Time Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ400); Ticker toggler; float temperature; int B=3975; // B value of the thermistor float resistance; const char* server = "script.google.com"; // Server URL WiFiClient client; void errorBlink() { for (int i = 0; i < 10; i++) { pixels.setPixelColor(0, pixels.Color(127,0,0)); // Moderately bright green color. pixels.show(); // This sends the updated pixel color to the hardware. delay(300); pixels.setPixelColor(0, pixels.Color(127,127,0)); // Moderately bright green color. pixels.show(); // This sends the updated pixel color to the hardware.digitalWrite(outputLed, LOW); delay(300); } } void wifiBegin() { Serial.print("Attempting to connect to SSID: "); Serial.println(ssid); WiFi.begin(ssid, password); } void wifiReconnect() { Serial.print("Attempting to connect to SSID: "); WiFi.disconnect(true); Serial.println(ssid); WiFi.begin(ssid, password); } bool checkWifiConnected() { // attempt to connect to Wifi network: int count = 0; while (WiFi.status() != WL_CONNECTED) { Serial.print("."); // wait 1 second for re-trying delay(1000); count++; if (count > 15) { // about 15s // Serial.println("(wifiConnect) failed!"); errorBlink(); return false; } } Serial.print("Connected to "); Serial.println(ssid); return true; } void send(String value1) { while (!checkWifiConnected()) { wifiBegin(); } Serial.println("\nStarting connection to server..."); if (!client.connect(server, 443)) { Serial.println("Connection failed!"); } else { Serial.println("Connected to server!"); // Make a HTTP request: String url = value1; client.println("GET " + url + " HTTP/1.1"); client.print("Host: "); client.println(server); client.println("Connection: close"); client.println(); Serial.print("Waiting for response "); //WiFiClientSecure uses a non blocking implementation int count = 0; while (!client.available()) { delay(50); // Serial.print("."); count++; if (count > 20 * 20) { // about 20s Serial.println("(send) failed!"); errorBlink(); return; } } // if there are incoming bytes available // from the server, read them and print them: while (client.available()) { char c = client.read(); // Serial.write(c); } // if the server's disconnected, stop the client: if (!client.connected()) { Serial.println(); Serial.println("disconnecting from server."); client.stop(); } } } void setup() { Serial.begin(115200); Serial.print("booting"); pixels.begin(); // This initializes the NeoPixel library. pinMode(outputLed, OUTPUT); pinMode(Name1Button, INPUT); pinMode(Name2Button, INPUT); pinMode(Name3Button, INPUT); pinMode(Name1LED, OUTPUT); pinMode(Name2LED, OUTPUT); pinMode(Name3LED, OUTPUT); delay(100); pixels.setPixelColor(0, pixels.Color(127,0,0)); // Moderately bright green color. pixels.show(); // This sends the updated pixel color to the hardware. toggler.attach(60*10,wifiReconnect); wifiBegin(); while (!checkWifiConnected()) { wifiBegin(); } digitalWrite(Name1LED, HIGH); digitalWrite(Name2LED, HIGH); digitalWrite(Name3LED, HIGH); pixels.setPixelColor(0, pixels.Color(0,0,127)); // Moderately bright green color. pixels.show(); // This sends the updated pixel color to the hardware. } void loop() { // HTTPClient http; if (digitalRead(Name1Button) == HIGH) { if (!outputState && millis() - t >= 5000) { pixels.setPixelColor(0, pixels.Color(0,127,0)); // Moderately bright green color. pixels.show(); // This sends the updated pixel color to the hardware. outputState = true; if(Name1Home == true){ send(Name1GOOUTURL); digitalWrite(Name1LED, LOW); Name1Home = false; }else{ send(Name1BACKURL); digitalWrite(Name1LED, HIGH); Name1Home = true; } t = millis(); } } else if (digitalRead(Name2Button) == HIGH) { if (!outputState && millis() - t >= 5000) { pixels.setPixelColor(0, pixels.Color(0,127,0)); // Moderately bright green color. pixels.show(); // This sends the updated pixel color to the hardware. outputState = true; if(Name2Home == true){ send(Name2GOOUTURL); digitalWrite(Name2LED, LOW); Name2Home = false; }else{ send(Name2BACKURL); digitalWrite(Name2LED, HIGH); Name2Home = true; } t = millis(); } } else if (digitalRead(Name3Button) == HIGH) { if (!outputState && millis() - t >= 5000) { pixels.setPixelColor(0, pixels.Color(0,127,0)); // Moderately bright green color. pixels.show(); // This sends the updated pixel color to the hardware. outputState = true; if(Name3Home == true){ send(Name3GOOUTURL); digitalWrite(Name3LED, LOW); Name3Home = false; }else{ send(Name3BACKURL); digitalWrite(Name3LED, HIGH); Name3Home = true; } t = millis(); } } else { pixels.setPixelColor(0, pixels.Color(0,0,127)); // Moderately bright green color. pixels.show(); // This sends the updated pixel color to the hardware. outputState = false; } } ``` SLACKに投稿するGASの内容は以下の通り。 このスクリプトでは公開URLにアクセスがあるとName1さんが出かけましたとSlackにメッセージ送信を行います。 ```arduino:GAS function doGet() { var url = "https://slack.com/api/chat.postMessage"; var body = '\nName1さんが出かけました'; body = Getnow() +body; // 変更するのは、この部分だけ! var payload = { "token" : "xxxxxxxxxx",//Slackのtoken "channel" : "xxxxxxx",//投稿先のchannel ID "text" : body }; var params = { "method" : "post", "payload" : payload }; // Slackに投稿する UrlFetchApp.fetch(url, params); } function Getnow() { var d = new Date(); var y = d.getFullYear(); var mon = d.getMonth() + 1; var d2 = d.getDate(); var h = d.getHours(); var min = d.getMinutes(); if(min<10){min = "0"+min;} var s = d.getSeconds(); if(s<10){s = "0"+s;} var now = y+"/"+mon+"/"+d2+"("+GetDayOfWeek()+")"+" "+h+":"+min+":"+s; return now; } function GetDayOfWeek() { var date = new Date(); var dayOfWeek = date.getDay(); var dayOfWeekStr = [ "日", "月", "火", "水", "木", "金", "土" ][dayOfWeek]; Logger.log(dayOfWeekStr); return dayOfWeekStr }``` たまに忘れることはあっても自分で携帯から送信するより楽で楽しいのでほぼ忘れずに連絡が来るようになりました。