3月も下旬にさしかかり、うららかな陽気に心躍る季節となりました
いよいよ桜の開花も近づいてきましたね。
今回はそんなワクワク桜の開花予報をSlackへ通知してみようと思います🌸
完成イメージ
sustenでは毎朝天気などともに始業をお知らせしてくれる "sustenくん" というSlackBotがいます。
こちらに桜の開花予報通知機能(赤枠部分)を追加してみることにします。
こんな通知が毎朝通知がくれば 陰鬱な始業時間でも 朝からワクワクが止まらないことこの上なしですね!!
どうやって予測するのか
桜の開花に関する法則で「桜の開花600度の法則」という有名な法則があります。
これは、2月1日から毎日の最高気温を足していき、その累積が600度になったときに桜が開花するというものです。
今回はこの法則に従って2月以降の累積温度を計算し桜開花600度まであとどのくらいかSlackに通知することにします。
実装の流れ
お手軽に定時実行を行いたかったため GoogleAppsScript を利用した実装を行います。
- 気象庁のページから2/1から前日までの最高気温を取得(初回のみ)
- 気象庁のページから前日の最高気温を取得(デイリー)
- 取得した気温に当日の最高気温(予想)を足し合わせる
- 桜開花の進捗をSlackへ通知
前日の最高気温を取得する処理
気象庁のページでは気象に関する様々な情報を提供してくれています。
これらのデータは毎日5時、11時、17時の発表に基づいて更新されます。
今回はGASのParserというライブラリを用いて東京都の過去天気ページをクロールし、前日の最高気温を取得することにします。
/*
* 気象庁のページから前日の最高気温を取得する
*/
function _getYesterdayMaxTemperature() {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth() + 1;
const TARGET_URL = `https://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?prec_no=44&block_no=47662&year=${year}&month=${month}&day=&view=p1`;
// 指定したURLからコンテンツを取得
const html = UrlFetchApp.fetch(TARGET_URL).getContentText();
// 取得したコンテンツデータから気象情報をフィルタする
const rows = Parser.data(html)
.from(
'<tr class="mtx" style="text-align:right;">'
)
.to("</tr>")
.iterate();
// テーブル内の最高気温(8列目のデータ)をすべて抜き出して数値が入っているものだけ抜き出す
const maxTemps = rows.map(row => row.split("</td>")[7].split('">')[1]).filter(data => data !== "");
// 一番最後のものが直近(昨日のデータのはず)なので返却する
return maxTemps.slice(-1)[0];
}
このような処理で前日の最高気温を取得してスプレッドシートに記録を行っており、累積気温はスプレッドシート側で計算させています。
かなり雑なコードですが社内用なので大目に見てください🙈
スプレッドシートには記録せずにreduceで足し合わせてもよいのですが、月またぎの処理が面倒くさそうだったので今回はスプレッドシードに記録する方法を採用しました。
桜開花の進捗をSlackへ通知
次にSlackへの通知部分を実装してきましょう!
/*
* 桜開花状況をSlackへ通知する
*/
function notifyCherryTreeBloom() {
const MAX = 600;
const sheet = SpreadsheetApp.openById("xxxxxxxxxxxxxx").getSheetByName("cherry_blossom");
// シートから累積気温(実績)を取得
const total = sheet.getRange("B1").getValue();
// シートから今日の気温(予測)を取得
const today = sheet.getRange("D1").getValue();
// Slackに投稿するメッセージの組み立て
const percent = Math.floor(((today + total) / MAX) * 100);
const remain = Math.floor(((MAX - (today + total)) * 10) / 10);
const cumulativeTemperature = Math.floor((today + total) * 10) / 10;
const graph = [...Array(100 / 5)].map((_, i) =>
(i + 1) * 5 <= percent ? "▓" : "▒"
);
let message = "";
message += `2/1からの累積温度は ${cumulativeTemperature} ℃ :chart-up:\n`;
// 累積気温が600度を超えていたら開花宣言
if (MAX <= cumulativeTemperature) {
message +=
":cherry_blossom::cherry_blossom: さくらは開花しています!! :cherry_blossom::cherry_blossom:";
} else {
message += `さくらの開花まであと ${remain} ℃ :exclamation:\n`;
message += `:seedling: 0 ℃ [` + graph.join("") + "] 600 ℃:cherry_blossom:";
}
return message;
}
まとめ
記録したデータを基に日々の気温と累積気温をグラフにしてみました。
東京では3月18日に600度を超えてますが、この記事を書いている2024/03/26時点でまだ開花の発表はありません。
見事に外れてますが人生そんなもんです。