スマートハウス化に向けての一歩【GoogleHome→IFTTT→ラズパイ】

## はじめに
一年ぶりくらいにまたEDF隊員として活動できるのが嬉しいですね！
![スクリーンショット 2017-12-09 11.51.06.png](https://qiita-image-store.s3.amazonaws.com/0/74580/2336fb95-7c15-d130-7e4c-c40414bb061d.png)


これで年末は楽しく過ごせそうだと思っていた矢先。。部屋の蛍光灯が切れました。
なのでそれを変えようと電気カバーを外したのですが、、魔がさし「ただ変えるのもつまらないなー」などと考えてしまいました。。「何か新しいことを」ということで、電気交換を行うついでにGoogleHomeを使って過ごしやすい環境を作ってみることにしました！

## 最初のイメージ
こんな感じなのはわかっていました。
![スクリーンショット 2017-12-10 11.27.50.png](https://qiita-image-store.s3.amazonaws.com/0/74580/3a7ac543-2dda-69f8-463b-c81f9fb05add.png)

そしてエアコンとかテレビが赤外線で反応していることも何となく知っていました。なので考えるべきは2つ。

 - どうやって赤外線の部分を作るのか
 - GoogleHomeと赤外線の部分のつなぎはどうするのか


そして「以前社内ハッカソンの時ラズパイってのを触ったなー」ということを思い出しました。
そこで決まります。赤外線の部分はラズパイにしよう！

![スクリーンショット 2017-12-10 11.32.05.png](https://qiita-image-store.s3.amazonaws.com/0/74580/f82ecaf2-27db-85f9-2bf4-03aa25d28d3e.png)

このあとは軽くググりました。そうすると多くの記事でIFTTTというのが出てきました。
調べてみるといろんなサービスと連携することができ、GoogleHome以外でも例えばLineで何か指示しても動作できるような環境も作れ汎用性高いということで使ってみることにしました。

![スクリーンショット 2017-12-08 23.43.21.png](https://qiita-image-store.s3.amazonaws.com/0/74580/970d523d-cb0e-6c30-29e6-8c2b33737aa4.png)

### 赤外線でどうやって操作しているんだ？
作るにあたってこの辺りを理解しないと進めないなと思い、「赤外線」と言われているものが何なのかからリモコンの仕組みについてをちょっと調べたのでまとめようかなと思います。

#### 赤外線とは
目に見えない光のことを指すらしく周りのあらゆるものから赤外線が発せられているとかなんとか・・

日常の中で「光」と聞くと目に見える物イメージを持ちますが、実は「光」は電波やマイクロ波と同じ電磁波でそれらの波の長さ（波長と呼ばれているもの）によって目に見えたり、見えなかったりします。
そして人の目で見える光を可視光線と言い、可視光線の赤の外側にある波長なので赤外線と言います。ちなみに紫の外側の波長は紫外線と言います。

![スクリーンショット 2017-12-10 2.28.50.png](https://qiita-image-store.s3.amazonaws.com/0/74580/9abd0e60-12e4-5d17-09ae-11178924e65f.png)


赤外線はおよそ750～1,000nmの間の波長で、400nm～800nm位の間の波長が可視光線、 10～400nmの間の波長が紫外線となっています。ちなみに放射線は紫外線よりも短い波長のことを言うらしいです。

#### 赤外線リモコンとは
そもそも赤外線センサーには大きく2種類に分けられます。

- 熱型
    - 発信された赤外線を受け取った物体（厳密には受光素子）が赤外線を吸収することにより温度上昇を起こす。
    - 温度センサでその温度変化読み取り、電気信号に変換している。

![スクリーンショット 2017-12-10 2.38.00.png](https://qiita-image-store.s3.amazonaws.com/0/74580/ecf7d1eb-0e67-3b34-12ac-34709656a011.png)


- 量子型
    - 赤外線を光子としてとらえ、電気信号に変換している。

![スクリーンショット 2017-12-10 2.38.47.png](https://qiita-image-store.s3.amazonaws.com/0/74580/77ce7fd1-5ec0-2283-a53c-b6c56f85ec8f.png)

どちらにもメリットデメリットが存在しています。で赤外線リモコンは量子型の方に分類されます。



ざっくりとした仕組みとしてはリモコンの場合

> リモコンでは制御信号を赤外線の点滅に変換して、リモコンから電化製品本体へ伝えられます。

とのことです。

そしてこの点滅のしかたの基本がPPM信号と言われる方式です。

#### PPM(Pulse Position Modulation)信号とは
赤外線の点灯時間と消灯時間の長さの組み合わせによってビット値を表現しているものです。

![スクリーンショット 2017-12-10 3.03.01.png](https://qiita-image-store.s3.amazonaws.com/0/74580/4ea0edc4-fee2-f342-b228-9c64ad527cbf.png)

1回目と3回目の時に点灯で1回目と3回目の時に消灯みたいな感じで0、1で表現します。
縦軸に対して消灯時間が短い部分を0として、消灯時間が長い部分を1としてデータを読むと、上の図のデータは「１０１０」となります。

このように点灯・消灯の１セットで１ビットを表し、点灯時間・消灯時間の長さの組み合わせによって０か１を判定する方式をＰＰＭ方式と言います。


通信フォーマットで調べると、日本国内の殆どの家電をカバーしているのが3種類ありNEC/家製協/SONYフォーマットと呼ばれているものが出てきますがこれは「消灯時間の長さで０／１を判定する方式なのか点灯時間の長さで０／１を判定する方式なのか」の違いでしかないです。

_________________________________

### 簡単にまとめると
 - 赤外線とは光の波長のこと
 - 赤外線リモコンの操作では光を変換して行っている
 - 0,1で管理されており、機器によってそれらの形が異なる

ここまでくると何をするべきかが明確になると思います。つまりやることとして

- ラズパイの他に光（赤外線）を発信する装置が必要
- 発信するにあたりどんな形なのかをあらかじめ知っておく必要があるので光を受信する装置も必要

あとは

- ラズパイがIFTTTからのトリガーに対して指定されたアクションを行うためのスクリプトが必要

何をするべきか、用意するべきかがわかったので準備に入ります。

【参考URL】
[赤外線基礎知識](https://jsirgakuseikai.jimdo.com/赤外線基礎知識/)
[wikipedia](https://ja.wikipedia.org/wiki/赤外線センサ)
[赤外線リモコンについて](http://www.256byte.com/remocon.htm)
[初歩の電波（無線と電波について）](http://www.ibsjapan.co.jp/tech/details/elementary-electric-wave/eewave-04-15.html)
[赤外線リモコンの通信フォーマット](http://elm-chan.org/docs/ir_format.html)
_______________
## 構成
改めて構成です。

- 声をトリガーにGoogleHomeがIFTTTにアクセスしてあらかじめ用意していたレシピを実行する
- IFTTTがラズパイのスクリプトを叩く
- あらかじめ用意されていたスクリプトを発信し各々のアクションが実行される

![スクリーンショット 2017-12-08 23.43.21.png](https://qiita-image-store.s3.amazonaws.com/0/74580/970d523d-cb0e-6c30-29e6-8c2b33737aa4.png)

## 準備
本当はラズパイを赤外線リモコン化して、赤外線を学習させて発進させるみたいなものを作りたかったのですが、、、調べてみると赤外線でどこまでデータを持たせるのかでbit数が異なるらしくハックするのに時間がかかりそう。。。
今回は時間をあまりかけたくなかったので、簡単にサクッとできる方法かつ安価で済ませるというのを軸に選定してみました！

- GoogleHome
- IFTTTへの登録
- ラズパイ3、本体
    - 電源
    - microSDHCカード
    - ディスプレイ
    - キーボード
    - マウス
- 赤外線リモコン[irMagician](http://www.omiya-giken.com/?page_id=837)（IRkitとかRM Mini3、Nature Remoを使用したかったが高かった）
- リモコンとラズパイをつなぐコード
- LEDシーリングライト（電気交換したかったので笑）

スマートホーム化に向けてのざっくりした初期費用

- GoogleHome → 8000円
- ラズパイ本体 → 6000円
- ラズパイを動かすための付属品
    -  電源 → 1500円
    -  SDカード → 1300円
    -  ディスプレイ → 0円（テレビにつなげることにしました）
    -  キーボード → 1000円
    -  マウス → 500円
-  赤外線リモコンirMagician → 5000円
-  [リモコンとラズパイをつなぐコード](https://www.amazon.co.jp/gp/product/B00G4TS530/ref=oh_aui_detailpage_o03_s00?ie=UTF8&psc=1) → 1000円

計約25,000円

僕はここから今まで有線だったのを無線に変更したり、電気買ったりしたので40,000円くらいでした。

## 手順
電気を変えたかったのでここでは電気について説明します。

### 前準備
#### 電気の種類を確認
部屋の照明がヒモ式の手動だったのでそこを赤外線対応させる必要がありました。
工事が必要になるんだったら諦めようかなと思っていましたがどうやら個人でできるっぽいので実行してみました！

- 電気のカバーを外す
![スクリーンショット 2017-12-09 11.12.51.png](https://qiita-image-store.s3.amazonaws.com/0/74580/6dbedadc-433f-a92f-a224-c57bd062aedd.png)

- どういう形式なのかみてみる
![スクリーンショット 2017-12-09 11.15.22.png](https://qiita-image-store.s3.amazonaws.com/0/74580/923874cd-f53f-5802-8df1-c8275c31d4a3.png)


（参考までに）
![スクリーンショット 2017-12-09 11.04.50.png](https://qiita-image-store.s3.amazonaws.com/0/74580/8b51b79f-0c8b-3f5d-93d9-e0b931a4d72e.png)
埋め込みローゼットやシーリングが外部接続されている天井の場合は工事が必要になるそうです。

- 電気を購入　[LEDシーリングライト](https://www.amazon.co.jp/gp/product/B01N9UVN4Z/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1)

- URL先で購入した器具を設置する
    - まず今まで使っていた”本体”（って言われるらしいんですが）それを外します   
![スクリーンショット 2017-12-09 11.19.12.png](https://qiita-image-store.s3.amazonaws.com/0/74580/66f6d075-7cb2-79f3-cabb-7bcaef6ae7f9.png) 
    - 付随しているアダプタも外します 
    - （参考までに）と載せている画像のどれかが天井についてます
    - 購入したセットの中に新しいアダプタがあるのでそれをはめる
    - 購入したセットの中の新しい本体をつける
    - カバーをつける
- 終わり

初めて行ったのですが作業としては5分もかからなかったです。

#### 管理人に相談
事後報告なのであまり意味ないのですが一応確認してみました。穴開けたわけではないし、誰にも迷惑かからないとのことで快諾してくれました！管理人と仲良くなっておいてよかった・・笑。
![スクリーンショット 2017-12-09 11.34.01.png](https://qiita-image-store.s3.amazonaws.com/0/74580/180701b7-cd82-771c-607e-f02058b25c83.png)

### 実際の作業

- ラズパイの設定
- 赤外線リモコンのセットアップと発信する赤外線の学習
- ラズパイでスクリプト作成
- IFTTTでのレシピ制作


## 流れ
### ラズパイのセットアップ
【参考にさせていただきました！】
[Raspberry Pi 3にRaspbianをインストール(Mac OS X を使用)](https://qiita.com/onlyindreams/items/acc70807b69b43e176bf)


- OSをダウンロード   
https://www.raspberrypi.org/downloads/raspbian/  
めっちゃ時間かかってしかもfaildという結果だった。ミラー版で対応。  
http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian/images/  
そしてunzipで詰まる。。。下記コードで解決

```
ditto -x -k 2017-11-29-raspbian-jessie.zip .

最後の . 必要です！
```    

【参考URL】https://qiita.com/ikai/items/f7f2f31a00cd2279f963

- SDカードのフォーマッターをダウンロードしてパソコンにインストール 
- マイクロSDをフォーマット
- マイクロSDにOSを書き込む（何度経験しようとここは緊張します）
- 書き込まれたSDカードをラズパイに挿入
- ラズパイに電源装置をつけてコンセントに挿す（ラズパイの電源がつく）
- OSインストール実行
- デスクトップが開く
- 初期設定

### 赤外線リモコンのセットアップと発信する赤外線の学習
自作ではなく既存の完成されたものを使うという手間省きを選んだ甲斐がありました！
[Raspberry Piで音声認識システムを使ったホームオートメーション化計画](http://it-hack.net/2017/04/25/post-2601/) の通りに進めます。  

ラズパイに赤外線リモコンをつなぐ。
ファイルがないことを確認。（僕はあったりなかったりしました。。）

```
ls /dev/ttyACM0
```

ファイルを生成します。

```
sudo nano /boot/cmdline.txt
```

してconsole=serial0,115200の部分を削除します。
コメントアウトしておいた方が戻すときラクということだったのでコメントアウトで対応。

```
#dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait splash plymouth.ignore-serial-consoles
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait splash plymouth.ignore-serial-consoles
```

再起動

```
sudo reboot
```

ファイル確認する

```
ls /dev/ttyACM0
```

僕はいつもラズパイ使うときpython使っているので今回も使用。
先ほど載せたURLでもpythonを使っていたので都合がよかったです。

```
sudo apt-get install python-pip
sudo apt-get pip install pyserial
```

赤外線部分のシステムロジックを作成する

```
nano irm.py
```

まるまるコピーでおk-です！
[小型赤外線（IR）リモコン irMagician ファースト・インプレッション](http://netbuffalo.doorblog.jp/archives/4872290.html)

```
# -*- coding: utf-8 -*-

import sys
import serial
import time
import json
import argparse
import os

here = os.path.abspath(os.path.dirname(__file__))
ir_serial = serial.Serial("/dev/ttyACM0", 9600, timeout = 1)
#ir_serial = serial.Serial("/dev/tty.usbmodem01231", 9600, timeout = 1)

def captureIR(path):
  print "Capturing IR..."
  ir_serial.write("c\r\n")
  time.sleep(3.0)
  msg = ir_serial.readline()
  print msg
  if path and not 'Time Out' in msg:
    saveIR(path)

def playIR(path):
  if path and os.path.isfile(path):
    print ("Playing IR with %s ..." % path)
    f = open(path)
    data = json.load(f) 
    f.close()
    recNumber = len(data['data'])
    rawX = data['data']

    ir_serial.write("n,%d\r\n" % recNumber)
    ir_serial.readline()

    postScale = data['postscale']
    ir_serial.write("k,%d\r\n" % postScale)
    #time.sleep(1.0)
    msg = ir_serial.readline()
    #print msg
    
    for n in range(recNumber):
        bank = n / 64
        pos = n % 64
        if (pos == 0):
          ir_serial.write("b,%d\r\n" % bank)
    
        ir_serial.write("w,%d,%d\n\r" % (pos, rawX[n]))
    
    ir_serial.write("p\r\n")
    msg = ir_serial.readline()
    print msg
    #ir_serial.close() 
  else:
    print "Playing IR..."
    ir_serial.write("p\r\n")
    time.sleep(1.0)
    msg = ir_serial.readline()
    print msg

def saveIR(path):
  print ("Saving IR data to %s ..." % path)
  rawX = []
  ir_serial.write("I,1\r\n")
  time.sleep(1.0)
  recNumberStr = ir_serial.readline()
  recNumber = int(recNumberStr, 16)
  
  ir_serial.write("I,6\r\n")
  time.sleep(1.0)
  postScaleStr = ir_serial.readline()
  postScale = int(postScaleStr, 10)
  
  #for n in range(640):
  for n in range(recNumber):
      bank = n / 64
      pos = n % 64
      if (pos == 0):
          ir_serial.write("b,%d\r\n" % bank)
  
      ir_serial.write("d,%d\n\r" % pos)
      xStr = ir_serial.read(3) 
      xData = int(xStr, 16)
      rawX.append(xData)
  
  data = {'format':'raw', 'freq':38, 'data':rawX, 'postscale':postScale}

  f = open(path, 'w')
  json.dump(data, f)
  f.close()
  print "Done !"

if __name__ == "__main__":
  # parse options
  parser = argparse.ArgumentParser(description='irMagician CLI utility.')
  parser.add_argument('-c', '--capture', action="store_true", dest="cap", help="capture IR data", default=False)
  parser.add_argument('-p', '--play', action="store_true", dest="play", help="play IR data", default=False)
  parser.add_argument('-s', '--save', action="store_true", dest="save", help="save IR data", default=False)
  parser.add_argument('-f', '--file', action="store", dest="file", help="IR data file (json)", default=False)
  
  args = parser.parse_args()

  if args.play:
    playIR(args.file)

  if args.save and args.file:
    saveIR(args.file)
  
  if args.cap:
    captureIR(args.file)

  # release resources 
  ir_serial.close()
```

ここまでで赤外線の学習と、発信の準備完了。
学習させます。


```
sudo python irm.py -c
```

というコマンドを走らせます。
Captureing IR…と検知タイムに入るのでその間にirMagicianの赤外線受信モジュールに向かって赤外線信号を送信してやります。（今回は電気のon offをしたかったので赤外線受信モジュールに向けて電気のリモコンのonボタンを押す）
数字が出たら完了です。

次に確認します。

```
sudo python irm.py -p
```

これで電気がonにできれば完成です。
今のままだとバッファにデータが入っているだけなので他の赤外線信号をキャプチャした場合上書きされてしまいます。
ということで別ファイルに移します。

```
sudo python irm.py -s -f lightOn.json
```

で確認。

```
sudo python irm.py -p -f lightOn.json
```

電気がつけば完成です。
offのときも作りたいので作業を繰り返します。

```
#モジュールに向かってリモコンoffを発信させる
sudo python irm.py -c
#確認する
sudo python irm.py -p
#ファイル移す
sudo python irm.py -s -f lightOff.json
```
ラズパイ部分は完成です。これでコマンドを叩けば電気のon offができます。
あとは繋ぎこみをしていきます。

### IFTTTでレシピ制作
このあたりはこちらの方が全体感がわかると思います。
[【初心者のイフト入門】IFTTTの使い方とレシピの作り方を徹底解説！WEB作業を効率化しよう！！](https://kotoba-box.com/how-to-use-ifttt)

- まずはsearch画面でgoogle assistantを検索
- クリックしてレシピ登録画面にいく
- "this"をクリックしてレシピ作成
- そのあと"that"で「webhoook」をクリック
- webhook画面にて下記のように設定する
- 完了

あとは動くかどうかの確認をします。

## まとめ
実際に手を動かしてみるとそこまでハードル高くないので興味ある方は初期費用結構かかりますが年末にでもやってみてはいかがでしょうか？

## 個人的に今後やりたいこと
「GoogleHomeでできないこと」と調べてみるとこの辺が出てきました。

- 配送状況の追跡
- スリープタイマー
などなど・・・・

ただスリープタイマーは確かにあると便利だなーと思っています。そんなに難しくはないかなと思っています。現状ラズパイで制御できることは「指定した機器へのon off」です。そしてそれはスクリプト管理されている。。。ということはcronで時間指定したら止めることはできるのではないか？と思っています。

あと自宅の「鍵」を制御したいなと思っています。ただ管理人さんに聞いたところ鍵を赤外線に交換するのはダメ！ということだったので、赤外線を使わずに物理的に鍵を開けれるものを作らないといけません。

### ロボット用アーム

<img width="232" alt="スクリーンショット 2017-12-10 16.59.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/74580/49f6d90b-a3d1-e649-f613-96db461d737c.png">

- 大きすぎるので玄関に設置すると邪魔になりそう
- 電源どうしようか
- 2kg以上とか重すぎ


ということでアーム系で考えるのをやめました。「小さくて軽くて回転する系」だったらあとは制御の問題なのでなんとかなりそう。で思いついたのがラジコン。そしてラジコンについて見てたら「マイクロサーボ」なるものがあるらしい、ということに気がつきました。

### マイクロサーボとは？
ロボットの間接等の可動部によく用いられるモーターの事で、位置を指定して回転させてピタっと止められることから決まった角度まで動かしたいという場合に便利なモーター。

![スクリーンショット 2017-12-13 12.29.48.png](https://qiita-image-store.s3.amazonaws.com/0/74580/1a6c32e8-a6f1-e10f-5905-bab4c99c30f3.png)

これでいけそうですね。


こんな感じ？笑
![スクリーンショット 2017-12-14 8.05.59.png](https://qiita-image-store.s3.amazonaws.com/0/74580/e54873b2-9553-c3da-0ac4-f2b2a274931a.png)


できれば充電器とかつけて赤外線で受信したら動くみたいなのを理想なのでこの辺も詰めておいた方が良さそうですね。

![スクリーンショット 2017-12-13 12.50.07.png](https://qiita-image-store.s3.amazonaws.com/0/74580/c3b7d779-4d50-5d30-0b5e-1786704414b9.png)

[マイクロサーボ SG90の応用（3）赤外線受信編](http://skomo.o.oo7.jp/f41/hp41_12.htm)

________________________
ということで今後やりたいこととしては「スリープタイマー設定」と「赤外線対応していない鍵の制御」です。構成はざっくりこんなものをイメージしています。

スリープタイマー

- IFTTTで別レシピ追加
- 指定された時間をもとにcronの記述に変換し、書き込む  
（もしかしたら1時間用 2時間用とかをあらかじめ用意してそれを叩くみたいなものになるかもしれません）

鍵制御

- マンションのエレベータを乗った時にスマホから「帰宅」と打つとwebhook経由でapi叩く
- マイクロサーボを回転させる
- 鍵が開く

2つ目の方を先人の方が行っていました！これを参考にやってみようかなと思います。[お家の照明をリモコンで操作できるようにしよう](https://qiita.com/narikei/items/ff2d53d902e701cb1d13)


あと本日からこんなのも出ましたね！！！触ってみたい。
[ラズパイを赤外線学習リモコンに](https://fabcross.jp/news/2017/20171210_adrsir.html)
_________________________

## 最後に...
Atraeでは、一緒に闘ってくれる仲間を全力で探しております！！
まずは気軽に話す程度でも構いません！
ぜひ、一緒に世の中を変えるサービスを創りましょう！
https://www.green-japan.com/job/51812?jo=blur_pc