環境センサーの値をGrafanaで可視化する！

# はじめに
オムロンの環境センサーの値を取得してGrafanaで可視化する


# 使うセンサー
https://www.fa.omron.co.jp/products/family/3723/

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/f1d9a616-0e22-b6d2-c248-971d5e22766a.jpeg" width="20%">


改めて調べたら生産終了してた
USB直差しできる[こっち](https://www.fa.omron.co.jp/products/family/3724/)の方が今後はいいかも

### 特徴
* 6個の環境データを取得可能
    * 温度、湿度、照度、UV、気圧、騒音
* ボタン電池で駆動可能(好きな置き場所を選べる)
    * 電池持ちはそんなに良くない
    * 1分間隔でデータ取得して1ヶ月半ぐらいの電池持ち


# データ処理の流れ

1. RaspberryPiが環境センサーの値を取得する
1. influxdbに取得したデータを記録する
1. Grafanaでデータを可視化する
1. スマホとかで見る

イメージはこんなん

![Screenshot from 2023-05-06 09-32-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/a5b90842-db69-9834-582f-aeb321a80b46.png)



# 環境の準備

```bash
sudo apt install build-essential libssl-dev libffi-dev python3-dev libglib2.0-dev
sudo pip install bluepy influxdb-client influxdb
```

# 環境センサのMACアドレスを調べる

`lescan`コマンドを使って調べる
```bash
sudo hcitool lescan

LE Scan ...
4C:EC:43:67:50:DF (unknown)
4C:EC:43:67:50:DF (unknown)
47:BB:5D:77:4F:BB (unknown)
xx:xx:xx:xx:xx:xx Env
C0:78:83:73:35:9D (unknown)
```

Envが環境センサー

# データ取得とDBに書き込み
実際のデータ取得スクリプトは以下

```python:GetEnvData.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from bluepy import btle
from time import sleep
import struct
import Influxdb

ADDR_TYPE_PUBLIC = "public"
ADDR_TYPE_RANDOM = "random"
MAC_ADDRESS = 'xx:xx:xx:xx:xx:xx' # 環境センサのMACアドレスを設定する
OMRON_UUID = '0C4C3001-7700-46F4-AA96D5E974E32A54'
UUID3002 = '0C4C3002-7700-46F4-AA96D5E974E32A54'


def main():
    peripheral = btle.Peripheral(
        MAC_ADDRESS, addrType=ADDR_TYPE_RANDOM, iface=0)
    while True:
        try:
            characteristic = peripheral.getCharacteristics(uuid=OMRON_UUID)[0]
            dataRow = characteristic.read()
            (seq, tempature, humidity, illumination, uv, press, noise, discom, heat, battery) = struct.unpack('<BhhhhhhhhH', dataRow)

            tempature = float(tempature / 100)
            humidity = float(humidity / 100)
            uv = float(uv / 100)
            press = float(press / 10)
            noise = float(noise / 100)
            battery = float(battery / 1000)

            print('temp = ' + str(tempature))
            Influxdb.WriteDB(dbname='HomeDB', meas="Environment", field='Tempature', data=tempature)
            print('humidity = ' + str(humidity))
            Influxdb.WriteDB(dbname='HomeDB', meas="Environment", field='Humidity', data=humidity)
            print('illumination = ' + str(illumination))
            Influxdb.WriteDB(dbname='HomeDB', meas="Environment", field='Illumination', data=illumination)
            print('uv = ' + str(uv))
            Influxdb.WriteDB(dbname='HomeDB', meas="Environment", field='UV', data=uv)
            print('press = ' + str(press))
            Influxdb.WriteDB(dbname='HomeDB', meas="Environment", field='Press', data=press)
            print('noise = ' + str(noise))
            Influxdb.WriteDB(dbname='HomeDB', meas="Environment", field='Noise', data=noise)
            print('battery = ' + str(battery))
            Influxdb.WriteDB(dbname='HomeDB', meas="Environment", field='Battery', data=battery)

            sleep(60)

        except btle.BTLEException as e:
            print('args:' + str(e.args))
            peripheral = btle.Peripheral(
                MAC_ADDRESS, addrType=ADDR_TYPE_RANDOM, iface=0)
            sleep(60)


if __name__ == "__main__":
    main()
```

influxdbに書き込む部分は別スクリプト化してる

```python:Influxdb.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-

from influxdb import InfluxDBClient
from datetime import datetime
from pytz import timezone


def WriteDB(dbname, meas, field, data, time=None):
    if time is None:
        time = datetime.now(timezone('UTC')).isoformat('T').split('.')[0]
    json_body = [
        {
            "measurement": meas,
            "time": time,
            "tags": {
                "hard": "RasPi4+"
            },
            "fields": {
                field: data
            }
        }
    ]
    client = InfluxDBClient(database=dbname)
    client.write_points(json_body)
```

`GetEnvData.py`を実行すると60秒毎に環境センサのデータがDBに書き込まれる
実際にはsystemdでデーモン化して動かしてる


# 可視化

DBに登録した値をGrafanaで可視化する

1. パネルを追加
1. Data sourceで`HomeDB`を選択（事前にGrafanaの設定でHomeDBに接続しておく）
1. select measurementで`Environment`を選択
1. field(value)で表示したいデータを選択（ここでは`Noise`を選択)

![Screenshot from 2023-05-06 10-07-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/0552cbb1-5c91-0e13-37a2-88e9dc1a7d25.png)


## 実際のGrafanaがこんな感じ

![Screenshot from 2023-05-06 09-09-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/a791505b-6896-dac0-4db3-3e588b32b103.png)

複数パネルを並べるとそれっぽい感じに仕上がる

以上