Raspberry と言えば、電子工作ですよね。
Lチカは、「ScratchでLチカ」や、「LチカをWebで制御する」の形で掲載したので、今回は温湿度がターゲットです。
今回の目標
DHT11で取得した温湿度を、データベース(Postgres)に記録し、照会する機能(Streamlit)を準備します。
利用する機材
① DHT11(基盤に乗っている扱いの簡単な機材を選択しました)
② ジャンパー線3本 (メス・メス)
DHT11
DHT11というと青い格子に足4本ですが、使い易い状態で基盤にはんだ付けされた物もあります。青い格子に足4本ですと、抵抗を入れる必要がある、不要な足がある等、扱いが少し面倒なので、便利な既製品を御薦めします。(回路作りを楽しみたい方は、青い格子に足4本で頑張りましょう)
データシートで性能を確認する限り、測定誤差が大きく御遊び感多々です。
私が選択した基盤にはんだ付けされた物ですが、足は3本で、
VCC / DATA / GND
と記載があります。色々な電材で必要な知識ですので覚えましょう。
電材のデータシート
電材の説明書みたいなものです。(英語が多く面倒ですが…)
性能や必要となる電圧等、利用に重要な内容が記載されていますので、利用の際には、必ず確認しましょう。
Raspberry Pi の準備
Raspberry Pi OS は Lite を利用します。
Postgresを使いたいので、以前の 安価なWeb開発勉強環境の構築 を参照して、インストールを進めます。
SQLAlchemy まで準備し、テーブルの作成は、下記で準備しましょう。
create table t_data (
kizai varchar(10),
nitiji timestamp,
ondo numeric(4,2),
situdo numeric(4,2),
kiatu numeric(6,2),
primary key ( kizai, nitiji ) );
他には、以下で準備してみます。
sudo mkdir /test (作業用ディレクトリ作成)
cd /test (カレント移動)
sudo python3 -m venv venv (仮想準備)
sudo chmod 777 -R /test (扱いやすいように権限を落とす)
source /test/venv/bin/activate (仮想環境起動)
pip install psycopg2-binary (Postgresコネクターインストール)
pip3 install SQLAlchemy (SQLAlchemyインストール)
他に必要な手順としては、venvの仮想でGPIOを利用したいので、「ScratchでLチカ」の「余談」対応が必要です。
sudo apt-get install pip (デフォルトのpipを補填します)
pip install RPi.GPIO (仮想環境にGPIOのパッケージを用意します)
Git-Hub に公開されているプログラムを利用させて頂きたいと思います。
sudo apt-get install git (Gitの利用の為インストール)
git clone https://github.com/szazo/DHT11_Python.git (Gitよりクローン)
「/test/DHT11_Python」が作成されているはずです。この中に、example.py のサンプルプログラムが用意されています。
サンプルプログラムを見ると、下記のように、GPIO-14 を利用しているようです。
# read data using pin 14
instance = dht11.DHT11(pin=14)
このプログラムを、そのまま利用したいと思います。
vcc(電源)2番ピン(5v)と、data(情報の制御用)8番ピン(GPIO-14)と、GNDは数か所ありますが 14番ピンを使ってみましょう。
cd /test/DHT11_Python (カレント移動)
pyhon example.py (プログラム実行)
Last valid input: 2024-11-03 14:51:25.319791
Temperature: 24.5 C
Humidity: 53.0 %
のような処理結果が、6秒置きに表示されるはずです。<ここまで出来れば、現実世界の準備は完了です>
「CTRL+C」でプログラムを終了させます。 次にプログラム(example.py)を修正して、今回のお題を実現するプログラムを準備します。
まずは、Postgres へのアクセスを SQLAlchemy で操作するプログラムを用意します。
from sqlalchemy import create_engine, Column, Integer, String, DateTime, Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('postgresql://flask1:パスワード@localhost:5432/flask1')
Base = declarative_base()
Ses = sessionmaker(bind=engine)
class t_data(Base):
__tablename__ = 't_data'
kizai = Column(String(10), primary_key=True)
nitiji = Column(DateTime)
ondo = Column(Float)
situdo = Column(Float)
kiatu = Column(Float)
cp example.py dht11p.py (サンプルプログラムをコピー作成して編集します)
import RPi.GPIO as GPIO
import dht11
import time
import datetime
import db
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
instance = dht11.DHT11(pin=14)
dtCtrl = db.Ses()
try:
while True:
result = instance.read()
if result.is_valid():
print("Last valid input: " + str(datetime.datetime.now()))
print("Temperature: %-3.1f C" % result.temperature)
print("Humidity: %-3.1f %%" % result.humidity)
newDt = db.t_data(
kizai='DHT11',
nitiji=datetime.datetime.now(),
ondo=result.temperature,
situdo=result.humidity,
kiatu=0
)
dtCtrl.add(newDt)
dtCtrl.commit()
dtCtrl.close()
break
time.sleep(6)
except KeyboardInterrupt:
print("Cleanup")
GPIO.cleanup()
一度実行してみましょう。
python dht11p.py (プログラム実行)
先程と同じように、時間・温度 が表示されて、今回はプログラムが終了するはずです。
これを、1分おきに、自動実行するように設定していきます。
sudo crontab -e (ジョブ設定に下記を追加します)
* * * * * /bin/bash -c 'source /test/venv/bin/activate && python /test/DHT11_Python/dht11p.py'
ここから、以前の記事「Raspberryでstreamlitを勉強してみる②」で照会機能を準備します。
今回はサイドバーは、無しで簡単なプログラムを準備します。
import streamlit as st
from sqlalchemy import create_engine, select, text
engine = create_engine('postgresql://flask1:パスワード@localhost:5432/flask1')
with engine.connect() as conn:
stmt = select('*').select_from(text('t_data'))
result = conn.execute(stmt)
data = result.fetchall()
import pandas as pd
df = pd.DataFrame(data, columns=['器具', '日時', '温度', '湿度', '気圧'])
df['日時'] = pd.to_datetime(df['日時'])
df.set_index('日時', inplace=True)
df['温度'] = df['温度'].astype(float)
df['湿度'] = df['湿度'].astype(float)
st.title('温度・湿度') # 気圧はDHT11では計測できないです
st.line_chart(df[['温度', '湿度']], use_container_width=True)
プログラムが完成したらテスト確認しましょう。
(仮想環境のまま)streamlit run graph.py (streamlitが実行されます)
その後、パソコンより「http://(RaspberryのIPアドレス):8501」へアクセスします。
少し時間を取られた問題発生
streamlitのデフォルトportが、8501なのですが、稀に別のポートで起動されるようです。
streamlit run すると、port番号が明示されるので、確認してから起動しましょう。
最後に、streamlitをサービス起動するように変更しましょう。
以前の記事「Raspberryでstreamlitを勉強してみる①」の「streamlitをサービス起動する方法」を利用します。
上記の問題で迷わないように、ポートは指定してサービス稼働したいと思います。
sudo vi /etc/systemd/system/streamlit_service.service
[Unit]
Description=Streamlit Service
After=network.target
[Service]
WorkingDirectory=/test
Environment=PATH=/test/venv/bin:$PATH
ExecStart=/test/venv/bin/streamlit run --server.port 8501 /test/DHT11_Python/graph.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
編集が終わったら、サービスを起動して確認します。
sudo systemctl daemon-reload
sudo systemctl start streamlit_service
問題無ければ、サービスを登録しましょう。
sudo systemctl enable streamlit_service (サービス起動として登録)
sudo reboot (raspberryを再起動して確認しましょう)
これで、通電したら、即計測開始&即グラフ提供開始の実現です。
お疲れさまでした~。