ラスパイから、AmbientにCPU温度、CPU負荷、室温、湿度のデータをアップロードして可視化してみました。
Ambientサービスのチャンネル作成
下記のサイトでアカウントを作成し、データをアップロードするチャンネルを作成します。https://ambidata.io/ 今回は、Raspberry Pi というチャンネルを作成しました。チャンネル一覧に表示される、チャンネルID、リードキー、ライトキーは、データのアップロードに必要となります。
チャンネル一覧
チャンネルの設定は、下記のようにしました。データは8個まで送信でき、今回は、データ1~4までを使用して、CPU温度、CPU負荷、室温、湿度を割り当てました。
チャンネル設定
ラズパイへの温度センサー接続ラズパイへの温度センサー接
ラズパイで、室温、湿度を計測するための温湿度センサーを接続します。今回は、DHT22を使用しました。 使用するラズパイは、Raspberry Pi 3B+で、 ラズパイとDHT22を右のように接続しました。Raspberry Pi 4Bでも同様の接続になるかと思います。 使用するDHT22は、抵抗含めてモジュール化された3PIN接続のものです。使用するセンサーによっては抵抗の追加などが必要になるかと思います。
DHT22接続
PIN GPIO DHT22 2 5V Power + (プラス) 35 Ground – (マイナス) 36 GPIO OUT
GPIOアクセスのパーミッション設定
DHT22を使用するには、GPIOの制御が必要になります。下記のサイトを参考に、GPIO制御のパーミッションを設定しました。https://askubuntu.com/questions/1247005/controlling-gpio-on-ubuntu-20-04-64-bit-arm-raspberry-pi 今回使用する環境のOSは、Ubuntu 20.04 です。Raspbian 等のOSを使用している場合は、 設定が異なる可能性があるので参考程度にご覧ください。 lsb_releaseコマンドの出力結果は下記のとおりです。
$ lsb_release -d
Description: Ubuntu 20.04.2 LTS
rpi.gpio-common のパッケージをインストールします。
$ sudo apt install rpi.gpio-common
デバイス接続時のルール作成。viで、/etc/udev/rules.d/60-rpi.gpio-common.rules を作成しました。
$ sudo vi /etc/udev/rules.d/60-rpi.gpio-common.rules
設定ファイルの内容は下記の通り。
SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="dialout", MODE="0660"
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"
ユーザーをdialoutグループに追加して再起動します。
$ sudo adduser $USER dialout
$ sudo reboot
データ送信のスクリプト作成
次に、Ambientへのデータ送信用スクリプトを作成します。 ラズパイのCPU温度取得に、vcgencmd を使用するので、下記のパッケージをインストールしました。
$ sudo apt-get install libraspberrypi-bin
$ sudo -H pip3 install psutil
$ sudo -H pip3 install Adafruit_DHT
$ sudo -H pip3 install git+https://github.com/AmbientDataInc/ambient-python-lib.git
スクリプトは、どこに作成してもよいのですが、今回は、$HOME/bin/bin/ambi_pi_temp.py というファイル名で保存しています。 チャンネルID、リードキー、ライトキーは、ご自身の環境に合わせて修正してください。
#!/usr/bin/python3
import datetime
import psutil
import subprocess
import time
import ambient
import Adafruit_DHT as DHT
AmbiChannelID=<チャンネルID>
AmbientReadKey="<リードキー>"
AmbiWriteKey="<ライトキー>"
# read data using pin 16
pin=16
def is_float(s):
try:
float(s)
except ValueError:
return False
else:
return True
def res_cmd(cmd):
return subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).communicate()[0]
def get_raspi_temp():
cmd = ("vcgencmd measure_temp | sed -e 's/temp=//g' -e \"s/'C//g\" | tr -d '\n'")
return res_cmd(cmd).decode('utf-8')
def get_room_temp():
for num in range(30):
humidity, temperature = DHT.read(DHT.DHT22, pin)
if is_float(temperature) and (-40.0 < temperature < 80.0) and is_float(temperature) and (0.0 < humidity < 100.0):
break
time.sleep(0.5)
return humidity, temperature
if __name__ == '__main__':
ambi = ambient.Ambient(AmbiChannelID, AmbiWriteKey)
pi_temp = get_raspi_temp()
pi_load = psutil.cpu_percent(interval=1, percpu=False)
humidity, temperature = get_room_temp()
dt_now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print("[%s] Raspi temp:%5s'C CPU: %5s%%" % (dt_now, pi_temp, pi_load))
print("[%s] Room temp: %3.1f'C humidity: %3.1f%%" % (dt_now, temperature, humidity))
r = ambi.send({"d1":pi_temp, "d2":pi_load,
"d3":temperature, "d4":humidity})
スクリプトに権限を付与します。
$ chmod 777 ~/bin/ambi_pi_temp.py
単体でスクリプト実行してエラーが発生しなければ、データがアップロードできていると思います。
$ ./ambi_pi_temp.py
[2021-07-18 11:34:45] Raspi temp: 39.2'C CPU: 0.0%
[2021-07-18 11:34:45] Room temp: 30.0'C humidity: 52.2
cronで5分周期でデータを送信するようにします。
エディタが起動したら、下記の一行を追加します。これで、5分周期でコマンドが実行されます。
*/5 * * * * ~/bin/ambi_pi_temp.py > /dev/null 2>&1
Ambientのサイトでアップロードの内容を確認
Ambientのサイトに戻り、チャンネル一覧から今回作成したチャンネルを設定します。 今回は、下記のようなチャンネル設定にしています。
設定画面を閉じるとグラフが表示されます。
これでラズパイからの温度データアップロードは終了です。次回は、MQTTコマンドでデータ送信がアップロードできるようにしたいと考えています。