RaspberryPiでgrove Sensor HATを動かし、MQTTでpublishする方法

# はじめに
この記事は[TDU CPSLab Advent Calendar 2020](https://adventar.org/calendars/5298)の5日目の記事です
#### どうしてこんな記事書くの？
卒研の追加実装なら技術系の記事をかけると思ったため。
また、少し詰まったところがあったのでこの先同じことをしようとした人が詰まったりしないようにしたいので

対象者:
スムーズにgroveセンサー開発をラズパイでしたい人向け

## 機材
+ RaspberryPi Model 3B+
+ [Grove Base Hat for Raspberry Pi](https://wiki.seeedstudio.com/Grove_Base_Hat_for_Raspberry_Pi/)
+ [MQ-9 Gas Sensor](https://wiki.seeedstudio.com/Grove-Gas_Sensor-MQ9/)

## 環境
+ Raspbian (debian 10.6)

# 構築手順
[こちらのページ](https://qiita.com/fujit33/items/763b09a6e71e65519740)を参照してi2cをラズパイでできるように設定する
+  i2c-toolsをinstall 

```
pi@raspberrypi:~ $ sudo apt-get install i2c-tools
```

+ raspi configでi2cを有効にする

```
pi@raspberrypi:~ $ sudo raspi-config
```
+ 再起動

```
pi@raspberrypi:~ $ sudo reboot
```

+ groveセンサーライブラリをクローンし、インストール

```
git clone https://github.com/Seeed-Studio/grove.py
cd grove.py
pip3 install .
```

サンプルスクリプトを[ここのページ](https://wiki.seeedstudio.com/Grove-Gas_Sensor-MQ9/)に則ってやる

```python

import math
import sys
import time
from grove.adc import ADC
 
 
class GroveGasSensorMQ9:
 
    def __init__(self, channel):
        self.channel = channel
        self.adc = ADC()
 
    @property
    def MQ9(self):
        value = self.adc.read(self.channel)
        return value
 
Grove = GroveGasSensorMQ9
 
 
def main():
    if len(sys.argv) < 2:
        print('Usage: {} adc_channel'.format(sys.argv[0]))
        sys.exit(1)
 
    sensor = GroveGasSensorMQ9(int(sys.argv[1]))
 
    print('Detecting...')
    while True:
        print('Gas value: {0}'.format(sensor.MQ9))
        time.sleep(.3)
 
if __name__ == '__main__':
    main()

```

# MQTT通信で取れたガスセンサの値を送る

ちょっと改造してMQTTで自分のローカルで作ったBrokerへPublishしてみる

[このページ](https://qiita.com/hsgucci/items/6461d8555ea1245ef6c2)からコードをお借りする

```python

#!usr/bin/env python
# -*- coding: utf-8 -*-
import time
import paho.mqtt.client as mqtt     # MQTTのライブラリをインポート
from time import sleep              # 3秒間のウェイトのために使う
import math
import sys
from grove.adc import ADC


class GroveGasSensorMQ9:

    def __init__(self, channel):
        self.channel = channel
        self.adc = ADC()

    @property
    def MQ9(self):
        value = self.adc.read(self.channel)
        return value
# ブローカーに接続できたときの処理


def on_connect(client, userdata, flag, rc):
    print("Connected with result code " + str(rc))

# ブローカーが切断したときの処理


def on_disconnect(client, userdata, flag, rc):
    if rc != 0:
        print("Unexpected disconnection.")

# publishが完了したときの処理


def on_publish(client, userdata, mid):
    print("publish: {0}".format(mid))

# メイン関数   この関数は末尾のif文から呼び出される


def main():
    client = mqtt.Client()                 # クラスのインスタンス(実体)の作成
    client.on_connect = on_connect         # 接続時のコールバック関数を登録
    client.on_disconnect = on_disconnect   # 切断時のコールバックを登録
    client.on_publish = on_publish         # メッセージ送信時のコールバック
    sensor = GroveGasSensorMQ9(0)

    client.connect("localhost", 1883, 60)  # 接続先は自分自身

    # 通信処理スタート
    client.loop_start()    # subはloop_forever()だが，pubはloop_start()で起動だけさせる

    # 永久に繰り返す
    while True:
        client.publish("pub/gas", sensor.MQ9)    # トピック名とメッセージを決めて送信
        sleep(3)   # 3秒待つ


if __name__ == '__main__':          # importされないときだけmain()を呼ぶ
    main()    # メイン関数を呼び出す

```

#node-redで受け取る
今回はnode-redで終わらせます・・・（卒研め）

aedesをnode-redでインストールしてください
aedesはmosca mqtt brokerの後継的存在でパフォーマンスが向上しているとのこと・・・・

node-redの　パレットを管理　> ノードを追加から
```node-red-contrib-aedes```
と検索し追加する

追加できたらaedes brokerとmqtt inノード、デバッグノードを追加する
![スクリーンショット 2020-12-05 22.34.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238493/f241b3b2-fa72-3ddf-5826-6cfe4edab356.png)

デプロイしたら、pythonスクリプトを実行すると
![スクリーンショット 2020-12-05 22.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238493/ded61283-ee83-2ead-914b-505baa7f629f.png)

こうなったら完了！

#おわりに
卒研が佳境の中の低クオリティ記事ではありますが、少しでも助けになれば幸いです。
ここまで見ていただいた方ありがとうございます。