ESP-WROOM-02とMQTT + openHABでホームオートメーションに挑戦 (1)

前回はMQTTプロトコルとESP-WROOM-02を使ってLEDをリモート操作しましたが、LEDだけでは物足りないので自宅の門柱灯を操作する目標を立てました。この電灯は少し不便なところにスイッチがあって普段は残念ながらほとんど使われていません。遠隔操作が出来れば便利に使えそうです。完成までの道のりは長そうですが一つずつクリアしていきたいと思います。

前回はCHROMEアプリのMQTTlensからLEDを操作しましたが、電灯を操作するのに毎回トピック等を入力するのでは、あまりにも操作性が悪いです。そこでオープンソフトウエアのopenHABというホームオートメーションソフトを導入しました。

openHABホーム http://www.openhab.org/

openHabはこちらに書かれていたので知ったのですが、インターネットで検索しても日本語の解説があまり無いようです。多機能ですが設定も難しそうです。いつものことですが今回も手探りの状態です。

openHABの特徴です。

  • webやiOS,Androidから操作するユーザーインターフェースがある。
  • 色々なデバイスやシステム(スイッチのON,OFFのみならずセンサーの値を表示する機能,その他諸々)を統合して管理することができる。
  • 制御に関するルール(時間、近接、明暗、温度、センサーで読んだ値に関連付け)をプログラムすることができる。
  • Java 1.7.の走るWindows, MacOS X or Linuxマシンで動かすことができる。などなど

MQTTのプロトコルにも対応していますので、前回インストールしたMQTTブローカーと連携することができます。リモート操作だけではなく、センサーやタイマーと連動するインテリジェントな動作も構築可能ですね。

上記のサイトにインストール方法等の記述がありましたので、それに沿ってインストールを行いました。(以下の記述はほぼ上記サイトの転記になってしまいました。)

openHab (version 2012/10/10現在 1.7.1) 今回は例によって自宅サーバ Debian Weezyにインストールしました。 Raspberry Pi 2にもインストールされて使われている実績があるようなので将来的にはそちらに移行するかも知れません。

java ver 1.6 以上がインストールされていることが必要だということなので調べます。

$ java -version

条件を満たしていない時

$ sudo apt-get install openjdk-7-jre

$ sudo update-alternatives --config java

openHAB本体のインストールです

$ wget -qO - 'https://bintray.com/user/downloadSubjectPublicKey?username=openhab' | sudo apt-key add -
$ echo "deb http://dl.bintray.com/openhab/apt-repo stable main" | sudo tee /etc/apt/sources.list.d/openhab.list

$ sudo apt-get update
$ sudo apt-get install openhab-runtime openhab-addon-binding-mqtt 

openHABが自動起動するようにします。私の環境の場合次のコマンドで設定しました。

$ sudo update-rc.d openhab defaults

openHAB本体のインストールが完了しましたので デモコンフィグレーションをダウンロードします。

$ wget https://bintray.com/artifact/download/openhab/bin/distribution-1.7.1-demo.zip

$ unzip distribution-1.7.1-demo.zip

$ sudo cp configurations /usr/share/openhab/
$ sudo cp addons /etc/openhab/

openHABを起動してデモを見てみます。

$ sudo /etc/init.d/openhab start

ブラウザでアクセスします。IPアドレスはインストールしたサーバのIPアドレスに読み替えてください。

http://192.168.xx.xx:8080/openhab.app?sitemap=demo

デモサイト

デモサイト

このデモを見ると照明や窓の開閉スイッチ操作だけではなく、気温や窓などのセンサーの値も表示することができるのがわかります。スイッチ操作も簡単ですね。また、ブラウザだけではなくAndroidやiOSのユーザーインターフェースも用意されています。下記はiOSのアプリです。

https://itunes.apple.com/jp/app/openhab/id492054521?mt=8

iOSへアプリをインストール後デモを見るための設定です

setting より
openHAB URL
 Local    http:サーバIPアドレス:8080
 Remode   同上

MISC
 Demo mode のチェックをはずす

 Select sitemap  Demo Houseを選択

またopenHABは非常に多くの機能をアドオンとして使うことができるようです。詳しくは下記で参照できます。

https://github.com/openhab/openhab/wiki/Linux—OS-X

さて今度はopenHabを自分の環境にカスタマイズしていきましょう。今回は動作確認ですので最低限の設定を行います。ハードは前回使用したブレッドボードに組んだ物を使います。まずサーバ側の設定です。

■opnehab.cfgの設定

$ sudo cp /etc/openhab/configurations/openhab_default.cfg /etc/openhab/configurations/openhab.cfg
$ sudo vi /etc/openhab/configurations/openhab.cfg

