読者です 読者をやめる 読者になる 読者になる

RaspberryPiとAppleWatchでエアコンを操作するリモコンを作ってみた

最近はすっかり秋めいてきて、冷房を使うこともすくなってきましたが、 夏の間僕はよくエアコンをつけっぱなしにしたまま外出してしまうという失敗をしていました。
そこで今回は、エアコンをRaspberry Piを利用して外からでも「ON・OFF」出来るようにしてみました。 更にせっかくなので、持て余しつつあったAppleWachから操作できるようにアプリも作りました。 ものとしては簡易的なものですが、せっかくなので作り方を解説しようと思います。

出来たもの↓

www.youtube.com

f:id:itarenai:20151008012909j:plain

おしながき

前提

今回は、エアコンの「ON」「OFF」操作のみやってみました、応用すれば他の設定も操作できます。

  • 「Raspberry Pi」と周辺機器を持っていて、「 Raspberry Pi」の基本設定ができていること。(これは絶対)

種類はなんでもいいけど、僕はこれで作りました。

Raspberry Pi 2 Model B (1)

Raspberry Pi 2 Model B (1)

(基本設定ができていない場合はこちらを見てセットアップするといいかも)

qiita.com

  • AppleWatch。。。。なくても、ブラウザからのエアコン操作までは出来ます!

手順

部品購入

リモコンソフト準備

インストール
$ apt-get upgrade
$ apt-get update
$ sudo apt-get install lirc
設定

以下を開き

nano /boot/config.txt

以下をファイルの一番下に追記。 ここで、センサーとのつなぎ込みで利用するGPIOのPIN番号を定義する。

dtoverlay=lirc-rpi, gpio_in_pin=24, gpio_out_pin=25
#pio_in_pin={GPIOの任意の番号、学習時に利用する}, gpio_out_pin={GPIOの任意の番号、制御時に利用する}

再起動

reboot

以下のコマンドで確認、存在したら成功。

$ ls /dev/lirc* -la

crw-rw---T 1 root video 245, 0  1月  1  1970 /dev/lirc0

更に以下のファイルを適切に書き換えます。

$ nano /etc/lirc/hardware.conf 

#書き換えた部分
LIRCD_ARGS=""
↓
LIRCD_ARGS="--uinput"

DRIVER="UNCONFIGURED"
↓
DRIVER="default"

DEVICE=""
↓
DEVICE = "/dev/lirc0"

MODULES=""
↓
MODULES = "lirc_rpi"

赤外線パターン学習

前準備

エアコンのリモコンを準備しておきます。
学習には、材料購入の部分で説明した「 赤外線リモコン受信モジュール」を利用します。
以下の図のような形で接続します。
GPIOのPIN番については「24」に設定しています。 f:id:itarenai:20151004184809p:plain

学習テスト

以下のコマンドを実行して、リモコンを「 赤外線リモコン受信モジュール」に向けて適当なボタンを押してみます。 受信できていれば、数字などが表示されます。これでテストは完了です。

$ sudo /etc/init.d/lirc stop
$ mode2 -d /dev/lirc0

space 2609553
pulse 417
space 449
pulse 424
space 447
pulse 427
space 449
pulse 420
space 463
pulse 408
...
学習

実際に学習させてみます。
以下のコマンドを打った後、リモコンを赤外線受光器に向けてボタンを押します。
「電源ON」ボタンを押して、以下を実行する、数値が出てくると思うのでそれが止まったら 「Ctrl+C」(連打とかはしない)

$ mode2 -d /dev/lirc0 | tee on

「電源OFF」ボタンを押して、以下を実行する、数値が出てくると思うのでそれが止まったら 「Ctrl+C」(連打とかはしない)

$ mode2 -d /dev/lirc0 | tee off

それぞれが終了したら、「on」と「off」というファイルができているはずなので確認します。

$ ls -lsa

以下のスクリプトを用いて、先ほど出力したファイル「on」と「off」を加工します。

lines =  File.open(ARGV[0]).readlines #行ごとに配列として読み込み
lines_without_first = lines.slice(1..-1) #先頭の行は不必要なので省く
puts lines_without_first.map{|line|line.split(" ")[1]}.join(" ") #整形して表示

以下の様な出力がされると思います。
この数値は、先ほどの出力した文字列の数字部分のみを並べたものです。

$ ruby parse.rb off
412 451 423 446 424 452 420 451 419 451 421 25294 3475 1752 426 1321 429 447 424 441 423 464 405 1325 426 450 414 451 423 450 422 451 423 1318 438 436 423 1315 433 1313 424 446 427 1320 473 1269 422 1321 426 1321 428 1313 423 453 421 449 419 1324 423 450 416 470 405 447 427 482 386 455 419 452 422 449 418 455 420 450 420 454 420 1320 420 454 416 453 420 455 418 453 417 456 420 449 423 454 432 448 405 454 423 451 420 474 393 451 426 449 421 444 425 453 419 449 493 381 424 460 411 449 421 462 411 451 485 380 424 456 421 449 445 422 422 451 422 455 434 436 422 451 487 ....

