FunnyGeek

Home > This page

うちのワンコを真夏の暑さから守る(Datadogで)

RaspberryPiで室温を計測して、Datadogで温度監視とアラート通知をする。アラート受けたら自分が助けに行く。

ゴール設定

うちのワンコはトイプードルの「しえる」って言います。犬を飼っている皆さんは、真夏の暑い日に万が一、エアコンが故障したり、停止したままだったり、室内でも熱中症になりそうなくらい暑くなっていたらどうしよう、と心配した事ありませんか? そこで、うちの「しえる(トイプ)」を真夏の暑さから守る為にアラート通知付き室温センサーを作ります。

ワンコとエアコンと温度センサーのイラスト

やることは:

  • 1-1. ラズパイの温度センサーで、部屋の温度を計測する。
  • 1-2. Datadogで温度データを可視化する。
  • 1-3. Datadogの温度データが閾値を超えたらアラート通知をメール送信する。

ラズパイの部品構成(1-wire, I2C)

  • 2-1. Raspberry Pi3 A+
  • 2-2. 温度センサー:[1-wire]インターフェースのDS18B20、温度だけ計測できる。
  • 2-3. UVセンサー:[I2C]インターフェースのSI1145、UVインデックス/可視光/赤外線を計測できる。

快適温度は湿度にも影響するので、どうせI2C使うならM5stackで使った温湿度センサー(BHT12)も繋げちゃおう、と思ったのだが、ラズパイの[i2cdetect]コマンドで認識できたI2Cデバイスアドレス0x5cで取得できるデータは0xFFとか0xXXばかり。あちこちインターネットで解決策を探し回ったけれど、結局、相性が悪く正しくデータ検出できなかったので止む無く温度のみセンサー(DS18B20)を使うことにした。

ラズパイとセンサーの配線図(RaspberryPi3, DS18B20, SI1145)

スクリプトの構成(python, datadog-agent)

センサーから取得した温度データは、jsonファイル[図. data.json]を経由してDatadogエージェント[図. DD agent]に渡すことにした。最初、Datadogエージェントのカスタムメトリックから直接、センサーデータを取得しようとしたが、datadogエージェントでの自作pythonのimport処理が上手くモジュールを読み込んでくれなかったので、その追及を止めてpythonでのデータ取得[図. python get data]とdatadogエージェントの機能を分離した。

  • 3-1. 自作スクリプト[i2c_write_json.py]と関連モジュール:センサーの値を取得してjsonファイルに出力する。
  • 3-2. Datadogエージェント[~/.datadog-agent/bin/agent]:監視エージェントの本体シェルスクリプト。jsonファイルを読んでDatadog監視サーバーにデータを送信する。

構成図; ラズパイ(RaspberryPi), Datadog監視ダッシュボード

温度データを取得(python)

インストールした関連モジュール4つ:
インストールコマンドを使っていないのでファイル名は変更しています(例:ディレクトリAdafruit_GPIOにあるI2C.pyファイルはAdafruit_GPIO_I2C.pyというファイル名で保存)。

Adafruit関連:MIT: Copyright (c) 2014 Adafruit Industries

https://github.com/adafruit/Adafruit_Python_GPIO

  • 4-1. Adafruit_GPIO_I2C.py
  • 4-2. Adafruit_GPIO_Platform.py
  • 4-3. Adafruit_GPIO_PureIO_smbus.py

SI1145関連:MIT: Copyright (c) 2014 Joe Gutting

https://github.com/THP-JOE/Python_SI1145

  • 4-4. SI1145.py

自作pythonスクリプト

  • 4-5. i2c_write_json.py
#!/usr/bin/python

import time
import SI1145 as SI1145
import os
import commands
import json

sensor = SI1145.SI1145()

def getSensors( strSensor ):
        VIS = sensor.readVisible()
        IR = sensor.readIR()
        UV = sensor.readUV() / 100.0
        CPU = float(commands.getoutput("cat /sys/class/thermal/thermal_zone0/temp"))/1000
        TEMP = "cat /sys/bus/w1/devices/28-031652ddc4ff/w1_slave"
        TEMP = commands.getoutput( TEMP )
        TEMP = float(TEMP[-5:])/1000

        if( strSensor == "VIS" ):
                return float(VIS)
        elif( strSensor == "IR" ):
                return float(IR)
        elif( strSensor == "UV" ):
                return float(UV)
        elif( strSensor == "CPU" ):
                return float(CPU)
        elif( strSensor == "TEMP" ):
                return float(TEMP)
        else:
                return int(0)


if __name__ == '__main__':
        iotdata = { "VIS": getSensors("VIS"), \
                "IR": getSensors("IR"), \
                "UV": getSensors("UV"), \
                "TEMP": getSensors("TEMP"), \
                "CPU": getSensors("CPU") }
        enc = json.dumps(iotdata)
        print(enc)
        with open('iotdata.json','w') as f:
                json.dump(iotdata, f, ensure_ascii=False)
  

テスト(試してみる)

センサーの値の単位が合っているのか、イマイチ不安だけどとりあえず値を取得できてjsonファイルにも出力できている。

$ python i2c_write_json.py
{"VIS": 262.0, "IR": 255.0, "CPU": 47.236, "TEMP": 24.812, "UV": 0.01}
$ cat iotdata.json
{"VIS": 260.0, "IR": 256.0, "CPU": 47.236, "TEMP": 24.875, "UV": 0.02}
  

自動実行の設定

毎分、センサー値をjsonファイルに出力するように crontab -e で登録した。

