Raspberry Pi 3 で部屋の赤外線受信できる機器をコントロール。

### 最近はまっていたラズパイで赤外線受信できる機器をコントロールした時のメモ

#　はじめに

最近は、お家ハックをよくやっている。外出先からエアコンと照明を操作したい。

参考になったサイト。[^1][^2][^3][^4]


完成した送信機とコントローラ↓
![IMG_3212.JPG](https://qiita-image-store.s3.amazonaws.com/0/110060/cbf26eee-a396-e4e5-5ad8-a995f7feb645.jpeg)
![Screenshot from 2017-02-16 03:54:18.png](https://qiita-image-store.s3.amazonaws.com/0/110060/edd81689-ca70-d4dc-1763-de6c4a4073fc.png)



# 準備物

自分の部屋の赤外線受信できる機器を携帯で操作する。
まずSlack経由で家の外からエアコンをON, OFFできるという情報を手に入れたのでそれに沿って準備した。[^1]
今回用意するもの。

* Raspberry Pi ３ B
* 5mm赤外線LED 「OSI5FU5111c-40」
* 赤外線リモコン受信モジュール 「PL-IRM2161-XD1」
* LEDキャップ 「OS-CAP-5MK-1」(私は使用しなかった)
* 抵抗 (50Ωくらい)

#### Apache, phpのインストール

```sh
$ sudo apt-get install apache2
$ sudo apt-get install php5
$ sudo update-rc.d apache2 defaults 
```

インストール直後は、/var/wwwがドキュメントルートである。

次にLEDを光らせみる。

~2019/01/29追記　RaspberryPi3の配線図に変更
<img width="478" alt=" 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/9963e2e7-b38b-e666-f573-9acd8173f561.png">

プログラムは以下

``` sh
echo 2 > /sys/class/gpio/export #「GPIO2」を使う
sleep 1
echo out > /sys/class/gpio/gpio2/direction #「GPIO2」を出力用に使う

echo 1 > /sys/class/gpio/gpio2/value #点灯
sleep 1                              #1秒休む
echo 0 > /sys/class/gpio/gpio2/value #消灯
sleep 1
echo 1 > /sys/class/gpio/gpio2/value
sleep 1
echo 0 > /sys/class/gpio/gpio2/value
sleep 1
echo 1 > /sys/class/gpio/gpio2/value
sleep 1
echo 0 > /sys/class/gpio/gpio2/value

echo 2 > /sys/class/gpio/unexport #「GPIO2」の使用を終了
```

外部からのアクセスは以下のコードで、

```php

<?php exec('sudo sh /var/pi/blink.sh'); ?>
LEDを点滅させました！
```

上記コードで大丈夫です。
あとsudo権限を追加(visudoにて)

```
www-data ALL=NOPASSWD:/bin/sh #この行を追加
```

#いろいろ記事を調べるうちにLIRCを諦めろという記事がいっぱい。

全然諦める必要はなかった。
きちんと作動した。


ここからは、LIRCを交えたメモ。

LIRCに関してはこの記事が大変参考になった。[^4]



# LIRCの設定

前回からraspberry pi 3を使って部屋のエアコンと照明をスマートフォンから操作することを頑張っていましたが、LIRCに苦戦しながらも達成することができたのでメモとして残しておく。

LIRCを使ってリモコンのコードを解析した。
まずLIRCのインストール

```sh
$ sudo apt install lirc
```

上記コマンドで完了。
次にLIRCの設定。
検索で出てくる他のラズパイ記事で「LIRCはあきらめましょう」と言う内容の記事がたくさんありました。
何度か私もこの段階で失敗していたのですが、うまくいきました。

まず以下コマンドを実行。

```sh
cp /etc/lirc/hardware.conf ~/hardware.conf
sed -i -e "s/LIRCD_ARGS=\"\"/LIRCD_ARGS=\"--uinput\"/g" ~/hardware.conf
sed -i -e "s/DRIVER=\"UNCONFIGURED\"/DRIVER=\"default\"/g" ~/hardware.conf
sed -i -e "s/DEVICE=\"\"/DEVICE=\"\/dev\/lirc0\"/g" ~/hardware.conf
sed -i -e "s/MODULES=\"\"/MODULES=\"lirc_rpi\"/g" ~/hardware.conf
cat ~/hardware.conf
sudo mv /etc/lirc/hardware.conf /etc/lirc/hardware.conf.bak
sudo cp ~/hardware.conf /etc/lirc/hardware.conf
```

次にピンの指定。
/boot/config.txt
に次のコードを末尾に入力。

```sh
# IR-Remote controller
dtoverlay=lirc-rpi
dtparam=gpio_in_pin=24
dtparam=gpio_out_pin=25

```

ここまでできましたら、一旦再起動。
私のリモコンでは半自動で生成してくれる$ irrecordというLIRCのコマンドが使用不能だった。
手動で作っていきたいと思う。

#信号解析
サイトから借用。Raspberrypiにブレッドボードの通りにつないだ。[^4]

~2019/01/29追記　RaspberryPi3の配線図に変更
<img width="280" alt=" 3.png" src="https://qiita-image-store.s3.amazonaws.com/0/110060/aaa0767d-6f31-07aa-c669-1bd4add7db02.png">

ここで24と書かれていますがGPIOのことなので実際には下図の⑱へつなぐこと。
ピンを間違えないように。（私は間違えた。）

![Raspberry-Pi-GPIO-Layout-Model-B-Plus-rotated-2700x900.png](https://qiita-image-store.s3.amazonaws.com/0/110060/f5dd2e70-8976-8113-d762-e6ddb8d534a1.png)

つないでみた様子。
![ダウンロード (3).png](https://qiita-image-store.s3.amazonaws.com/0/110060/574173b6-70ae-3c98-1a8b-26ea19ed49d3.png)


```sh

$ mode2 -d /dev/lirc0 | tee AIRON
space 4898472
pulse 3516
space 1710
pulse 460
space 404
pulse 457
space 1278
pulse 457
space 406
pulse 457
space 405
pulse 458
space 404
pulse 448
space 414
```

```shell-session

$ mode2 -d /dev/lirc0 | tee AIROFF
===以下略＝＝＝
```

カレントディレクトリに、"AIRON" "AIROFF"というファイルができる。これらを数値のみのデータに変換し、/etc/lirc/lircd.confに書き込む。

さて変換ですが、Rubyでの変換プログラムを見つけたので拝借。

```ruby
# parse_pulse.rb
lines =  File.open(ARGV[0]).readlines
lines_without_first = lines.slice(1..-1)
puts lines_without_first.map{|line|line.split(" ")[1]}.join(" ")
```

``` ruby
$ ruby parse_pulse.rb AIRON
$ ruby parse_pulse.rb AIROFF
```

2018/10/08追記〜
上記コードは適切な改行をしてくれない。
また、最近リモコンが増えたため、新規にコマンドを追加していたのだが、正直面倒である。
shellスクリプトを組んで変換した。

```shell:parse_shell.sh
#!/bin/bash
echo パースしたいファイル名を入力してください。
read filename
count=0
cat $filename | awk '{print $2}' | while read line
do
  if [ $count = 80 ]; then
     echo "${line}"
     count=0
  else
     echo "${line} \c"
  fi
count=`echo "$count+1" | bc`
done

```

```shell:terminal
$ sh parse_shell.sh
```

これで一発変換可能。〜

さていよいよLIRC設定ファイル作成。
/etc/lirc/lircd.conf
に以下の内容を記述。

```ruby
begin remote

  name  room
  flags RAW_CODES
  eps            30
  aeps          100

  gap          200000
  toggle_bit_mask 0x0

      begin raw_codes
    name hot_on
# AIR_ONの中身
3483 1748 423 492 370 1307 428 493 370 472 391 491 371 492 369
492 370 493 369 493 375 487 369 493 370 492 369 493 369 1315 422
491 370 493 369 494 367 495 368 493 368 494 368 500 362 1314 420
1368 368 1314 423 495 366 497 367 1319 413 497 366 497 368 442
418 497 365 496 366 496 368 494 366 496 366 496 374 487 367 497
……

    name off
# AIR_OFFの中身
3476 1747 421 468 394 1319 417 466 396 466 395 492 371 466 394
472 392 467 395 467 395 466 395 470 393 467 395 492 371 1338 398
466 395 469 393 469 395 467 394 468 394 470 392 469 393 1321 416
1325 411 1338 401 489 369 494 368 1323 414 468 392 494 369 467
395 468 394 468 394 493 369 467 395 493 370 468 394 492 369 467
……

      name cold_on
===以下略===
      name light_on
===以下略===
      name light_off
===以下略===

      end raw_codes

end remote
```

ここで注意なのですが必ず変換したコードを八十字ほどで改行しなければならない。

あとはirsendで信号を送信する。

```
$ irsend LIST "" ""
irsend: room

$ irsend LIST room ""
irsend: 0000000000000001 hot_on
irsend: 0000000000000002 off
irsend: 0000000000000003 cold_on
irsend: 0000000000000004 light_on
irsend: 0000000000000005 light_off

$ irsend SEND_ONCE room hot_on
```

上記コマンドでうまく送信できた。
私の場合上の設定で手抜きした箇所やピンを間違えていたり。
ですが、最後にはきちんと作動した。

さてわざわざこのコマンドを打たないと操作できないのも不便である。
とりあえず、shellscriptでコマンドを単純化。
allon.sh
alloff.sh
上記のようなファイルを作成する。

```sh:allon.sh
irsend SEND_ONCE room hot_on
irsend SEND_ONCE room light_on

```

上記のようにファイルに書き込み。
以下のコマンドで実行できるようになる。

```
$ sh allon.sh
```
まだ、手順が複雑である。
#### 単純化を図りたい。

# Apache , phpでリモコンボタンを作る。

```ruby
$ sudo apt-get install apache2
$ sudo apt-get install php5
$ sudo update-rc.d apache2 defaults 
```

下図のように、web経由で操作できるようにapache,phpを利用(すでに設定済み)
以下のように操作したい。
![Screenshot from 2017-02-16 03:54:18.png](https://qiita-image-store.s3.amazonaws.com/0/110060/254ccea6-d8e9-7e65-188b-1894d362396c.png)

以下
/var/www/html
フォルダー内の記述内容。
このフォルダーへの書き込みはsudo権限が必要である。

```
$ sudo vim index.html
```

以下の内容を記述。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>MyRoom</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
    <link rel="apple-touch-icon" href="images/mook_house.jpg"/>
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
	<div class="jumbotron">
	 <div class="well">
	  <h1>Welcome to My Room Controller!</h1>
	  <a class="center btn btn-success" href="http://XX.XX.XX.XX/allon.php">MyRoomを起動する。</a>
<br />
<br />
	  <a class="center btn btn-primary" href="http://XX.XX.XX.XX/alloff.php">MyRoomをスリープする。</a>
<br />
<br />
	  <a class="center btn btn-default" href="http://XX.XX.XX.XX/lightoff.php">MyRoomの電気を消灯する。</a>
</div>
</div>
         <a class="center btn btn-primary" href="http://XX.XX.XX.XX/autoon.php">自動制御オン</a>
<br />
<br />
         <a class="center btn btn-primary" href="http://XX.XX.XX.XX/autooff.php">自動制御オフ</a>
<br />
<br />
  </body>
</html>

```

XX.XX.XX.XXの部分はラズパイのIPアドレスを！

2018/10/08追加〜
Raspberry PiのIPアドレスは動的に変わってしまうことが多いです。

```php

<?php
var_dump( system('hostname -I', $ret) );
var_dump( $ret );
?>
```
上記のようにIPを取得してあげることで、いちいち書き換える必要が無くなります。
このコードをはめ込んでお使いください。〜

次にコマンド実行ページを作成する。

```sh
$ sudo vim allon.php
```

```php:allon.php
<?php exec('sudo sh /var/pi/allon.sh'); ?>
<script type="text/javascript">
location.replace('http://XX.XX.XX.XX/');
</script>

```

この記述で、
sudo sh /var/pi/allon.sh
とありますがそのコードの通り先ほど作ったsh実行ファイルを
/var/piに置く必要がある。

```sh
$ sudo mkdir /var/pi
```

上記の要領で全てのコマンド実行ページを作成。（他ファイル生成方法省略している。）
![Screenshot from 2017-02-16 10:56:02.png](https://qiita-image-store.s3.amazonaws.com/0/110060/b9868c26-02ed-3ffa-ef65-7f9309594e01.png)


それからさっき作ったファイルをpiディレクトリに移動しなければならない。

![Screenshot from 2017-02-16 10:59:53.png](https://qiita-image-store.s3.amazonaws.com/0/110060/d7a41a45-5cbe-bbbb-3d28-3a9c34f17dc6.png)

最後に、アクセスにはラズパイのIPアドレスをブラウザに直接打つこと。
外出先から操作したければ、http通信のポートをオープンにして
パブリックIPをブラウザに打つこと。
ポートを開けるときはセキュリティーに気をつけなければならない。
私は80番をポートマッピングして運用している。

これでボタンひとつでコントロールできるようになった。

# おまけ
最後にcronでタスクを自動化したいと思う。
いつも二時までには睡眠を取るようにしているので、
　　・深夜二時にスリープ
　　・朝六時に起動
上記のように設定した。
この実現にはRaspberry Pi OS RASPBIANのcrontabを使っている。

```sh
$ crontab -e
```
でnanoエディタが起動し設定内容を記述する。
今回の場合のサンプル。
次のコードを末尾に入力。

```ruby
# m h  dom mon dow   command
0 2 * * * sudo sh /home/pi/alloff.sh
0 6 * * * sudo sh /home/pi/allon.sh

```

上記のコードの

```
* * *
```

これは、何を示しているかと言うと、ワイルドカードで毎日を表している。

```
0 2
0 6
```

は順に、
　　・０分２時
　　・０分６時
という意味である。
cronはとても便利である。
詳しくは割愛する。

よく眠れるようになった。

(後日談)
部屋の温度をモニタリングして、自動でON,OFFしたり温度を上げ下げできるように考えており、実験中です。
https://qiita.com/_kazuya/items/ca2a60f4d54461dab4dc

### 参考文献[^5][^6][^1][^2][^3][^4]

[^1]: 「Slack経由で家の外からエアコンをon, offできる装置を、Raspberry Piで作ってみた。（しかも御坂美琴ちゃんが応答してくれる）」http://qiita.com/KAKY/items/55e6c54fa2073cdc0bbe
[^2]: 「Raspberry Pi 3 model B でエアコンをコントロールした話」http://s4kr4.hatenablog.com/entry/2016/07/24/114444
[^3]: 「Raspberry PiでLIRCをインストールする」http://qiita.com/Library/items/35eec18fbe11387be6d5
[^4]: 「Raspberry Pi 3 Model Bで赤外線受信センサーと赤外線 LEDでリモコン信号を送受信する方法」http://www.neko.ne.jp/~freewing/raspberry_pi/raspberry_pi_3_lirc_ir_remote_control/
[^5]: 「LM35DZ 温度センサIC」 https://www.switch-science.com/catalog/2508/
[^6]: 「ポアソン分布に従う時系列データから3σ法を用いて異常検知する」 https://qiita.com/FooQoo/items/3cb92f4a5bc0fedd1fd0
[^7]: 「正規分布の標準偏差と信頼区間の計算について」　https://friedrice-mushroom.hatenablog.com/entry/2019/03/17/193332