ノードと JavaScript だけで実現できるのか?
気象庁のアメダス情報を取得し、 PHP で1地点だけ情報を抽出する の記事では、 PHP を併用しながらアメダス要素を取得、 TC001 で表示させることにした。
しかし、この場合別途 PHP の動く環境を用意しなければならず、煩雑となる。
Node-RED で全部処理できれば、 Node-RED 環境だけを構築すればよいことになるので管理も楽になる。
フローや JavaScript の組み合わせで実現方法を模索する。
さほど難しくはないが、落とし穴がいくつかある
結論から言うと、問題なく実装することができた。
フロー図は以下の通りである。
URL の日時処理
1つ目、巻き戻し日時を含めた URL の日時であるが、まずは現在時刻の数値化が必要になる。これは getTime
を使えばよい。ただし、この数値は単位がミリ秒であることに注意(ハマった)。
あとは7分引いて YYYYMMDDhhmmss の形にしてやればよいが、ここで toLocaleString
のスウェーデンフォーマットがよいという情報を得る。なかなかトリッキーなやり方だが、一々年月日時分ごとに取り出さなくてよくなったので安堵。
スクリプトは以下のようになる。
var getdate = new Date();
var gettime = new Date().getTime() - 7*60*1000;
getdate.setTime(gettime);
var urltime = getdate.toLocaleString("sv-SE", { timeZone: "Asia/Tokyo" }).replace(/[^0-9]/g,"").slice(0,11) + "000"
var url = "https://www.jma.go.jp/bosai/amedas/data/map/" + urltime + ".json";
msg.payload = url;
return msg;
URL を http requrst へ渡す
続いてこの URL を http request にわたす方法だが、公式クックブックにある通り、 change ノードで msg.url に割り当て直せばよい(というか、そもそも function で msg.payload のかわりに msg.url へ代入すればよい)。
ただし、このクックブックの記述には落とし穴がある。
msg.URL
と書いてあるが、 url は大文字にしてはいけない。
もう一度書くと、 msg.URL
ではなく msg.url
としなければならない。
http request と parse
大文字小文字トラップを乗り越えたらもう一息である。
http request ノードは URL 空欄でよい。
JSON から要素を抜き出すのもさほど難しくはない。
アメダスの地点コードは数値扱いになってしまうが、頭が0の地点がないので問題は起きないだろう(地点コードを文字列で与えようと、数値で与えようと適当に処理してくれる)。
気温を取り出す際の下1桁の扱いが問題になるが、 toFixed(1)
で有効数字小数第1位まで(.0を付加)とすることができる。
完成です
あとは mqtt out ノードに繋いでやれば完成(ノードと実行例は省略)。
この方法だと PHP を用いる方法と違って、 JSON ファイルの読み込みは1回だけで、複数地点のアメダスデータを一気に取得することができる。
気象庁サーバーにかける負担も若干減らすことができるので、この方法が本来望ましいだろう。