4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

会場内のCO2濃度をGrafana上に可視化してみた

Last updated at Posted at 2022-12-11

はじめに

概要

2022年11月21, 22日に開催されたCloudNativeDays Tokyo 2022 (CNDT2022) というカンファレンスに運営側として参加しました。PrometheusなどのObservabilityの知見獲得と社外コミュニティを作りたいと思ったことをきっかけに参加して、今回で2回目のカンファレンスになります。その際に会場内のCO2濃度を可視化する企画のメインメンバとして活動したので備忘録として記事に残しておきます。

対象読者

私としては、「CO2濃度を取得する記事自体はあるが 取得したデータをグラフ化する部分を書いている記事が少ないので参考になるものを書きたい」のと、「ラズパイやセンサーを初めて触っているので、同じような初心者の勉強になる記事を書きたい」といった思いを込めて書いています。

  • 同じようなことを考えている企画者
  • Prometheus,Grafanaを勉強したい初級者
  • Raspberry Pi, CO2センサーを触ってみたい初級者

といった方々に参考になれば幸いです。

CO2濃度を取得するまで

準備

まず、今回の要件である「会場内の1室の二酸化炭素濃度を取得して既存のPrometheus, Grafanaに連携する」に近しい記事を探してきて、必要になりそうなものを購入しました。

Raspberry Piのセットアップ

購入してからのセットアップはYoutubeとかで調べれば簡単に出てくるので詳細には説明しませんが、主にやったこととしては

  • ヒートシンクをつける
  • OSインストール
  • Wifiの設定
  • SSHの有効化

CO2センサーのセットアップ

MZ-H19Cにはpythonのライブラリがあって、これを利用すれば簡単にCO2濃度を取得することができます。

なので今回はこのライブラリに記載されている下図のようにジャンパー線でRaspberry PiとMH-Z19Cを繋ぎます。
CO2センサー回路

うまく繋がってセンサーが点滅した状態になればOKです。

ラズパイ

ライブラリを実行した結果、CO2濃度の値が返ってくれば無事完了です。

$ sudo pip install mh_z19
$ sudo python -m mh_z19
{"co2": 851}

Grafana上に表示する

構成

今回はPrometheusのPushgatewayを使用しました。Pushgatewayとはいわばメトリクスのキャッシュのようなもので、監視対象がメトリクス情報をPushgatewayにプッシュする中で、最後にプッシュされた情報だけを保持します。PrometheusはPushgatewayをスクレイプしておくことで、Pushgatewayに保持されたメトリクスを取得して内部に保存し、そのメトリクス情報をGrafanaなどに連携することでグラフ化できます。Prometheusは監視対象から定期的にスクレイプするPull型のアーキテクチャのため、継続的に実行されないバッチジョブのようなものには不向きであり、そこを補填するのがPushgatewayです。

最終的に下図のような構成にしました。
概要図
※本番のkubernetes構成の場合ingressリソースなどが存在しますが、今回は省略します。

環境の構築

実際はkubernetes環境上で動いていますが、ローカルで簡単に試せるように今回はdockerで動かします。

Prometheus & Grafanaつかってみた」 の記事で必要なコンポーネントが全て書いてあったので今回はこちらを動かします。用意するのは下記2ファイルです。

  • docker-compose.yaml
    • prometheus,pushgateway,grafanaのコンテナを使用する
    • 基本設定・ポートはデフォルトのもので良い
    • grafanaのコンテナだけ参考記事とは別のものを使う
  • prometheus/prometheus.yaml
    • pushgatewayをスクレイプする設定を追加する
docker-compose.yaml
version: '3.1'

services:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    ports:
      - 9090:9090
    networks:
      - public
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml

  pushgateway:
    image: prom/pushgateway
    container_name: pushgateway
    ports:
      - 9091:9091
    networks:
      - public

  grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - 3000:3000
    networks:
      - public

networks:
  public:
prometheus/prometheus.yml
scrape_configs:
  - job_name: 'pushgateway'
    scrape_interval: 1s
    static_configs:
      - targets: ['pushgateway:9091']
        labels:
          environment: "hoge"
          category: "pushgateway"

ファイルの作成が完了したら起動します。

$ docker-compose up -d

必要に応じてRaspberry PiからPushgatewayへアクセスできるように9091ポートを開放します。

スクリプト作成

  • 前述したmh-z19ライブラリを使ってCO2濃度を取得します
  • prometheus_clientライブラリを使って取得したメトリクスをpushgatewayへ送信します
requirement.txt
prometheus_client
mh-z19
main.py
import time
import os
import mh_z19

from prometheus_client import CollectorRegistry, Gauge, push_to_gateway

# 送信先と送信間隔を環境変数として読み込む
PUSHGATEWAY_ADDRESS = os.getenv("PUSHGATEWAY_ADDRESS", "localhost:9091")
INTERVAL_SEC        = int(os.getenv("INTERVAL_SEC", "10"))

