気の向くままに辿るIT/ICT/IoT
IoT・電子工作

ブラウザ版スマートホーム操作パネルを作る

ホーム前へ次へ
ESP8266って?

ブラウザ版スマートホーム操作パネルを作る

ブラウザ版スマートホーム操作パネルを作る

PCブラウザ版スマートホーム用メイン操作パネル例
2019/04/20

 これまでESP8266/ESP-WROOM-02/ESP-WROOM-32で自作したスマートリモコンスマートコンセント/スマートプラグ用、つまり、スマートホーム/スマートハウス/IoT家電用にブラウザ版の操作パネルを作ってみるページ。

スマホブラウザ版スマートホーム用メイン操作パネル例

 ブラウザですからスマホ、タブレット、パソコンどれでも使えるわけですが、これらの間で万能にするためには、HTML/CSSでちょっとした工夫を要しますし、状況に応じてこれらの間で使い分ける場合には、ESPやRaspberry Piなどでローカルにでも都度起動、もしくは、常時稼働のサーバを立てておくのがベターでしょう。

概要

 詳細は各リンク先に譲りますが、自作したスマートリモコンやスマートコンセントは、サーバを立ててトップページ(index.html)など任意のページにアクセスすると当該家電の操作パネルを表示したり、指定したアドレスへのアクセスやONやOFFなどキーとなるワードをformタグを使って投げることで個別操作ができるように作ってあります。

 よって全てを網羅するページを1つ作ってURLへアクセスする、もしくは、キーを設定、送信すればよいことになり、それぞれメイン画面を作ってあれば、そこへのリンクを張ることで画面遷移し、そこで操作、そうでなくとも、それぞれの操作ボタン用のURLへのリンクを張れば、そのまま操作が可能という算段です。

 ウェブ上では、ハイパーリンクやフォームのボタンなどを使って実装できます。

 物理的な操作パネルもタッチパネルならパネル自体やパネルレイアウトなどはともかく、また、ボタン付きの操作ボックスを作るなら筐体や押しボタンスイッチなどはともかく、中身としては、パソコンなどの代わりにサーバとしたESP8266/ESP32ボードにHTMLファイルをアップロードして、そこから操作するようにすればよいでしょう。

必要なモノ

 HTMLファイルを作るだけなのでスマホでもタブレットでもパソコンでも何でも構いませんが、ファイル編集できる環境さえあればOKです。

 ちなみにメイン操作パネルの操作は、同一ネットワークアドレスに参加する特定のパソコンからのみということであれば、ローカルにHTMLファイルを置いておくこともできますが、前述の通り、操作するデバイスが複数ある場合、それぞれにファイルを保存しておくというのは微妙。

 よって前述のように何れかの家電用に使用するESPにファイルを持たせておくか、別途、その都度起動、または、常時起動のサーバを立てておくのが無難でしょう。

家電操作用メインパネルを入れたESP32/WeMos LOLIN32

 ちなみに自身は、音声操作がメインになり、ほぼOFF状態になるとは思いますが、一応、サーバというか、メインパネル用のHTMLファイルをSPIFFSに入れ、これを表示できるように書いたスケッチをアップしたESP開発ボード(ESP32/WeMos LOLIN32)をスイッチ付きコンセント-USB充電器にUSBケーブルを介して挿してあります。

前提

 Arduino IDEが利用できることは、もちろん、ESP8266やESP32をArduino IDEで使えるようにしておくこと。

 ESP-01やESP-02〜ESP14などのESP8266チップなら、Arduino IDEの[ツール] => [ボード]から[Generic ESP8266 Module]を選択、ESPモジュールにスケッチをアップロードできる状態であること。

 ESP32なら、[espressif/arduino-esp32]の要領でESPモジュールにスケッチをアップロードできる状態であること。

 ちなみにこれらArduino IDEの環境設定で追加する方法の場合、カンマ区切りで複数指定可能。

 参考までに自身の使用しているOSは、Debian(Linux)、Arduino IDEのバージョンは、1.8.8。

開発ボードの場合[2019/05/14追記]

 尚、ESP8266やESP32の開発ボードである場合、先のようにArduino IDEで利用可能にするとボード情報に様々な関連ボードが追加されるので、使うボードに適したものを選択することになるわけですが、例えば、次のようになります。

 ESP8266 NodeMCUボードなら、Arduino IDEの[ツール] => [ボード]から[NodeMCU 0.9 (ESP-12 Module)]や[NodeMCU 1.0 (ESP-12E Module)]などを選びます。

 ちなみにESP8266 NodeMCUボードについては、ボード上のピン番号(D0-D8)と実際のGPIOが異なるのでプログラム・スケッチを書く場合、標準でインクルードされる模様のpins_arduino.hの定義に沿って指定します。

 また、ESP32 DevKitCやDevKitボードなら、[ESP Dev Module]を、WeMos LOLIN32なら[WEMOS LOLIN32]を選びます。

 開発ボードについては、あとは基本的にArduinoボードと同様にスケッチをアップロード、電源としてUSBケーブルをつなぐか、VIN(5V)/G(ND)に5Vを供給して組んだ回路を実行するだけです。

