記憶力が無い

プログラミングと室内園芸と何か

ラズパイゼロで室内環境モニタリング環境を作る

はじめに

Grafana Cloud の一部機能が無料で使えるようになったので、ちょっと気になっていました。

今週部屋の掃除をしていたら、数年前の技術書典(技術書典5)で購入したっきりその辺にポイっとしてた室内環境センサーが出土しました。 これとラズパイゼロを組み合わせて、結果を Grafana Cloud に突っ込んで見れるようにするというのを思いつきででやってみました。

誰得な内容ですが、ラズパイゼロで取得したデータを Grafana Cloud に突っ込むというのはいろいろ応用できると思うので、参考にしていただけたらと思います。

使った部材

室内環境センサー

github.com

部屋の掃除をしていたら数年ぶりに出土。 技術書典5 で ArtifactNoise さんのブースで購入したものになります。 確か 6000 円くらいだったと思います。

同じものはもう売ってないようですが、USB-TypeC 版がスイッチサイエンスで買えるみたいです。

AN-301 環境計測モジュールwww.switch-science.com

Raspberry Pi Zero WH

千石電商で一個 2,400 円くらいで買った記憶。

USB ハブ

ラズパイゼロには micro B 端子が一つしかないので、有線 LAN アダプターと室内環境センサーを接続するために使います。

※ 無線 LAN で接続することもできますが、設定を入れるのが面倒なので有線 LAN で接続します。

有線 LAN アダプター

完成形態

後ろにごちゃごちゃした配線が見えてますが、こんな感じです。

Grafana Cloud の設定

Grafana Cloud に登録する

grafana.com

このページの Start for free のボタンから登録できます。

外部サービス(Google, Github, Microsoft)の認証が使えます。 自分は Google アカウントで登録しました。

その後、サブドメインに使用する文字列を求められるので、好きなものを入力します。

API キーの発行

メトリクスデータを書き込むための API キーを発行します。

  • Grafana Cloud Portal の左側のメニューで API Keys をクリック ↓

  • 遷移先のページ上部にある + Add API Key をクリック ↓

  • API キー名を入力し、Role を選択します ↓

メトリクスの書き込みに使うので Role は MetricsPublisher を選びます。

API キーは一度しか表示されないので、紛失した場合は元のものを削除して発行しなおしてください。

エンドポイントとユーザ名の取得

メトリクスの取り込み先は Prometheus と Graphite の二つが選べます。 今回は Prometheus を選びました。

メトリクスの送信先エンドポイントとユーザ名を確認します。

ポータルの Prometheus のカードの Send Metrics をクリックします。

遷移先のページに Remote Write Endpoint と Username が表示されているので控えておきます。

ラズパイゼロの設定

OS のインストール & SSH の有効化

OS のインストールは Raspberry Pi Imager を使います。 OS は Raspberry Pi OS Lite (32-bit) を使います。

起動時に SSH サーバーが起動するようにするため、インストール後の SD カードの直下に ssh という名前で空ファイルを作成します。

※ mini-HDMI を画面に表示するためのケーブルを持ってないので、初回起動直後からネットワーク越しに SSH で接続できるようにしています。

部品の装着

ラズパイゼロ ─ USB ハブ ┬ 有線 LAN アダプタ ─ スイッチングハブ
                        └ 室内環境センサー

こんな感じになるように各種部品を接続します(装着後の状態は上に張った画像の通りです)。

OS の設定

ユーザの発行や初期パスワードの変更は必要に応じて実施してください。 今回はユーザは pi ユーザをそのまま使用し、パスワードだけ変更しておきます。

passwd

念のため OS のアップデートもかけておきます。

sudo apt update
sudo apt upgrade

Grafana Agent のインストール

  • Grafana Agent の入手先
  • 現時点(2021-06-11)の最新版は v0.15.0
  • Raspberry Pi Zero の CPU は Armv6 なので grafana-agent-0.15.0-1.armv6.deb を選択
wget https://github.com/grafana/agent/releases/download/v0.15.0/grafana-agent-0.15.0-1.armv6.deb
sudo apt install ./grafana-agent-0.15.0-1.armv6.deb
追記 2024-01-22

32-bit ARM プロセッサ向けのビルドは v0.33.0 から提供されなくなったみたいです:

Release v0.33.0 · grafana/agent · GitHub

Support for 32-bit ARM builds is removed for the foreseeable future due to Go compiler issues. We will consider bringing back 32-bit ARM support once our Go compiler issues are resolved and 32-bit ARM builds are stable.

Grafana Agent の設定

