#はじめに
Raspberry Piに、Telegraf、InfluxDB、Grafanaをインストールして、各種の情報を可視化していますが、今回は TelegrafのPlug Inを用いて、OpenWeatherMapのサービスから、場所を指定した地点の天気情報(現在+予想)を取得して、InfluxDBに蓄積し、Grafanaで可視化する試みを行いました。
参考にしたのは、githubにある、telegraf/README.mdの情報です。
#準備
##インストール
先にtelegraf、influxDB、Grafanaを、Raspberry Piにインストールしておきます。別の投稿などを参照。
##OpenWeatherMapのapi-keyを取得する
ここから、api-keyを取得します。
サインアップ
まず、アカウントの作成が必要です。ここから入って、画面の指示どおりに、必要事項の入力します。指定したメールアドレスに、確認が来るので、それをクリックして、アカウント作成は終了です。
API-Keyを画面上からコピー
得られたAPI-Keyをコピーしておきます。
##city-idを取得する。
登録されている場所の中に、自分が調べたい市町村があるかどうかを確認します。ここから、サーチします。
地名を、アルファベットで入力して、searchすると、地名が登録されていれば、以下のように表示されます。見つからない場合は、近くの地名で試してみるとよいかもしれません。
私の調べたいのは、ひとつめの場所なので、ここをクリックすると、以下のように表示されます。このURLの最後の数字が、city-idになります。私の場合は、1861949です。
##telegrafを設定する。
Raspberry Piの terminalから、telegrafの設定ファイルを変更します。設定ファイルは、/etc/telegraf/telegraf.confです。sudo しないと編集できません。6000行以上ある設定ファイルですが、この中の、openweathermapの設定を探します。vi なら、/openweathermap で出来ます。
$ sudo vi /etc/telegraf/telegraf.conf
openweathermapに関連する設定は、これだけです。
# # Read current weather and forecasts data from openweathermap.org
# [[inputs.openweathermap]]
# ## OpenWeatherMap API key.
# app_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
#
# ## City ID's to collect weather data from.
# city_id = ["5391959"]
#
# ## Language of the description field. Can be one of "ar", "bg",
# ## "ca", "cz", "de", "el", "en", "fa", "fi", "fr", "gl", "hr", "hu",
# ## "it", "ja", "kr", "la", "lt", "mk", "nl", "pl", "pt", "ro", "ru",
# ## "se", "sk", "sl", "es", "tr", "ua", "vi", "zh_cn", "zh_tw"
# # lang = "en"
#
# ## APIs to fetch; can contain "weather" or "forecast".
# fetch = ["weather", "forecast"]
#
# ## OpenWeatherMap base URL
# # base_url = "https://api.openweathermap.org/"
#
# ## Timeout for HTTP response.
# # response_timeout = "5s"
#
# ## Preferred unit system for temperature and wind speed. Can be one of
# ## "metric", "imperial", or "standard".
# # units = "metric"
#
# ## Query interval; OpenWeatherMap updates their weather data every 10
# ## minutes.
# interval = "10m"
この中の、app_idに先ほど取得したAPI-Keyを記入し、city_idに、先ほど取得したcity_idを入力し、表示言語を選択(日本語ならja)します。必要な設定をした結果は、以下のとおりです。
# # Read current weather and forecasts data from openweathermap.org
[[inputs.openweathermap]]
# ## OpenWeatherMap API key.
app_id = "9d1eaaaac************"
#
# ## City ID's to collect weather data from.
city_id = ["1861949"]
#
# ## Language of the description field. Can be one of "ar", "bg",
# ## "ca", "cz", "de", "el", "en", "fa", "fi", "fr", "gl", "hr", "hu",
# ## "it", "ja", "kr", "la", "lt", "mk", "nl", "pl", "pt", "ro", "ru",
# ## "se", "sk", "sl", "es", "tr", "ua", "vi", "zh_cn", "zh_tw"
lang = "ja"
#
# ## APIs to fetch; can contain "weather" or "forecast".
fetch = ["weather", "forecast"]
#
# ## OpenWeatherMap base URL
# # base_url = "https://api.openweathermap.org/"
#
# ## Timeout for HTTP response.
# # response_timeout = "5s"
#
# ## Preferred unit system for temperature and wind speed. Can be one of
# ## "metric", "imperial", or "standard".
units = "metric"
#
# ## Query interval; OpenWeatherMap updates their weather data every 10
# ## minutes.
interval = "10m"
##telegrafを再起動します。
再起動後、statusで、正しく再起動できたかどうかを確認します。設定ファイルに何らかの間違いがある場合には、エラーが表示されます。
$ sudo systemctl restart telegraf
$ sudo systemctl status telegraf
さて、これで、telegrafは起動していることが確認できました。設定にはエラーがなさそうですが、どうやってデータを取得するのでしょう。
influxでデータベースを確認します。
しばらく待って influxdbを確認します。更新が10分毎なので、スタート直後にはデータはありません。
influxコマンドで、開いて、show measurementsをすると、weatherというmeasurement(テーブル)が生成されていました。
$ influx
Connected to http://localhost:8086 version 1.8.0
InfluxDB shell version: 1.8.0
> use telegraf
Using database telegraf
> show measurements
name: measurements
name
----
cpu
cpu_frequency
cpu_temperature
disk
diskio
kernel
mem
net
processes
swap
system
weather
> select * from weather limit 5
name: weather
time city city_id cloudiness condition_description condition_icon condition_id condition_main country forecast host humidity pressure rain sunrise sunset temperature visibility wind_degrees wind_speed
---- ---- ------- ---------- --------------------- -------------- ------------ -------------- ------- -------- ---- -------- -------- ---- ------- ------ ----------- ---------- ------------ ----------
1591056576000000000 Ichinomiya 1861949 75 曇りがち 04d 803 Clouds JP * rpi3bp001 88 1009 0 1591040351000000000 1591092164000000000 24.25 10000 0 0.5
1591066800000000000 一宮市 1861949 43 雲 03d 802 Clouds JP 3h rpi3bp001 56 1009 0 27.74 273 1.97
1591077600000000000 一宮市 1861949 55 曇りがち 04d 803 Clouds JP 6h rpi3bp001 36 1007 0 29.98 270 4.5
1591088400000000000 一宮市 1861949 98 厚い雲 04d 804 Clouds JP 9h rpi3bp001 31 1008 0 28.63 284 2.83
1591099200000000000 一宮市 1861949 90 厚い雲 04n 804 Clouds JP 12h rpi3bp001 32 1008 0 25.53 332 2.14
>
一宮市の現在気温、予測気温、雲の予測、日の出、日の入り、湿度、気圧、風速、風向予測等のデータが格納されているようです。
#可視化
このデータを一つ一つ、自分でDashboardに作り上げても良いのですが、結構大変そうです。探して見ると、これをDashboardとして作って共有されているものがありましたので、それをまず使ってみます。
ダッシュボードのインポート
下記のように、ID番号 9710でインポートできそうです。
grafanaからインポート
+アイコンからインポートを選択し、IDを入力してloadします。
次の画面で、データベース名(この場合は、telegraf)を入力してimportを実行します。
ダッシュボードに表示
さて、何がわるいのでしょう・・
measurement名やフィールド名が合っていなかった。
一つ一つのパネルに記載されている、measurement名やフィールド名が、今回 telegrafからinfluxdbに書き込まれたものと一致していない事が判明。
インポートしたDashboardでは、measurement名が、 openweathermap なのに対して、influxdbに入っているのは、weatherというmeasurement名です。これを一つ一つに手入力し、併せてフィールド名も、一番近そうなモノを選んで表示してみたら、以下の表示になりました。
でも、全然結果がおかしい(気圧が914hPaっておかしいだろう・・)のと、10分後のupdateデータが入ってきていません。
なぜでしょう。
Dashboard番号、12368という、少し新しいものがありましたので、こちらで試してみると、measurement名やフィールド名は、私のtelegraf環境と一致しており、直ぐに可視化出来ました。しかし、値がおかしいのは同じです。
influxdbの中に入っているpressureは、1007程度を指しています。この値が、何故、ダッシュボードで 914hPaになってしまうのか。何か演算がおかしい気がします。
> select "pressure" from weather
name: weather
time pressure
---- --------
1591056576000000000 1009
1591060164000000000 914
1591066800000000000 1008
1591066800000000000 1008
1591077600000000000 1007
1591077600000000000 1007
1591088400000000000 1008
1591099200000000000 1008
1591110000000000000 1008
1591120800000000000 1007
1591131600000000000 1008
1591142400000000000 1008
1591153200000000000 1007
1591164000000000000 1006
1591174800000000000 1006
1591185600000000000 1007
1591196400000000000 1007
1591207200000000000 1006
1591218000000000000 1007
1591228800000000000 1007
1591239600000000000 1006
1591250400000000000 1005
1591261200000000000 1006
1591272000000000000 1008
1591282800000000000 1008
1591293600000000000 1008
1591304400000000000 1008
1591315200000000000 1008
1591326000000000000 1007
1591336800000000000 1006
1591347600000000000 1006
1591358400000000000 1008
1591369200000000000 1008
1591380000000000000 1007
1591390800000000000 1007
1591401600000000000 1007
1591412400000000000 1007
1591423200000000000 1006
1591434000000000000 1007
1591444800000000000 1009
1591455600000000000 1009
1591466400000000000 1009
1591477200000000000 1010
1591488000000000000 1011
>
> select * from weather limit 5
name: weather
time city city_id cloudiness condition_description condition_icon condition_id condition_main country forecast host humidity pressure rain sunrise sunset temperature visibility wind_degrees wind_speed
---- ---- ------- ---------- --------------------- -------------- ------------ -------------- ------- -------- ---- -------- -------- ---- ------- ------ ----------- ---------- ------------ ----------
1591060164000000000 Ichinomiya 1861949 29 雲 03d 802 Clouds JP * rpi3bp001 63 914 0 1591040351000000000 1591092164000000000 27.22 0 315 1.37
1591066800000000000 一宮市 1861949 43 雲 03d 802 Clouds JP 3h rpi3bp001 47 1008 0 28.35 273 1.97
1591077600000000000 一宮市 1861949 55 曇りがち 04d 803 Clouds JP 6h rpi3bp001 32 1007 0 30.24 270 4.5
1591088400000000000 一宮市 1861949 98 厚い雲 04d 804 Clouds JP 9h rpi3bp001 30 1008 0 28.71 284 2.83
1591099200000000000 一宮市 1861949 90 厚い雲 04n 804 Clouds JP 12h rpi3bp001 32 1008 0 25.54 332 2.14
>
データを見てみると、確かに 914hPaというのが、pressure の現在値として入っているようです。forecastの気圧は正しいのに・・・。
もう少し、時間をおいてから、再度データを取得してみます。
強制的に削除
1時間後に確認したら、現在値も正しい値で入ってきたので、どうも、起動直後の最初のレコードがおかしい気がします。
強制的に、influxの操作で対象レコードを削除してみます。消すべきタイムスタンプは、1591060164000000000です。
> select * from weather limit 10
name: weather
time city city_id cloudiness condition_description condition_icon condition_id condition_main country forecast host humidity pressure rain sunrise sunset temperature visibility wind_degrees wind_speed
---- ---- ------- ---------- --------------------- -------------- ------------ -------------- ------- -------- ---- -------- -------- ---- ------- ------ ----------- ---------- ------------ ----------
1591060164000000000 Ichinomiya 1861949 29 雲 03d 802 Clouds JP * rpi3bp001 63 914 0 1591040351000000000 1591092164000000000 27.22 0 315 1.37
1591063780000000000 Ichinomiya 1861949 75 曇りがち 04d 803 Clouds JP * rpi3bp001 61 1008 0 1591040351000000000 1591092164000000000 26 10000 0 1
1591066800000000000 一宮市 1861949 43 雲 03d 802 Clouds JP 3h rpi3bp001 45 1008 0 28.86 273 1.97
1591077600000000000 一宮市 1861949 55 曇りがち 04d 803 Clouds JP 6h rpi3bp001 31 1007 0 30.46 270 4.5
1591088400000000000 一宮市 1861949 98 厚い雲 04d 804 Clouds JP 9h rpi3bp001 29 1008 0 28.77 284 2.83
1591099200000000000 一宮市 1861949 90 厚い雲 04n 804 Clouds JP 12h rpi3bp001 32 1008 0 25.55 332 2.14
1591110000000000000 一宮市 1861949 39 雲 03n 802 Clouds JP 15h rpi3bp001 40 1008 0 23.11 342 2.08
1591120800000000000 一宮市 1861949 28 雲 03n 802 Clouds JP 18h rpi3bp001 48 1007 0 21.64 357 2.1
1591131600000000000 一宮市 1861949 88 厚い雲 04d 804 Clouds JP 21h rpi3bp001 49 1008 0 21.96 354 1.69
1591142400000000000 一宮市 1861949 87 厚い雲 04d 804 Clouds JP 24h rpi3bp001 37 1008 0 27.31 306 0.87
>
> delete from weather where "time"=1591060164000000000
> select * from weather limit 10
name: weather
time city city_id cloudiness condition_description condition_icon condition_id condition_main country forecast host humidity pressure rain sunrise sunset temperature visibility wind_degrees wind_speed
---- ---- ------- ---------- --------------------- -------------- ------------ -------------- ------- -------- ---- -------- -------- ---- ------- ------ ----------- ---------- ------------ ----------
1591063780000000000 Ichinomiya 1861949 75 曇りがち 04d 803 Clouds JP * rpi3bp001 61 1008 0 1591040351000000000 1591092164000000000 26 10000 0 1
1591066800000000000 一宮市 1861949 43 雲 03d 802 Clouds JP 3h rpi3bp001 45 1008 0 28.86 273 1.97
1591077600000000000 一宮市 1861949 55 曇りがち 04d 803 Clouds JP 6h rpi3bp001 31 1007 0 30.46 270 4.5
1591088400000000000 一宮市 1861949 98 厚い雲 04d 804 Clouds JP 9h rpi3bp001 29 1008 0 28.77 284 2.83
1591099200000000000 一宮市 1861949 90 厚い雲 04n 804 Clouds JP 12h rpi3bp001 32 1008 0 25.55 332 2.14
1591110000000000000 一宮市 1861949 39 雲 03n 802 Clouds JP 15h rpi3bp001 40 1008 0 23.11 342 2.08
1591120800000000000 一宮市 1861949 28 雲 03n 802 Clouds JP 18h rpi3bp001 48 1007 0 21.64 357 2.1
1591131600000000000 一宮市 1861949 88 厚い雲 04d 804 Clouds JP 21h rpi3bp001 49 1008 0 21.96 354 1.69
1591142400000000000 一宮市 1861949 87 厚い雲 04d 804 Clouds JP 24h rpi3bp001 37 1008 0 27.31 306 0.87
1591153200000000000 一宮市 1861949 84 曇りがち 04d 803 Clouds JP 27h rpi3bp001 29 1007 0 31.23 200 0.84
>
これでDashboardを確認すると、当然ですが、1008hPaという正しい数値が表示されました。もうしばらく、様子を見る事にします。
一時間に一回しかデータ取得されないのは何故?
ネットの情報を見ると、どうも他の方も同様の問題が発生しているらしいです。
念のために、ここを参考にして、telegrafのhttpからデータを取得して、influxdbに書き込んでみました。実験用に intervalを 1分にしてみて、データがどのように変化するか見てみました。
# Openweathermap
[[inputs.http]]
urls = [
"http://api.openweathermap.org/data/2.5/weather?id=XXXXX&units=metric&appid=XXXXX"
]
name_override = "openweathermap"
method = "GET"
interval = "1m"
timeout = "15s"
data_format = "json"
これで、influxからデータベースを見てみると、
> select * from openweathermap limit 1
name: openweathermap
time clouds_all cod coord_lat coord_lon dt host id main_feels_like main_humidity main_pressure main_temp main_temp_max main_temp_min sys_id sys_sunrise sys_sunset sys_type timezone url visibility weather_0_id wind_deg wind_speed
---- ---------- --- --------- --------- -- ---- -- --------------- ------------- ------------- --------- ------------- ------------- ------ ----------- ---------- -------- -------- --- ---------- ------------ -------- ----------
1591072860000000000 75 200 35.3 136.8 1591072620 rpi3bp001 1861949 29.64 51 1006 28 28 28 8009 1591040351 1591092164 1 32400 http://api.openweathermap.org/data/2.5/weather?id=1861949&units=metric&appid=9d1eaaaacb81c160be33d48c9c891ad9 10000 803 250 1
>
のように、各フィールド名が先に試したDashboard番号 9710の設定と同じなので、こちらのDashboardを再度試してみる事にしました。
毎分、apiにアクセスして influxdbに書き込み、可視化してみましたが、結果は10分に一回、サーバー側で更新されていることが分かりますので、毎分APIを呼んでもやはり意味はなさそうです。APIコールは5分に1回に変更します(/etc/telegraf/telegraf.confで intervalを修正)。
ただ、致命的に残念な事に、結果がめちゃめちゃです。
気温が33度越え、気圧が912hPaという数字は実際の数値とはかけ離れており、全然使い物になりません。
なぜ、こんなにひどいのか・・・。場所の指定がだめなのか? その懸念を確認するために、例えばニューヨーク(city-ID : 5128581) だったらどうなのか? 確認してみます。複数の場所を同時に取得する方法があるので、そちらを使います。(ニューヨークと東京で試してみます)
# Openweathermap
[[inputs.http]]
urls = [
"http://api.openweathermap.org/data/2.5/group?id=5128581,1850144&units=metric&appid=9d1eaaaac*****"
]
name_override = "openweathermap"
method = "GET"
interval = "1m"
timeout = "15s"
data_format = "json"
この方法を取ると、フィールド名も変更されるので、Dashboardの設定も変更が必要になりますが、確認してみます。フィールド名は、以下のようになります。list_0_から始まるのが最初に指定したNew Yorkの情報、list_1から始まるのが二つ目に指定した東京の情報です。
$ influx
> use telegraf
> show field keys
途中を略
name: openweathermap
fieldKey fieldType
-------- ---------
cnt float
list_0_clouds_all float
list_0_coord_lat float
list_0_coord_lon float
list_0_dt float
list_0_id float
list_0_main_feels_like float
list_0_main_humidity float
list_0_main_pressure float
list_0_main_temp float
list_0_main_temp_max float
list_0_main_temp_min float
list_0_sys_sunrise float
list_0_sys_sunset float
list_0_sys_timezone float
list_0_visibility float
list_0_weather_0_id float
list_0_wind_deg float
list_0_wind_speed float
list_1_clouds_all float
list_1_coord_lat float
list_1_coord_lon float
list_1_dt float
list_1_id float
list_1_main_feels_like float
list_1_main_humidity float
list_1_main_pressure float
list_1_main_temp float
list_1_main_temp_max float
list_1_main_temp_min float
list_1_sys_sunrise float
list_1_sys_sunset float
list_1_sys_timezone float
list_1_visibility float
list_1_weather_0_id float
list_1_wind_deg float
list_1_wind_speed float
一応、データは取れますが・・・・
前のIchinomiyaに比べると、とんでもないデータは無いように見えますが、ほぼ1時間単位でしか情報に変化が無く、細かい変化は、やはり取れません。apiへのアクセスインターバルを、上記の設定のように1分にしてみても、データの変化は、結局1時間に一回程度でした。(途中でバタバタ、異様にバウンスするデータも見受けられます)
#おわりに、
「TelegrafのPluginで OpenWeatherMapから天気情報を取得し、InfluxDBに記録し、Grafanaで可視化する」というテーマに対しては、一応実現出来た事になりますが、そもそも、OpenWeatherMapから得られる情報が信頼性に欠ける面もあるので、継続して、別のWeather APIで何かいい所が無いかを探して見たいと思います。
残念・・・