操作パネルの作り方

 この内容を細かく書いても単なるHTML/CSS講座になってしまいますし、自身の環境におけるパネルを書いても意味がなさそうかなとも思いましたが、概略だけでも書いておくことにしました。

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Arduino.h>
#include <FS.h>
 
const char* path_root   = "/index.html";
 
const char *ssid     = "SSID;";
const char *password = "PASSPHRASE";
 
#define BUFFER_SIZE 16384
uint8_t buf[BUFFER_SIZE];
 
ESP8266WebServer server ( 80 );
 
boolean readHTML() {
  File htmlFile = SPIFFS.open(path_root, "r");
  if (!htmlFile) {
    Serial.println("Failed to open index.html");
    return false;
  }
  size_t size = htmlFile.size();
  if (size >= BUFFER_SIZE) {
    Serial.print("File Size Error:");
    Serial.println((int)size);
  } else {
    Serial.print("File Size OK:");
    Serial.println((int)size);
  }
  htmlFile.read(buf, size);
  htmlFile.close();
  return true;
}
 
void handleRoot() {
  Serial.println("Access");
 
  server.send(200, "text/html", (char *)buf);
}
 
void handleNotFound() {
 
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
 
  for ( uint8_t i = 0; i < server.args(); i++ ) {
    message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
  }
  server.send ( 404, "text/plain", message );
}
 