Grafaba Agent 経由で Grafana Cloud の Prometheus にデータを送信します。 プログラム側で直接 Prometheus にデータを送るのではなく http サーバーを立てて Grafana Agent に scrape してもらう方式でやります(scrape_configs の部分がその設定になります)。

設定中に先ほど確認した API キー、ユーザ名、エンドポイントを入れてください。

後ほどセンサーで読み取った値を localhost:8000 経由で Grafana Agent に渡すためのプログラムを示します。

cat << EOS | sudo tee /etc/grafana-agent.yaml
server:
  http_listen_address: '127.0.0.1'
  http_listen_port: 9090

prometheus:
  global:
    scrape_interval: 15s
  wal_directory: '/var/lib/grafana-agent'
  configs:
  - name: default
    remote_write:
    - basic_auth:
        password: ここに API キー
        username: ここにユーザ名
      url: ここにエンドポイント
    scrape_configs:
    - job_name: home_env_monitor
      static_configs:
      - targets:
        - localhost:8000
EOS

設定を入れたら Grafana Agent を起動します

sudo systemctl start grafana-agent.service
sudo systemctl enable grafana-agent.service

必要なライブラリのインストール

sudo apt install python3-pip

# センサーの値を読み取るのに必要なライブラリのインストール
python3 -m pip install PyMCP2221A

# 読み取った値を Grafana Agent に渡すためのライブラリのインストール
python3 -m pip install prometheus-client

pi ユーザでデバイスに接続するための設定

pi ユーザだとデバイスにアクセスできないので、次の設定を入れます。

echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="04d8", MODE="0666", GROUP="plugdev"' |
sudo tee /etc/udev/rules.d/90-BME280.rules

設定を入れたら室内環境センサーの USB を一旦抜き差しします。

センサーで読み取った値を Grafana Agent に渡すためのプログラム

温度を home_env_tmp, 湿度を home_env_hum, 気圧を home_env_pressure という名前のメトリクスに設定しています。 start_http_server(8000) で 8000 番ポートで http サーバーを立ち上げ、先ほどインストールした Grafana Agent にデータを渡します。

BME280.py は https://raw.githubusercontent.com/nonNoise/USB_StartUpModule/master/AN-USB-BME280/example/PyMCP2221A/BME280.py から入手して、同じディレクトリに配置します(pip install したものには含まれないので注意!)。

mkdir ~/home_env_monitor
cat << EOS > ~/home_env_monitor/main.py
import BME280
import time
from prometheus_client import start_http_server, Gauge

start_http_server(8000)
device = BME280.BME280()

temp = Gauge('home_env_temp', 'home_env')
hum = Gauge('home_env_hum', 'home_env')
pressure = Gauge('home_env_pressure', 'home_env')
di = Gauge('home_env_di', 'home_env')

while True:
    device.readData()
    temp.set(device.temperature)
    hum.set(device.var_h)
    pressure.set(device.pressure / 100)
    di.set(device.DI)
    time.sleep(10)
EOS

wget -P home_env_monitor/ https://raw.githubusercontent.com/nonNoise/USB_StartUpModule/master/AN-USB-BME280/example/PyMCP2221A/BME280.py

プログラムの実行

python3 ~/home_env_monitor/main.py

これで Grafana Cloud の Prometheus にメトリクスが取り込まれるようになったはずです。

Grafana の Explore でメトリクスが表示されたら OK です。

systemd サービス化

そのままだとシェルを閉じるとメトリクスの送信が止まってしまうので、バックグラウンドでも動作するように systemd サービス化します。

# ユニットファイルの設置
mkdir -p ~/.config/systemd/user
cat << EOS > ~/.config/systemd/user/home_env_monitor.service
[Unit]
Description=Home Environment Monitor
After=network-online.target

[Service]
WorkingDirectory=/home/pi/home_env_monitor
ExecStart=/usr/bin/python3 main.py
Restart=always

[Install]
WantedBy=default.target
EOS

# ログアウト中にもサービスが動くようにするおまじない
loginctl enable-linger

# サービスの起動
systemctl --user enable home_env_monitor
systemctl --user start home_env_monitor

ここまでやったら、電源を入れたら自動でサービスが立ち上がり、Grafana Cloud にメトリクスが送信されるようになります。

ダッシュボードの作成

あとは、取り込んだメトリクスをいい感じに表示するためのダッシュボードを作って完成です。

まとめ

  • Grafana Cloud 無料版でもそこそこ使える
  • Grafana Agent を使えばメトリクスの取り込みが簡単にできる
  • これで出先でも家の温度が確認できるぞ!
Copyright © 2017 ttk1