5-1.人を検知してリモコン制御とメール送信 (IFTTT)
概要
2-1-6まで電子工作したキットをそのまま利用し、今回は新たにクラウドを利用してメール通知を行うことを学習していきます。
クラウドは無料で利用可能なIFTTTを利用します。IFTTTとは、異なるソーシャルメディアやプラットフォーム、サービスを連携させるWebサービスです。また、「If This Then That」の頭文字の略称となり、日本語にすると「もしこれをしたらあれをして」という感じで、「this(これ)」をトリガーに「that(あれ)」のアクションを行うというサービスになります。
IFTTTを利用した構成イメージを以下に示します。
クラウド(IFTTT)利用設定
IFTTTには以下からアクセスできます。IFTTTにはGoogleやAmazonだけでなく、TwitterやMicrosoftなど多くのサービスが利用可能となっています。また、利用も完全無料になっていますが、基本的に全て英語となります。
IFTTTを利用したメール送信の利用方法について、まずIFTTTの設定から説明します。
(スマホアプリもありますが、PC版での利用方法を説明していきます。)
(1)IFTTTサイトにアクセスして「Sign Up」をクリックしています。
(2)Google/Facebookアカウントを利用してログインができます。また、それ以外のアカウントを利用も可能で、Or use your password to sign upの「Sign Up」をクリックして、メールアドレスとパスワードを入力してアカウントを作成しログインします。
(3)ログイン後、右上のアイコンをクリックし、メニューから「Create」をクリックします。
(4)トリガーの「This」を選択し、検索窓に「web」と入力し「Webhooks」をクリックします。
(5)「Receive a web request」アイコンをクリックし、次画面のEvant Nameは任意の名前で良いのですが、今回は「iotMail」と入力し「Create trigger」をクリックします。
(6)アクションの「That」を選択し、検索窓に「email」と入力し「Email」をクリックします。
(7)「Send me an email」アイコンを選択し、既にSubjectなども全て入力されていますので、そのまま「Create action」をクリックします。
(必要に応じてSubjectやBody内容は変更してもらっても問題ありません)
(8)「Finish」をクリックして、Appletの作成が完了です。
以上でIFTTTアプレットの作成が完了です。
今作成したIFTTTアプレットのWebhooksで設定したURLにIoT端末からアクセスすることでメールを送信できます。
WebhooksのアクセスするURLは以下の方法で確認します。
「MyApplet」から「Service」タブを選択し、検索窓に「web」と入力し「Webhooks」をクリックします。
右上の「Documentation」をクリックし以下の画面を表示し、アクセスするURLを確認し、IoT端末のスケッチにプログラムしていきます。
上記の内容をスケッチに書き込み、HTTPアクセスを実現します。スケッチの記載方法は以下を参照ください。
電気回路と電子工作
回路と配線は2-1-6まで電子工作したキットとなりますので2-1-6を参照して下さい。
スケッチ(制御ソフトウェア)
人を感知した時にリモコン制御とメール送信を行うスケッチを以下に示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
// IoT電子工作キット // 5-1.人を検知してリモコン制御とメール送信 (IFTTT) // ①ライブラリを読み込み #include <WiFiClientSecure.h> // ②ピン配置とグローバル変数定義 const byte LED_PIN = 12; // LED制御 const byte IR_S_PIN = 32; // リモコン送信制御 const byte MOTN_SNR = 17; // 人感センサのピン設定 bool motionCheck = true; // 感知チェックON // ③リモコン送信データを設定 unsigned short irData[] ={ 347,172,46,・・・41,46 }; // ④Wi-Fi設定 const char *ssid = "##### SSID #####"; const char *password = "### PASSWORD ###"; IPAddress ip(192, 168, 1, 123); // IPアドレス(本機が利用するIP) IPAddress gateway(192, 168, 1, 1); // デフォルトゲートウェイ IPAddress subnet(255, 255, 255, 0); // サブネットマスク IPAddress DNS(192, 168, 1, 1); // DNSサーバ WiFiClientSecure client; // TLSを利用するためクライアント変数定義 // ⑤IFTTT設定 const char *iftttHost = "maker.ifttt.com"; // IFTTT Server const char *iftttEvent = "iotMail";// IFTTT Event const char *iftttKey = "##### IFTTT-KEY #####";// IFTTT Key const char *ifttt_ca_cert = \ "-----BEGIN CERTIFICATE-----\n" \ "MIIGpzCCBY+gAwIBAgIIW2O1ayPtDEEwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV\n" \ (省略) "LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB\n" \ "-----END CERTIFICATE-----\n" \ ; void setup() { // ⑥Serial設定 Serial.begin(115200); Serial.println ( ); // ⑦ピンモード設定 pinMode ( LED_PIN, OUTPUT ); pinMode ( IR_S_PIN, OUTPUT ); pinMode ( MOTN_SNR, INPUT); // ⑧無線Wi-Fi接続 WiFi.config( ip, gateway, subnet, DNS ); // DNSがないとHTTPS接続不可 WiFi.begin ( ssid, password ); // ⑨Wi-Fi接続処理(接続するまで無限ループ) bool ledFlag = true; while ( WiFi.status() != WL_CONNECTED ) { // ⑩LEDを1秒毎に点滅する ledFlag = !ledFlag; digitalWrite(LED_PIN, ledFlag); delay ( 1000 ); Serial.print ( "." ); } // ⑪Wi-Fi接続できたのでシリアルモニターにIPアドレス表示 Serial.print ( "Wi-Fi Connected! IP address: " ); Serial.println ( WiFi.localIP() ); digitalWrite ( LED_PIN, true ); // ⑫HTTPS用の証明書を設定 client.setCACert(ifttt_ca_cert); } // ⑬1秒毎に人感センサーで感知したらリモコンとメール送信 void loop() { delay(1000); // ⑭感知チェック、かつ、モーションセンサー感知状態 if (motionCheck && digitalRead(MOTN_SNR)) { Serial.println( "Detected!" ); motionCheck = false; // ⑮感知フラグOFF irSend (); // ⑯赤外線送信する関数を実行 iftttMail (); // ⑰IFTTTでメール送信 } else { Serial.println( "No detected." ); motionCheck = true; // ⑱感知チェックON } } // ⑲赤外線送信処理 void irSend () { // ⑳ローカル変数定義 unsigned short irCount = 0; // HIGH,LOWの信号数 unsigned long l_now = 0; // 送信開始時間を保持 unsigned long sndt = 0; // 送信開始からの経過時間 // ㉑HIGH,LOWの信号数を計算 irCount = sizeof(irData) / sizeof(irData[0]); // ㉒送信開始時間を取得 l_now = micros(); // ㉓0,1の信号回数分をFor文でループ for (int i = 0; i < irCount; i++) { // ㉔送信開始からの信号終了時間を計算 sndt += irData[i]; do { // ㉕iが偶数なら赤外線ON、奇数ならOFFのまま // ㉖キャリア周波数38kHz(約26μSec周期の半分)でON時間で送信 digitalWrite(IR_S_PIN, !(i&1)); microWait(13); // ㉗キャリア周波数38kHz(約26μSec周期の半分)でOFF時間で送信 digitalWrite(IR_S_PIN, 0); microWait(13); // ㉘送信開始からの信号終了時間が超えるまでループ } while (long(l_now + (sndt * 10) - micros()) > 0); } } // ㉙マイクロ秒単位で待つ void microWait(signed long waitTime) { unsigned long waitStartMicros = micros(); // ㉚指定されたマイクロ秒が経過するまでWhileでループ処理(待つ) while (micros() - waitStartMicros < waitTime) {}; } // ㉛赤外線送信処理 void iftttMail () { // ㉜URL決定 maker.ifttt.com/trigger/{event}/with/key/{key} String value1 = "Motion is detected!"; String pathUrl = "/trigger/" + String(iftttEvent) + "/with/key/" + String(iftttKey); String json = "{\"value1\":\"" + value1 + "\"}"; delay(10); // ㉝LED消灯(処理中が判別できるように消灯している) digitalWrite(LED_PIN, false);// 処理中はLED消灯 // ㉞HTTPS接続と結果判定 if (!client.connect(iftttHost, 443)) { // ㉟HTTPS接続失敗時のシリアルモニタ表示 Serial.println("Connection failed!"); } else { // ㊱HTTPS接続成功時のシリアルモニタ表示 Serial.println("Connected to ifttt!\n"); // ㊲HTTPSデータ送信処理 client.println("POST https://" + String( iftttHost ) + pathUrl + " HTTP/1.1"); client.println("Host: " + String(iftttHost) + ":443"); client.println("Content-Type: application/json"); client.println("Connection: Keep-Alive"); client.println("Content-Length: "+ String(json.length())); client.println(""); client.println(json); // ㊳HTTPS接続確認 if (client.connected()) { // ㊴ヘッダの受信表示処理 Serial.println("--- Header ---"); while (1) { String line = client.readStringUntil('\n'); Serial.println(line); if (line == "\r") { break; // ヘッダの末尾は\r\nのため、\r時に終了 } } // ㊵本文(Body)の受信表示処理 Serial.println("--- Body ---"); while (client.available()) { char c = client.read(); Serial.write(c); } } // ㊶HTTPS通信の終了 client.stop(); } // ㊷終了処理(LED点灯、シリアルモニタ表示) digitalWrite(LED_PIN, true); Serial.println("ifttt end"); } |
スケッチは今までの人感センサに関するプログラムとリモコン送信に関するプログラムを合わせて、さらにメール送信に関するプログラムが追加されています。
今回、追加した部分を主に説明していきます。
今まで同様にネットワーク環境に応じて、SSIDやパスワード、IPアドレス、サブネット、DNSを変更して下さい。また、送信するリモコン信号も変更する必要があります。
最初に取得したIFTTTのWebhooksのKeyを⑤でIFTTTのトリガーに関する設定「##### IFTTT-KEY #####」の部分に変更して設定して下さい。IFTTT Event名はIFTTTのWebhooksとスケッチで合わせる必要があり今回「iotMail」と設定していますが、利用用途に応じて任意の名称をつけても問題ありません。この設定値はWebhooksのリクエストURLを作成するためのパラメータとして利用されます。
また、HTTPSで利用する証明書についてifttt_ca_certで設定しています。本変数は⑫setCACertで設定しています。設定する証明書の取得方法は下に記載した【証明書の取得方法】を参照して下さい。
loop関数内では1秒毎に人感センサの検出を行なっています。⑭で状態を検知していますが、motionCheckがtrueの場合のみ人感センサを検出しています。
人感センサが1秒毎に検知し何度もメールを送信してしまうため、変数motionCheckで状態が変化するまではセンサを検出しないようにしています。
人感センサが検出すると、irSend関数でリモコン制御を行い、メール送信に関しては㉛iftttMail関数で実施しています。
IFTTTで設定したAppletのWebhooksのリクエストURLにアクセスすることでメール送信を行います。そのため、㉜でリクエストURLと送信データを設定しています。
㉞にHTTPS接続を行い失敗時は㉟でシリアルモニタに表示します。成功時は㊱で「Connected to ifttt!」と表示し㊲で一行毎にデータ送信を行っています。
㊳HTTPS通信の接続確認を行い㊴で受信データのヘッダ部分の表示を行います。㊵ではデータ部分の表示を行っています。
通信が完了したら㊶でHTTPS終了処理を行い㊷でLEDを点灯、シリアルモニタに「ifttt end」を表示し動作を判別できるようにしています。
実行時に表示されるシリアルモニタは、人感センサが感知した時に「Detected!」と表示されIFTTTアクセスの内容が下図のように表示されれば動作が正常に完了しています。
HTTPS(SSL)通信概要
WebサーバにおいてHTTPSのSSL通信を行う理由は大きく以下の2点です。
①偽サイトへのアクセスを防ぐ(フィッシング対策)
②通信の暗号化(盗聴、改竄の防止)
WebサイトにあるSSL証明書はWebブラウザに設定されているルート証明書で判定することで正しいサイトであることを確認しています。
Webブラウザ(Chome)で利用されるルート証明書は複数設定されていますので、該当のWebサイトで利用される(ルート)証明書を利用する必要があります。
そのため、該当サイトで利用されるWebブラウザのルート証明書をESP32マイコンに設定することでESP32マイコンでもSSL通信を実現します。
Webブラウザでは「https://maker.ifttt.com」が表示できないため、次項(以下)で「openssl」によるルート証明書(以下、証明書で省略させて頂きます)の取得方法を説明させて頂きます。
証明書の取得方法
証明書は以下のコマンドを各端末で実行することで取得できます。
openssl s_client -showcerts -connect maker.ifttt.com:443
Mac,Linux端末はターミナルで上記コマンドを入力することで取得できますが、Windows端末ではopensslコマンドが使えるソフトを”https://slproweb.com/products/Win32OpenSSL.html”からインストールし利用する必要があります。
(Webブラウザから証明書をダウンロードできますのでそちらでも問題ありませんが、バージョンにより操作が異なるためコマンドでの取得方法を紹介しています。)
ルート証明書に至るまでの証明書チェインが表示されます。
depth=2がルート証明書、depth=1が中間証明書、depth=0がmaker.ifttt.comのサーバ証明書になりますので、以下の例に示すようにdepth=2の証明書の「—–BEGIN CERTIFICATE—–」から「—–END CERTIFICATE—–」までをコピーして、スケッチに設定して下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
2 s:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 i:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority -----BEGIN CERTIFICATE----- MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVT MSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNVBAsTKEdv IERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMTAx MDcwMDAwWhcNMzEwNTMwMDcwMDAwWjCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHku Y29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1 dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3Fi CPH6WTT3G8kYo/eASVjpIoMTpsUgQwE7hPHmhUmfJ+r2hBtOoLTbcJjHMgGxBT4H Tu70+k8vWTAi56sZVmvigAf88xZ1gDlRe+X5NbZ0TqmNghPktj+pA4P6or6KFWp/ 3gvDthkUBcrqw6gElDtGfDIN8wBmIsiNaW02jBEYt9OyHGC0OPoCjM7T3UYH3go+ 6118yHz7sCtTpJJiaVElBWEaRIGMLKlDliPfrDqBmg4pxRyp6V0etp6eMAo5zvGI gPtLXcwy7IViQyU0AlYnAZG0O3AqP26x6JyIAX2f1PnbU21gnb8s51iruF9G/M7E GwM8CetJMVxpRrPgRwIDAQABo4IBFzCCARMwDwYDVR0TAQH/BAUwAwEB/zAOBgNV HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9BUFuIMGU2g/eMB8GA1Ud IwQYMBaAFNLEsNKR1EwRcbNhyz2h/t2oatTjMDQGCCsGAQUFBwEBBCgwJjAkBggr BgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMDIGA1UdHwQrMCkwJ6Al oCOGIWh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Ryb290LmNybDBGBgNVHSAEPzA9 MDsGBFUdIAAwMzAxBggrBgEFBQcCARYlaHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNv bS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAWQtTvZKGEacke+1bMc8d H2xwxbhuvk679r6XUOEwf7ooXGKUwuN+M/f7QnaF25UcjCJYdQkMiGVnOQoWCcWg OJekxSOTP7QYpgEGRJHjp2kntFolfzq3Ms3dhP8qOCkzpN1nsoX+oYggHFCJyNwq 9kIDN0zmiN/VryTyscPfzLXs4Jlet0lUIDyUGAzHHFIYSaRt4bNYC8nY7NmuHDKO KHAN4v6mF56ED71XcLNa6R+ghlO773z/aQvgSMO3kwvIClTErF0UZzdsyqUvMQg3 qm5vjLyb4lddJIGvl5echK1srDdMZvNhkREg5L4wn3qkKQmw4TRfZHcYQFHfjDCm rw== -----END CERTIFICATE----- |