以下のテンプレートを、適当な適当なテキストエディターにコピペします。

$ nano /etc/lirc/lircd.conf
# Please make this file available to others
# by sending it to <lirc@bartelmus.de>
#
# this config file was automatically generated
# using lirc-0.9.0-pre1(default) on 2015
#
# contributed by <% YOUR NAME %>
#
# brand: <% BRAND %>
# model no. of remote control: <% MODEL No. %>
# devices being controlled by this remote: <% DEVICE %>
#

begin remote

  name  aircon
  flags RAW_CODES
  eps            30
  aeps          100

  gap          200000
  toggle_bit_mask 0x0

      begin raw_codes
    name on
     <%A%>

    name off
    <%B%>
      end raw_codes

end remote

そして、以下の2つの置換作業を行ってください。
この時「parse.rb」で加工した数値は長いので、スペースが開いている部分で適度に改行を入れてください。
また、<% ... %>で囲まれた部分は自分の情報を入れてください。

  • <%A%>をここに「on」ファイルから「parse.rb」で加工した数値に置き換えます。
  • <%B%>をここに「off」ファイルから「parse.rb」で加工した数値に置き換えます。

以下を開き、上で作成した設定データで上書きしてください。

$ nano /etc/lirc/lircd.conf

以上で「赤外線パターン学習」は終了です。

エアコン操作

ここからは、いよいよエアコンを操作してみましょう。

まずは、「赤外線LED」をraspberry piと以下のように接続してください。

アノード(+:長い方)をGPIOのPIN番号25

カソード(ー:短い方)をGND

f:id:itarenai:20151004214130p:plain

接続が終わったら、lircdの起動を起動させます。

$ sudo /etc/init.d/lirc start

自動で起動したい場合は、update-rc.dで登録します。

$ sudo update-rc.d lirc defaults

正常に動いてるか確認します、それぞれのコマンドを実行して、それぞれの下に出てるような文字列が出力されていたら、成功です。

$ irsend LIST '' ''
irsend: aircon
$ irsend LIST aircon ''
irsend: 0000000000000001 off
irsend: 0000000000000002 on

エアコンにLEDを向けて、以下のコマンドで 実行します、この時エアコンはオフにしておいてください。

$ irsend SEND_ONCE aircon on

うまくいっていれば、エアコンの電源がつくはずです!
(赤外線LEDの強度は弱いので、動かなかった場合はエアコンに近づけてやってみてください。)

WEBサーバの準備

外部からのHTTP通信経由でエアコンの操作を行えるようにしたいので、Apachephpのインストールを行います。 Apachephpを選んだのは一番手軽だったからです。

以下のコマンドでインストールできます。

$ sudo apt-get install apache2
$ sudo apt-get install php5
$ sudo update-rc.d apache2 defaults #起動時にapacheが自動で立ち上がるように設定

動いているか確認したいので、ドキュメントルートにPHPファイルを作って見ます。

echo "<?php echo 'Hello World'; ?> " >> /var/www/index.php

ブラウザで、raspberry piのIPにアクセスしてみてください。 このように、表示されていたら成功です。

f:id:itarenai:20151004220518p:plain

それでは、WEB経由でエアコンを操作できるようにしていきます。
以下のソース/var/www/index.phpに貼り付けてください。

<?php 

$type = $_GET["type"];
if (empty($type)) {
    echo json_encode(array("status"=>500,"text"=>"ステータスが不明です"));
}

if ($type === "on") {
    exec("irsend SEND_ONCE aircon on");
    echo json_encode(array("status"=>200,"text"=>"ONにしました!"));
    exit();
}else if ($type === "off") {
    exec("irsend SEND_ONCE aircon off");
    echo json_encode(array("status"=>200,"text"=>"OFFにしました!"));
    exit();
}else{
    echo json_encode(array("status"=>500,"text"=>"ステータスが不明です"));
    exit();

}

$type = $_GET["type"];これでURLクエリーを取得します。

exec("");こちらのexecというのがShellコマンドを動かすPHPの関数です。

その中に、先ほどの項でも利用したirsend SEND_ONCE aircon onという操作コマンドを入れています。

json_encode()関数でJSONを返すようにしています。

AppleWatchアプリの作成

プロジェクト立ち上げ

まずはXcodeを立ち上げて、プロジェクトを作成してください。
File > New > Project f:id:itarenai:20151004224656p:plain

作成するアプリの種類を選択する画面が出るのでAppleWachを選択 f:id:itarenai:20151004224831p:plain

アプリ名や作成者名を入れるところがあるので、適切に入れて、保存。 f:id:itarenai:20151004225010p:plain

作成画面に移る f:id:itarenai:20151004225254p:plain

UI作成

ストーリボードへアクセスする。
左のメニューバー>aricontoroller WatchKit App>Interface.storyboard f:id:itarenai:20151004225834p:plain
左下に「ボタン」や「ラベル」などの部品が置かれています。
そこから「ボタン」2つと「ラベル」を一つ、ドラックしてAppleWachっぽい枠の中に持って行ってください。

