はじめに
Siemens社オープンクラウドプラットフォーム "Insights Hub(旧名称 Mindsphere)" を利用して、石川県金沢市の気象情報(気圧、気温、湿度、風速、日照時間)を定期的に取得しデータ保存およびDashboard(折れ線グラフなど)表示に挑戦してみました。
今回のグラフ表示目標
以下のようなグラフ表示を目指します。
「気圧、気温、湿度、風速、日照時間」の前日分の折れ線グラフ表示と最大値or平均値等の表示です
データ取得対象
〇対象:「石川県 金沢市」の「過去の気象データ検索」、「10分ごとの値」
項目は気圧(現地)、気温、湿度、風速(最大)、日照時間の5項目とします。
「10分ごとの値」ですので1日に144件あります。
〇処理タイミング: 気象庁のサーバに負荷をかけないよう、
1日1回午前中に前日のデータを取得する処理とします。
〇リンク先 例 2024年2月27日
https://www.data.jma.go.jp/obd/stats/etrn/view/10min_s1.php?prec_no=56&block_no=47605&year=2024&month=2&day=27&view=
以下、少々長くなりますが、設定について説明させていただきます。
「事前準備」、「VisualFlowCreatorでの処理の構築」、「DashboardDesighnerでの設定」と進んでまいります。
事前準備 弊社で契約している"Insights Hub" 環境に Asset を作成します。
手順としては以下となります。
【1】Aspectを作成
・Datapoint01からDatapoint05までの5項目を属性doubleで作成
今回は汎用的な名称で作成しました。
汎用的な名称にするメリットはAspectの使いまわしによる設定工数の削減、
デメリットは、Dashboardによる可視化やファイルデータ活用の際、
項目の内容がわからないので、手元に読替用のメモが必要になることです。
【2】AssetType Datapoint01-05 を作成
【3】Assetを作成 Typeを利用してDatapoint01_05_Kanazawaを作成
Datapoint01に気圧(現地)、Datapoint02に気温、Datapoint03に湿度、Datapoint04に風速(最大)、Datapoint05に日照時間を割り当てする方針です。
VisualFlowCreatorでの処理の構築 フローの全体図
VisualFlowCreatorはInsights Hubで利用できるNode-REDとなります。
・1段目 「日付とURLの編集」、「HttpRequest」、「Html編集」
・2段目 「データのバックアップ」、「数値セット」、「Assetへのデータ保存」
に分かれております。
VisualFlowCreatorでの処理 1段目
【1】「Inject処理」
・Repeat(繰り返し) に at a specific time
(処理起動を手動にしたいときはNoneにします)
・at(時刻) に 09:00
・Timezone に Browser(Asia/Tokyo)
・OnWeekday すべての曜日にチェックをつけています
以下の処理をしております。
var urls = [];
const today = new Date();
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
var yy = yesterday.getFullYear();
var mm = ("00" + String(yesterday.getMonth() + 1)).slice(-2);
var dd = ("00" + String(yesterday.getDate())).slice(-2);
urls = "https://www.data.jma.go.jp/obd/stats/etrn/view/10min_s1.php?prec_no=56&block_no=47605&year=" + yy + "&month=" + mm + "&day=" + dd +"&view=";
msg.url = urls;
return msg;
・2行目 todayを取得
・3行目 yesterdayを計算 (todayから1日マイナス)
・5行目 yesterdayのyy(年)を編集しています
・6行目 yesterdayのmm(月)を編集しています
・7行目 yesterdayのdd(日)を編集しています
・8行目 Urlsに「石川県金沢市ー過去の気象データ検索ー10分ごとの値」の固定値
上記で計算したyy,mm,dd をセットしています。
※金沢の場合、prec_no=56&block_no=47605 となっています。
東京の場合は、prec_no=44&block_no=47662 で取得できると思います。
・9行目 msg.urlにUrlsをセットしています。
・Method に 「Get」を指定
・Return に 「UTF-8 string」を設定
【4】「Html編集」
・Selectorには .data2_s と tr と tdを設定
・outputは only the text・・・ 要素のテキストのみ
as a message・・・ 配列化した1つのメッセージ
【ご参考】Selector の data2_s について
「石川県金沢市 - 過去の気象データ検索 -10分ごとの値」ページのソース表示を実施した以下の 78行目に .data2_s があり、今回Selectorに設定しました。
【5】「Html編集」の後をdebugノードで表示
以下の通り、1544個のメッセージが出ていることがわかります。
●0項目目から10項目目が 0:10時点のデータとなっております。
・0項目目 00:10 が 時刻
・1項目目 1016.2 が 気圧(現地)
・4項目目 3.8 が 気温
・5項目目 92 が 湿度
・8項目目 2.8 が 風速 (最大)
・10項目目 "" が 日照時間(夜中のため数値は入っていません)
●11項目目から22項目目が 0:20時点のデータ となります
●144分 × 11項目 = 1584件 のデータが抽出できたことになります。
VisualFlowCreatorでの処理 2段目
【1】「データの退避」
・msg.payloadのデータをmsg.dataに退避します
以下に上記内容を表記しました。もう少し短いロジックになればよかったのですが、、、
ご容赦ください。
msg.topic = "xxxxxxxxx/Datapoint01_05";//asset id/aspect名
var ix1=0;
var ix2=0;
var values = [];var date = [];var unixTime = [];
var hh = [];var mm = [];var utc = [];
const today = new Date();
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
for (ix1 = 0; ix1 < msg.data.length;) {
hh = msg.data[ix1].substring(0,2);
mm = msg.data[ix1].slice(-2);
date = new Date(yesterday.getFullYear(), yesterday.getMonth(), yesterday.getDate(), hh, mm, 0);
utc = new Date(date.getTime() + (-540 * 60 * 1000));
unixTime = Math.floor(date.getTime() / 1000);
if( isNaN(msg.data[ix1 + 10]) == true){ msg.data[ix1 + 10] = 0;}
if( isNaN(msg.data[ix1 + 8]) == true){ msg.data[ix1 + 8] = 0;}
if( msg.data[ix1 + 10] == ""){ msg.data[ix1 + 10] = 0;}
values.push({ _time: utc, Datapoint01: msg.data[ix1 + 1], Datapoint02: msg.data[ix1 + 4], Datapoint03: msg.data[ix1 + 5], Datapoint04: msg.data[ix1 + 8], Datapoint05: msg.data[ix1 + 10]});
ix1=ix1+11;
ix2=ix2+1;
}
msg.payload = values;
return msg;
・1行目 msg.topicにAssetIdとAspect名称をセット ※xxxxxにはasset idをセット
・7行目 todayを取得
・8,9行目 yesterdayを計算 (todayから1日マイナス)
・11行目 For文 1544個のメッセージについて以下処理を実施
・12行目 時刻をhhにセット
・13行目 分をmmにセット
・14行目 dateに yesterday と hh と mm を統合した時刻情報をセット
・15行目 utc情報を計算 日本時間から世界時間へ変換(9時間(540分)マイナス)
・18行目 ・8項目目 風速 が Nan のとき 0をセット
・19行目 ・10項目目 日照時間 が Nanのとき 0をセット
・19行目 ・10項目目 日照時間 が ""のとき 0をセット
・20行目 Valuesに以下をセット
_time utc 15行目で計算した時刻情報
Datapoint01: msg.data[ix1 + 1] 1項目目 気圧(現地)
Datapoint02: msg.data[ix1 + 4] 4項目目 気温
Datapoint03: msg.data[ix1 + 5] 5項目目 湿度
Datapoint04: msg.data[ix1 + 8] 8項目目 風速 (最大)
Datapoint05: msg.data[ix1 + 10] 10項目目 日照時間
・21行目 indexに ix1に 11を加算
・22行目 indexに ix2に 1を加算
・24行目 msg.payload に valuesをセット;
上記の通り、
・Asset Datapoint01_05_Kanazawa
・Aspect Datapoint01_05
を選択します
。
DashboardDesighnerでの設定
次に、Dashboardの設定を実施します。
DashboardDesighnerはInsights Hubで利用できるGrafanaとなります。
DashboardDesighnerで
VisualFlowCreatorで処理し、Assetに保存したデータを呼び出します。
Dashboardでは「気圧、気温、湿度、風速、日照時間」を表示しています。
・「気温」の「折れ線グラフ表示」は以下のように行いました。
「Query」
「Series」欄で
「Datapoint01_05_Kanazawa」-「Datapoint01_05」-「Datapoint02」 を設定
「Function」 欄で
「alias(気温)」を設定 ・・・凡例表示が日本語で「気温」になります。
「Visualizaton」は「Graph」を選択
「Drawmodel」は「Line」をOn
・「気温」の「平均値の表示」について以下のように行いました。
「Visualizaton」は「Gauge」を選択
「Calc」を「Max(最大)」に設定しています
他に、「Last(最新値)」や「Mean(平均)」を選択可能です
「Query」は「気温」の「折れ線グラフ表示」と同じです
「Query」
「Series」欄で
「Datapoint01_05_Kanazawa」-「Datapoint01_05」-「」 を設定
・・・ 「」を設定することで「Datapoint01_05」の5項目すべてが出力対象になります。
「Visualizaton」は「Table」を選択
ちなみに、「Visualizaton」はいろいろとありますが、「Graph」、「Gauge」、「Table」を好んで使用しております
・前日、前々日の設定は以下で実施します。
・Dashboard右上のQuickRangeで「yesterday」を選択します。
Day before yesterday(前々日) などの設定も可能です。
おわりに
今後、今回作成したFlowをNode-REDに移植して動かしてみる予定です。
データをテキストファイルに保存、DashboardはNode-REDのノードでの作成を予定しています。
ちなみに、Insights hub上のVisualFlowCreatorでは処理計算時間に応じて課金が発生します。 弊社の環境では月に48時間まで、基本料金範囲内のプランとなっています。
2024年2月は約0.1時間(6分未満)でした。1日あたり10秒以下で処理できておりました。
留意点としては、気象情報のレイアウトが変更されてしまうと変更作業(VisualFlowCreator 2段目の【2】「数値セット」など)を実施する必要があるところです。