# メイン関数
def main():
    print(f"PUSHGATEWAY_ADDRESS = {PUSHGATEWAY_ADDRESS}")
    print(f"INTERVAL_SEC        = {INTERVAL_SEC} second")
    while True:
        # mh-z19ライブラリを使ってCO2濃度を取得
        co2_conce = mh_z19.read_all()["co2"]
        send_co2_conce(co2_conce)
        time.sleep(INTERVAL_SEC)

# https://github.com/prometheus/client_python に従って記載する
def send_co2_conce(co2_conce: int):
    registry = CollectorRegistry()
    g = Gauge("co2_conce", "CO2 Conce", registry=registry)
    g.set(co2_conce)
    push_to_gateway(PUSHGATEWAY_ADDRESS, job="co2", registry=registry)


if __name__ == "__main__":
    main()

必要なライブラリをインストールします。

$ python -m venv venv
$ . venv/bin/activate
$ pip install -r requirements.txt

サービス化する

上記スクリプトの無限ループでCO2濃度を取得し続けることができましたが、Pushgatewayと繋がらない時スクリプトが異常終了します。これでは、気づいたら落ちていたり、失敗したら再起動したりと面倒なオペレーションが発生するので、自動で再起動するようにサービス化します。
(ここは同じチームメンバの方が対応してくれて大変助かりました。。)

systemdの設定ファイルを用意します。

  • PUSHGATEWAY_ADDRESSを適宜変更する
  • 下記は前述のスクリプト類を/home/observability/observability/co2-sensorというディレクトリに置いた例
co2-sensor.service
[Unit]
Description=Measure co2 and upload data
After=network.target

[Service]
Environment=PUSHGATEWAY_ADDRESS=<自分の端末IP>:9091
Environment=PYTHONUNBUFFERED=1
WorkingDirectory=/home/observability/observability/co2-sensor
ExecStart=/home/observability/observability/co2-sensor/venv/bin/python -u /home/observability/observability/co2-sensor/main.py
Restart=on-failure
StartLimitBurst=0

[Install]
WantedBy=default.target

systemdに登録して、自動起動およびプロセスを開始します。

$ sudo cp co2-sensor.service /etc/systemd/system/
$ sudo systemctl daemon-reload
$ sudo systemctl enable co2-sensor
$ sudo systemctl start co2-sensor

Grafanaで描画する

CO2濃度を取得して、Prometheusに保存するところができたので最後にGrafanaで表示させます。

すでにコンテナは立ち上がっているので、http://localhost:3000をブラウザで開いて、初期ユーザ/Passであるadmin/adminでログインします。パスワード変更を求められるので適宜設定します。

まずはDataSourceを設定します。左タブの「歯車」 > 「add data source」 > 「Prometheus」を選ぶとPrometheusの設定画面に移動します。

  • URLでPrometheusを指定する。
  • 他はデフォルト値で良い
  • 必要に応じてスクレイピングの間隔を変えてもいい

次に左タブから「+New Dashboard」 > 「Add New Pannel」を開きます。
QueryのMetricをクリックするとco2_conceがあるので、選択してRun queriesを流すと無事グラフが表示されます。
ダッシュボード作成
あとは右タブで、グラフをゲージに変えたり、パネルにタイトルや単位をつけるなど適宜カスタマイズをして保存します。

グラフ表示

カンファレンス当日

当日はメインセッションの会場の端に配置しました。

設置場所 設置様子

会場設置時にスクショした画面がこちら。
グラフ表示

上図のグラフでは12時前後で大きく変わっていますが、これはスタッフの準備室の小さい部屋からホールAに移動したことによる変化になります。小さい部屋だと700ppm前後でしたが、大きい部屋だと400ppm程度でした。カンファレンス当日も観察していましたが、設置場所が悪かったのか換気が行き届いていたのか400ppm~500ppmで一定の数値を保っていて面白くなかったので準備時の画像を掲載しました。強いていうならキーノートで混み始めた際に、じわじわとCO2濃度が上昇していくのを観察できました。

さいごに

まずは3日間ちゃんと動いて安心しました。スクリプトの負荷は少ないので本番と準備で3日間動かしましたが、Raspberry Pi 1台で全く問題なかったです。ただ、ネットワークの通信が悪くなる時が少々あったので、こういった企画にはネットワークの整備およびリトライ処理が重要であることを改めて痛感しました。今後これを広げていくかは分かりませんが、Raspberry Piの価格が高くなっていたのでもう少々コストを抑える施策の検討が必要になるかもしれません。

この企画は自分の興味本位で始めたものでしたが、Prometheus,Grafana,Raspberry Pi,センサーの入門的勉強ができてよかったです。また、自己学習ではなくカンファレンスの一企画なので、目的・締切もはっきりして動け、自己学習の自己満足で終わらなかったのもよかったです。何よりも運営メンバーからいろいろなフィードバックをいただけたのでとても感謝しています。当初の勉強は達成できたので今後は開発周りを手伝えたらいいなと思っています。運営等に興味がある人は気軽に声をかけてください。

最後にお決まりの文言になってしまいますが、本記事は私個人が勉強した内容に関するものです。会社や本カンファレンスとは関係なく個人の意見であることをご了承ください。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?