複数ソース(SwitchBot, OpenWeater,etc)からの温度・湿度情報をInfluxDBに保存してGrafanaで表示する
今年も暑い
“今日も暑ーい1日になりそうです” ほら言ってる わっ超あおられる ♪
ほんとテレビのニュースをみると暑いって話ばかり。なので家で安全に過ごしたい。外に出る場合も温度や温度を把握しておきたい。
参考にした記事
次のデバイス or APIから温度あるいは湿度の情報を得て
- OpenWeather (Cloud API)
- SwitchBot温湿時計シリーズ (IoTデバイス)
- TEMPer温度計 (USBデバイス)
次の記事で InfluxDBv2 に格納し Grafana で可視化することができる。
やりたいこと
私は SwitchBot Hub2 も TEMPer も所有してるので、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
という名前のバケットに格納した。_measurement
のweather
に天気情報が入っているが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)をわかりやすい名前に変えていく(家族も見るので)。
できたグラフ
QNAPでGradana+InfluxDBを動かしReverse Proxyで公開してるので外からスマフォ画面で。
もろもろ
- Flux Queryがこれで良いのかどうか不明なので勉強する
- 夏に負けない
Discussion