LINEに通知できる火災報知器をラズパイゼロを使って自作する

※この記事で作成した火災報知器で火事が検知できなかったとしても、責任はおいかねますので、自己責任でお願いいたします。

## 背景
離れて暮らす祖父母がいるのですが、祖父が脳梗塞で倒れ、要介護状態になってしまいました。
祖母が主に面倒をみているのですが、祖父を家に残して買い物に行く時などに火事になってしまうことが心配です。
近くに住む家族がいるので、せめて火事になったときにLINE等で通知して、救出できる仕組みを作りたいと思いました。

![kaji_line.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50474/ce8efbee-0618-1380-b9ef-9315ec2b58d9.jpeg)

まず、スマホ等に通知できる火災報知器を探しました。

## スマホ通知できる火災報知器
panasonicからこのような商品が出ていることを知りました。
https://kaden.watch.impress.co.jp/docs/news/1280029.html

しかしこれ単体ではスマホに通知が送れないようで、AiSEG2というHEMSを搭載したハブを買う必要があり、これだけで8万円もします。

AUからはこのようなものもありましたが、AU光等を契約していないと使えません。
https://www.au.com/auhome/device/ufa01a/

Googleが出している Nest protectという製品もありますが、日本では販売しておらず、技適的にも微妙です。(販売中止になったらしい)

ということで、どれも微妙でしたので自作することにします。

## 用意するもの

| 物品 | 価格 |
|:-:|:-:|
|  Raspberry Pi Zero WH | 2000円程度 |
|  MQ-135 | 620円 |
| 10KΩ抵抗 x3 | 15円くらい |
|ブレッドボード|300円|
|ジャンパーピン|適量|
|ジャンパーワイヤー　メスオス　３本|セットで300円くらい|

特筆すべきは、MQ-135というガスセンサーです。煙が検出できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50474/ae01444b-1096-32f1-6856-cca5d25ad470.png)

私は[こちら](https://www.physical-computing.jp/product/1552)のピンが半田付けされたものを買いました。
MQ-数字、のようなガスセンサーがいくつかあり、数字によって検出できるガスの種類が異なります。

代表的なセンサーは以下の通りです。

| センサ | 検出できるガス |
|:-:|:-:|
|  MQ-2 |  メタン、ブタン、LPG、煙 |
|  MQ-3 |  アルコール、メタノール、煙 |
| MQ-5  |  天然ガス、LPG |
|  MQ-7 | 一酸化炭素  |
|  MQ-8 |  水素 |
| MQ-135  |  ベンゼン、アルコール、煙 |

センサーを変えれば、他のガス検出もできると思います。

## ラズパイゼロのセットアップ
ラズパイの初期設定を行います。Wifiに接続してSSHで繋げるようにしましょう。
世の中にはたくさんのラズパイセットアップの情報が溢れているので、ここでは詳細に扱いません。

ただ個人的に便利だと感じているのが、OSの入ったSDカードに情報を書き込んで起動することで、
画面やキーボードなしでWifiに接続できて、SSH接続ができるようになるこの方法です。

https://qiita.com/mascii/items/0d1a280ac58ed8f6f999

## センサ周りの配線

以下のように配線します。後ろの緑のセンサは気にしないで大丈夫です。
![2020-11-28 19.07.11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50474/3b12f10c-c26b-c47b-aa2d-6dd922804c79.jpeg)

VCCには５Vもしくは3.3Vが来るように、GNDには同じくGNDの端子を接続します。
白いジャンパーワイヤは今回GPIO17(14番)に繋げています。GPIOならどこでも良いです。

こちらのサイトのRaspi Zero WHのピン配置図がわかりやすいので参考にしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50474/8bad9469-bbd5-7fc6-1b13-6ba827ee2104.png)
https://www.ma-chanblog.com/2019/02/raspi-prepare.html

今回DOUTからの信号を使いますが、直接GPIOに接続せずに、少し抵抗を用いた回路の中にあります。
これは、DOUTからの出力が5Vであり、ラズパイに入力するときには3.3Vまで電圧を落としてあげる必要があるためです。

## センサーのテストとプログラム
ガスセンサーが正常に動作するか確認します。
確認のために、以下のコードを用意します。

```py:detect_smoke_test.py
import RPi.GPIO as GPIO
import time

GPIO_INPUT = 17

GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_INPUT, GPIO.IN)

try:
	while True:
		if GPIO.input(GPIO_INPUT) == GPIO.LOW:
			print("smoke detected")
			time.sleep(5)
		else:
			print("runninng")
			time.sleep(1)
```

