熱帯魚水槽のファン冷却 RaspberryPiとデジタル温度センサ(1wire)DS18B20、USBファン

熱帯魚の水槽の温度は、冬の間26℃程度のヒーターで25℃～26℃程度で維持されています。
しかし、夏場になると、直ぐに30℃程度に上がってしまい、ちょっと気を抜くと熱帯魚が死んでしまいます。

定期的に氷を周囲に配置するなどしてしのいできましたが、やはり、大変すぎる。
高度な外付けの冷却装置は、価格も高く大きさも大きいので、導入はためらわれていました。

そこに、気化熱を利用した送風ファンによる冷却が、私のところの45cm×21cm程度のスリム水槽程度なら、十分に機能することがわかりました。3℃程度の温度低下がかのうでした。
　水作のファン（ https://www.suisaku.com/product/lighting_temperature/2248/ ）を使っていました。
　ダイソーのUSB扇風機（ https://jp.daisonet.com/products/4550480275383?_pos=22&_sid=69730d5e3&_ss=r ）も併用しています

そこで、RaspberryPiZeroを用いて、水槽温度の記録と、その冷却ファンの電源ON/OFFの自動化を図りました。

　●温度計　：　DS18B20　(1-Waire)
　　で計測して
　●電源リレー　を制御して、　USDBファンのON/OFFを行う


以下の図の通りです。
![ondo-fan-raspberrypi_640.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325563/f5c967fe-b1d0-6c6e-a64d-1a0c305fe290.jpeg)

水槽の温度が高くなったら、USB接続のファンの電源をリレーで制御して、
ONにして、温度を下げます。
![ondo_test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325563/64c5d7c2-9ea2-52cd-a10b-bf84bf5a5599.jpeg)



さて、
以下にプログラムの接続構成を書きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325563/2a2cc8ab-e541-8ac7-d919-dfdad3304fe2.png)


1-1．1-wire の有効化
　RaspberryPiのConfigurationで、1-wireを有効にします。
　```$ sudo raspi-config```

1-2．GPIOの割り当て
　RaspberryPiの/bootにあるconfig.txtに以下のように追加して再起動する
　これで、GPIO-04が、1-wireになる
```text:/boot/config.txt
[all]
dtoverlay=w1-gpio-pullup,gpiopin=4
```
　再起動後、```ls /sys/bus/w1/devices/```とすると、
　1-wireのデバイスが表示されます。
　（わたくしの環境では２個つながっているので、以下のようになります）
```text: ls /sys/bus/w1/devices/
pi@raspberrypi:~ $ ls /sys/bus/w1/devices/
28-0114482d95aa  28-0114482f62aa  w1_bus_master1
```
　この場合、28-から始まるディレクトリがデバイスになります。

1-3．データの読み取り
　次のPythonプログラムで読み取っています。
```python:temparature.py
#!/usr/bin/python3

def temparature():
    file_name = "/sys/bus/w1/devices/28-0114482f62aa/w1_slave"

    try:
        file = open(file_name)
        data = file.read()
        #print(data)
    except Exception as e:
        print(e)
    finally:
        file.close()

    sp_data = data.split("\n")
    sp2_data = sp_data[1].split()
    sp3_data = sp2_data[9].split("=")
    temparature = float(sp3_data[1])/1000.0
    #print(temparature)

    return temparature

if __name__ == "__main__":
    data = temparature()
    print(data)
```
　結果は、別のプログラムから使いたいので、温度だけ戻しています。
```
pi@raspberrypi:~/temparature $ python3 temparature.py
27.75
```

2-1．GPIOの出力ON/OFFで、5VリレーをON/OFF
　USB電源を操作する5VのリレースイッチをGPIOポートの
　出力で制御します。
　外部から状況を確認できるようにもしておきたいので、
　簡易なWebサーバ(Flask)から、GPIOポートを制御しています。
　（Node-Redとか使えばよいのですが、まぁこれで）
　（適当すぎるプログラムですが、動けば良いので、GPIO-23を使いました）

