📈

複数ソース(SwitchBot, OpenWeater,etc)からの温度・湿度情報をInfluxDBに保存してGrafanaで表示する

2024/06/25に公開

今年も暑い

“今日も暑ーい1日になりそうです” ほら言ってる わっ超あおられる ♪

ほんとテレビのニュースをみると暑いって話ばかり。なので家で安全に過ごしたい。外に出る場合も温度や温度を把握しておきたい。

参考にした記事

次のデバイス or APIから温度あるいは湿度の情報を得て

次の記事で InfluxDBv2 に格納し Grafana で可視化することができる。

https://qiita.com/yoroyasu/items/56e687df4e8970c5e49a

https://zenn.dev/tanny/articles/a5c0fa5c2230a7

https://qiita.com/hkato/items/173e1008cbec8054787b

やりたいこと

私は SwitchBot Hub2TEMPer も所有してるので、OpenWeather 含め、これらの温湿度情報まとめて表示したい。

Grafana から InfluxDB の Flux Query

Fluxを良くわかってないので間違っているかもしれません。とりあえずユニオンすれば良いかなぁとやって出来たので…他に良い方法があるのかもしれませんが…。

SwitchBotの記事の様に単一の情報元なら次の様なクエリーでGrafanaに表示できる。

from(bucket: "switchbot")
  |> range(start: v.timeRangeStart, stop:v.timeRangeStop)
  |> filter(fn: (r) =>
    r._measurement == "MeterPlus" and
    r._field == "humidity"
  )

じゃあ複数をまとめるには?

fromで取得したデータはstreamという様なので、各情報を一旦streamに入れる。

OpenWeatherMap

上記のOpenWeatherの参考記事の様にTelegrafのOpenWeatherMap PlugIn で取得しているのでCPU, MEMなどの情報も入っている。ここから私はraspiという名前のバケットに格納した。_measurementweatherに天気情報が入っているがcpu, memなども入っているのでweatherでフィルタし、温度の場合はtemperatureでフィルタする。後でまとめるセンサーのデータと混ぜるとcity,condition_nameなどが邪魔になるので最低限必要なカラムだけキープする。

openweathermap = 
from(bucket: "raspi")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "weather")
  |> filter(fn: (r) => r["_field"] == "temperature")
  |> keep(columns: ["_measurement", "_field", "_time", "_value"])

SwitchBot

上記のSwitchBotの参考記事のやり方で行い、switchbotバケットに入れているのと、私は複数デバイスを持っているのでtemperatureだけでフィルタした。

switchbot =
from(bucket: "switchbot")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_field"] == "temperature")

TEMPer

こちらも同様。

temper = 
from(bucket: "temper")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_field"] == "temperature")

まとめる

unionでまとめて必要なカラムだけ残す。

union(tables: [openweathermap, switchbot, temper])

結果

openweathermap = 
from(bucket: "raspi")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "weather")
  |> filter(fn: (r) => r["_field"] == "temperature")
  |> keep(columns: ["_measurement", "_field", "_time", "_value"])

switchbot =
from(bucket: "switchbot")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_field"] == "temperature")

temper = 
from(bucket: "temper")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_field"] == "temperature")

union(tables: [openweathermap, switchbot, temper])

同様に湿度はhumidityでフィルタ。

凡例の名前を変える

下記のGrafanaフォーラムに書かれた方法の通りの手順で凡例名(Legend names)をわかりやすい名前に変えていく(家族も見るので)。

https://community.grafana.com/t/grafana-time-series-mqtt-legend-names-change/72506

できたグラフ

QNAPでGradana+InfluxDBを動かしReverse Proxyで公開してるので外からスマフォ画面で。

もろもろ

  • Flux Queryがこれで良いのかどうか不明なので勉強する
  • 夏に負けない

Discussion