百均で買ってきたマッチを使ってテストしました。
マッチを２本くらいもって火をつけ、少し燃えたところで息を吹きかけて火を消します。
すると煙がでてくるので、すぐにガスセンサの近くに持ってきます。
煙が検出されると、センサ基盤の右側のLEDが赤く点灯します。

上記のプログラムを起動させて以上のテストを行います。実行は

```
$ python deetct_smoke_test.py
```
です。
正常ならば煙が検出されたときに
smoke detected
と表示されます。

## 運用のためのプログラムおよび設定
まずLINEに通知するために、LINE Notifyを使うための設定をします。

LINE Notifyの設定については、こちらのサイトをご覧ください
https://www.smilevision.co.jp/blog/tsukatte01/

すると、ライン通知を送るためのトークンが発行されます。こちらを控えておいてください。

そして、煙を検知したらラインに通知を送るためのプログラムを作成します。

```py:detect_smoke.py
# coding: UTF-8
import RPi.GPIO as GPIO
import time
import requests

GPIO_INPUT = 17 # 接続したGPIO番号にすること！！

GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_INPUT, GPIO.IN)

def line_notify():
    payload = {'message':'煙が検知されました'}  
    headers = {'Authorization': 'Bearer ' + 'token'} # tokenを置き換えること！
    requests.post('https://notify-api.line.me/api/notify', data=payload, headers=headers)

try:
	while True:
		if GPIO.input(GPIO_INPUT) == GPIO.LOW:
			line_notify()
			print("smoke detected")
			time.sleep(5)
		else:
			print("runninng")
			time.sleep(1)
except KeyboardInterrupt:
	print("stopped")
	GPIO.cleanup()
```

このプログラムを実行すると、煙が検知されたときに、このようにラインで通知がきます


![2020-11-28 20.11.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50474/5f6d9c62-f1e0-5d58-683b-c6978bdf2423.png)

基本的にはこのプログラムを実行しつづけておけばよいのですが、何らかの原因でプログラムがストップしてしまい、肝心なときに動作しなかったのでは意味がありません。
ですので、systemdにこのプログラムの実行および監視をしてもらい、プログラムが終了しても再起動してくれるようにします。

以下のファイルを作成します

```
$ sudo vim /etc/systemd/system/smoke_detect.service
```

```:/etc/systemd/system/smoke_detect.service
[Unit]
Description=start smoke detect script
[Service]
Type=simple
ExecStart=/usr/bin/python /opt/detect_smoke.py
Restart=always

[Install]
WantedBy=multi-user.target
```

先ほど作成したdetect_smoke.pyを/optに移動しておきます。

```
$ mv detect_smoke.py /opt/
```

そして作成したサービスを有効化して開始します

```
$ sudo systemctl enable smoke_detect.service
$ sudo systemctl start smoke_detect.service
```

サービスがちゃんと動いているかは、こちらのコマンドで確かめることができます

```
$ sudo systemctl status smoke_detect
● smoke_detect.service - start smoke detect script
   Loaded: loaded (/etc/systemd/system/smoke_detect.service; enabled; vendor pre
   Active: active (running) since Sat 2020-11-28 17:18:10 JST; 2h 35min ago
 Main PID: 327 (python)
   CGroup: /system.slice/smoke_detect.service
           └─327 /usr/bin/python /opt/detect_smoke.py

Nov 28 19:30:16 raspiWH1 python[327]: runninng
Nov 28 19:37:51 raspiWH1 python[327]: runninng
Nov 28 19:37:51 raspiWH1 python[327]: runninng
```
ここまで行うと、ラズパイを再起動したときにも自動で煙検知プログラムが起動しますし、終了してしまったときにも自動で再実行されます。

## 最後に
ひとつ弱点として、GPIOに繋がっているジャンパーワイヤーがアクシデントで抜けると、煙検知と見なされてずっとラインが飛んできます。これはセンサの仕様上、煙がない時にはDOUTからHIGHを、煙検知時にはLOWを出力するので、ワイヤーが抜けてもLOWなのでこうなってしまいます。
ブレッドボード実装だけではなく、ユニバーサル基盤でしっかりとハンダ付けしたほうがよいです。
まあラズパイ側もですが。

他に問題点が見つかったら追記します。

## 参考
[【電子工作】LINE連携IoT火災報知器を作ってみた【Raspberry Pi, Python, LINE notify】火災警報器, ラズベリーパイ](https://www.youtube.com/watch?v=sRb9POFZOAg)
[IoT火災報知器のコード Code of IoT fire alarm](https://ichiken-youtube.hatenablog.com/entry/2020/01/18/204140)