【初心者向け】Raspberry Pi 3 MODEL B + Slack でエアコンのリモコンを作ってみた

# はじめに
　　
　　はじめまして、 @shIbaInu42 です。
　　夏休みの自由研究(研究するとは言ってない)で、Raspberry Piを使ったエアコンを作成しました。
　　Qiita上や諸ブログで多く類似したネタが挙がっていますが、当方が初心者であるため、
　　初心者目線で記載しております。行き詰まったりしたので不要と思われる箇所は省きました。
　　参考になれば幸甚に存じます。
　　**【※】赤外線送信の疎通テストは実施済ですが、不良アリです。ご参考までに。**(いつかBugFixする、いt

# 0. 目次
- 1. 準備
    - 1.1. 完成品の確認
    - 1.2. 前提環境の確認
    - 1.3. 電子部品の準備
- 2. 環境構築
    - 2.1. 回路の実装
    - 2.2. 必要なOSS/プログラムの導入
    - 2.3. エアコンの信号の確認
-  3. プログラムの実装
    -  3.1. エアコンのプログラム作成
-  4. テスト
-  5. 終わりに

# 1. 準備
## 1.1. 完成品の確認
　　完成品の動作は次の通りです。
　　[![完成品の映像](http://img.youtube.com/vi/Km1y6mQR1LE/0.jpg)](http://www.youtube.com/watch?v=Km1y6mQR1LE)
　　「SlackからHubotに命令を出す」
　　→「Hubotが命令に応じた信号データを送信するプログラムを呼び出す」
　　→「予め定めたRaspberry PiのGPIOピンに信号データを流す」という仕組みです。

## 1.2. 前提環境の確認
　　今回の作成にあたっては前提環境を次の通りとしています。

```Qiita:前提環境
OS:           Mac OS X 10.10.5 Yosemite
Memory:       8GB
CPU:          2.66GHz
Raspberry Pi: 3 MODEL B (Amazonで ¥5,780 で購入。)
　※別途、モニタ、モニタとRaspberryを接続するコード、電源コード、microSDHCなどが必要となります。
```

## 1.3. 電子部品の準備
　　電子部品は Amazon.comさん, 千石電商さん(@秋葉原), マルツさん(@秋葉原) で購入しました。
　　# 秋月電子さんが夏季休暇期間中でした。ホワイト。。。
　　購入時に使ったおつかいリストを[Gist](https://gist.github.com/seiyashima/77c50d6da18e918f4f15e1a4349c0fbc)で公開します。(購入前はGistの型番で探していました)

```
項番|名称　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　|型名　　　　　　　　　　　 |価格　　　　　|入手元　　　　　　　　　　　　　　　　　　　 |備考
------------------------------------------------------------------------------------------------------------
　　　　　１|赤外線リモコン受信モジュール　　　　|GP1UX511QS|¥ 100|千石電商(@秋葉原)|特に無し
　　　　　２|丸形赤外線LED　　　　　　　　　　|SID1K10CM |¥  65|マルツ(@秋葉原)  |Gistで挙げたモノに放射強度、ピーク発光波長が近いものを購入。
　　　　　３|丸形LED拡散キャップ　　　　　　　 |不明       |¥  50|マルツ(@秋葉原)　 |特に無し
　　　　　4|抵抗 (270Ω: 1個)　　　　　　　 |不明       |¥　30|自分の道具箱　 　  |特に無し
　　　　　5|ジャンプワイヤ(オスメス: 3本)　　　|不明       |¥  54|Amazon.com　 　 |40本セットを購入し、セット価格が18円/本であったことに基づく。
　　　　　6|ジャンプワイヤ(固い&短い)　　　　　|不明       |¥   0|自分の道具箱　 　 |Arduino UNOのキットに入っていたものを流用。
------------------------------------------------------------------------------------------------------------
　　　　　　　　　　　　　　　　　　　　　　　　　　　合計|¥　　299| ※あくまで目安です。
------------------------------------------------------------------------------------------------------------
```

# 2. 環境構築
## 2.1. 回路の実装

　　[s4kr4さんの回路図](http://s4kr4.hatenablog.com/entry/2016/07/24/114444) を参考に作成しました。
　　![CirCuitOfAircon.jpg](https://qiita-image-store.s3.amazonaws.com/0/45731/b27dd04a-cfa6-397f-4d62-80a14d5a80a2.jpeg)

　　黒のジャンプワイヤはGPIOの21ピンから赤外線リモコン受信モジュールの左端に繋がっています。
　　(赤外線リモコン受信モジュールの足が5b〜7bに刺さっており、黒のジャンプワイヤは5eに刺さっています。)
　　![CircuitFromUponIt.jpg](https://qiita-image-store.s3.amazonaws.com/0/45731/ac8be8e3-d184-6146-bb7d-561635f19166.jpeg)

## 2.2. 必要なOSS/プログラムの導入

### Hubotのインストール

まず、Hubotのインストールを行います。

```Vim:command
$ mkdir <Hubot関連のデータを格納したいフォルダの名前: (例)homebot>
$ cd <mkdirで作成したフォルダ: (例)homebot>
$ sudo npm install -g hubot coffee-script yo generator-hubot
```

botの作成を行います。Owner, Bot name, Descriptionは任意ですが、
Bot adapterはslackとしましょう。

```Vim:command
$ yo hubot
? Owner: <任意: (例)seiyashima>
? Bot name:  <任意: (例)airconbot>
? Description:  <任意: (例)airconbot turn on cooler or heater depends on commands.>
? Bot adapter: slack
```

### Slackの導入

- [こちら](http://qiita.com/hhyuga201515/items/d072b886dd914d4a2a4a)を参考にSlackをインストール(雑)。
- [こちらの"slackとhubotの連携"](http://kaiware007.hatenablog.jp/entry/2015/08/30/012221)を参考にトークンを取得。(トークンはxoxbXXXXXXXという文字列です。)
- ブラウザ上で次の通りURLを入力し実行する。

```URL:URL
https://slack.com/api/users.list?token=<取得したトークン: (例)xoxbXXXXXXXXXXXXXX>
```

- SlackのユーザーIDを取得し、メモ帳などに残しておく(3章で使います)。

　　表示されたJSONの、idが記載されている"UXXX〜"がユーザーIDとなります。idが複数ある場合はread_name等でご判断を。

```Vim:command
{"id":"UXXXXXX","team_id":"TXXXXXX","name":"hogehoge","deleted":false,"color":"9f69e7","real_name":"John Doe","tz":"Asia\/Tokyo","tz_label":"Japan Standard Time","tz_offset":32400,...........
```

### wiringPiのクローンとビルド

```command
$ cd <プログラムを置きたい階層: (例)/etc/dev>
$ git clone git://git.drogon.net/wiringPi
$ cd wiringPi
$ ./build
```

wiringPiの確認

```Vim:バージョン確認コマンド
gpio -v
```

このコマンドによって、次の通りバージョン情報が表示されれば正常通りビルドできていることになります。

```Vim:バージョン情報
gpio version: 2.42
Copyright (c) 2012-2017 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
  Type: Pi 3, Revision: 02, Memory: 1024MB, Maker: Embest
  ...
```

## 2.3. エアコンの信号の確認

　　エアコンに使用しているリモコンの信号を読み取ります。
　　赤外線リモコン受信モジュールによって受信し、それを信号データファイルとして保存し、
　　送信時に用いる、といった流れになっています。
　　受信用および送信用プログラムは[ラズベリーパイ研究室](http://feijoa.jp/laboratory/raspberrypi/infrared/)さんから拝借しました。
　　私の環境ではhomebot/wirPiの階層に受信用と送信用のプログラムを配置しています。
　　もし、この通りでない場合は3章のプログラム中で指定している階層が変わってきますのでお含みおきの上、
　　プログラムを修正してください。
　　配置したら、C言語のプログラムから実行ファイルを生成します。(gcc未インストールの場合はインストールが必要です)


```:command
sudo gcc scanir.c -o scanir -lwiringPi
sudo gcc sendir.c -lm -o sendir -lwiringPi
```

### 受信プログラムの実行

　　私の環境ではGPIOの21ピンから赤外線の信号を取得しますので、該当するwiringPiのピン番号(wPi)29を引数としています。
　　GPIOの21ピンを用いていない場合は`gpio readall`にてGPIOとwPiの関係を調査して、引数に指定してください。

```:冷房の場合
sudo ./scanir coolIr.data 29
```

```:暖房の場合
sudo ./scanir heatIr.data 29
```

### 送信プログラムの実行

　　**【※】**この箇所が疎通テスト未完了となっている箇所です。ご参考までに。
　　homebot/wirPiの階層で次の通り実行すると、信号データが送信される(予定です ><;)。
　　私の環境ではGPIOの20ピンを用いているため、出力ピン番号は28となります。

```:送信する場合(冷房)
sudo ./sendir coolIr.data 28
```

```:送信する場合(暖房)
sudo ./sendir heatIr.data 28
```

# 3. プログラムの実装
　　私の場合、homebot/scriptsに次の通りプログラムを作成しました。
　　皆さんがbotを擬人化して作成されているため、私も倣って[おしゅし](https://matome.naver.jp/odai/2138467338950751001)botにしました。

### cp.execの行の解説
　　homebot/wirPiのsendir(実行ファイル)を呼び出し、
　　同じくwirPiフォルダにあるcoolIr.dataやheatIr.dataを送信しています。
　　送信する.dataファイルはSlack上でcool/heatのどの命令を入力したかによって変わります。

```CoffeeScript:airconbot.coffee
#
# airconbot can turn on as cooler or heater depends on commands
#           and turn off the room aircon
#

# userID(userlist from Slack)
uid = [ 'UXXXXXXXXX' ] # 2.2節で取得したユーザーIDを入力

# For executing script from coffeeScripts
cp = require 'child_process'

oshushi = (command, success, msg) ->  
  if msg.message.user.id in uid
     cp.exec "sudo ./wirPi/sendir ./wirPi/#{command}Ir.data 1", (error, stdout, stderr) ->
      if !error
        msg.reply "#{success}"
      else
        msg.reply "#{error}"
  else
    msg.reply '知らない子ですねぇ。。。'

module.exports = (robot) ->
  robot.respond /heat/i, (msg) ->
    oshushi('heat', '暖房のスイッチを入りぇたよ！', msg)

  robot.respond /cool/i, (msg) ->
    oshushi('cool', '冷房のスイッチを入りぇたよ！', msg)

  robot.respond /off/i, (msg) ->
    oshushi('off', 'エアコンのスイッチを切りゅよ！', msg)

```

# 4. テスト

　　本テストではSlackから命令を送信してエアコンが電源ONになるまで...ではなく、
　　Slackから命令を送信し、Raspberry Pi上で正常に実行されるまでを確認します。

### Raspberry Pi側のセッティング
　　homebotの階層で次の通りhubotを立ち上げます。
　　Raspberry Pi側のセッティングはこれだけです。

```:command
bin/hubot -a slack
```

### Slack側のセッティング

　　iPhoneでもPC上のブラウザ/クライアントアプリでも構いませんが、
　　Appsスレッドのairconbotを開きます。
　　開いたら、まずは疎通確認を行います。

```:command
ping
```

　　すると自動でairconbotから"PONG"のリプライがあります。これで疎通確認は完了です。

　　　　　　　　　　![スクリーンショット 2017-08-21 17.09.32.png](https://qiita-image-store.s3.amazonaws.com/0/45731/bba893d5-57b2-d0be-192e-af9ff43a022c.png)

　　最後にairconbotに対して、"cool"/"heat"を入力してみましょう。

　　　　　　　　　　<img width="320" alt="connectedWithAirconbot.png" src="https://qiita-image-store.s3.amazonaws.com/0/45731/25b3cd58-109c-5a07-bee0-afc0fdf6e81d.png">

　　画像がおしゅしではないので可愛さが激減しています。
　　画像を変えてやってみましょう。

　　　　　　　　![スクリーンショット 2017-08-21 17.17.43.png](https://qiita-image-store.s3.amazonaws.com/0/45731/91db2e6f-a9f6-f765-8bf7-26916540388a.png)

### **かわいい！！！！！**(おしまい)

# 5. 終わりに
### LIRCは無理ぽでした。。。
　　当初、s4kr4さんがトライされていたので海外サイト等も参考に、LIRC(Linux Infrared Remote Controller)で
　　赤外線の送受信を試みてみましたが、トラブルシューティングにかなり時間を要しました。
　　初心者は使用しないことをお薦めします。。。

### ヘルプやアドバイス、待ってます
　　この手順に沿って作成したにも関わらず、トラブルが発生した場合は
　　ご一報いただければ微力ながらヘルプしたいと思います(細やかな責任感)。
　　また、プロフェッショナルな方々、お手数ですが
　　「こうやったらできるよ」「ここは違うんじゃない〜？」といったご指導ご鞭撻いただけると幸いです。

### 以上、初投稿でした　　
　　読んでいただき、ありがとうございました！

　　**P.S.** [おしゅし](https://twitter.com/oshushidayo?lang=ja)、すごくかわいいので皆さんも、是非。
　　　　(夏休みに行った「帰ってきた大おしゅし展」で撮影した写真です。)

![oshushi_atLast.jpg](https://qiita-image-store.s3.amazonaws.com/0/45731/96e00a12-f4ac-30fd-317f-031cc7618f66.jpeg)

# 参考文献

- [LEDの接続方法](http://www.iccraft.com/parts/di/led.html)
- [Raspberry Pi 3 model B でエアコンをコントロールした話](http://s4kr4.hatenablog.com/entry/2016/07/24/114444)　　
- [赤外線リモコン信号受信・送信](http://feijoa.jp/laboratory/raspberrypi/infrared/)