📈

IoT実験:ラズパイで温度取得しグラフ表示 (3)ラズパイでデータ送信、サーバで可視化

2023/06/30に公開

概要

ラズパイ(Raspberry Pi、ラズベリーパイ)で温度を取得し、それをグラフで可視化する記事の3回目です。今回が最終回となります。

参考:
前々回「(1)ラズパイで温度取得」
前回「(2)サーバでデータベース」

まず、システム内の大まかな機能を示します。

  1. ラズパイ:温度センサから温度データを取得 (済み)
  2. ラズパイ:取得した温度データをネットワークを介してサーバへ送信
  3. サーバ:受信した温度データをデータベースへ保存 (済み)
  4. サーバ:ユーザの要望に応じて温度データを可視化

システム内の大まかな機能
システム内の大まかな機能

今回は、2番目「ラズパイ:取得した温度データをネットワークを介してサーバへ送信」と4番目「サーバ:ユーザの要望に応じて温度データを可視化」を行い、すべて完了となります。

今回の実験環境

ラズパイからのデータ送信

項目 内容
データ収集・送信ツール telegraf 1.26.2-1 (実験時最新のもの)

ラズパイからのデータ収集・送信には、telegraf というソフトウエアを使用します。これは、前回サーバにインストールした InfluxDB の専用ツールとして開発されたものです。

telegraf の設定ファイルに、「どこからデータを収集するか」や「どこへデータを送信するか」などを記述するだけで、自動的にデータを収集し、サーバへデータ送信します。

可視化

項目 内容
可視化 InfluxDB 2.7.0-1 (実験時最新のもの)

前回、時系列データベースとしてサーバに InfluxDB をインストールしましたが、保存したデータの可視化ツールも含まれていますので、これを使用します。

telegrafとInfluxDBの関係

今回ラズパイにインストールするtelegrafと前回サーバにインストールしたInfluxDBの関係を以下に示します。

telegrafとInfluxDBの関係
telegrafとInfluxDBの関係

前回までの実験環境

ラズパイ

項目 内容
本体 Raspberry Pi 3B+
OS Raspberry Pi OS Lite
Release date: May 3rd 2023
System: 64-bit
Kernel version: 6.1
Debian version: 11 (bullseye)
開発言語 Python 3.9.2
ホスト名 raspi01.local
IPアドレス DHCP (192.168.130.0/24)

温度センサ

項目 内容
型番 DS18B20
通信方式 1-wire
抵抗 4.7kΩ(プルアップ用)

サーバ

項目 内容
本体 Windows 10上の仮想マシン(VMware使用)
OS Ubuntu MATE 22.04.2 LTS
IPアドレス 192.168.130.50/24 (固定IPアドレス)

データベース

項目 内容
データベース InfluxDB 2.7.0-1 (実験時最新のもの)

ラズパイにtelegrafをインストール

ラズパイに telegraf をインストールするには、InflaxData社(telegrafの開発元)のリポジトリを追加して apt によりインストールします。

(1) 現在時刻確認と修正

apt 等のパッケージ管理システムを使用する際、システムの時刻が合っていないとインストールができないことがあります。また、今回のデータ可視化の実験では、日時を伴うデータを扱うので、時刻は正確である必要があります。

ラズパイは、シャットダウン中の時刻を保持する機能が、標準では装備されていません。ラズパイを正式運用で使用する場合、電池バックアップによる時刻保持機能や、ネットワーク経由での時刻同期機能などを使用して時刻を合わせる必要があります。

ただ、今回は実験的な使用となりますので、手動で時刻を合わせます。

$ date
...

$ sudo date mmddHHMM
...

1番目のコマンドは、現在時刻を表示するコマンドです。これで時刻が概ね合っていれば問題ありません。時刻が正しくない場合、2番目のコマンドを実行します。引数の意味は、次のとおりです。

  • mm ... 月2桁
  • dd ... 日2桁
  • HH ... 時2桁
  • MM ... 分2桁