*/1 * * * * python /home/pi/myProgram/i2c_write_json.py
  

データを可視化(datadog)

datadogエージェント一式に加えて、独自コンフィグ/独自チェックの3つを設定する。
ここでラズパイにdatadogエージェントをインストールするのだが、これがとっても大変だった。理由は、公式なサポートプラットフォームではないのでOSの[rasbian]を選べず[from source]からエージェントをインストールすることになるからだった。

やってみて失敗した事

Datadogサポートに相談

  • 私「(英語で)こんにちは。いろいろ3日間がんばったけれど、エージェントをインストールできなかった。対象外のOSかもしれないけれど、ラズパイで、アドバイスを頂けますか?」
  • サポート「(英語)arm64プラットフォームはこれでインストールしてみて(↓)」
DD_API_KEY= sh -c "$(curl -L https://raw.githubusercontent.com/DataDog/dd-agent/nate_perkins-revert_pip_to_18.1/packaging/datadog-agent/source/setup_agent.sh)"
  
  • 私「(英語で)大晦日なのに、素早い回答ありがとうござます! 無事に動きましたーっ! そしてHappy New Year 2020 !」 無料なのに12時間以内に回答があってDatadog社のサポート凄いです。

ラズパイにインストールしたDatadogエージェント

Datadoエージェントv5は自動起動しないので(v6以降は自動起動した)、ラズパイ再起動時に自動起動するように[/etc/rc.local]ファイルを設定すること。手動でDatadogエージェントの起動/再起動をするには[~/.datadog]ディレクトリに移動して、sudo権限でagentコマンドを実行する。

# /etc/rc.local
$ sudo /home/pi/myProgram/.datadog-agent/bin/agent start
  
$ cd ~/.datadog-agent
$ # エージェントを起動する(systemctl start xx 相当)
$ sudo bin/agent start
$ # エージェントの状態を確認する(systemctl status xx 相当)
$ sudo bin/agent info
$ # datadogチェックスクリプトが正しく動作しているかチェックできる
$ sudo bin/agent check 
  

ディレクトリ構成:

ディレクトリ構成(datadog-agent v5)

独自の監視コンフィグ(kano.yaml)

監視間隔60秒のみ。

init_config:

instances:
  - min_collection_interval: 60
  

独自の監視チェック(kano.py)

jsonファイルを読み込んで[self.gauge(監視名, 値, tag=[name:key])でdatadogサーバーに値を送信。[AgentCheck]モジュールをimportするのを忘れずに。監視名は'custom_'から始まる名前が推奨されている。versionは自分用の管理バージョン。

from datadog_checks.checks import AgentCheck
import json

__version__ = "1.0.0"

class KanoCheck(AgentCheck):
    def check(self, instance):
        f = open('/home/pi/myProgram/iotdata.json','r')
        jsonData = json.load(f)
        f.close()
        self.gauge('custom_iot.vis', jsonData['VIS'], tags=['host:razpi3A'])
        self.gauge('custom_iot.ir', jsonData['IR'], tags=['host:razpi3A'])
        self.gauge('custom_iot.uv', jsonData['UV'], tags=['host:razpi3A'])
        self.gauge('custom_iot.temp', jsonData['TEMP'], tags=['host:razpi3A'])
        self.gauge('custom_iot.cputemp', jsonData['CPU'], tags=['host:razpi3A'])
        self.gauge('custom_iot.debug', 1, tags=['host:razpi3A'])
  

モニタリング、アラート通知の設定

メトリックは自作したので、ここでは[custom_iot.temp]を選び、値が30[℃]を超えたらアラート通知のメールが送信されるように設定した。

(datadog)モニタリングとアラート通知の設定

試してみる(モニタリングする)

本番では「しえる」がいつも昼寝している部屋のソファーに近い場所に、温度センサーを設置する予定だが、UVセンサーもあるのでついでに窓際で太陽光も計測してみる。

ラズパイ試してみる(UVセンサーI2C SI1145, RaspberryPI, 温度センサーDS18B20)

Datadogダッシュボード

カッコイイですよね! 画像イメージファイルは、無料でお世話になっている[IBM Cloud ライトアカウント]のオブジェクトストレージに保存しておき、datadogダッシュボードの[image]タイルがURLを参照して表示しています。温度の計測はバッチリだ。なお、室内の温度が30℃以上に上昇するとメールが届くが、その時のアクションは、なるべく早く家に帰ってエアコンが故障していないか点検することだ。

Datadogダッシュボード(室温データの可視化、UVデータの可視化)

UV指数が5とか6とか本当なのか? 今日は曇り時々晴れなので値が上下するのはなんとなく分かるけれど...。 気象庁によると1月の日本のUV指数は2程度のようだ。なお、15:15ごろ、センサーを部屋の中に移動するとUV指数が0.05前後を示すようになった。計算式間違っているのかな、後日調べよっと。

気象庁(今日の紫外線の予測分布図)2020/1/4

出典:気象庁ホームページ  https://www.jma.go.jp/jp/uv/

まとめ

DatadogでRaspberry Piも監視できた。そしてRaspberry Piに接続した各種センサー(温度計/UVインデックス/可視光/赤外線)を独自のカスタムメトリックを作成してDatadogで見える化&アラート送信することができた。DatadogはSaaSなのでそれ自体の運用はベンダーに任せることができるので、データ通信は一方通行だが、ちょっとしたIoTならDatadogを使って可用性の高いIoT基盤としても活用できるのではないだろうか。

▲上に戻る