5-4.全機能実装スマートリモコン
概要(利用可能センサ)
全機能実装スマートリモコンは本キットで同梱する全てのセンサーを実装しています。利用するセンサは以下となります。
(1)LED
(2)照度センサ
(3)温湿度センサ
(4)人感センサ
(5)赤外線受信
(6)赤外線送信
回路と配線
回路と配線に関しては、4-3や5-1で製作したスマートリモコンと人感センサーを合わせた内容になっています。内容としては特に新しい内容はありませんので、各項目を個別に参照下さい。
回路図と配線図は全てのセンサを実装するため、以下のように実施する必要があります。(全てのセンサを一つのブレードボードで配線するため開発ボードの下も配線する必要があります。)
【ESP32-DevKitCの入出力端子はこちらを参照下さい】
配線したブレッドボードは以下となります。
制御・設定画面
温度情報の取得や家電リモコン設定制御は製作したIoT端末にアクセスすることで温度情報やリモコン制御や設定可能です。
(下図はスマホでアクセスした画面となります。)
また、AIスピーカ連携や人感センサーなども利用可能で、画面のボタン数やデザインなども自由に変更可能ですので、オリジナルのIoT端末を製作して下さい。
関連フォルダ及びスケッチ、HTML関連ファイル
スケッチなどの制御プログラムも4-3/5-1/5-2/5-3を合わせたものになりますので説明は割愛します。スケッチはダウンロードが可能となっていますのでご利用下さい。
ファイル構成と各ファイル内容を以下に示します。
利用するファイル構成
(3)5_4_aispeaker_allsensor.ino
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 |
// IoT電子工作キット // 5-4.全機能実装スマートリモコン // ①ライブラリ、Configファイルを読み込み #include <WiFiClientSecure.h> #include <EEPROM.h> #include <DHT.h> #include <SPIFFS.h> #include <ESPAsyncWebServer.h> #include <PubSubClient.h> #include <ArduinoJson.h> #include "config.h" // ②利用ライブラリの設定を変更(PubSubClientライブラリは128バイトなのを拡張) #define MQTT_MAX_PACKET_SIZE 1024 // ③人感センサーON/OFF(OFF時はコメントアウト) #define MOTION_CHECK // ④Wi-Fi、MQTTクライアントを設定 WiFiClientSecure wifiClient; // MQTT用 WiFiClientSecure wifiClientHttps; // HTTPS用 AsyncWebServer webServer ( 80 ); PubSubClient mqttClient(host, 8883, wifiClient); // ⑤起動時、最初に実行される処理 void setup(void) { // ⑥Serial設定 Serial.begin(115200); Serial.println ( ); // ⑦SPIFFS開始 SPIFFS.begin(); // ⑧EEPROM開始(サイズ指定:ボタン名10個分[65*10]) EEPROM.begin(650); // ⑨ピンモード設定 pinMode ( LED_PIN, OUTPUT ); pinMode ( IR_R_PIN, INPUT ); pinMode ( IR_S_PIN, OUTPUT ); pinMode ( LIGH_SNR, INPUT ); pinMode ( MOTN_SNR, INPUT ); // ⑩Wi-Fi接続処理 setup_wifi(); // ⑪WebServer設定処理 setup_webserver(); } // ⑫無線Wi-Fi設定 void setup_wifi() { // ⑬無線Wi-Fi情報設定 Serial.println ( "Wi-Fi SetUp" ); WiFi.config( ip, gateway, subnet, DNS ); // DNSがないとMQTT接続不可 WiFi.begin ( ssid, password ); // ⑭Wi-Fi接続処理(接続するまで無限ループ) while ( WiFi.status() != WL_CONNECTED ) { // ⑮LEDを1秒毎に点滅する ledFlag = !ledFlag; digitalWrite(LED_PIN, ledFlag); // ⑯1秒間Wait delay ( 1000 ); Serial.print ( "." ); } // ⑰Wi-Fi接続できたのでシリアルモニターにIPアドレス表示 Serial.print ( "Wi-Fi Connected! IP address: " ); Serial.println ( WiFi.localIP() ); // ⑱LED点灯(Wi-Fi接続状態) digitalWrite ( LED_PIN, true ); // ⑲クライアントにCA証明書を設定 wifiClient.setCACert(beebottle_ca_cert); } // ⑳setup完了後、電源OFFまで繰り返し処理 void loop(void){ // ㉑現在時刻の取得 nowtime = millis(); // ㉒MQTT状態を確認し接続状態でなかったらMQTT接続処理 if (!mqttClient.connected()) { reconnect(); } // ㉓MQTTクライアント処理 mqttClient.loop(); // ㉔------- MOTION_CHECKがONの場合のみ ------- #ifdef MOTION_CHECK // ㉕1Sec毎にCheck処理 if ( (long)(nowtime / 1000) != mCheck ) { mCheck = (long)(nowtime / 1000); // ㉖感知チェック、かつ、モーションセンサー感知状態 if (motionCheck && digitalRead(MOTN_SNR)) { Serial.println( "Detected!" ); motionCheck = false; // ㉗感知フラグOFF contRemocon ("1"); // ㉘赤外線送信する関数を実行 iftttMail (); // ㉙IFTTTでメール送信 } else { Serial.println( "No detected." ); motionCheck = true; // ㉚感知チェックON } } #endif // MOTION_CHECK } // ㉛MQTT接続処理 void reconnect() { // ㉜MQTT接続状態までループ処理 while (!mqttClient.connected()) { Serial.println("Attempting MQTT connection..."); // ㉝MQTT設定情報定義 String username = "token:"; username += channelToken; // ㉞MQTT接続処理 mqttClient.connect(clientID, username.c_str(), NULL); delay(2000); } Serial.println("MQTT connected"); // ㉟MQTTメッセージ受信時の処理設定 mqttClient.setCallback(callback); // ㊱MQTTメッセージを受信するTOPICの設定 mqttClient.subscribe(topic); } // ㊲MQTTメッセージ受信時の処理 void callback(char* topic, byte* payload, unsigned int length) { // ㊳MQTT受信メッセージを変数に保存 char recvData[MQTT_MAX_PACKET_SIZE]; snprintf(recvData, sizeof(recvData), "%s", payload); // ㊴MQTT受信メッセージをシリアルモニタ表示 Serial.print("Message arrived ["); Serial.print(topic); Serial.println("] "); Serial.println(recvData); // ㊵受信データのJSON形式を解析し変数へ保存 StaticJsonBuffer<MQTT_MAX_PACKET_SIZE> jsonBuffer; JsonObject& jsonBuf = jsonBuffer.parseObject(recvData); // ㊶JSON形式解析が成功しなかったらエラー表示し終了 if (!jsonBuf.success()) { Serial.println("parseObject() failed"); return; } // ㊷受信データ(data)を取得保存 const char* parsedPayload = jsonBuf["data"]; // ㊸受信データ(data)が存在するか判定 if (parsedPayload != NULL) { Serial.print("payload: "); Serial.println(parsedPayload); // ㊹受信データ(data)に送信リモコン番号 if (contRemocon( parsedPayload )) { Serial.println("MQTT send OK"); } else { Serial.println("MQTT send NG"); } } } |
(4)irRecvSend.ino
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 161 162 163 164 165 166 167 168 169 170 171 172 |
// ①赤外線受信(信号受信 or 30秒間を処理) void setRemocon (AsyncWebServerRequest *request) { // ②利用する変数を宣言 unsigned short irCount = 0; // HIGH,LOWの信号数 uint32_t lastt = 0; // 1つ前の経過時間を保持 uint32_t deltt = 0; // 1つ前の経過時間を保持 uint32_t sMilli; // 本処理の開始時間 uint32_t wMilli; // 赤外線の待ち開始時間 uint32_t sMicro; // 処理の開始時間 uint32_t cMicro; // 現在時間 bool rState = 0; // 赤外線受信モジュールの状態 0:LOW,1:HIGH // ③現在の時間をミリ秒で取得 sMilli = millis(); // ④特定条件(信号受信 or 30秒経過)するまで無限ループ while(1) { // ⑤Ir受信を待つ開始時間を取得 wMilli = millis(); // ⑥反転信号の受信待ち while (digitalRead(IR_R_PIN) == rState) { // ⑦待ち始めて0.5秒以上経過したら if (millis() - wMilli > 500) { // ⑧待ち始めて0.5秒以上経過したら if ( irCount > 10 ) { Serial.println(""); Serial.println("recvOK!"); delay(1); // ⑨ボタン名をEEPROMへ、リモコンデータをファイルへ保存 //xTaskCreatePinnedToCore(saveIr,"saveIr", 4096, ((irCount - 1), request), 1, NULL, 1); //Task1実行 if (saveIr( (irCount - 1), request)) { // ⑩正常に終了したため、WebサーバからOKを返答 request->send(200, "text", "OK"); Serial.println("setRemocon OK"); } else { // ⑪信号保存に失敗したためNGを返答 request->send(200, "text", "NG"); Serial.println("setRemocon NG"); } return; // ⑪正常に完了 } // ⑫0,1信号が10個以上ない場合は雑音のため再度ゼロから受信 irCount = 0; } // ⑬処理が15秒以上経過したらタイムアウト if ( millis() - sMilli > 15000 ) { request->send(200, "text", "NG");// ⑭タイムアウトしたのでNGを送信 Serial.println("setRemocon T.O."); return; // ⑮15秒経過で処理終了(受信なし) } } // ⑯信号受信開始時の現在の時間や経過時間を取得 if ( irCount == 0 ) { sMicro = micros(); lastt = 0; irCount++; Serial.print("ir:"); // ⑰信号受信処理開始後の処理(irCountが1以上) } else { // ⑱赤外線受信部の状態変化が最後に変化した時間からの経過時間を計算 cMicro = micros(); deltt = ( (cMicro - sMicro)/ 10 ) - lastt; irData[(irCount - 1 )] = deltt; // ⑲次回経過時間計算のため最後に変化した経過時間を保存 lastt = lastt + deltt; irCount++; Serial.print( deltt ); Serial.print(","); } // ⑳次回While内で状態変化を検知する値を変更 rState = !rState; } } // ㉑ボタン名をEEPROMへ、リモコンデータをファイルへ保存 bool saveIr(unsigned short irLength, AsyncWebServerRequest *request){ String setirname = ""; String setNumStr = ""; // ㉒ボタン番号の取得とチェック(HTTP GETリクエストのパラメータ) if (request->hasParam("n")) { setNumStr = request->getParam("n")->value(); } else { return false; } // ㉓ボタン名の取得とチェック(HTTP GETリクエストのパラメータ) if (request->hasParam("a")) { setirname = request->getParam("a")->value(); } else { return false; } // ㉔ボタン番号をString型をint型へ変換 int setNum = setNumStr.toInt(); // ㉕ボタン名に識別用文字"O:"を先頭に付与 setirname = "O:" + setirname; // ㉖EEPROMに保存用の型が一致した変数を定義 st_remocon remRom; // ㉗Stringからchar型に変換(終了文字を付与するためLengthは+1) setirname.toCharArray(remRom.remo_name, setirname.length()+1); // ㉘メモリ位置を計算しEEPROMへ書き込み int memPos = (65 * setNum); EEPROM.put<st_remocon>(memPos, remRom); EEPROM.commit(); Serial.println("setIr:" + String(setNum) + ":" + setirname); // ㉙リモコン信号を保存するためファイル名を作成(ファイル名はボタン番号) String t_file = "/" + setNumStr; Serial.println( "recvFile:" + t_file); // ㉚ファイルを書き込みモードで開く File fw = SPIFFS.open(t_file.c_str(), "w"); // ㉛リモコン信号の長さを最初に書き込み(最初の行) fw.println( String( irLength, HEX ) ); // ㉜リモコン信号の0,1の時間長さを書き込み(2行目以降) for (int i = 0; i < irLength; i++) { fw.println( String( irData[i], HEX ) ); } // ㉝書き込みが完了したのでファイルを閉じる fw.close(); // ㉞正常に処理が完了したのでtrueを返す return true; } // ㉟赤外線送信処理 bool contRemocon (String setNumStr) { // 送信番号保存 // ㊱変数宣言 unsigned short irCount = 0; // HIGH,LOWの信号数 unsigned long l_now = 0; // 送信開始時間を保持 unsigned long sndt = 0; // 送信開始からの経過時間 // ㊲リモコン信号をファイルから取得(ファイル名はボタン番号) String t_file = "/" + setNumStr; Serial.println( "sendFile:" + t_file); // ㊳ファイルを開く File fr = SPIFFS.open(t_file.c_str(), "r"); // ㊴ファイルを開く if(!fr || fr.isDirectory()){ Serial.println("FileOpen NG"); return false; } // ㊵最初の1行のみ読み出し信号長さ(0,1の数)を取得 String snum = fr.readStringUntil('\n'); // ㊶1行目の文字列を数値型に変換 irCount = strtol(snum.c_str(), NULL, 16); Serial.print( "sendData:" + String(irCount)); // ㊷一旦ファイルから変数irDataに読み出し保存 for (int i = 0; i < irCount; i++) { snum = fr.readStringUntil('\n'); irData[i] = strtol(snum.c_str(), NULL, 16); } fr.close(); // ㊸送信開始時間を取得 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); } // ㊾正常に終了したので、trueを返答 Serial.println(":End"); return true; } // ㊿マイクロ秒単位で待つ void microWait(signed long waitTime) { unsigned long waitStartMicros = micros(); while (micros() - waitStartMicros < waitTime) {}; } |
(5)web_mail.ino
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 |
// ①WebServer設定処理 void setup_webserver() { // ②WebServer処理設定(制御画面を送信) webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ Serial.println ( "Top" ); request->send(SPIFFS, "/top.html", "text/html"); }); // ③WebServer処理設定(制画面のJavascriptを送信) webServer.on("/rem.js", HTTP_GET, [](AsyncWebServerRequest *request){ Serial.println ( "js" ); request->send(SPIFFS, "/rem.js", "text/html"); }); // ④WebServer処理設定(設定画面を送信) webServer.on("/set", HTTP_GET, [](AsyncWebServerRequest *request){ Serial.println ( "set" ); request->send(SPIFFS, "/set.html", "text/html"); }); // ⑤WebServer処理設定(温度情報送信) webServer.on("/gettemp", HTTP_GET, [](AsyncWebServerRequest *request){ Serial.println ( "gettemp" ); getTemprature(request); }); // ⑥WebServer処理設定(ボタン情報送信) webServer.on("/getrem", HTTP_GET, [](AsyncWebServerRequest *request){ Serial.println ( "getrem" ); getRemocon(request); }); // ⑦WebServer処理設定(リモコン受信設定) webServer.on("/setrem", HTTP_GET, [](AsyncWebServerRequest *request){ Serial.println ( "setrem" ); setRemocon(request); }); // ⑧WebServer処理設定(リモコン送信) webServer.on("/cntrem", HTTP_GET, [](AsyncWebServerRequest *request){ Serial.println ( "cntrem" ); // ⑨ボタン番号を取得とチェック(HTTP GETリクエストのパラメータ)及び送信処理 if (request->hasParam("n") && contRemocon( request->getParam("n")->value() )) { request->send(200, "text", "OK"); Serial.println("Web send OK"); } else { request->send(200, "text", "NG"); Serial.println("Web send NG"); } }); // ⑩WebServer開始処理 webServer.begin(); Serial.println ( "Web server started" ); } // ⑪ボタン情報送信関数 void getRemocon(AsyncWebServerRequest *request) { // ⑫送信データを作成(JSON形式) String senddata = "{"; // ⑬EEPROMデータを保存する変数を宣言 st_remocon remRom; // ⑭ボタン情報10個分を読み出し返答する for (byte i = 0; i < 10; i++) { // ⑮EEPROMメモリ位置を計算 int memPos = (65 * i); // ⑯前回の値'O:'が残らないように消す remRom.remo_name[0] = 'n'; // ⑰EEPROMからデータ取得 EEPROM.get<st_remocon>(memPos, remRom); // ⑱データが保存されているかCheck if (remRom.remo_name[0] == 'O' && remRom.remo_name[1] == ':' ) { // ⑲返答文字列長が1を超える場合は","をつける(2つ目以降との区切り) if (senddata.length() > 1) { senddata += ","; } // ⑳返答する値を一度String型に置き換える("O:"を削除するため) String getirname = String(remRom.remo_name); // ㉑返答文字列作成("O:"を削除するため2から最後まで) senddata += "\"" + (String)i + "\":\"" + getirname.substring(2,getirname.length()) + "\""; } } // ㉒最後にJSONデータを閉じるため"}"をつける senddata += "}"; // ㉓作成した返答(JSON)データをWebサーバから返答する request->send(200, "text", senddata); Serial.println( "getRemocon:" + senddata); } // ㉔温・湿・照度情報送信関数 void getTemprature(AsyncWebServerRequest *request) { // ㉕温湿度センサーの宣言 DHT dht(TEMP_SNR, DHT11); // ㉖温湿度センサーの情報取得 float g_humidity = dht.readHumidity(); float g_temperature = dht.readTemperature(); // ㉗温湿度センサーの情報表示 Serial.print( "get_temp:" ); Serial.print( String(g_temperature) ); Serial.print( ":" ); Serial.print( String(g_humidity) ); // ㉘照度センサの情報取得(1〜100) unsigned short g_light = analogRead(LIGH_SNR) * 100 / 4095; // ㉙照度センサーの情報表示 Serial.print( ":" ); Serial.println( String(g_light) ); // ㉚センサーデータを作成し送信 String senddata = "{\"t\":" + String(g_temperature) + ",\"h\":" + String(g_humidity) + ",\"l\":" + String(g_light) + "}"; request->send(200, "text", senddata); // ㉛送信したセンサーデータを表示 Serial.print("gTem:"); Serial.println(senddata); } // ㉜赤外線送信処理 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 (!wifiClientHttps.connect(iftttHost, 443)) { // ㊲HTTPS接続失敗時のシリアルモニタ表示 Serial.println("Connection failed!"); } else { // ㊳HTTPS接続成功時のシリアルモニタ表示 Serial.println("Connected to ifttt!\n"); // ㊴HTTPSデータ送信処理 wifiClientHttps.println("POST https://" + String( iftttHost ) + pathUrl + " HTTP/1.1"); wifiClientHttps.println("Host: " + String(iftttHost) + ":443"); wifiClientHttps.println("Content-Type: application/json"); wifiClientHttps.println("Connection: Keep-Alive"); wifiClientHttps.println("Content-Length: "+ String(json.length())); wifiClientHttps.println(""); wifiClientHttps.println(json); // ㊵HTTPS接続確認 if (wifiClientHttps.connected()) { // ㊶ヘッダの受信表示処理 Serial.println("--- Header ---"); while (1) { String line = wifiClientHttps.readStringUntil('\n'); Serial.println(line); if (line == "\r") { break; // ヘッダの末尾は\r\nのため、\r時に終了 } } // ㊷本文(Body)の受信表示処理 Serial.println("--- Body ---"); while (wifiClientHttps.available()) { char c = wifiClientHttps.read(); Serial.write(c); } } // ㊸HTTPS通信の終了 wifiClientHttps.stop(); } // ㊹終了処理(LED点灯、シリアルモニタ表示) digitalWrite(LED_PIN, true); } |
(6)config.h
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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
// ①ピン配置など const byte LED_PIN = 22; // LED緑 const byte IR_R_PIN = 36; // リモコン受信 const byte IR_S_PIN = 23; // リモコン送信 // ADC2回路(GPIO32~39以外)は現在WiFi機能と並行して利用できず常に4095 const byte LIGH_SNR = 39; // 照度センサ(A18) const byte TEMP_SNR = 21; // 温・湿度センサ const byte MOTN_SNR = 34; // 人感センサのピン設定 const char *host = "mqtt.beebotte.com"; unsigned long nowtime; // 現在時間を保持(msec) unsigned long mCheck = 0; // 1Sec毎のチェック時間 4,294,967,295(unsigned long)を1000徐算値 bool ledFlag = true; // LED制御フラグ bool motionCheck = true; // 感知チェックON // ②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サーバ // ③EEPROMで利用する型(構造体)を宣言(ボタン名を保存する型) struct st_remocon { char remo_name[65]; }; // ④リモコンデータ保存用 (unsigned short型の配列1500個) unsigned short irData[1500]; // ⑤IFTTT設定 const char *iftttHost = "maker.ifttt.com"; // IFTTT Server const char *iftttEvent = "iotMail";// IFTTT Event const char *iftttKey = "### IFTTT-KEY ###";// IFTTT Key // 以下は2019年5月の証明書データ(必要により書き換え下さい) const char *ifttt_ca_cert = \ "-----BEGIN CERTIFICATE-----\n" \ "MIIGpzCCBY+gAwIBAgIIW2O1ayPtDEEwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV\n" \ "BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow\n" \ "GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz\n" \ "LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1\n" \ "cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMTgwOTA2MTcwMDE1WhcN\n" \ "MjAwOTI4MjIxMzU0WjA5MSEwHwYDVQQLExhEb21haW4gQ29udHJvbCBWYWxpZGF0\n" \ "ZWQxFDASBgNVBAMMCyouaWZ0dHQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n" \ "MIIBCgKCAQEA8c1HRaRBFWER/SG2eXN++ykWLSoCyJ1xcxOXy15Bk57WXGLIBZHn\n" \ "Y8/SN+H1KuUcN40KC35NuGhaQP43cELcBSG/BiYTlFPIAizauX2K9VZh+zWhwkgq\n" \ "y8bJ5+yvZKH5gwqNL248Y4gjwaPeU8o2K1xrFYWSfM/7kFQFul2goWOA3HIn5qE3\n" \ "NUsgxF8uLh2BSuJKQF73WDvM1zE86MIU20M9+PEo/pV5orIPZX/54cAZgXnr+59t\n" \ "KPL14Rl9qqTiptMJC8y2CIqKC9zHBwIwX4uYPOquom1oqAuItWgqAJwtC3z5a20r\n" \ "wbI2eNbDPdbeweT/4RtCjTwKlQuHmzeLbwIDAQABo4IDNTCCAzEwDAYDVR0TAQH/\n" \ "BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQD\n" \ "AgWgMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Rp\n" \ "ZzJzMS04NjUuY3JsMF0GA1UdIARWMFQwSAYLYIZIAYb9bQEHFwEwOTA3BggrBgEF\n" \ "BQcCARYraHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5\n" \ "LzAIBgZngQwBAgEwdgYIKwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8v\n" \ "b2NzcC5nb2RhZGR5LmNvbS8wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jZXJ0aWZpY2F0\n" \ "ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS9nZGlnMi5jcnQwHwYDVR0jBBgwFoAU\n" \ "QMK9J47MNIMwojPX+2yz8LQsgM4wIQYDVR0RBBowGIILKi5pZnR0dC5jb22CCWlm\n" \ "dHR0LmNvbTAdBgNVHQ4EFgQUTv/uQ1GFjIW3WdcM3sn8fwtzoKQwggF9BgorBgEE\n" \ "AdZ5AgQCBIIBbQSCAWkBZwB1AKS5CZC0GFgUh7sTosxncAo8NZgE+RvfuON3zQ7I\n" \ "DdwQAAABZa/TxpgAAAQDAEYwRAIgdYZfhny1zdZj9H560jR5UrHgRn3ICcW1InPx\n" \ "zw8neN4CIEWuBSawq4hAhcBLMnfi+PW2OIj2J0WSMGSG9kxmpE4xAHYA7ku9t3XO\n" \ "YLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFlr9PLqwAABAMARzBFAiA5I3ux\n" \ "1COAWE65DzDJUkG1KCdtlFD3XqLhjhozKthb9AIhAKIql04vTpqM5swE5YoO539r\n" \ "IUILnDZREGEYznWgKB13AHYAXqdz+d9WwOe1Nkh90EngMnqRmgyEoRIShBh1loFx\n" \ "RVgAAAFlr9PMhQAABAMARzBFAiBN0mgVDHNItBVC0zu85QRgcdJWmHPkzkp0un6x\n" \ "W6Mc4wIhALjsHONTT0w4kdik30ajXRZO82iTypNiLL+HNMRfsCJjMA0GCSqGSIb3\n" \ "DQEBCwUAA4IBAQBfJREWuoH4U1MIbufLfnkcuj5dfOcwwvCeUUQWibb97Xf0dvG6\n" \ "iGuYkJYLIHsf7d8eH7iHpWw/nJTu7P2XMwj4nohIzE6rxt7Ab/6ma6j/0sV2Vbx4\n" \ "aSloxa/6zXcZ1T/UlQqtD7PLNNcFDJYACQeo8BYzSsCO6HSpltBrbaRYNAvn1Dbo\n" \ "F73XIMqc/K60UGehrMYV/9D0/cTyk6Z6OtLXnUxD9kgYugR06drmQ6a0anJETcCS\n" \ "Bsa/pZc1HMb34v0eOz7UB2Eo0V4Qnng3ulzVajS5crRvO1lR/flg5Pv+YMmucreQ\n" \ "Dy8rstIiWXEa6liRoKEPIg3QDTcL3pfhSXty\n" \ "-----END CERTIFICATE-----\n" \ "-----BEGIN CERTIFICATE-----\n" \ "MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx\n" \ "EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT\n" \ "EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp\n" \ "ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3\n" \ "MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH\n" \ "EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE\n" \ "CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD\n" \ "EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi\n" \ "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD\n" \ "BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv\n" \ "K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e\n" \ "cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY\n" \ "pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n\n" \ "eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB\n" \ "AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV\n" \ "HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv\n" \ "9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v\n" \ "b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n\n" \ "b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG\n" \ "CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv\n" \ "MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz\n" \ "91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2\n" \ "RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi\n" \ "DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11\n" \ "GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x\n" \ "LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB\n" \ "-----END CERTIFICATE-----\n" \ ; // ⑥Beebotteパラメータ const char *clientID = "esp32_001"; const char *channelToken = "### Beebotte-TOKEN ###"; const char *topic = "TestChannel/resource1"; // 以下は2019年5月の証明書データ(必要により書き換え下さい) const char *beebottle_ca_cert = \ "-----BEGIN CERTIFICATE-----\n" \ "MIIFWDCCBECgAwIBAgIQc+iqrz6j/mo1ROEggN1a9TANBgkqhkiG9w0BAQsFADCB\n" \ "kDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n" \ "A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxNjA0BgNV\n" \ "BAMTLUNPTU9ETyBSU0EgRG9tYWluIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZlciBD\n" \ "QTAeFw0xNDA4MDQwMDAwMDBaFw0xOTA4MDMyMzU5NTlaMFUxITAfBgNVBAsTGERv\n" \ "bWFpbiBDb250cm9sIFZhbGlkYXRlZDEUMBIGA1UECxMLUG9zaXRpdmVTU0wxGjAY\n" \ "BgNVBAMTEW1xdHQuYmVlYm90dGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\n" \ "MIIBCgKCAQEA1CXVd9uNvtbjwOsBWQJXBSInzP7adEhENtCSvncIli5GaelOBslm\n" \ "XgwPfrorxFItoDtFNvHpuSgORZU01mhzGLSGTP781DpeFhuPlBUr8QvCDnykX8wP\n" \ "siLBJQkU9Ryo5qF2S07ABMimnuBB7E+LAd3PGABEe0PAJd/N1PstDJJEW5fwgJfy\n" \ "eoVM1qL/dKZ10HjwS1e0rxa0oT7oYrv48Vfh76nc83t7ogqUIwBzH6RqPH/OYZ0P\n" \ "K42XcVo2n4G4ljV+I+G7qLd4ltsFK2aXgW2wbj38+Prn/qY4oLMIyrQI7NU+ROwI\n" \ "Vd8Ph1PGlv6ldjTcEGFVfKMusIUkFSb0+wIDAQABo4IB5jCCAeIwHwYDVR0jBBgw\n" \ "FoAUkK9qOpRaC9iQ6hJWc99DtDoo2ucwHQYDVR0OBBYEFIQkJfpBIb+8Fuk9YlvY\n" \ "7brK+30eMA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQG\n" \ "CCsGAQUFBwMBBggrBgEFBQcDAjBQBgNVHSAESTBHMDsGDCsGAQQBsjEBAgEDBDAr\n" \ "MCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8ubmV0L0NQUzAIBgZn\n" \ "gQwBAgEwVAYDVR0fBE0wSzBJoEegRYZDaHR0cDovL2NybC5jb21vZG9jYS5jb20v\n" \ "Q09NT0RPUlNBRG9tYWluVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNybDCBhQYI\n" \ "KwYBBQUHAQEEeTB3ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LmNvbW9kb2NhLmNv\n" \ "bS9DT01PRE9SU0FEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCQG\n" \ "CCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wMwYDVR0RBCwwKoIR\n" \ "bXF0dC5iZWVib3R0ZS5jb22CFXd3dy5tcXR0LmJlZWJvdHRlLmNvbTANBgkqhkiG\n" \ "9w0BAQsFAAOCAQEAMi2wfDj1bxWbkUUXP07XP9SA12zYrwUXvf+ft3r4FTFXkEXz\n" \ "dKrGHPfa/Y83ZIU5qJzysHq96kegJ81W0mGDd87zkaVJqWGzGzJHw9+mEfwv2X6+\n" \ "TAvXEMB3ly7KG1iEpALo3oj7ksUbNUy1ArAtdvna9ieVdR5lJN1sQpL76UqN7cS+\n" \ "Af8wq3+ErQkkwz45njQNIGoyOqZ8DhNX/rbUsgwuY+i7mhTMR8heG4t3pfYS6K8A\n" \ "6XiO0i2LHrgQ3KWTnKHGABHQe5ahkE0u8TEWZ5Ut92Uw13FJ+ltolG1F9W/udSeH\n" \ "kT9UpgO0CHEsi3MljGVOk74A2aCUPk7Swfin0w==\n" \ "-----END CERTIFICATE-----\n" \ "-----BEGIN CERTIFICATE-----\n" \ "MIIGCDCCA/CgAwIBAgIQKy5u6tl1NmwUim7bo3yMBzANBgkqhkiG9w0BAQwFADCB\n" \ "hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n" \ "A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV\n" \ "BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMjEy\n" \ "MDAwMDAwWhcNMjkwMjExMjM1OTU5WjCBkDELMAkGA1UEBhMCR0IxGzAZBgNVBAgT\n" \ "EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR\n" \ "Q09NT0RPIENBIExpbWl0ZWQxNjA0BgNVBAMTLUNPTU9ETyBSU0EgRG9tYWluIFZh\n" \ "bGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" \ "ADCCAQoCggEBAI7CAhnhoFmk6zg1jSz9AdDTScBkxwtiBUUWOqigwAwCfx3M28Sh\n" \ "bXcDow+G+eMGnD4LgYqbSRutA776S9uMIO3Vzl5ljj4Nr0zCsLdFXlIvNN5IJGS0\n" \ "Qa4Al/e+Z96e0HqnU4A7fK31llVvl0cKfIWLIpeNs4TgllfQcBhglo/uLQeTnaG6\n" \ "ytHNe+nEKpooIZFNb5JPJaXyejXdJtxGpdCsWTWM/06RQ1A/WZMebFEh7lgUq/51\n" \ "UHg+TLAchhP6a5i84DuUHoVS3AOTJBhuyydRReZw3iVDpA3hSqXttn7IzW3uLh0n\n" \ "c13cRTCAquOyQQuvvUSH2rnlG51/ruWFgqUCAwEAAaOCAWUwggFhMB8GA1UdIwQY\n" \ "MBaAFLuvfgI9+qbxPISOre44mOzZMjLUMB0GA1UdDgQWBBSQr2o6lFoL2JDqElZz\n" \ "30O0Oija5zAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV\n" \ "HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgG\n" \ "BmeBDAECATBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNv\n" \ "bS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcB\n" \ "AQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9E\n" \ "T1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21v\n" \ "ZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAE4rdk+SHGI2ibp3wScF9BzWRJ2p\n" \ "mj6q1WZmAT7qSeaiNbz69t2Vjpk1mA42GHWx3d1Qcnyu3HeIzg/3kCDKo2cuH1Z/\n" \ "e+FE6kKVxF0NAVBGFfKBiVlsit2M8RKhjTpCipj4SzR7JzsItG8kO3KdY3RYPBps\n" \ "P0/HEZrIqPW1N+8QRcZs2eBelSaz662jue5/DJpmNXMyYE7l3YphLG5SEXdoltMY\n" \ "dVEVABt0iN3hxzgEQyjpFv3ZBdRdRydg1vs4O2xyopT4Qhrf7W8GjEXCBgCq5Ojc\n" \ "2bXhc3js9iPc0d1sjhqPpepUfJa3w/5Vjo1JXvxku88+vZbrac2/4EjxYoIQ5QxG\n" \ "V/Iz2tDIY+3GH5QFlkoakdH368+PUq4NCNk+qKBR6cGHdNXJ93SrLlP7u3r7l+L4\n" \ "HyaPs9Kg4DdbKDsx5Q5XLVq4rXmsXiBmGqW5prU5wfWYQ//u+aen/e7KJD2AFsQX\n" \ "j4rBYKEMrltDR5FL1ZoXX/nUh8HCjLfn4g8wGTeGrODcQgPmlKidrv0PJFGUzpII\n" \ "0fxQ8ANAe4hZ7Q7drNJ3gjTcBpUC2JD5Leo31Rpg0Gcg19hCC0Wvgmje3WYkN5Ap\n" \ "lBlGGSW4gNfL1IYoakRwJiNiqZ+Gb7+6kHDSVneFeO/qJakXzlByjAA6quPbYzSf\n" \ "+AZxAeKCINT+b72x\n" \ "-----END CERTIFICATE-----\n" \ "-----BEGIN CERTIFICATE-----\n" \ "MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv\n" \ "MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk\n" \ "ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF\n" \ "eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow\n" \ "gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" \ "BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD\n" \ "VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkq\n" \ "hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNw\n" \ "AHG8U9/E+ioSj0t/EFa9n3Byt2F/yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR6\n" \ "2RRr55yzhaCCenavcZDX7P0N+pxs+t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onr\n" \ "ayzT7Y+YHBSrfuXjbvzYqOSSJNpDa2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt\n" \ "4Q08RWD8MpZRJ7xnw8outmvqRsfHIKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIq\n" \ "m1y9TBsoilwie7SrmNnu4FGDwwlGTm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/\n" \ "vOldxJuvRZnio1oktLqpVj3Pb6r/SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT\n" \ "8dm74YlguIwoVqwUHZwK53Hrzw7dPamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IE\n" \ "IlKVgJNp6I5MZfGRAy1wdALqi2cVKWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfO\n" \ "KJwGRXa/ghgntNWutMtQ5mv0TIZxMOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPO\n" \ "GHFrK+ymircxXDpqR+DDeVnWIBqv8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/\n" \ "s1Hap0flhFMCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g\n" \ "JMtUGjAdBgNVHQ4EFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQD\n" \ "AgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9\n" \ "MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVy\n" \ "bmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6\n" \ "Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQ\n" \ "zbihKVcN6Fr30ek+8nYEbvFScLsePP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfj\n" \ "Jw5dhHk3QBN39bSsHNA7qxcS1u80GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLY\n" \ "Uspzgb8c8+a4bmYRBbMelC1/kZWSWfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5\n" \ "B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx\n" \ "PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR\n" \ "pu/xO28QOG8=\n" \ "-----END CERTIFICATE-----\n" \ "-----BEGIN CERTIFICATE-----\n" \ "MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU\n" \ "MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs\n" \ "IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290\n" \ "MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux\n" \ "FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h\n" \ "bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v\n" \ "dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt\n" \ "H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9\n" \ "uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX\n" \ "mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX\n" \ "a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN\n" \ "E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0\n" \ "WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD\n" \ "VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0\n" \ "Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU\n" \ "cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx\n" \ "IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN\n" \ "AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH\n" \ "YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5\n" \ "6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC\n" \ "Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX\n" \ "c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a\n" \ "mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=\n" \ "-----END CERTIFICATE-----\n" \ ; |
(7)top.html
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 |
<!doctype html> <html> <!-- ①headタグ --> <head> <meta charset='UTF-8'/> <meta name='viewport' content='width=device-width'/> <!-- ②StyleSheet --> <style type='text/css'><!-- #contents { width: 100%; max-width: 320px; } #menu{ color: #fff; background: #222; } .autumn { background-image: -webkit-radial-gradient(27% 185%, #F9F6F1 0%, #D7D0C5 100%); background-image: radial-gradient(27% 185%, #F9F6F1 0%, #D7D0C5 100%); } button { width:155px; height:35px } #dispStatus{ color: #f00; } footer { text-align: right; } --></style> <!-- ③Javascript --> <script type='text/javascript' src='rem.js'></script> </head> <!-- ④bodyタグ --> <body class='autumn'><center><div id='contents'> <!-- ⑤headerタグ --> <header><h3>IoT電子工作キット<font size=-1> [ver1]</font></h3></header> <!-- ⑥menu名 --> <div id='menu'>リモコン制御画面</div> <div align=right><a href='/set'>[設定]</a></div> <!-- ⑦温度・湿度・照度情報 --> <font size=-1><table> <tr><td>温度:</td><td id='curTemp'>-- ℃</td> <td style='padding-left:10px'>湿度:</td><td id='curHum'>-- %</td> <td style='padding-left:10px'>照度:</td><td id='curLig'>--</td></tr> </table></font> <!-- ⑧tableタグ --> <table> <tr> <!-- ⑨buttonタグ --> <td><button id='btn0' class='cntbtn' onClick="snd(0)"> <font size=+1><span id='spn0'>-</span></font></button></td> <td><button id='btn1' class='cntbtn' onClick="snd(1)"> <font size=+1><span id='spn1'>-</span></font></button></td> </tr> <tr> <td><button id='btn2' class='cntbtn' onClick="snd(2)"> <font size=+1><span id='spn2'>-</span></font></button></td> <td><button id='btn3' class='cntbtn' onClick="snd(3)"> <font size=+1><span id='spn3'>-</span></font></button></td> </tr> <tr> <td><button id='btn4' class='cntbtn' onClick="snd(4)"> <font size=+1><span id='spn4'>-</span></font></button></td> <td><button id='btn5' class='cntbtn' onClick="snd(5)"> <font size=+1><span id='spn5'>-</span></font></button></td> </tr> <tr> <td><button id='btn6' class='cntbtn' onClick="snd(6)"> <font size=+1><span id='spn6'>-</span></font></button></td> <td><button id='btn7' class='cntbtn' onClick="snd(7)"> <font size=+1><span id='spn7'>-</span></font></button></td> </tr> <tr> <td><button id='btn8' class='cntbtn' onClick="snd(8)"> <font size=+1><span id='spn8'>-</span></font></button></td> <td><button id='btn9' class='cntbtn' onClick="snd(9)"> <font size=+1><span id='spn9'>-</span></font></button></td> </tr> </table> <!-- ⑩状態表示 --> <div id='dispStatus'><br></div> <!-- ⑪footerタグ --> <footer><font size=-1>2019 IoT電子工作キット [SOCINNO Inc.]</font></footer> </div></center></body> </html> |
(8)set.html
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 |
<!doctype html> <html> <!-- ①headタグ --> <head> <meta charset='UTF-8'/> <meta name='viewport' content='width=device-width'/> <!-- ②StyleSheet --> <style type='text/css'><!-- #contents { width: 100%; max-width: 320px; } #menu{ color: #fff; background: #222; } .autumn { background-image: -webkit-radial-gradient(27% 185%, #F9F6F1 0%, #D7D0C5 100%); background-image: radial-gradient(27% 185%, #F9F6F1 0%, #D7D0C5 100%); } input { width:78px; height:15px; } .setbtn { width:47px; height:22px; padding:0; } #dispStatus{ color: #f00; } footer { text-align: right; } --></style> <!-- ③Javascript --> <script type='text/javascript' src='rem.js'></script> </head> <!-- ④bodyタグ --> <body class='autumn'><center><div id='contents'> <!-- ⑤headerタグ --> <header><h3>IoT電子工作キット<font size=-1> [ver1]</font></h3></header> <!-- ⑥menu名 --> <div id='menu'>リモコン設定画面</div> <div align=right><a href='/'>[制御]</a></div> <!-- ⑦tableタグ --> <table> <tr> <!-- ⑧inputタグ --> <td align=left >1<input id='ir0'/> <button class='setbtn' onClick="rcv(0)">設定</button></td> <td align=right>2<input id='ir1'/> <button class='setbtn' onClick="rcv(1)">設定</button></td> </tr> <tr> <td align=left >3<input id='ir2'/> <button class='setbtn' onClick="rcv(2)">設定</button></td> <td align=right>4<input id='ir3'/> <button class='setbtn' onClick="rcv(3)">設定</button></td> </tr> <tr> <td align=left >5<input id='ir4'/> <button class='setbtn' onClick="rcv(4)">設定</button></td> <td align=right>6<input id='ir5'/> <button class='setbtn' onClick="rcv(5)">設定</button></td> </tr> <tr> <td align=left >7<input id='ir6'/> <button class='setbtn' onClick="rcv(6)">設定</button></td> <td align=right>8<input id='ir7'/> <button class='setbtn' onClick="rcv(7)">設定</button></td> </tr> <tr> <td align=left >9<input id='ir8'/> <button class='setbtn' onClick="rcv(8)">設定</button></td> <td align=right>10<input id='ir9'/> <button class='setbtn' onClick="rcv(9)">設定</button></td> </tr> </table> <!-- ⑨状態表示 --> <div id='dispStatus'><br></div> <!-- ⑩footerタグ --> <footer><font size=-1>2019 IoT電子工作キット [SOCINNO Inc.]</font></footer> </div></center></body> </html> |
(9)rem.js
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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
// ①onloadは画面が読み込まれた時に実行 window.onload = function () { // ②アクセスしているURLを取得しページ判定(例:http://192.168.1.123:12193/set) var url = window.location.href; var urlarr = url.split("/"); // ③設定ページでない場合にIF文内を処理 if ( urlarr[3].indexOf("set") == -1 ) { // ④温・湿・照度情報の更新処理実行 updateTemp(); } // ⑤リモコンボタン情報の更新処理実行 updateIr(); } // ⑥温・湿・照度情報取得・表示 function updateTemp() { // ⑦HTTPリクエストを作成 var xhr = new XMLHttpRequest(); // ⑧アクセスしているURLを取得し同じホスト(Port)取得(例:http://192.168.1.123:12193/getrem) var url = window.location.href; var urlarr = url.split("/"); // ⑨同じホスト(Port)へデータ取得アクセスURIを設定 url = "http://" + urlarr[2] + "/gettemp"; // ⑩タイムアウト処理時の処理 xhr.timeout = 5000; // 5秒 xhr.ontimeout = function(e){ document.getElementById('dispStatus').innerHTML = "<b>本体へのアクセスが失敗</b>"; }; // ⑪HTTP GETアクセス xhr.open("GET", url); xhr.send(""); // ⑫応答時の処理 xhr.addEventListener("load",function(ev){ // ⑬応答データを取得しJSONデータを解析してgeRecvに保存 var resGeStr = xhr.responseText; var geRecv = JSON.parse(resGeStr); // ⑭受信データ(温度情報)が存在するか確認 if ( geRecv.t != "" ) { // ⑮Webページに温・湿・照度情報を表示 document.getElementById('curTemp').innerHTML = "<b><font size=+1>" + geRecv.t + "</font></b> ℃"; document.getElementById('curHum').innerHTML = "<b><font size=+1>" + geRecv.h + "</font></b> %"; document.getElementById('curLig').innerHTML = "<b><font size=+1>" + geRecv.l + "</font></b>"; } }); } // ⑯リモコンボタン情報取得・表示 function updateIr() { var xhr = new XMLHttpRequest(); var url = window.location.href; var urlarr = url.split("/"); // ⑰アクセスURL作成(例:http://192.168.1.123:12193/getrem) url = "http://" + urlarr[2] + "/getrem"; xhr.timeout = 5000; xhr.ontimeout = function(e){ document.getElementById('dispStatus').innerHTML = "<b>本体へのアクセスが失敗</b>"; }; xhr.open("GET", url); xhr.send(""); xhr.addEventListener("load",function(ev){ var resGtStr = xhr.responseText; var gtRecv = JSON.parse(resGtStr); // ⑱ボタン10個分のデータを確認 for ( i=0 ; i<10 ; i++) { // ⑲受信データ(ボタン名)が存在するか確認 if ( gtRecv[i] != "" && typeof gtRecv[i] !== "undefined" ) { var idname = "spn" + i; if ( document.getElementById(idname) != null ) { // ⑳"spn0-9"が存在した場合(制御画面)にボタン名を入力 document.getElementById(idname).innerHTML = gtRecv[i]; } else { // ㉑"spn0-9"が存在しない場合(設定画面)にボタン名を"ir0-9"に入力 idname = "ir" + i; document.getElementById(idname).value = gtRecv[i]; } } else { // ㉒"btn0-9"が存在した場合(制御画面)でボタン名がなければボタンを無効化 var idname = "btn" + i; if ( document.getElementById(idname) != null ) { document.getElementById(idname).disabled = true; } } } }); } // ㉓グローバル変数を定義(送受信の関数で利用) irFlg=false; // 受信処理中フラグ(true:処理中、false:処理可能) flgRed=true; // 状態表示の表示・非表示フラグ count=0; // 1秒毎にカウントしタイムアウト判定用 rcvTimer=15; // タイムアウト秒数 // ㉔リモコン信号処理 function snd(setNum) { // ㉕処置中判定 if (irFlg) { // ㉖処置中の場合は処理中表示し終了 document.getElementById('dispStatus').innerHTML = "<b>処理中です</b>"; return; } // ㉗処置フラグを処理中とし、受信中表示処理実施 irFlg=true; document.getElementById('dispStatus').innerHTML = "<b>リモコン送信中</b>"; var xhr = new XMLHttpRequest(); var url = window.location.href; var urlarr = url.split("/"); // ㉘アクセスURL作成(例:http://192.168.1.123:12193/cntrem?n=1) url = "http://" + urlarr[2] + "/cntrem?n=" + setNum; xhr.timeout = 5000; xhr.ontimeout = function(e){ dispfail(); }; xhr.open("GET", url); xhr.send(""); xhr.addEventListener("load",function(ev){ var resStr = xhr.responseText; // ㉙OKを受信したらif文内を状態表示。それ以外はelse内を状態表示 if ( resStr.indexOf("OK") != -1 ) { document.getElementById('dispStatus').innerHTML = "<b>リモコン送信しました。</b>"; } else { document.getElementById('dispStatus').innerHTML = "<b>リモコン送信に失敗しました。</b>"; } // ㉚処置フラグを戻す irFlg=false; }); } // ㉛リモコン受信処理 function rcv(setNum){ // ㉜処理カウンタリセット count = 0; // ㉝処置中判定 if (irFlg) { // ㉞処置中の場合は処理中表示し終了 document.getElementById('dispStatus').innerHTML = "<b>処理中です</b>"; return; } // ㉟処置フラグを処理中とし、受信中表示処理実施 irFlg=true; setMsgTenmetu(); // ㊱入力したボタン名を取得 var idname = "ir" + setNum; var setName = document.getElementById(idname).value; // ㊲受信設定処理へ本体へアクセス var xhr = new XMLHttpRequest(); var url = window.location.href; var urlarr = url.split("/"); url = "http://" + urlarr[2] + "/setrem?n=" + setNum + "&a=" + setName; xhr.timeout = rcvTimer * 1000; xhr.ontimeout = function(e){ dispfail(); }; xhr.open("GET", url); xhr.send(""); xhr.addEventListener("load",function(ev){ var resStr = xhr.responseText; // ㊳OKを受信したらif文内を状態表示。それ以外はelse内を状態表示 if ( resStr.indexOf("OK") != -1 ) { // ㊴フラグを受信完了へ。状態表示に完了表示 irFlg=false; document.getElementById('dispStatus').innerHTML = "<b>リモコン設定が完了しました。</b>"; } else { // ㊵失敗表示 dispfail(); } }); } // ㊶状態表示の点滅処理(リモコン受信中) function setMsgTenmetu(){ // ㊷受信完了していない。かつ、タイムアウト前 if (irFlg == true && count < rcvTimer ) { // 受信完了してなければ // ㊸flgRedで1秒毎にIF文内とelse文内を交互に表示(受信中を点滅) if(flgRed){ document.getElementById('dispStatus').innerHTML = "<b>リモコン受信中(" + rcvTimer + "秒間)</b>"; }else{ document.getElementById('dispStatus').innerHTML = "<br>"; } // ㊹状態表示状態を反転 flgRed=!flgRed; // ㊺1秒後に、再度setMsgTenmetu()を実行 setTimeout("setMsgTenmetu()",1000); count++; // ㊻タイムアウトしていた場合は失敗処理へ } else if (count >= rcvTimer) { dispfail(); } } // ㊼失敗時の表示 function dispfail(){ // ㊽点滅しないようにタイマーアウトにカウントを合わせる count=rcvTimer; irFlg=false; // ㊾状態に失敗を表示 document.getElementById('dispStatus').innerHTML = "<b>リモコン受信に失敗しました。</b>"; } |