気象衛星ひまわりとは
気象庁が開発した気象衛星です。静止軌道にいるため、常に地球の同じ位置を観測することができます。
観測データが高頻度化、高分解能化、観測波長も増えたおかげで、膨大なデータを得ることができ、気象予報の精度向上に役立っています。
ひまわりの画像が見たい
先日Twitter(X)で、円形ディスプレイとRaspberry Piを使って、気象衛星ひまわりが撮像した画像をリアルタイムで表示しているツイート(ポスト)が流れてきました。
きれい!欲しい!これ作りたい!思い立ったが吉日、その日のうちに円形ディスプレイを購入しました。
設計方針
- 頑張らない
- 難しいことはしない
- 早く作る
- かっこよく作る
ここは趣味なのでこれでいきましょう。
システム設計
図のような構成で作ります。
ディスプレイに表示するためのGUIは悩みましたが、HTMLとJavascriptで作成し、Chromiumのkioskモードを使用して表示することにしました。
これなら外部サーバに置いておき、定期的に見に行くだけで良いのでデバッグやメンテナンスが楽です。必要なら他の情報も書き足せます。
円形ディスプレイのほうは、まずはサイズ感。存在感を出したかったので5inchを選びました。
また、DSI接続のものとHDMI接続のものがありますが、汎用性を考慮するとHDMI接続のほうが楽です。
用意するもの
- 円形ディスプレイ
Aliexpress で購入。インタフェースの詳細は以下
https://www.waveshare.com/wiki/5inch_1080x1080_LCD - Raspberry Pi
ご家庭に4-5台は転がっているRaspberry Pi。今回はRaspberry Pi 3Bを使用。高い性能は不要。 - その他
電源、ケーブル等
画像取得元
実はここが一番大変だった。公式ページにはAPIが載っていない。
NICTの公開ページからデータをもらってくることにしました。
ひまわり8号リアルタイムWeb
また、このページから入手できるデータは、550pixの正方形画像に分割されています。
※ちなみに最高解像度では、連結後の1画像で130MBもありました。でかすぎ。
プログラム
Javascript で作成します。
function GenerateImgSrc(){
var now = new Date (+new Date() - (30 * 60 * 1000)); // 30分前の時刻を取得
var year = now.getUTCFullYear();
var month = (now.getUTCMonth() + 1).toString().padStart( 2, '0'); // ゼロ埋め
var day = now.getUTCDate().toString().padStart( 2, '0'); // ゼロ埋め
var hour = now.getUTCHours().toString().padStart( 2, '0'); // ゼロ埋め
var min = now.getUTCMinutes();
min = Math.floor(min/10)*10; // 撮像時刻は10分毎
min = ('00' + min).slice( -2 ); // ゼロ埋め
let url = 'https://himawari8-dl.nict.go.jp/himawari8/img/D531106/4d/550/' + year + '/' + month + '/' + day + '/' + hour + min +'00';
// 画像のソースを設定
var elem = document.getElementById("image00");
elem.src = url + '_0_0.png';
var elem = document.getElementById("image01");
elem.src = url + '_0_1.png';
var elem = document.getElementById("image02");
elem.src = url + '_0_2.png';
var elem = document.getElementById("image03");
elem.src = url + '_0_3.png';
var elem = document.getElementById("image10");
elem.src = url + '_1_0.png';
var elem = document.getElementById("image11");
elem.src = url + '_1_1.png';
var elem = document.getElementById("image12");
elem.src = url + '_1_2.png';
var elem = document.getElementById("image13");
elem.src = url + '_1_3.png';
var elem = document.getElementById("image20");
elem.src = url + '_2_0.png';
var elem = document.getElementById("image21");
elem.src = url + '_2_1.png';
var elem = document.getElementById("image22");
elem.src = url + '_2_2.png';
var elem = document.getElementById("image23");
elem.src = url + '_2_3.png';
var elem = document.getElementById("image30");
elem.src = url + '_3_0.png';
var elem = document.getElementById("image31");
elem.src = url + '_3_1.png';
var elem = document.getElementById("image32");
elem.src = url + '_3_2.png';
var elem = document.getElementById("image33");
elem.src = url + '_3_3.png';
}
解説
ひまわり画像のURLは以下のようになっています。
https://himawari8-dl.nict.go.jp/himawari8/img/D531106/4d/550/yyyy/mm/dd/hhmmss_y_x.png
-
https://himawari8-dl.nict.go.jp/himawari8/img/
ここまでがベースラインのURLです。NICTが配付してるんですね。 - D531106
センサの名前のようですが、詳細は不明です。他の観測データもあるみたいです。 - 4d
分割数。[1,4,8,16,20]の5段階? - 550
1タイルの幅。 - yyyy/mm/dd/hhmmss_y_x
画像データの日付とタイルの位置(x,y)です。
UTCで、10分間隔でデータが存在します。
時刻の取得
var now = new Date (+new Date() - (30 * 60 * 1000)); // 30分前の時刻を取得
ひまわりの最新画像の時刻は、以下のURLからjson形式で取得できます。
https://himawari8-dl.nict.go.jp/himawari8/img/D531106/latest.json
ですが、ブラウザ上でJavascriptを実行するとCORSポリシー(クロスドメインエラー)によりはじかれます。
頑張らない方針なので、ここは諦めて30分程度前の画像を得ることにします。
画像の設定
// 画像のソースを設定
var elem = document.getElementById("image00");
elem.src = url + '_0_0.png';
HTML上のimg.srcに、画像のURLを設定します。
HTML
シンプルです。10分に1回、自動でリロードさせます。
<html>
<head>
<title>Himawari</title>
<script src="GetHimawariUrl.js"></script>
<meta http-equiv="refresh" content="600; URL=">
</head>
<body onload = "GenerateImgSrc()">
<img id = "image00" src="" vertical-align="0" width="270"><!--
--><img id = "image10" src="" vertical-align="0" width="270"><!--
--><img id = "image20" src="" vertical-align="0" width="270"><!--
--><img id = "image30" src="" vertical-align="0" width="270"><!--
--><br><!--
--><img id = "image01" src="" vertical-align="0" width="270"><!--
--><img id = "image11" src="" vertical-align="0" width="270"><!--
--><img id = "image21" src="" vertical-align="0" width="270"><!--
--><img id = "image31" src="" vertical-align="0" width="270"><!--
--><br><!--
--><img id = "image02" src="" vertical-align="0" width="270"><!--
--><img id = "image12" src="" vertical-align="0" width="270"><!--
--><img id = "image22" src="" vertical-align="0" width="270"><!--
--><img id = "image32" src="" vertical-align="0" width="270"><!--
--><br><!--
--><img id = "image03" src="" vertical-align="0" width="270"><!--
--><img id = "image13" src="" vertical-align="0" width="270"><!--
--><img id = "image23" src="" vertical-align="0" width="270"><!--
--><img id = "image33" src="" vertical-align="0" width="270"><!--
--></body>
</html>
Raspberry Piの設定
以下を参考に、Raspberry Pi が起動すると、自動的にChromiumをkioskモードで起動するよう設定します。
結果
※画面サイズ1080x1080に対して、HTMLの要素が1080以上あるようで、微妙にスクロールしてしまう。消し方が分からないので、width=270を、269に減らした。(消し方分かる方いたら教えて欲しい)
おまけ
夜にデバッグしているとほとんどの時間で地球が真っ暗でつまらなかったので、以下を参考に時計機能を付けました。
クリックすると時計が表示され、もう一度クリックすると消えます。
(ライセンスが記載されてないのでここには転記しません)
https://www.nishishi.com/javascript-tips/realtime-clock-setinterval.html
次は赤外画像の取得したいところ。。。
謝辞
気象庁(JMA)
情報通信研究機構(NICT)
の公開データを利用させていただきました。