Introduction: Raspberry Piでホームオートメーション

About: 組み込み系システム、ガーデニング、ドローンに興味あり

このページで紹介していたConductor piは、より簡易に使えるConductor-liteに移行しましたので、これから試したい方はConductor-liteのページをご覧ください。

=======================================

Raspberry piを使ってGPIOを制御したりセンサーの値を読んだりするための方法は数多くの情報がありますが、Webブラウザから制御したり、タイマーで制御したりするためには、やはりそれなりのプログラムの作成が必要になってしまいます。そこで、そのプログラミングの労力を減らすことのできるミドルウェアConductor piを使って、ホームオートメーションを作成することにしました。Conductor piを使うとブラウザ経由でGUIを使って制御論理を組み上げたり、リモートでIOを制御することができます。

STEP1〜STEP6では、Raspberry piの出力ポートをタイマーやWebブラウザでON/OFFする基本的な方法を紹介しています。STEP7では番外編でAppleのHomekitとの連携を記載しています。

将来的には(興味のある方が多いようなら)、気温や気圧、湿度を観測し、それらの値や季節によって、庭の散水や池の給水を制御したり、スマートフォンから制御するシステムを紹介する予定です。

ここの例では、クライアント(開発環境)にMac(ブラウザはSafari)を使っています。

Step 1: SD CardへOSをインストール

OSのRaspbianをSDカードに書き込む。python(ver.2)も必要であるがデフォルトで含まれている。基本的にはこれだけで動作環境は十分であるが、リモートでの操作を行うためには、次のツール類もインストールすることが望ましい。

  • bonjour : Macからのファイル共有に便利
  • netatalk:Macからのファイル共有に便利

  • VNC:リモート操作(画面共有)に便利
  • upstart:ホームオートメーションソフトの自動起動に便利

    なお、これらをインストール済みのSDカードイメージもある。ただし、Raspberry pi 2 B用。

    https://docs.google.com/uc?id=0B1YenBZAdjVCdFFLd09ucGhtbjg&export=download

Step 2: リモートコントロール用アプリのインストール

リモートコントロール用アプリConductor piをインストールする。

https://koji047.stores.jp/items/573f040500d331e1c6002e70

からzipファイルをダウンロードして解凍し、Raspberry piのホームディレクトリ配下に置く。

アプリの起動は、アプリのディレクトリ(uniTimer)に移り(cd ~/uniTimer/)、CGIMain.pycを起動し、

> python CGIMain.pyc

パソコンのブラウザからRaspberry piのIPアドレスを指定しhttpでポート8080でindex.htmlにアクセスする。(下記の例では、Raspberry piのIPアドレスは192.168.1.7)

http://192.168.1.7:8080/index.html

2つ目の写真のような画面が表示されれば成功。

Step 3: タイマー設定

タイマーでGPIOをON/OFFするプログラムを作る。

