センサのアナログ出力をA/D変換し、アラートをチャットアプリに飛ばす

業務でRaspberry Piにセンサを接続し、
閾値を超えたらアラートを飛ばすという仕組みを作ったのでメモしておく。

一応、LineとChatworkの２つのアプリにアラートを飛ばしてみた。
Slackはユーザー層が合わないのでパスする。

# 概要

フォトレジスタ(光依存性抵抗)を用いて、
工場のランプに取り付け、ランプが付いたら検知してアラートを飛ばすようにする。

# 使用パーツ

+ Raspberry Pi 3 Model B
+ [Raspberry Pi用センサー](https://www.amazon.co.jp/gp/product/B01FYQ6EWC/ref=oh_aui_detailpage_o09_s00?ie=UTF8&psc=1)
    + フォトレジスタ
    + A/Dコンバータ(ADC0832)

# 回路

![photo_register.png](https://qiita-image-store.s3.amazonaws.com/0/172314/3770d903-8858-7313-006c-51866656540a.png)

![circuit.jpg](https://qiita-image-store.s3.amazonaws.com/0/172314/b3696fb5-3893-fc55-fef9-227d43d975de.jpeg)

フォトレジスタの抵抗値を測ることによって、光が当てられたかどうかを判定するための回路。
また、フォトレジスタの出力を`ADC0832`でA/D変換する。

ただし、[これ](https://www.amazon.co.jp/gp/product/B01FYQ6EWC/ref=oh_aui_detailpage_o09_s00?ie=UTF8&psc=1)に入っているフォトレジスタは、下図のようになっており、上図のように抵抗を挟むのではなく、Signalピンから直接青い線を伸ばせばよい。

![PhotoRW.png](https://qiita-image-store.s3.amazonaws.com/0/172314/ca2a0dbc-66ea-fc6a-5760-233b5025911c.png)

なお、ADC0832は以下のようなピン配置となっている。
![2015-08-21_21h13_40.jpeg](https://qiita-image-store.s3.amazonaws.com/0/172314/51794840-2d91-95b2-b990-551aa7def599.jpeg)

上図のように、CSをGPIO11、CLKをGPIO12、DIとDOをGPIO13に接続した。

# ライブラリの準備

[ここ](https://github.com/sunfounder/Sunfounder_SensorKit_Python_code_for_RaspberryPi)から`ADC0832.py`と`20_photoRes.py`をダウンロードし、Raspberry Piの同じディレクトリに配置する。

ピン番号ではなく、GPIOの番号で指定する方が好みなので、`ADC0832.py`のGPIOの指定モードを変更した。

ここで指定している番号が、先程接続した回路と合うようにする。

```ADC0832.py
def setup(cs=11, clk=12, dio=13):
    global ADC_CS, ADC_CLK, ADC_DIO
    ADC_CS = cs
    ADC_CLK = clk
    ADC_DIO = dio
    GPIO.setwarnings(False)
-    GPIO.setmode(GPIO.BOARD)    		# Number GPIOs by its physical location
+    GPIO.setmode(GPIO.BCM)
    GPIO.setup(ADC_CS, GPIO.OUT)		# Set pins' mode is output
    GPIO.setup(ADC_CLK, GPIO.OUT)		# Set pins' mode is output
```

# Lineにアラートを飛ばす

## LINE Developers Trialに登録する

(PUSH_MESSAGEが使えるプランならなんでも良い)
登録方法はいろんな記事が公開されているので、説明を省く。

## line-bot-sdkをインストール

[Python用のSDK](https://github.com/line/line-bot-sdk-python)が公開されているので、READMEの通りにインストール。

```
$ pip install line-bot-sdk
```

## メッセージをPUSHする

`20_photoRes.py`をベースにPUSHメッセージを遅れるように書き換える。

```photo_regsiter.py
#!/usr/bin/env python
# coding: UTF-8

import ADC0832
import sys
import time
from datetime import datetime
from linebot import (
    LineBotApi
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)

line_bot_api = LineBotApi('Access Token')


def init():
    ADC0832.setup()


def loop():
    error = False
    while True:
        res = ADC0832.getResult()
        if res <= 10:
            if not error:
                line_bot_api.push_message("Your user ID", TextSendMessage(text='エラーランプが点灯しました。'))
            error = True
        else:
            error = False
        time.sleep(0.4)

if __name__ == '__main__':
    init()
    try:
        loop()
    except KeyboardInterrupt:
        ADC0832.destroy()
        print 'The end !'

```

`Access Token`と`Your user ID`はLine Developersコンソールで確認する。
特に`Your user ID`は一般ユーザーが使う`@hogehoge`みたいなやつではないので注意する。

これをRaspberry Pi上で実行すると、フォトレジスタの抵抗が著しく下がった(=光が当てられた)場合にラインのメッセージが飛ぶようになる。
適当なアカウントで友だちになっておくと、メッセージが確認できる。


# Chatworkにアラートを飛ばす

こちらもAPIが公開されているので、遠慮なく使用する。
個人アカウントを持っていたら、「API設定」から簡単にAPIトークンを取得できる。

pythonからAPIを使用するため`requests`パッケージをインストール。

```
$ pip install requests
```

## メッセージをPUSHする

```photo_register_chatwork.py
#!/usr/bin/env python
# coding: UTF-8

import ADC0832
import sys
import time
from datetime import datetime
import requests


APIKEY = 'API KEY'
ENDPOINT = 'https://api.chatwork.com/v2'
ROOMID = 'ROOM ID'

post_message_url = '{}/rooms/{}/messages'.format(ENDPOINT, ROOMID)
headers = {'X-ChatWorkToken': APIKEY}
params = {'body': 'エラーランプが点灯しました。'}


def init():
    ADC0832.setup()


def loop():
    error = False
    while True:
        res = ADC0832.getResult()
        if res <= 10:
            if not error:
                resp = requests.post(post_message_url,
                                     headers=headers,
                                     params=params)
            error = True
        else:
            error = False
        time.sleep(0.4)


if __name__ == '__main__':
    init()
    try:
        loop()
    except KeyboardInterrupt:
        ADC0832.destroy()
        print 'The end !'
```

`API KEY`は先程取得したAPIトークンの値を、
`ROOM ID`はメッセージをPUSHしたいチャットルームのIDを指定する。

`ROOM ID`とはチャットルームのアドレスの`rid`以降の数字のことである。

# まとめ

+ Raspberry PIでセンサのアナログ値をデジタル値に変換して取得することができた
+ センサの値によってLineやChatworkといったチャットアプリで通知することができた