ボタン

f:id:itarenai:20151004230213p:plain

ラベル

f:id:itarenai:20151004230233p:plain

ボタンとラベルに以下の様な名前をつけます。
部品の中心部分をダブルクリックすれば、編集できるようになります。 f:id:itarenai:20151004230359p:plain

動きをつけていく

ここから実際に動きをプログラムしUIと関連付けていきます。

ソースを書くファイルを作成します。
左のメニューバー>aricontoroller WatchKit Extension>右クリック>New File f:id:itarenai:20151004230832p:plain

追加するファイルの種類が選択できるので「WachOS」の「Wachkit Class」をクリックします。 f:id:itarenai:20151004231112p:plain

ファイル名などの設定が出るので、以下の設定を行います。

Class:AriController
Subclass of:WachkitController f:id:itarenai:20151004231211p:plain

ソースコードの雛形がでます。 f:id:itarenai:20151005004350p:plain

以下のソースを、「AriController 」に貼り付けます。

//
//  AirController.swift
//  aircontrollerapp
//
//  Created by wanwan on 2015/10/03.
//  Copyright © 2015年 wanwan. All rights reserved.
//

import WatchKit
import Foundation

class AirController: WKInterfaceController {
    
    @IBOutlet var StatusLabel: WKInterfaceLabel!
    var task: NSURLSessionDataTask?
    
    override func willActivate() {
        self.Set("");
        super.willActivate()
    }
    
    @IBAction func OnAction() {
        self.Set("on");
    }
    
    @IBAction func OffAction() {
        self.Set("off");
    }
    private func Set(type:String){
        
        let url = NSURL(string:"http://{IPアドレス}/index.php?type="+type)!
        let conf = NSURLSessionConfiguration.defaultSessionConfiguration()
        let session = NSURLSession(configuration: conf)
        print(url);
        self.task = session.dataTaskWithURL(url) { (data, res, error) -> Void in
            if let e = error {
                print("dataTaskWithURL fail: \(e.debugDescription)")
                return
            }
            if let d = data {
                print(d)
                do{
                    let dict = try NSJSONSerialization.JSONObjectWithData(d, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
                    var text = dict["text"]
                    //self.StatusLabel.setAttributedText(text as! String?)
                    print(text as! String)
                    self.StatusLabel.setText(text as! String)
                    
                }catch{
                    print("error")
                }

                
            }
        }
        task!.resume()
    }

    override func didDeactivate() {
        super.didDeactivate()
    }
}

ストーリボードに戻り、右側にある設定バーの上側にある「Custom Class」の「Class」の部分に「AirController」を設定します。 これで、ソースとUIのひも付けが終わりました。

f:id:itarenai:20151004231836p:plain

f:id:itarenai:20151004231809p:plain

ソースとストーリボードを同時に見たいので、Xcodeの右上にある「輪っか」の重なったようなボタンをクリックします。

f:id:itarenai:20151004232001p:plain

以下のように、ストーリボードで作成したUIと先ほど貼り付けたソースコードが同時に見えます。 f:id:itarenai:20151005005451p:plain

以下のように、「部品」とソースコードの関数と関連付けていきます。
部品をクリックして、コントロールを押したまま、該当の場所にドラックしていきます。 f:id:itarenai:20151005010244g:plain

以上で作業は完了です。

HTTPを許可する

IOS9からはデフォルトだとhttpは禁止されるようになったようです、なのでこのままだとサーバにアクセスしようとしときにエラーが出てしまいます。

Info.slitを修正してhttpを許可する必要があります。
以下を開いてください 。

「aircontrollerapp WatchKit Extension」>「Info.plist」>右クリック > SouceCode

以下の設定を追記してください、これでhttp通信が可能になります

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

f:id:itarenai:20151007000403g:plain

動作確認

シュミレータで立ち上げてみます。

実際に「ON・OFF」ボタンを押してみて、挙動を確かめてください。 正常に動けば完成です!

f:id:itarenai:20151005010835g:plain

f:id:itarenai:20151007001916g:plain

まとめ

なんか、長くなりましたが、多分この記事を読めば完成する気がします。
逆に知ってる人にとっては長ったらしい解説になったかもしれないですが(間違えも多いかも)・・・

ただ僕は知ってる体で進められる解説記事が苦手で、よく行間にある「常識」みたいなのを知らないで引っかかっているタイプの人間なので、今回はちょっと頑張って行間みたいなのを限りなく減らそうと努力してみました。

補足や抜けミスなどがあれば、Twitterとかでメンションしていただければです><
ではお疲れ様でした〜(つ∀-)

あ、ソースも貼っときます

github.com

参考

qiita.com

itpro.nikkeibp.co.jp

yjo の覚え書き: Volumio を赤外線リモコンでコントロールする (1) lircの導入

d.hatena.ne.jp

nlogic.jp