アーカイブ : 2021年 7月 18日

ラズパイからAmbientにCPU負荷と温度、湿度を送信する

ラスパイから、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接続
PINGPIODHT22
25V Power+ (プラス)
35Ground– (マイナス)
36GPIOOUT

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分周期でデータを送信するようにします。

$ crontab -e

エディタが起動したら、下記の一行を追加します。これで、5分周期でコマンドが実行されます。

*/5    *       *       *       *       ~/bin/ambi_pi_temp.py > /dev/null 2>&1

Ambientのサイトでアップロードの内容を確認

Ambientのサイトに戻り、チャンネル一覧から今回作成したチャンネルを設定します。
今回は、下記のようなチャンネル設定にしています。

設定画面を閉じるとグラフが表示されます。

これでラズパイからの温度データアップロードは終了です。次回は、MQTTコマンドでデータ送信がアップロードできるようにしたいと考えています。