今回はMQTTブローカーと同じサーバにインストールしたので、下記の設定をopenhab.cfgの最下行に書き加えます。

mqtt:broker.url=tcp://127.0.0.1:1883
mqtt:broker.clientId=openHab

■sitemapの作成

$ sudo vi /etc/openhab/configurations/sitemaps/my_home.sitemap
sitemap my_home label="Main Menu"
{
   Frame label="MQTT" {
   Switch item=lamp1 label="Gatepost Lamp"
  }  
}

■itemsの作成

$ sudo vi /etc/openhab/configurations/items/my_home.items
Group All

Switch lamp1 "gatepost Lamp" (all){mqtt=">[broker:/home/gatepost/lamp/com:command:on:ON],>[broker:/home/gatepost/lamp/com:command:off:OFF],<[broker:/home/gatepost/lamp/state:state:default]"}

次にesp-wroom-02クライアント側です。 前回使用したarduinoスケッチを一部手直しします。

/* 
 Basic ESP8266 MQTT example

 This sketch demonstrates the capabilities of the pubsub library in combination
 with the ESP8266 board/library.

*/ 2015/10/12 改変
  - subscribes to the topic "/home/gatepost/lamp/com", printing out any messages
   - If the characters of the topic "/home/gatepost/lamp/com" are "ON", switch ON the ESP Led, "OFF" switch off
/*  

*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "your_SSID";
const char* password = "your_Password";
const char* mqtt_server = "192.168.xx.xx";  // mqttサーバのアドレスを設定します。

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
//unsigned char LampStatus = LOW;

void setup() {
  pinMode(5, OUTPUT);     // Initialize the 5 pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }


  // check whether ON or OFF
  if( payload[0] == 'O' && payload[1] == 'N' ) {
    digitalWrite( 5, LOW );
    client.publish("/home/gatepost/lamp/state", "ON"); 
  }
  else if( payload[0] == 'O' && payload[1] == 'F' && payload[2] == 'F' ) {
    digitalWrite( 5, HIGH );
    client.publish("/home/gatepost/lamp/state", "OFF"); 
  }
  else {
    Serial.print( "Unknown command : " );
    // Serial.println( (char*)payload );
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("/home/gatepost/lamp/com");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 75, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
}

動作のフローです。openHABがwebや携帯端末から命令をうけるとトピック名 "/home/gatepost/lamp/com"へ"ON"又は"OFF"をパブリッシュします。esp-wroom-02側は同じトピックをサブクライブしていて電灯(LED)の点灯消灯の処理を行います。またesp-wroom-02側からはトピック名"/home/gatepost/lamp/state"にて現在の状態をパブリッシュしてopenHABに知らせることができます。

■動作確認です

  • ブラウザより
    http://192.168.xx.xx:8080/openhab.app?sitemap=my_home
  • iOSアプリより
    setting -MISC
    Select sitemap Main Menuを選択

スイッチをクリック(タップ)してesp-wroom-02側のLEDが点灯又は消灯すれば成功です。

作成したサイト

作成したサイト

ESP-WROOM-02とMQTT + openHABでホームオートメーションに挑戦 (1)」への2件のフィードバック

  1. すみません、教えてください。
    arduinoとOpenHABとの使い方で たどり着きました。
    ここの記事の 機器構成がよくわからないので 教えてください。
    ESP-WROOM-02 は 何の役割をしているのでしょうか?
    ポート5をON-OFFしているのかと思いましたが
    pinMode(5, OUTPUT); あるのですが、
    メインでは ポート5は使われてませんよね。
    教えていただければ 幸いです。
    ちなみに、ESP8266やESP32は よく使ってます。

    • 大越さんこんにちは。ご質問ありがとうございます。

      ご質問の件ですが、この記事は前回の”ESP-WROOM-02とArdinoIDEでMQTTを使った遠隔Lチカの実験“の続きでして、esp8266はMQTTクライアントとして動いています。ここではPort5にLEDを繋げてOpenHabのユーザーインターフェースから動作可能かどうか実験しました。イメージ的には下記の通りです。

      【OpenHAB・MQTT Server (LinuxPC) 】<==Wifi==> MQTT Client (esp8266 LED点滅)

      この記事を書いてから、かなりの時間が経過しましたので、OpenHABのバージョンも変わってしまい記事の内容が現況に即していない様になってしまいました。ご了承ください。
      ちなみに作成した機器は数回の改良を経て現在は車庫シャッターの動作を行える様にしました。iPhoneから操作してますが、とても安定してますよ。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください