ラズベリーパイで気温・湿度監視モニターの作成 （pigpio版）

GPIO制御をpigpioに変えてDHT22から温湿度値を取得します。
今後他のセンサーを制御するにあたりpigpioに移行した方が良さそうだと感じましたのでMyPyDHTで作成したものを作り直しました。

[ラズベリーパイで気温・湿度監視モニターの作成](https://qiita.com/dev_greentea/items/ee07f2cdbc2900974d53)
のpigpio版です。

## 事前準備

pigpioはこちらのWebにあるようにラズベリーパイへインストールします。
http://abyz.me.uk/rpi/pigpio/download.html

とりあえず、下のコマンドを実行すれば、良いはず。

```bash
sudo apt-get update
sudo apt-get install pigpio python-pigpio python3-pigpio

sudo pigpiod
```

DHTの制御コードもpigpio作成者のExamplesページにありましたでそのまま、使用します。
http://abyz.me.uk/rpi/pigpio/code/DHT.py


[RasPi＋FastAPIを使う](https://qiita.com/dev_greentea/items/3d3d34b26d14e22ab76d)

### DHT22センサーとラズベリーパイの接続

GPIO４番にDAT端子を接続して、VCCには５Vを与えています。

## ファイル構成

| ファイル | 説明 |
|--------|------|
| templates/index.html | HTMLファイル、JavaScriptで５秒ごとにデータを取得する |
| dht_server.py | Pythonサーバ、DHT22のセンサー処理を含む　|
| DHT.py | pigpio作成者のDHTセンサ制御コード（DHT11/21/22/33/44 ）に自動対応らしい　|

## DHT22のメイン制御

DHTの制御コード(DHT.py)を引数にGPIO値付けて実行すると２秒ごとに、GPIO値に+100をつけるとコールバック制御で温室度値を取得します。

```bash
python DHT.py 4
or
python DHT.py 104
```

DHT.pyからメイン処理だけ抜き出して、実行すると２秒ごとに温室度値を取得するコードを一旦記載します。
DHT.pyは同じフォルダ内に保存してください。
後ほどこのコードをサーバに転記することになります。

```python:dht22_pigpio.py
import time
import DHT
import pigpio
import datetime

DHT_PIN = 4 

if __name__== "__main__":
    pi = pigpio.pi()
    if not pi.connected:
        print(f"cannot connect to pigpio")
        exit()

    s = DHT.sensor(pi, DHT_PIN)

    while True:
        try:
            d = s.read()
            today = datetime.datetime.fromtimestamp(d[0]).strftime ("%Y/%m/%d %H:%M" )
            temperature = d[3]
            humidity = d[4]
            dat = {"time": today, "temperature": temperature, "humidity": humidity}
            print(f"json: {dat}")
            time.sleep(2)
        except KeyboardInterrupt:
            break

    s.cancel()
    print(f"cancelling")
    pi.stop()
```

## html code

Pythonサーバからfetchを使用して５秒ごとに気温と湿度情報を取得する。
（前回と同じ）

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <title>気温・湿度監視モニター</title>
</head>

<body>
    <div>
        <div class="container">
            <h1>気温・湿度監視モニター</h1>
            <h2 id="time">time</h2>
            <h2 id="temperature">temperature</h2>
            <h2 id="humidity">humidity</h2>
        </div>
    </div>
    <script>
        // サーバから温室度値の取得
        var sensor_read = function () {
            fetch("/data", {
                method: 'GET'
            }).then((response) => {
                return response.json();
            }).then((data) => {
                console.log(data);
                var time = document.querySelector("#time")
                time.innerHTML = data.time
                var temperature = document.querySelector("#temperature")
                temperature.innerHTML = `気温：${data.temperature}度`
                var humidity = document.querySelector("#humidity")
                humidity.innerHTML = `湿度：${data.humidity}％`
            }).catch((err) => {
                console.error(err);
            });
        };

　　　　 // ５秒タイマー
        setInterval(sensor_read, 5000);
    </script>
</body>

</html>
```

## Python code

/dataへアクセスした時にDictで気温・湿度データを渡す。

```python:dht_server.py
import uvicorn
from fastapi import FastAPI
from starlette.templating import Jinja2Templates
from starlette.requests import Request
import datetime
import DHT
import pigpio

app = FastAPI()

templates = Jinja2Templates(directory="templates")
jinja_env = templates.env

DHT_PIN = 4 
sensor = None

@app.get("/")
def root(request: Request):
    return templates.TemplateResponse('index.html',
                                      {'request': request})

@app.get("/data")
def data():
    """温湿度値を返す"""
    try:
        data = sensor.read()
        today = datetime.datetime.fromtimestamp(data[0]).strftime ("%Y/%m/%d %H:%M")
        status = data[2]
        temperature = data[3]
        humidity = data[4]
        if status == DHT.DHT_GOOD:
            dat = {"time": today, "temperature": temperature, "humidity": humidity}
            print(f"json: {dat}")
            return dat
        else:
            raise Exception(f"dht sensor error: {status}")
    except Exception as e:
        print(f"err: {str(e)}")

    return None


if __name__ == "__main__":
    pi = pigpio.pi()
    if not pi.connected:
        print(f"cannot connect to pigpio")
        exit()

    sensor = DHT.sensor(pi, DHT_PIN)
    # サーバ起動
    uvicorn.run(app, host="0.0.0.0", port=8000)

    sensor.cancel()
    print(f"cancelling")
    pi.stop()
```

## サーバを起動する。

ラズベリーパイのIPを調べて、ブラウザでアクセスする。
0.0.0.0はラズベリーパイ上でifconfigなどで調べて置き換えてください。

```bash
 $ python dht_server.py 
```