このとき、年は変更なし、秒は00秒に設定されます。(年も設定する場合は、分2桁に続けて西暦年4桁を指定します。)

たとえば、今年の6月1日 20時30分に時刻を合わせる場合、次のように実行します。

$ sudo date 06012030

秒の指定や文字列による指定も可能です。詳細はマニュアルなどを参照してください。

(2) リポジトリ追加

インストールの準備として、開発元である InflaxData社のリポジトリを追加しますが、まず、正しいサイトかどうかを確認するためのGPGキーをシステムに登録します。

$ sudo mkdir -p /usr/local/share/keyrings

$ curl -fsSL https://repos.influxdata.com/influxdata-archive.key | sudo gpg --dearmor -o /usr/local/share/keyrings/influxdata-archive.gpg

$ ls /usr/local/share/keyrings/
...  influxdata-archive.gpg  ...

1番目のコマンドはディレクトリの作成、2番目はキーをダウンロードしてシステムに登録、3番目はファイルの存在を確認しています。

続いて、リポジトリを追加します。

$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/local/share/keyrings/influxdata-archive.gpg] https://repos.influxdata.com/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
...

コマンドの意味は、ダブルクォーテーション(")で囲まれた部分を、画面と末尾で指定したファイルに出力する、となります。

(3) aptによるインストール

aptやapt-getでインストールを実行します。

$ sudo apt update
...

$ sudo apt install telegraf
...

1番目のコマンドはパッケージ情報の更新で、2番目のコマンドが telegraf のインストールとなります。

telegrafの設定情報

telegraf は、データ収集およびデータ送信のツールです。この元となるプログラムやサーバは、前回と前々回の記事で完了しています。その情報を以下に示します。

データ収集元

今回扱うデータは温度データです。前々回の記事にて、Pythonで作成したスクリプトがデータ収集元となるものです。

項目 内容 telegrafの設定項目
データ収集元 Pythonスクリプト
/usr/local/bin/w1_temp.py
commands

データ送信先

データ送信先は、前回の記事にて、サーバにInfluxDBを構成しました。

項目 内容 telegrafの設定項目
送信先 http://192.168.130.50:8086 urls
APIトークン (前回の記事で生成した文字列) token
組織名 my_org organization
バケット my_bucket bucket

telegrafの設定

telegrafの設定ファイル

telegrafの設定ファイルは、/etc/telegraf/telegraf.conf です。

以下は、viエディタで設定ファイルを開く例です。viエディタは操作が特殊ですので、必要なら別の使い慣れたエディタで作業してください。

$ sudo vi /etc/telegraf/telegraf.conf

データ収集元の指定

まず、データ収集元の指定を行います。設定ファイルの末尾に以下を追記してください。

[[inputs.exec]]
  commands = ["/usr/local/bin/w1_temp.py"]
  name_override = "w1_temp"
  data_format = "value"
  data_type = "float"

1行目の [[inputs.exec]] は、コマンド実行結果をデータ入力元とする場合の指定方法です。今回は、Pythonスクリプトの実行結果をデータ入力元としますので、このような記述となります。

2行目以降は、実行するコマンドをcommandsに、値の種類をdata_formatdata_typeに(数値データ(value)で小数点を含む値(float)など)を記述します。またname_overrideはデータに付ける名前で、サーバ側では、この名前で参照できます。

データ送信先の指定

続いて、データ送信先を指定します。上の手順の続きで操作します。

エディタの検索機能を使用してキーワード「influxdb_v2」などで以下の部分を見つけてください。

# [[outputs.influxdb_v2]]
# ...
# ...
...

[[outputs.influxdb_v2]] は、出力先(データ送信先)として「InfluxDB v2系」を使う設定部分となります。

行内で # より後ろはコメントとして無視される部分です。初期状態の設定ファイルでは、上のように、InfluxDB v2系への送信設定部分がすべてコメント化されていますので、初期状態では無効な設定となっています。

これに対して、必要な行の行頭の # を削除することで、設定を行います。
以下の項目を有効化(行頭の#を削除)して、上表「データ送信先」で示した値を記述してください。tokenには、前回生成したAPIトークンをコピー&ペーストしてください。

[[outputs.influxdb_v2]]
  urls = ["http://192.168.130.50:8086"]
  token = "APIトークンをここにコピー&ペースト"
  organization = "my_org"
  bucket = "my_bucket"

設定ファイルの保存

以上が完了したら、設定ファイルを上書き保存します。

telegrafの再起動

修正した設定ファイルを読み込ませるため、telegrafサービスを再起動させます。

$ sudo systemctl restart telegraf.service

$ sudo systemctl status telegraf.service
● telegraf.service - Telegraf
     Loaded: loaded (/lib/systemd/system/telegraf.service; enabled; vendor preset: enabled)
     Active: active (running) since Xxx 202x-xx-xx xx:xx:xx JST; 6s ago
     ...

以上で、ラズパイの設定は完了です。

サーバで、温度データを可視化

上記の方法でラズパイのtelegrafを設定すると、ラズパイで取得した温度データがサーバに送られるようになります。また、前回サーバ設定は完了していますので、サーバが受信したデータはInfluxDBのデータベースへ保存されています。

ここでは、保存されたデータをグラフで表示させます。

(1)InfluxDBのサーバ管理ツールにログイン

ブラウザを起動して、InfluxDBのサーバ管理ツールにログインします。URLは、http:// サーバのIPアドレス :8086/ です。
今回の例では、http://192.168.130.50:8086/ となります。

ログインするユーザアカウントは、前回、初期ユーザ設定で指定したユーザです。例では「db_user」というユーザを初期設定しました。

サーバ管理ツールにログイン
ユーザ名とパスワードを入力して、「SIGN IN」ボタンをクリック

(2)グラフの作成

「Data Explorer」というツールを使用して、グラフを作成します。

「Data Explorer」アイコンをクリック
「Data Explorer」アイコンをクリック

右上「Switch to old Data Explorer」をクリックしスイッチON状態に
右上「Switch to old Data Explorer」をクリックしスイッチON状態に(ON状態にすることで、バケット名やデータ名などを選択するだけで簡単にグラフを作成できるようになる)

バケット名やデータ名を選択
バケット名「my_bucket」、データ名「w1_temp」、列名「value」、ホスト名「raspi01.local」などを選択し、「SUBMIT」をクリック

上部に指定した条件のグラフが表示される
上部に指定した条件のグラフが表示される

(3)グラフの保存

上で表示させたグラフで問題なければ保存を行います。グラフは「ダッシュボード」と呼ばれる場所に保存しますが、今回は新しい「w1_temp」というダッシュボードを作成して保存します。

「SAVE AS」ボタンをクリック
「SAVE AS」ボタンをクリック

「Create a New Dashboard」をクリック
「Create a New Dashboard」をクリック

New Dashboard Nameに「w1_temp」と入力し、「SAVE AS DASHBOARD CELL」ボタンをクリック
New Dashboard Nameに「w1_temp」と入力し、「SAVE AS DASHBOARD CELL」ボタンをクリック

w1_tempダッシュボードに保存される
w1_tempダッシュボードに保存される

グラフはマウス操作で幅や高さを変更できる
グラフはマウス操作で幅や高さを変更できる

(4)1日後のグラフ

1日間、温度を記録した後に、もう一度グラフを表示したものが以下です。

1日後、右上の選択肢から「Past 24h」(過去24時間)を選択したグラフ
1日後、右上の選択肢から「Past 24h」(過去24時間)を選択したグラフ

サーバ管理ツールは、一定時間操作がないと自動的にログアウトされます。再度ログインしたときに、ダッシュボードを表示するには、左側の「dashboards」アイコン(四角が4つあるアイコン)をクリックした後、表示したいダッシュボード名をクリックします。

(5)ユーザの追加

概要

グラフを閲覧したい人に対して、管理者ユーザである db_user のパスワードを教えるわけにはいきません。通常は、閲覧用のユーザアカウントを作成してそれを閲覧者に教えます。

今回使用しているWebベースのサーバ管理ツールでは、ユーザ作成機能がなさそうです。コマンドでは作成可能ですので、ここではコマンドによるユーザ作成方法を紹介します。

InfluxDBを管理するコマンドは influx コマンドです。そして、ユーザ作成は、サブコマンドを指定して influx user create となります。

config

influx コマンドの実行は、db_userユーザとして実行する必要がありますが、これを指定するのがconfigです。configは、InfluxDBのURLや組織名、ユーザ名などを一塊の情報として保存しておくものです。

ユーザ作成を行うには、以下のようなconfigをまず作成し、このconfigを使用してユーザ作成コマンドを実行します。

項目 内容
InfluxDBのURL http://localhost:8086
組織名 my_org
ユーザ名 db_user

では、まずconfigを作成します。configには名前を付けますが、ここでは「my_conf」とします。configの作成コマンドは influx config create です。

$ influx config create \
  --config-name my_conf \
  --host-url http://localhost:8086 \
  --org my_org \
  --username-password db_user \
  --active
...

各行の末尾 \ は、コマンドが次の行へ続くことを意味しています。つまり、上のコマンドは複数行ですが、実際には influx config create から --active までが1行と見なされます。

最後のオプション --active は、このconfigをアクティブにすることを意味します。アクティブなconfigとは、influx コマンドを実行するときに使用されるconfigのことです。

ちなみに、複数のconfigを作成した際、アクティブを切り替えるには、influx config アクティブにする名前 と実行します。

ユーザ作成

続いて、ユーザ作成です。ここでは、以下のようなユーザを作成します。

項目 内容 備考
ユーザ名 ex_user
パスワード xxxxxxxx 適当に修正のこと
所属組織 my_org

上の続きで操作すれば、db_userを指定したconfigがアクティブになっていますので、管理者であるdb_userでコマンドが実行できます。

$ influx user create \
  --name ex_user \
  --password xxxxxxxx \
  --org my_org
Please provide your password:
...

influx コマンドを実行すると、「Please provide your password:」とパスワードの問い合わせがあります。これは、現在アクティブなconfigで使用するユーザ(つまり db_user)のパスワード問い合わせです。

ですので、db_user のパスワードを入力し、それが正しければ、influxコマンドが実行され、ex_userユーザが作成されます。

Webブラウザで確認

最後にWebブラウザを開き、サーバ管理ツールにて ex_user でログインしてグラフを確認してみてください。

ex_userでログイン
ex_userでログイン

まとめ

以上ですべて終了です。

以下に、3回の記事で行った作業を簡単にまとめておきます。
これと同じ方法で、異なるセンサーの可視化も可能です。

  1. ラズパイ:(初回のみ)Raspberry Pi OS のインストール
  2. ラズパイ:センサーを接続
  3. ラズパイ:(必要なら)センサーとの通信方式を有効化(今回1-wire、このほか SPI, I2C など)
  4. ラズパイ:センサーからのデータ取得プログラム作成
  5. サーバ:(初回のみ)OSのインストール、IPアドレス等設定
  6. サーバ:(初回のみ)InfluxDBインストール、初期ユーザ設定
  7. サーバ:(必要なら)APIトークン生成
  8. ラズパイ:(初回のみ)telegrafのインストールとデータ送信先設定
  9. ラズパイ:telegrafのデータ収集元を設定(データ収集元=上のデータ取得プログラム)
  10. サーバ:グラフによる可視化

(初回のみ)の項目は、インストール作業等ですので、最初の1回行っておけば済みます。また、(必要なら)の項目は、不要なら行う必要はありません。したがって、すでにインストール作業等を行っていて、追加項目が不要なら、以下の4ステップで別のセンサの可視化が行えます。

  1. ラズパイ:センサーを接続
  2. ラズパイ:センサーからのデータ取得プログラム作成
  3. ラズパイ:telegrafのデータ収集元を設定(データ収集元=上のデータ取得プログラム)
  4. サーバ:グラフによる可視化

このうち「ラズパイ:センサーからのデータ取得プログラム作成」は少し知恵を絞る必要がありますが、これさえクリアできればデータ取得~可視化は比較的簡単に行えます。

おまけ:NTP

上述のとおり、ラズパイはシャットダウン中の時刻保持ができません。このため、RTC(Real Time Clock)とボタン電池を組み合わせて時刻保持機能を別に用意したり、ネットワーク経由の時刻同期機能を使用したりします。

以下では、NTP(Network Time Protocol)を使用したネットワーク経由の時刻同期機能の設定方法を紹介します。

ラズパイの設定

ラズパイでは、systemd-timesyncd というサービスを利用してネットワーク時刻同期を行います。

このサービスがインストールされているかどうかは、以下のコマンドで調べられます。

$ dpkg -l | grep systemd-timesyncd
ii  systemd-timesyncd                    247.3-7+deb11u2                  arm64        minimalistic service to synchronize local time with NTP servers

何も出力されなければ、インストールされていませんので、apt等でインストールしてください。

systemd-timesyncdサービスの設定ファイルは、/etc/systemd/timesyncd.conf です。編集するには管理者権限が必要です。たとえば、以下のように実行します。(viエディタを使用する例。)

$ sudo vi /etc/systemd/timesyncd.conf

時刻同期をする最小の設定は、次のとおりです。「ホスト名」部分にLAN内のNTPサーバやプロバイダ等が用意するサーバ名を記述します。

[Time]
NTP=ホスト名

設定が完了したら、サービスを再起動させることで、時刻同期が行われます。確認のため、サービス再起動の前後で dateコマンドにより現在時刻を表示させます。以下の例では、2023年5月22日 12:39 だったものが、2023年6月5日 14:55に修正されたことが分かります。

$ date
Mon May 22 12:39:20 JST 2023

$ sudo systemctl restart systemd-timesyncd.service
...

$ date
Mon Jun  5 14:55:02 JST 2023

なお、時刻同期が実行されるまで、数分~10分程度かかることがありますので、少し待ってから3番目のコマンド(dateコマンド)を実行してみてください。

Ubuntu MATEによるNTPサーバ構築

本来は、ネットワーク管理者がLAN内に用意したNTPサーバや、プロバイダ等が用意したサーバを使用しますが、ラズパイから外部サーバへの接続が難しいなどにより時刻サーバへアクセスできない場合の回避策として、今回InfluxDBをインストールしたUbuntu MATEに、NTPサーバを構築する方法を示します。

NTPサーバは、ntpというサービスを利用します。ntpがインストールされているか確認します。

$ dpkg -l | grep ntp

何も出力されなければ、インストールされていませんので、apt等でインストールしてください。

$ sudo apt update
...

$ sudo apt install ntp
...
以下のパッケージは「削除」されます:
  systemd-timesyncd
...

上の出力例にもありますとおり、ntpをインストールすると、ラズパイでも使用したsystemd-timesyncdが「削除されます」とメッセージが表示されます。
もし、systemd-timesyncdサービスで、NTPサーバに時刻同期していた場合、ここでインストールしたntpサービスに設定し直します。(下の設定例の(2)にて。)

ntpサービスの設定ファイルは、/etc/ntp.conf です。エディタで開き、以下の修正を行います。

...
### (1) pool から始まる行は、先頭に # を付ける(コメント化)。
#pool 0.ubuntu.pool.ntp.org iburst
#pool 1.ubuntu.pool.ntp.org iburst
#pool 2.ubuntu.pool.ntp.org iburst
#pool 3.ubuntu.pool.ntp.org iburst
...
#pool ntp.ubuntu.com

### (2) systemd-timesyncdサービスを使っていた場合、NTPサーバ名を以下に記述。
### もし使っていなければ、以下の行は不要。
server NTPサーバ名
...
### (3) ファイル末尾に以下2行を追加(192.168.130.0/24ネットワークの場合)
restrict 192.168.130.0 mask 255.255.255.0 nomodify notrap
server 127.127.1.0

(1) は、poolから始まる行の先頭に # を記述してコメント化します。poolから始まる行は、外部のNTPサーバの指定行です。この設定をコメント化して無効にします。

(2) は、削除されたsystemd-timesyncdサービスでNTPサーバを設定していた場合、そのホスト名をここに記述します。systemd-timesyncdサービスを使用していなかった場合、(2) の作業は不要です。

(3) は、ファイル末尾に追加します。restrictの行は、指定ネットワークからのNTP問合せに応答する設定です。これを行うことで、NTPサーバとして動作するようになります。記述例は 192.168.130.0/24 ネットワークの例となりますので、自身のネットワークに変更してください。serverの行は、サーバ自身の時刻を参照する設定です。

設定を行った後は、サービスを再起動させて設定を読み込ませます。

$ sudo systemctl restart ntp.service

最後に、Ubuntu MATE起動時にntpサービスが自動的に起動されるかを確認します。以下を実行して、enabled と表示されることを確認してください。

$ systemctl is-enabled ntp.service
enabled

もし、enabled と表示されなかった場合、以下を実行してください。

$ sudo systemctl enable ntp.service
...

おまけ:Grafana

可視化ならGrafana

今回の実験ではInfluxDBのサーバ管理ツールを使用してグラフを表示しましたが、可視化ツールとしては、Grafanaというソフトウエアがよく利用されます。
Grafanaは非常に柔軟に様々なデータベースの可視化が可能であり、InfluxDBのデータ可視化も可能です。

InfluxDBのサーバ管理ツールは、あくまで管理ツールであるため可視化以外の操作もできてしまいますが、Grafanaは可視化ツールであるためグラフ表示に特化しており、非常に使い勝手がよいです。

Grafanaを使用するには、別途インストールが必要です。

GrafanaにはFluxクエリの直接入力が必要

ただ、今回Grafanaを使用しなかったのは、InfluxDB v2系を利用したためです。

InfluxDB v1系でのデータベースの問い合わせ文(クエリと呼ぶ)は、データベースシステムで標準的に使用されるSQL言語に似た InfluxQL という言語を使用していましたが、v2系では Flux という全く新しい言語に置き換わりました。GrafanaもFlux言語には対応していますが、それが試験的であることと、著者がFluxに関して知識不足のため、Grafanaは使用しませんでした。

Grafanaでは、InfluxDB v2系のグラフィカルな画面でのグラフ作成が行えないようで(これが「試験的」の理由?)、直接Flux言語のクエリを入力してグラフ作成する必要があります。
このため、Flux言語をある程度理解していないと、Grafanaでグラフ作成することができません。

InfluxDBでグラフ作成とFluxクエリ表示、Grafanaにペースト

ただ、上で行ったように、InfluxDBのサーバ管理ツールなら、グラフィカル画面でバケット(my_bucketなど)やメジャメント(w1_tempなど)をマウスでクリックして選択するだけでグラフ作成が行えましたので(裏側ではFlux言語のクエリが作成されていました)、これを利用して、少し手間にはなりますが、以下の方法でGrafanaでの可視化が実現できます。

  1. InfluxDBで、グラフィカル画面にてグラフ作成(上で実施したとおり) →裏側ではFluxクエリが生成されている
  2. 作成したグラフのFlux言語のクエリを表示する
  3. このクエリをクリップボードへコピーする
  4. Grafanaのグラフ作成画面で、Flux言語のクエリをペーストする → Grafanaでグラフが表示される

Grafanaのグラフ作成画面でFluxクエリのペースト
Grafanaのグラフ作成画面でFluxクエリのペースト

Grafanaでのグラフ表示
Grafanaでのグラフ表示

前半で示した「telegrafとInfluxDBの関係」にGrafanaを追加した図を以下に示します。

telegrafとInfluxDBとGrafanaの関係
telegrafとInfluxDBとGrafanaの関係

Discussion