以下は、サンプルプログラム(every10sec)を変更して、毎時30分に1分間だけGPIO18(12番ピン)をONにするプログラムを作成し、起動する例である。

  1. ブラウザでRaspberry piのConductor piにアクセスする。(IPアドレスが192.168.1.7なら、http://192.168.1.7:8080/index.html/)
  2. メニューの「Editor」を選択する。(30秒ほど時間がかかる)
  3. 「File」メニューからOpenを選択し「Open」ボタンを押す。

  4. 「File」メニューからSave Asを選択してファイル名を入力し(ここではremoteControl)「Save」ボタンを押す。

  5. 「every10sec」エレメントをポイントして、ダブルクリック、もしくは右ボタンからeditPropertyを選択する。

  6. 適切なインスタンス名(ここではevery10min)とし、SecプロパティをMinプロパティに変えて値を30に、Keepaliveを60に設定し、「Set」ボタンを押す。
  7. 「File」メニューからSaveを選択する。

  8. 「File」メニューからExitを選択する。
  9. Load&Startのメニューに、上記で作成したプログラム(remoteControl)を指定し、「Load&Start」ボタンを押す。

Step 4: Webブラウザで状態を見る

Conductor pi ver.0.5.2以降に付属しているsample-accessToObj.pyにアクセスすれば、ポートの状態をWebブラウザで確認することができる。raspberry piのIPアドレスが192.168.1.7ならば、

http://192.168.1.7:8080/sample-accessToObj.py

である。

sample-accessToObj.pyは、Conductor piの uniTimer/WebServer/配下に配置されており、このソースの

ConductorAPI.getObjectByName("IO")

によってエレメントにアクセスできる。ここで"IO"は、エレメントのインスタンス名であり、STEP3の"IO"エレメントである。

Step 5: Webブラウザでポートを制御する

STEP3で作成したremoteControlプログラムを改造して、WebブラウザでIOエレメントのポートをON/OFFできるようにする。

remoteControlを編集して、図のように、ORエレメントと、「インスタンス名をremoteとした」ANDエレメントを追加する。これにより、毎時30分になるか、または、WebブラウザでONを指定するか、いずれかの条件の時に、IOエレメントがONになる。

Webブラウザからのアクセスには、サンプルで付属しているsample-setToObj.pyを利用する。

http://192.168.1.7:8080/sample-setToObj.py

sample-setToObj.pyは、Conductor piの uniTimer/WebServer/配下に配置されており、このソースの

ConductorAPI.getObjectByName("remote") によってremoteエレメントにアクセスしている。

Step 6: 制御回路

STEP5までで作成したプログラムでGPIO18(Raspberry pi2 type Bの12番ピン)をON/OFFできるので、このポートにドライバをつければ外部機器を操作できる。

例えば、秋月電子のSSRを接続すればAC100Vの機器をON/OFFできる。回路図の例は図の通り。1つのSSRであればこの回路図のように直接接続できるが、複数を接続する際にはRaspberry piのポートの容量を超える可能性があるため、トランジスタでドライブすることが望ましい(ON/OFFが反転されるので注意)。なお、家庭用電源(AC100V)の取り扱いは資格等を有することもあるので十分留意のこと。

SSRで電磁弁を制御すれば散水システムになる。電磁弁はモノタローなどで購入可能。家庭用の水道の多くの呼び径は8A(1/4)である。また接続にはシーリングテープを使って水漏れを防ぐ。

Step 7: 番外編 Apple Homekit

AppleのHomekitが本格化しつつあるので、ネットを探してみると、homebridgeと呼ばれるソフトウェアが流行っているようだ。Node.js上で動作し、フロントエンドのhomebridgeとバックエンドのソフトウェアからなり、バックエンドはカスタマイズができるらしい。汎用的なバックエンドもあって、homebridge-readablehttpはhttpのリクエストインタフェースを提供する。すなわち、homebridgeとhomebridge-readablehttpを使えば、iPhone等のiOSアプリのホームや、Siriによる音声でhttpインタフェースを持つ機器をON/OFFできる。

以下は、Conductor pi 0.5.3以降に付属する(予定の)サンプルプログラムsample-remote-triggerを使ってHomeKitに対応させる例である。GPIOで電磁弁をつけて散水を制御する想定である。Siriに「散水をオンにして」と指示すれば散水が開始され、sample-remote-triggerでプログラムされている時間だけ散水を行うことができる。このように単にON/OFFをリモートで制御するのみでなく、一定時間だけ散水したりすることをカスタマイズできることが、Conductor piの特徴である。

早速インストールしてみることにしたが、Node.jsのバージョンや、Conductor piのhttpインタフェースで少々てこずった。インストールについては、幾つかのサイトで紹介されているのでそれらも参考にして欲しいが、概ね次のような手順である。

  1. raspberry piを最新化
    • sudo apt-get update、
    • sudo apt-get upgrade
  2. ライブラリのインストール
    • sudo apt-get install libavahi-compat-libdnssd-dev
  3. Node.jsのインストール。nvmを利用。
  4. homebridgeのインストール
    • npm install -g node-gyp

      sudo npm install -g homebridge
      sudo npm install -g homebridge-readablehttp

      なお、自動起動を設定していないで、raspberry piを再起動したような場合には、

      source ~/.nvm/nvm.sh

      nvm install 4.6.0

      の手順を踏む必要がある。

      以上のインストールが終わったら、~/.homebridge 直下にconfig.jsonを作る。内容は次の通り。usernameはEthernetアドレスを記載するらしい。pinはiOSアプリの設定に使う番号になるが、任意で問題ないようだ。

      {
      "bridge": {

      "name": "RaspiBridge",

      "username": "E1:95:53:70:AA:AA",

      "port": 51826,

      "pin": "030-40-200"

      },

      "description": "HomeBridge HTTP Status Control",

      "accessories": [

      {

      "accessory": "Http",

      "service": "Light",

      "name": "さんすい",

      "username": "",

      "password": "",

      "sendimmediately": "",

      "http_method": "GET",

      "on_url": "http://192.168.1.7:8080/sample-homebridge.py?rw=seton",

      "on_body": "",

      "off_url": "http://192.168.1.7:8080/sample-homebridge.py?rw=setoff"

      ,

      "off_body": "",

      "read_url": "http://192.168.1.7:8080/sample-homebridge.py?rw=read",

      "brightnessHandling": "no",

      "http_brightness_method": "",

      "brightness_url": ""

      }

      ]

      }

      ここで重要なのはread_url。このリクエストで対象の装置がONの場合は1を、OFFの場合は0を返すようにしておかないと、homebridgeがクラッシュすることがある。

      上記のhttpリクエストを処理するConductor piのsample-homebridge.pyの内容は次の通り。このソースをWebServerディレクトリ配下に配置する。動作させるプログラムは冒頭に記載したようにsample-remote-triggerである。(ソースをコピーペーストしたらpythonコードなのにインデントが崩れてしまった。悪しからず)

      def run(env) :
      import ConductorAPI

      try :

      obj = ConductorAPI.getObjectByName("remote")

      except :

      return "Cannot find IO",".txt"

      if env['REQUEST_METHOD'] == "GET" :

      import cgi

      query = cgi.parse_qsl(env.get('QUERY_STRING'))

      if len(query) > 0 :

      kv = query[0]

      if kv[0] == "rw" :

      if kv[1] == "read" :

      if obj.getState() :

      return "1",".txt"

      else :

      return "0",".txt"

      elif kv[1] == "seton" :

      obj.trigger( None, None )

      return "1",".txt"

      elif kv[1] == "setoff" :

      obj.trigger( None, "endOfKeephold" )

      return "0",".txt"

      return "-1",".txt"

      また、iOSアプリの設定(アクセサリ)の削除などを繰り返すと二度とアプリに表示されなくなる現象も見られたが、上記のusernameやpinを変えたら回復したりと、怪しげな挙動もあった。iOSのホームアプリの設定の説明は省略するが、設定は容易である。設定が終わると写真のような画面になり、Siriのコントロールも可能である。