```python:gpio-switing-web.py
#!/usr/bin/python3
# coding: utf-8

import RPi.GPIO as GPIO # RPi.GPIOモジュールを使用
from flask import Flask
app = Flask(__name__)

global_sw_status = 0

@app.route('/swon')
def swon():
    global global_sw_status
    gpio_num = 23
    global_sw_status = 1
    usbenergyonoff(gpio_num,1)
    return "SW ON"

@app.route('/swoff')
def swoff():
    global global_sw_status
    gpio_num = 23
    global_sw_status = 0
    usbenergyonoff(gpio_num,0)
    return "SW OFF"

@app.route('/swstatus')
def swstatus():
    global global_sw_status
    return "SW status: " + str(global_sw_status)

def usbenergyonoff(gpio_num,sw_status):

    # GPIO番号指定の準備
    GPIO.setmode(GPIO.BCM)

    # GPIOを出力に設定
    GPIO.setup(gpio_num, GPIO.OUT)

    # sw_statusが1(0より大きい)の場合(ON)
    if sw_status > 0:
        GPIO.output(gpio_num, 1)    # 出力1(ON)

    # sw_statusがそれ以外の場合(OFF)
    else:
        GPIO.output(gpio_num, 0)    # 出力0(OFF)

if __name__ == "__main__":
    # 利用するGPIO番号
    # 必要に応じて変更
    gpio_number = 23

    #flask run
    #app.run(debug=True)
    app.run(debug=False,  host='0.0.0.0', port=8000)

    # 後処理 GPIOを解放
    GPIO.cleanup(gpio_number)
```

　信頼性低いですが、このプログラムを、rebootしたら、起動するように
　crontabに登録しておきます。（その前に```chmod 755 gpio-switing-web.py```）
```text: crontab -e
@reboot /home/pi/goip-sw/gpio-switing-web.py
```

2-2．1のプログラムで、制御する
　１で作ったプログラムで、温度を取得して、その結果により
　2-1のWebサーバにアクセスして、USB電源の状態を変更します。
```python: ondo.py
#!/usr/bin/python3
# coding: utf-8

#1-3で作ったプログラムをライブラリとして読み込む
import temparature
#HTTP-GETのためのライブラリを入れる
import requests
#記録のため出力で時間を書きだすために入れるdatetime
import datetime

if __name__== '__main__':
    #温度を確認
    data1 = temparature.temparature()
    print("{}, {}".format(datetime.datetime.now(), data1))

    ## data check
    if( data1 > 28.0 ):
        print("SW ON!")
        res = requests.get('http://localhost:8000/swon')
    else:
        print("SW OFF!")
        res = requests.get('http://localhost:8000/swoff')

    print("SW Status: {}".format(res.text))
```
　結果は、そろそろSWが入らないとまずいですね。
```
pi@raspberrypi:~/temparature $ python3 ondo.py
2023-08-15 05:07:30.223605, 27.812
SW OFF!
SW Status: SW OFF
```

　このプログラムは、crontabで5分おきに起動させるなどします。
　（2-1と同じく、実行パーミッションに```chmod 755 ondo.py```
```text: crontab -e
*/5 * * * * /home/pi/temparature/ondo.py >> /home/pi/temparature/log.log
```

という感じで、一応、動き続けています。
現状は次の通り、
http://testiot.starfree.jp/8ol0jupyod8j/sensor.php?deviceid=1



参考にさせて頂いたページ
●https://qiita.com/STDNUL/items/f76a65f7eb4e27d44b5f
●https://qiita.com/rukihena/items/477f976d266c3984418b
●https://101010.fun/raspi-water-temp.html

部品
●https://www.amazon.co.jp/gp/product/B07M886SBK
●https://www.suisaku.com/product/lighting_temperature/2248/
●https://www.amazon.co.jp/gp/product/B08CKGNHP9/
●https://akizukidenshi.com/catalog/g/gK-15022/