void setup() {
  Serial.begin(115200);
 
  SPIFFS.begin();
  if (!readHTML()) {
    Serial.println("Read HTML error!!");
  }
 
  WiFi.begin(ssid, password);
  Serial.println("");
  WiFi.mode(WIFI_STA);
 
  //wait for connection
  while ( WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
 
  if (!MDNS.begin("esphamainsrv")) {
    Serial.println("Error setting up MDNS responder!");
    while (1) {
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");
 
  server.on("/", handleRoot);
  server.onNotFound(handleNotFound);
 
  server.begin();
  Serial.println("HTTP server started");
 
  // Add service to MDNS-SD
  MDNS.addService("http", "tcp", 80);
}
 
void loop() {
  server.handleClient();
}

 例えば、サーバとするESP8266のスケッチは、こんな感じにします。

 ESP32の場合、ESP8266WebServer.h、ESP8266WiFi.h、ESP8266mDNS.hの代わりにESP32WebServer.h、WiFi.hとESPmDNS.hを、更に追加でSPIFFS.hをinclude、ESP8266WebServer server ( 80 );は、ESP32WebServer server(80);とします。

 mDNSを使っており、ここでは、esphamainsrvとしたのでブラウザでesphamainsrv.localにアクセスすると操作パネルが表示されます。

 mDNS.localでアクセスできる利便性の為、各家電用スケッチでもmDNSを使うのが賢明でしょう。

 もちろん、ESP8266/ESP32のメモリ上に配置した操作パネルとなるHTMLファイルを表示させるためには、SPIFFS環境を整え、スケッチをアップロードした上でスケッチフォルダに[data]フォルダを作成、そこにアップロードしたいindex.htmlなどの任意のファイルを置き、Aruino IDEの[ツール]メニューから[ESP8266 Sketch Data Upload]/[ESP32 Sketch Data Upload]する必要があります。

<!DOCTYPE html>
<html><head>
<meta charset="utf-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
<title>ESP8266 Home Automation</title>
<style>
body { width: 90% ;background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }
form { margin:10px ;padding:10px ;width: 100% ; }
form input { margin:2px ;padding:2px ;width: 40% ;height:100px ;background-color:blue ;color:yellow ;font-size:110% ; }
h1 { font-size: 80% ; }
</style>
</head>
<body>
<h1>ESPスマートホーム操作パネル</h1>
<form action="/" method="post">
<input type="button" name="tv" value="テレビ" onClick="location.href='http://esptv.local'">
<input type="button" name="aircon" value="エアコン" onClick="location.href='http://espaircon.local'">
<input type="button" name="aircleaner" value="空気清浄機" onClick="location.href='http://espaircleaner.local'">
<input type="button" name="ir_cool_fans" value="扇風機" onClick="location.href='http://espcoolfans.local'">
</form>
</body></html>

 同じく、SPIFFSでサーバとするESP8266/ESP32ボードのメモリ上に保存するHTMLファイルは、こんな感じにします。

 ここでは、メイン操作パネルからは、各家電の操作パネルに遷移(URLアクセス)することを想定しています。

 また、リンクには、aタグを使っても構いませんが、ここでは、フォームボタンを使っています。

 formのinputタグを使う場合、onClickイベントで[location.href=]に遷移したいURLをクォートで括って指定すれば良いわけですが、この時のtypeはbuttonにする必要があり、submitでは機能しませんでした。

 他方、遷移先の家電操作でESP8266/ESP32にデータを投げる場合は、onClickイベントは使わず、inputタグのtype属性値は、submitにする必要があり、buttonだと機能しませんでした。

 よって各家電メニューからメインメニューに戻るボタンのみtypeをbuttonに、機能操作部分は、submitにすることになるでしょう(スケッチ内容は、後段リンク先の各家電用に譲ります)。

 ちなみにメモリ上に配置するファイルサイズさえ許容されれば、HTMLファイル上で使うCSSやJavaScriptは、あくまでスマホ、タブレットやPCのブラウザで処理されることである為、ESP8266/ESP32ボードで使えるかどうかを気にかける必要はありません。

備考

 当初、自身は操作パネルのことを想定していなかったのですが、考えてみれば、あれば便利なこともあるでしょうし、ここでは、このようにすれば、簡単に集中操作パネルができますよねという情報に留め、詳細は割愛します。

 尚、市販品があるくらいなので大丈夫かなと思う一方、1軒で家電をことごとくIoT化するとWiFi帯域を結構消費するかもしれないと思うと微妙かなと...。

 よって後段リンクにある通り、既にエアコン、テレビ、空気清浄機、扇風機などリモコン家電は自作スマートリモコンで対応できていますし、自作スマートコンセントで非リモコン家電もほぼ動かせる状態ですが、今時点、検証に留め、常時稼働させているものはありません。

[2019/04/30 訂正・追記:]
 勘違い...、APモードにする(Soft_APを立てる)必要があると思い込んでいましたが、その必要はなかったので近隣への影響はないでしょう、が、宅内無線LANルーターやアクセスポイントの対応接続数に依存する?四六時中操作するわけじゃないから関係ない?、これも杞憂ですかね、なら常設もありかなと。

 ちなみに自身は、ブラウザ上の操作パネルを使うよりも自作Raspberry Pi/Julius/Open JTalkスマートスピーカーメインPCにも搭載の自作スマートスピーカー機能で音声操作する機会の方が圧倒的に多くなると思います。

 それと自身は、今のところ、外出先など外から家電を操作するつもりはありません。

 また、屋内操作でも消し忘れやスマートスピーカー操作において誤認識などから勝手にONしてしまう可能性も排除しきれない点を考慮し、転倒しても電源が落ちない直置きタイプの家電、何れにしても水がこぼれる可能性があったり、熱を発することが目的の直置き・床置き家電の無線操作による使用は考えていません。

 検証済みの扇風機や空気清浄機、サーキュレーターも所有のものは、たぶん転倒しても電源は落ちないと思いますし、テレビのように台との間に転倒防止樹脂?があり密着していて分離して持ち上げられない、台を削らないと剥がせないのではと思うほど強力な転倒防止対策もしていないので無線操作は控えようかと。

 となると実際には、宅内で遠隔操作するとしてもテレビとエアコン、自作電動スイッチ(ArduinoでなくESP8266/ESP32なら自作スマートスイッチ)を使った壁面スイッチの照明くらいになりそうです。

[2019/06/13]
 既にアップ後編集もできるというこんなすごいパネルを作ってる方がいらっしゃいました。

[2021/04/10]

 あれからすぐのことだったと思いますが、思いを改め、少なくとも今日時点、クラウドなしで快適スマートホームDIYのようにあらゆる自作スマート家電を日常的に稼働させています。

[2022/07/29]

 自身の愛用ブラウザはFirefox、スマートホーム操作パネルも作って以降、ずっとFirefoxを使っていましたが、今日、操作パネルのみMidoriに変更しました。

 というのも、なぜか、スマートカーテンだけパネルを開くのに1分40秒ほどかかるようになり、マイコン側の問題かと思いきや、Midori、Opera、Chromiumなど他のブラウザで試すと以前のFirefoxでもそうだったように10秒前後で開くことがわかったから。

 そもそも今のFirefoxでも、他の自作スマート家電については、1秒程度と即開くんですけどね。

 ちなみにDebian bullseye 11.4 stable(安定版)におけるFirefoxの現在のバージョンは、[Mozilla Firefox 91.11.0esr]。

 なぜ、ここにきてFirefoxのみ、カーテンの操作パネルを開く時だけ圧倒的に遅くなってしまったのか...謎。

[2022/08/14]

 自作スマートカーテンには最初から付けていたリセットボタンですが、それとは別にサーボモータを使ったものは、取り付け方にもよるかもしれませんが、ホーン(羽根?)を振り切ったままフリーズすることがあり、電源のON/OFFで対処していたものの、そう多くないとは言え、面倒なので、やはり、遠隔で操作できるリセットボタンをつけることにしました。

 自作IoT・スマート家電の動作方法にもよりますが、HTMLファイルにリセットボタンを追加、ESP8266/ESP32ボード側では、POSTされた、その値で判断してESP.restart()するようにしておくだけ。

 自作スマートカーテンのように駆動モータが別電源の場合は、それを止める処理は必須、サーボモータだけの場合は、ボードのソフトウェアリセットだけで十分ですが、気になるのであれば、その前にスイング角度を基準位置に戻しておくのも良いでしょう。

[2023/06/03]

 市販スマート家電用ブラウザ操作パネルと操作スクリプトを自作してみました。

 全てとは言わないまでも汎用として使えるはずです。

 これなら、ここで作ったESP32ボード上のスマートホーム用操作パネルから呼ぶこともできます。

ホーム前へ次へ