【おうちハック】ESP8266で家に帰ったらテレビつける・家を出たらテレビ消すをやってみる

# やろうと思ったきっかけ
- 自分は仕事でテスト自動化とかデプロイ自動化とか推進していく立場である。
- プライベートでも自動化できることは自動化したい。
- 毎日やる定常作業を効率化して時間を有効的に使いたい。
- だって仕事から家に帰った後って時間なくて家のことやってるとすぐ時間過ぎちゃうし。
- 趣味やプライベートの時間をもっと増やしたい。

なのでやります。おうちの定常作業自動化。

家に帰って/家を出る時に必ずやることってなんでしょう。自分の場合は…

1. 鍵を開ける/閉める
2. 照明つける/消す
3. エアコンつける/消す
4. テレビつける/消す
5. 手を洗う
6. ソファーでだらだら…

1は「Qurio Smart Lock」があればできそうですね！
なんと電池2つで600日連続利用可能（理論値）らしいですよ！
取り付けに工事は不要だし賃貸でも外したあとのダメージが少ないんだって！
今度絶対買おう！
[Qrio Smart Lock (キュリオスマートロック) スマートフォンで自宅のドアをキーレス化 Q-SL1](https://www.amazon.co.jp/dp/B00XXYALDG//ref=as_li_ss_il?_encoding=UTF8&m=AN1VRQENFRJN5&linkCode=li2&tag=donkeykey-22&linkId=289b67d055f62ade58fa164e949be67f" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B00XXYALDG&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=donkeykey-22)
<a href="https://www.amazon.co.jp/dp/B00XXYALDG//ref=as_li_ss_il?_encoding=UTF8&m=AN1VRQENFRJN5&linkCode=li2&tag=donkeykey-22&linkId=289b67d055f62ade58fa164e949be67f" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B00XXYALDG&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=donkeykey-22" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=donkeykey-22&l=li2&o=9&a=B00XXYALDG" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

5は無理だとして、2〜4は自動化できそうですよね。
うちは照明、エアコン、テレビが赤外線で制御できます。
その部分だけでも自動化できれば帰ってソファーでだらだらするまでの時間が短縮されそうです。
ほんの少しだけ。
塵も積もればウンタラカンタラ。

今回はその第一歩として「家に帰ったらテレビをつける・家を出たらテレビ消す」を実現させたいと思います。

# 赤外線で機器を制御する仕組み
900nm帯の赤外線をキャリアとして利用しています。
リモコンの赤外線出力は38kHzのパルス波です。
さらにそのデューティー比は1/3です。

つまり1秒間に38000回点滅していて、1周期の間で点灯している時間が全体の3分の1ということです。
<img src=https://qiita-image-store.s3.amazonaws.com/0/105205/de14e011-eb20-2200-188e-fc42edd691d1.png width=400px>

さらに、この信号が0.56ms続いた後に1.69ms消灯していれば1で、
0.56ms続いた後に0.565ms消灯していれば0と解釈されます。
<img src=https://qiita-image-store.s3.amazonaws.com/0/105205/4e3a245c-e260-2489-0ad9-a7033e605743.png width=300px>

# 赤外線フォーマット
よく利用される赤外線の通信フォーマットは主に

- NECフォーマット
- 家電製品協会フォーマット
- SONYフォーマット

があります。
この3種類で日本国内ほとんどの家電をカバーしているそうです。
参照：[赤外線リモコンの通信フォーマット](http://elm-chan.org/docs/ir_format.html)

# 赤外線の信号を見てみる
今回はこのライブラリにお世話になります。
[https://github.com/markszabo/IRremoteESP8266](https://github.com/markszabo/IRremoteESP8266)

ESP8266に赤外線受信モジュールを付けて下記プログラムを焼きこんで実行します。
[IRremoteESP8266/IRrecvDumpV2.ino at master · markszabo/IRremoteESP8266](https://github.com/markszabo/IRremoteESP8266/blob/master/examples/IRrecvDumpV2/IRrecvDumpV2.ino)

```
Encoding  : PANASONIC
Code      : 4004:19062F3 (48 bits)
Timing[99]: 
     +3600, -1750     + 500, - 400     + 550, -1250     + 550, - 400
     + 550, - 400     + 550, - 400     + 550, - 400     + 550, - 400
     + 550, - 400     + 550, - 400     + 550, - 400     + 500, - 400
     + 550, - 400     + 500, - 400     + 550, -1250     + 550, - 400
     + 550, - 400     + 550, - 400     + 550, - 400     + 550, - 400
     + 550, - 400     + 550, - 400     + 550, - 400     + 550, - 400
     + 550, -1250     + 550, -1250     + 550, - 400     + 550, - 400
     + 550, -1300     + 500, - 400     + 550, - 400     + 550, - 400
     + 550, - 400     + 550, - 400     + 550, -1300     + 500, -1250
     + 550, - 400     + 550, - 400     + 550, - 400     + 550, -1250
     + 550, - 400     + 550, -1250     + 550, -1250     + 550, -1250
     + 550, -1300     + 500, - 400     + 550, - 400     + 550, -1300
     + 500, -1250     + 550
unsigned int  rawData[99] = {3600,1750, 500,400, 550,1250, 550,400, 550,400, 550,400, 550,400, 550,400, 550,400, 550,400, 550,400, 500,400, 550,400, 500,400, 550,1250, 550,400, 550,400, 550,400, 550,400, 550,400, 550,400, 550,400, 550,400, 550,400, 550,1250, 550,1250, 550,400, 550,400, 550,1300, 500,400, 550,400, 550,400, 550,400, 550,400, 550,1300, 500,1250, 550,400, 550,400, 550,400, 550,1250, 550,400, 550,1250, 550,1250, 550,1250, 550,1300, 500,400, 550,400, 550,1300, 500,1250, 550};  // PANASONIC 4004:19062F3
unsigned int  addr = 0x4004;
unsigned int  data = 0x19062F3;
```
実際にテレビのリモコンのボタンを押して計測したデータがこちらです。
（これが何ボタンのデータだったか忘れました…）
おそらく、Timingの+[数字]はONの時間を表していて-[数字]はOFFの時間を表していると思われます。
先程の赤外線の仕組みを見て解釈すると、
+ 550, - 400 が 0 で
+ 550, - 1250 が 1 でしょう。
そして
+ 3600, - 1750 が Leaderで
最後の
+ 500 がTrailerかと思われます。

# 赤外線の送信
上記でテレビの電源を制御する信号を取り出すことができました。
あとはこれと同じ信号を赤外線LEDで表現するだけです。
ESP8266に赤外線LEDを取り付けて
```
irsend.sendPanasonic(0x4004, 0x100BCBD);
```
するだけで電源制御できました。

# 家に帰った/家を出たということをどう判断するか
さて、今回やりたいのは「家に帰ったらテレビつける・家を出たらテレビ消す」でした。
GPSで位置を測定するには専用アプリを入れてもらわなければいけないのでハードル高い。
IFTTTで地点登録しておいてそこに着いたらAPI叩いてもらったりするのも設定が面倒。
いつも持ち歩いてるデバイスが家のwifiに繋がったかどうかが一番楽そう。
どうせ家ついたらwifi繋がるデバイスひとつくらいは持ち歩いてるんだし。
ということでこの方法にしようと思います。
iPhoneのIPを固定にしてESP8266からそのIPにpingが届くかどうかで判断します。

# 実装

## コード

```
#include <ESP8266Ping.h>
#include <ESP8266WiFi.h>
#include <IRremoteESP8266.h>
const IPAddress remote_ip(xxx, xxx, xxx, xxx);
IRsend irsend(15);
const char* ssid     = "ssid";
const char* password = "password";
int flag = 0;
int flag_tmp = 0;

void setup() {
  Serial.begin(115200);
  irsend.begin();
  delay(10);

  Serial.println();
  Serial.println("Connecting to WiFi");

  WiFi.begin(ssid, password);

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

  Serial.println();
  Serial.print("WiFi connected with ip ");
  Serial.println(WiFi.localIP());
}

void loop() {
  if (Ping.ping(remote_ip)) {
    Serial.println("Success!!");
    flag = 1;
  } else {
    Serial.println("Error :(");
    flag = 0;
  }
  if (flag != flag_tmp) {
    Serial.println("send signal");
    irsend.sendPanasonic(0x4004, 0x100BCBD);
  }
  flag_tmp = flag;
}
```

## ハードウェア
![IMG_0524.JPG](https://qiita-image-store.s3.amazonaws.com/0/105205/0a07a8a6-6915-54fd-56c4-db95a0b47e8b.jpeg)
ブレッドボードに赤外線LEDと赤外線受信モジュールを差し込んだだけです。

# 完成

<iframe src="https://player.vimeo.com/video/185676228" width="640" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe> <p><a href="https://vimeo.com/185676228">ESP8266 IR Remocon</a> from <a href="https://vimeo.com/user27545073">Daichi Kawashima</a> on <a href="https://vimeo.com">Vimeo</a>.</p>

# 課題
- 電源がトグル式（同じ信号でONとOFFが切り替わる）
  - 解決策１：なんかしらの方法（音が出ているか？とか画面が明るいか？とか）で状態を把握する必要がある
  - 解決策２：確実にONする方法・確実にOFFする操作を行う
     - うちのテレビの場合、NETFLIXボタンでもONになる（OFFにはならない）
     - ONにする場合は、NETFLIXボタン→ホームボタン
     - OFFにする場合は、NETFLIXボタン→ホームボタン→電源ボタン
- iPhoneがスリープに入るとwifiが切れる or pingが通らなくなる
    - 家にいてもiPhoneがスリープに入るとテレビ消える
    - 帰ってiPhoneのスリープを解除しないとテレビつかない

# 今後やりたいこと
- 照明とエアコンも制御できるようにする
- 3Dプリンタで筐体作って製品っぽくする
- ブラウザからでも操作できるようにする